Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v3.14 194 lines 5.5 kB view raw
1#include <linux/sched.h> 2#include <linux/errno.h> 3#include <linux/slab.h> 4 5#include <scsi/scsi.h> 6#include <scsi/scsi_eh.h> 7#include <scsi/scsi_device.h> 8 9#include "usb.h" 10#include "scsiglue.h" 11#include "transport.h" 12#include "smil.h" 13 14static int SM_SCSI_Test_Unit_Ready(struct us_data *us, struct scsi_cmnd *srb); 15static int SM_SCSI_Inquiry(struct us_data *us, struct scsi_cmnd *srb); 16static int SM_SCSI_Mode_Sense(struct us_data *us, struct scsi_cmnd *srb); 17static int SM_SCSI_Read_Capacity(struct us_data *us, struct scsi_cmnd *srb); 18static int SM_SCSI_Read(struct us_data *us, struct scsi_cmnd *srb); 19static int SM_SCSI_Write(struct us_data *us, struct scsi_cmnd *srb); 20 21/* ----- SM_SCSIIrp() -------------------------------------------------- */ 22int SM_SCSIIrp(struct us_data *us, struct scsi_cmnd *srb) 23{ 24 int result; 25 26 us->SrbStatus = SS_SUCCESS; 27 switch (srb->cmnd[0]) { 28 case TEST_UNIT_READY: 29 result = SM_SCSI_Test_Unit_Ready(us, srb); 30 break; /* 0x00 */ 31 case INQUIRY: 32 result = SM_SCSI_Inquiry(us, srb); 33 break; /* 0x12 */ 34 case MODE_SENSE: 35 result = SM_SCSI_Mode_Sense(us, srb); 36 break; /* 0x1A */ 37 case READ_CAPACITY: 38 result = SM_SCSI_Read_Capacity(us, srb); 39 break; /* 0x25 */ 40 case READ_10: 41 result = SM_SCSI_Read(us, srb); 42 break; /* 0x28 */ 43 case WRITE_10: 44 result = SM_SCSI_Write(us, srb); 45 break; /* 0x2A */ 46 47 default: 48 us->SrbStatus = SS_ILLEGAL_REQUEST; 49 result = USB_STOR_TRANSPORT_FAILED; 50 break; 51 } 52 return result; 53} 54 55/* ----- SM_SCSI_Test_Unit_Ready() ------------------------------------- */ 56static int SM_SCSI_Test_Unit_Ready(struct us_data *us, struct scsi_cmnd *srb) 57{ 58 if (us->SM_Status.Insert && us->SM_Status.Ready) 59 return USB_STOR_TRANSPORT_GOOD; 60 else { 61 ENE_SMInit(us); 62 return USB_STOR_TRANSPORT_GOOD; 63 } 64 65 return USB_STOR_TRANSPORT_GOOD; 66} 67 68/* ----- SM_SCSI_Inquiry() --------------------------------------------- */ 69static int SM_SCSI_Inquiry(struct us_data *us, struct scsi_cmnd *srb) 70{ 71 BYTE data_ptr[36] = {0x00, 0x80, 0x02, 0x00, 0x1F, 0x00, 0x00, 0x00, 72 0x55, 0x53, 0x42, 0x32, 0x2E, 0x30, 0x20, 73 0x20, 0x43, 0x61, 0x72, 0x64, 0x52, 0x65, 74 0x61, 0x64, 0x65, 0x72, 0x20, 0x20, 0x20, 75 0x20, 0x20, 0x20, 0x30, 0x31, 0x30, 0x30}; 76 77 usb_stor_set_xfer_buf(us, data_ptr, 36, srb, TO_XFER_BUF); 78 return USB_STOR_TRANSPORT_GOOD; 79} 80 81 82/* ----- SM_SCSI_Mode_Sense() ------------------------------------------ */ 83static int SM_SCSI_Mode_Sense(struct us_data *us, struct scsi_cmnd *srb) 84{ 85 BYTE mediaNoWP[12] = {0x0b, 0x00, 0x00, 0x08, 0x00, 0x00, 86 0x71, 0xc0, 0x00, 0x00, 0x02, 0x00}; 87 BYTE mediaWP[12] = {0x0b, 0x00, 0x80, 0x08, 0x00, 0x00, 88 0x71, 0xc0, 0x00, 0x00, 0x02, 0x00}; 89 90 if (us->SM_Status.WtP) 91 usb_stor_set_xfer_buf(us, mediaWP, 12, srb, TO_XFER_BUF); 92 else 93 usb_stor_set_xfer_buf(us, mediaNoWP, 12, srb, TO_XFER_BUF); 94 95 96 return USB_STOR_TRANSPORT_GOOD; 97} 98 99/* ----- SM_SCSI_Read_Capacity() --------------------------------------- */ 100static int SM_SCSI_Read_Capacity(struct us_data *us, struct scsi_cmnd *srb) 101{ 102 unsigned int offset = 0; 103 struct scatterlist *sg = NULL; 104 DWORD bl_num; 105 WORD bl_len; 106 BYTE buf[8]; 107 108 dev_dbg(&us->pusb_dev->dev, "SM_SCSI_Read_Capacity\n"); 109 110 bl_len = 0x200; 111 bl_num = Ssfdc.MaxLogBlocks * Ssfdc.MaxSectors * Ssfdc.MaxZones - 1; 112 113 us->bl_num = bl_num; 114 dev_dbg(&us->pusb_dev->dev, "bl_len = %x\n", bl_len); 115 dev_dbg(&us->pusb_dev->dev, "bl_num = %x\n", bl_num); 116 117 buf[0] = (bl_num >> 24) & 0xff; 118 buf[1] = (bl_num >> 16) & 0xff; 119 buf[2] = (bl_num >> 8) & 0xff; 120 buf[3] = (bl_num >> 0) & 0xff; 121 buf[4] = (bl_len >> 24) & 0xff; 122 buf[5] = (bl_len >> 16) & 0xff; 123 buf[6] = (bl_len >> 8) & 0xff; 124 buf[7] = (bl_len >> 0) & 0xff; 125 126 usb_stor_access_xfer_buf(us, buf, 8, srb, &sg, &offset, TO_XFER_BUF); 127 128 return USB_STOR_TRANSPORT_GOOD; 129} 130 131/* ----- SM_SCSI_Read() -------------------------------------------------- */ 132static int SM_SCSI_Read(struct us_data *us, struct scsi_cmnd *srb) 133{ 134 int result = 0; 135 PBYTE Cdb = srb->cmnd; 136 DWORD bn = ((Cdb[2] << 24) & 0xff000000) | 137 ((Cdb[3] << 16) & 0x00ff0000) | 138 ((Cdb[4] << 8) & 0x0000ff00) | 139 ((Cdb[5] << 0) & 0x000000ff); 140 WORD blen = ((Cdb[7] << 8) & 0xff00) | ((Cdb[8] << 0) & 0x00ff); 141 DWORD blenByte = blen * 0x200; 142 void *buf; 143 144 145 if (bn > us->bl_num) 146 return USB_STOR_TRANSPORT_ERROR; 147 148 buf = kmalloc(blenByte, GFP_KERNEL); 149 if (buf == NULL) 150 return USB_STOR_TRANSPORT_ERROR; 151 result = Media_D_ReadSector(us, bn, blen, buf); 152 usb_stor_set_xfer_buf(us, buf, blenByte, srb, TO_XFER_BUF); 153 kfree(buf); 154 155 if (!result) 156 return USB_STOR_TRANSPORT_GOOD; 157 else 158 return USB_STOR_TRANSPORT_ERROR; 159 160 return USB_STOR_TRANSPORT_GOOD; 161} 162 163/* ----- SM_SCSI_Write() -------------------------------------------------- */ 164static int SM_SCSI_Write(struct us_data *us, struct scsi_cmnd *srb) 165{ 166 int result = 0; 167 PBYTE Cdb = srb->cmnd; 168 DWORD bn = ((Cdb[2] << 24) & 0xff000000) | 169 ((Cdb[3] << 16) & 0x00ff0000) | 170 ((Cdb[4] << 8) & 0x0000ff00) | 171 ((Cdb[5] << 0) & 0x000000ff); 172 WORD blen = ((Cdb[7] << 8) & 0xff00) | ((Cdb[8] << 0) & 0x00ff); 173 DWORD blenByte = blen * 0x200; 174 void *buf; 175 176 177 if (bn > us->bl_num) 178 return USB_STOR_TRANSPORT_ERROR; 179 180 buf = kmalloc(blenByte, GFP_KERNEL); 181 if (buf == NULL) 182 return USB_STOR_TRANSPORT_ERROR; 183 usb_stor_set_xfer_buf(us, buf, blenByte, srb, FROM_XFER_BUF); 184 result = Media_D_CopySector(us, bn, blen, buf); 185 kfree(buf); 186 187 if (!result) 188 return USB_STOR_TRANSPORT_GOOD; 189 else 190 return USB_STOR_TRANSPORT_ERROR; 191 192 return USB_STOR_TRANSPORT_GOOD; 193} 194