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

Configure Feed

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

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