1 #include <linux/sched.h>
2 #include <linux/errno.h>
3 #include <linux/slab.h>
6 #include <scsi/scsi_eh.h>
7 #include <scsi/scsi_device.h>
11 #include "transport.h"
13 int MS_SCSI_Test_Unit_Ready (struct us_data
*us
, struct scsi_cmnd
*srb
);
14 int MS_SCSI_Inquiry (struct us_data
*us
, struct scsi_cmnd
*srb
);
15 int MS_SCSI_Mode_Sense (struct us_data
*us
, struct scsi_cmnd
*srb
);
16 int MS_SCSI_Start_Stop (struct us_data
*us
, struct scsi_cmnd
*srb
);
17 int MS_SCSI_Read_Capacity (struct us_data
*us
, struct scsi_cmnd
*srb
);
18 int MS_SCSI_Read (struct us_data
*us
, struct scsi_cmnd
*srb
);
19 int MS_SCSI_Write (struct us_data
*us
, struct scsi_cmnd
*srb
);
21 //----- MS_SCSIIrp() --------------------------------------------------
22 int MS_SCSIIrp(struct us_data
*us
, struct scsi_cmnd
*srb
)
26 us
->SrbStatus
= SS_SUCCESS
;
29 case TEST_UNIT_READY
: result
= MS_SCSI_Test_Unit_Ready (us
, srb
); break; //0x00
30 case INQUIRY
: result
= MS_SCSI_Inquiry (us
, srb
); break; //0x12
31 case MODE_SENSE
: result
= MS_SCSI_Mode_Sense (us
, srb
); break; //0x1A
32 case READ_CAPACITY
: result
= MS_SCSI_Read_Capacity (us
, srb
); break; //0x25
33 case READ_10
: result
= MS_SCSI_Read (us
, srb
); break; //0x28
34 case WRITE_10
: result
= MS_SCSI_Write (us
, srb
); break; //0x2A
37 us
->SrbStatus
= SS_ILLEGAL_REQUEST
;
38 result
= USB_STOR_TRANSPORT_FAILED
;
44 //----- MS_SCSI_Test_Unit_Ready() --------------------------------------------------
45 int MS_SCSI_Test_Unit_Ready(struct us_data
*us
, struct scsi_cmnd
*srb
)
47 //printk("MS_SCSI_Test_Unit_Ready\n");
48 if (us
->MS_Status
.Insert
&& us
->MS_Status
.Ready
)
49 return USB_STOR_TRANSPORT_GOOD
;
53 return USB_STOR_TRANSPORT_GOOD
;
56 return USB_STOR_TRANSPORT_GOOD
;
59 //----- MS_SCSI_Inquiry() --------------------------------------------------
60 int MS_SCSI_Inquiry(struct us_data
*us
, struct scsi_cmnd
*srb
)
62 //printk("MS_SCSI_Inquiry\n");
63 BYTE data_ptr
[36] = {0x00, 0x80, 0x02, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x55, 0x53, 0x42, 0x32, 0x2E, 0x30, 0x20, 0x20, 0x43, 0x61, 0x72, 0x64, 0x52, 0x65, 0x61, 0x64, 0x65, 0x72, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x30, 0x31, 0x30, 0x30};
65 usb_stor_set_xfer_buf(us
, data_ptr
, 36, srb
, TO_XFER_BUF
);
66 return USB_STOR_TRANSPORT_GOOD
;
70 //----- MS_SCSI_Mode_Sense() --------------------------------------------------
71 int MS_SCSI_Mode_Sense(struct us_data
*us
, struct scsi_cmnd
*srb
)
73 BYTE mediaNoWP
[12] = {0x0b,0x00,0x00,0x08,0x00,0x00,0x71,0xc0,0x00,0x00,0x02,0x00};
74 BYTE mediaWP
[12] = {0x0b,0x00,0x80,0x08,0x00,0x00,0x71,0xc0,0x00,0x00,0x02,0x00};
76 if (us
->MS_Status
.WtP
)
77 usb_stor_set_xfer_buf(us
, mediaWP
, 12, srb
, TO_XFER_BUF
);
79 usb_stor_set_xfer_buf(us
, mediaNoWP
, 12, srb
, TO_XFER_BUF
);
82 return USB_STOR_TRANSPORT_GOOD
;
85 //----- MS_SCSI_Read_Capacity() --------------------------------------------------
86 int MS_SCSI_Read_Capacity(struct us_data
*us
, struct scsi_cmnd
*srb
)
88 unsigned int offset
= 0;
89 struct scatterlist
*sg
= NULL
;
94 printk("MS_SCSI_Read_Capacity\n");
97 if ( us
->MS_Status
.IsMSPro
)
98 bl_num
= us
->MSP_TotalBlock
- 1;
100 bl_num
= us
->MS_Lib
.NumberOfLogBlock
* us
->MS_Lib
.blockSize
* 2 - 1;
103 printk("bl_len = %x\n", bl_len
);
104 printk("bl_num = %x\n", bl_num
);
106 //srb->request_bufflen = 8;
107 buf
[0] = (bl_num
>>24) & 0xff;
108 buf
[1] = (bl_num
>>16) & 0xff;
109 buf
[2] = (bl_num
>> 8) & 0xff;
110 buf
[3] = (bl_num
>> 0) & 0xff;
111 buf
[4] = (bl_len
>>24) & 0xff;
112 buf
[5] = (bl_len
>>16) & 0xff;
113 buf
[6] = (bl_len
>> 8) & 0xff;
114 buf
[7] = (bl_len
>> 0) & 0xff;
116 usb_stor_access_xfer_buf(us
, buf
, 8, srb
, &sg
, &offset
, TO_XFER_BUF
);
117 //usb_stor_set_xfer_buf(us, buf, srb->request_bufflen, srb, TO_XFER_BUF);
119 return USB_STOR_TRANSPORT_GOOD
;
122 //----- MS_SCSI_Read() --------------------------------------------------
123 int MS_SCSI_Read(struct us_data
*us
, struct scsi_cmnd
*srb
)
125 struct bulk_cb_wrap
*bcb
= (struct bulk_cb_wrap
*) us
->iobuf
;
127 PBYTE Cdb
= srb
->cmnd
;
128 DWORD bn
= ((Cdb
[2]<<24) & 0xff000000) | ((Cdb
[3]<<16) & 0x00ff0000) |
129 ((Cdb
[4]<< 8) & 0x0000ff00) | ((Cdb
[5]<< 0) & 0x000000ff);
130 WORD blen
= ((Cdb
[7]<< 8) & 0xff00) | ((Cdb
[8]<< 0) & 0x00ff);
131 DWORD blenByte
= blen
* 0x200;
133 //printk("SCSIOP_READ --- bn = %X, blen = %X, srb->use_sg = %X\n", bn, blen, srb->use_sg);
136 return USB_STOR_TRANSPORT_ERROR
;
138 if (us
->MS_Status
.IsMSPro
)
140 result
= ENE_LoadBinCode(us
, MSP_RW_PATTERN
);
141 if (result
!= USB_STOR_XFER_GOOD
)
143 printk("Load MSP RW pattern Fail !!\n");
144 return USB_STOR_TRANSPORT_ERROR
;
147 // set up the command wrapper
148 memset(bcb
, 0, sizeof(struct bulk_cb_wrap
));
149 bcb
->Signature
= cpu_to_le32(US_BULK_CB_SIGN
);
150 bcb
->DataTransferLength
= blenByte
;
154 bcb
->CDB
[5] = (BYTE
)(bn
);
155 bcb
->CDB
[4] = (BYTE
)(bn
>>8);
156 bcb
->CDB
[3] = (BYTE
)(bn
>>16);
157 bcb
->CDB
[2] = (BYTE
)(bn
>>24);
159 result
= ENE_SendScsiCmd(us
, FDIR_READ
, scsi_sglist(srb
), 1);
170 buf
= kmalloc(blenByte
, GFP_KERNEL
);
172 return USB_STOR_TRANSPORT_ERROR
;
174 result
= ENE_LoadBinCode(us
, MS_RW_PATTERN
);
175 if (result
!= USB_STOR_XFER_GOOD
)
177 printk("Load MS RW pattern Fail !!\n");
178 result
= USB_STOR_TRANSPORT_ERROR
;
182 logblk
= (WORD
)(bn
/ us
->MS_Lib
.PagesPerBlock
);
183 PageNum
= (BYTE
)(bn
% us
->MS_Lib
.PagesPerBlock
);
187 if (blen
> (us
->MS_Lib
.PagesPerBlock
-PageNum
) )
188 len
= us
->MS_Lib
.PagesPerBlock
-PageNum
;
192 phyblk
= MS_LibConv2Physical(us
, logblk
);
193 blkno
= phyblk
* 0x20 + PageNum
;
195 // set up the command wrapper
196 memset(bcb
, 0, sizeof(struct bulk_cb_wrap
));
197 bcb
->Signature
= cpu_to_le32(US_BULK_CB_SIGN
);
198 bcb
->DataTransferLength
= 0x200 * len
;
202 bcb
->CDB
[5] = (BYTE
)(blkno
);
203 bcb
->CDB
[4] = (BYTE
)(blkno
>>8);
204 bcb
->CDB
[3] = (BYTE
)(blkno
>>16);
205 bcb
->CDB
[2] = (BYTE
)(blkno
>>24);
207 result
= ENE_SendScsiCmd(us
, FDIR_READ
, buf
+offset
, 0);
208 if (result
!= USB_STOR_XFER_GOOD
)
210 printk("MS_SCSI_Read --- result = %x\n", result
);
211 result
= USB_STOR_TRANSPORT_ERROR
;
220 offset
+= MS_BYTES_PER_PAGE
*len
;
222 usb_stor_set_xfer_buf(us
, buf
, blenByte
, srb
, TO_XFER_BUF
);
229 //----- MS_SCSI_Write() --------------------------------------------------
230 int MS_SCSI_Write(struct us_data
*us
, struct scsi_cmnd
*srb
)
232 struct bulk_cb_wrap
*bcb
= (struct bulk_cb_wrap
*) us
->iobuf
;
234 PBYTE Cdb
= srb
->cmnd
;
235 DWORD bn
= ((Cdb
[2]<<24) & 0xff000000) | ((Cdb
[3]<<16) & 0x00ff0000) |
236 ((Cdb
[4]<< 8) & 0x0000ff00) | ((Cdb
[5]<< 0) & 0x000000ff);
237 WORD blen
= ((Cdb
[7]<< 8) & 0xff00) | ((Cdb
[8]<< 0) & 0x00ff);
238 DWORD blenByte
= blen
* 0x200;
241 return USB_STOR_TRANSPORT_ERROR
;
243 if (us
->MS_Status
.IsMSPro
)
245 result
= ENE_LoadBinCode(us
, MSP_RW_PATTERN
);
246 if (result
!= USB_STOR_XFER_GOOD
)
248 printk("Load MSP RW pattern Fail !!\n");
249 return USB_STOR_TRANSPORT_ERROR
;
252 // set up the command wrapper
253 memset(bcb
, 0, sizeof(struct bulk_cb_wrap
));
254 bcb
->Signature
= cpu_to_le32(US_BULK_CB_SIGN
);
255 bcb
->DataTransferLength
= blenByte
;
259 bcb
->CDB
[5] = (BYTE
)(bn
);
260 bcb
->CDB
[4] = (BYTE
)(bn
>>8);
261 bcb
->CDB
[3] = (BYTE
)(bn
>>16);
262 bcb
->CDB
[2] = (BYTE
)(bn
>>24);
264 result
= ENE_SendScsiCmd(us
, FDIR_WRITE
, scsi_sglist(srb
), 1);
273 WORD len
, oldphy
, newphy
;
275 buf
= kmalloc(blenByte
, GFP_KERNEL
);
277 return USB_STOR_TRANSPORT_ERROR
;
278 usb_stor_set_xfer_buf(us
, buf
, blenByte
, srb
, FROM_XFER_BUF
);
280 result
= ENE_LoadBinCode(us
, MS_RW_PATTERN
);
281 if (result
!= USB_STOR_XFER_GOOD
)
283 printk("Load MS RW pattern Fail !!\n");
284 result
= USB_STOR_TRANSPORT_ERROR
;
288 PhyBlockAddr
= (WORD
)(bn
/ us
->MS_Lib
.PagesPerBlock
);
289 PageNum
= (BYTE
)(bn
% us
->MS_Lib
.PagesPerBlock
);
293 if (blen
> (us
->MS_Lib
.PagesPerBlock
-PageNum
) )
294 len
= us
->MS_Lib
.PagesPerBlock
-PageNum
;
298 oldphy
= MS_LibConv2Physical(us
, PhyBlockAddr
);
299 newphy
= MS_LibSearchBlockFromLogical(us
, PhyBlockAddr
);
301 result
= MS_ReaderCopyBlock(us
, oldphy
, newphy
, PhyBlockAddr
, PageNum
, buf
+offset
, len
);
302 if (result
!= USB_STOR_XFER_GOOD
)
304 printk("MS_SCSI_Write --- result = %x\n", result
);
305 result
= USB_STOR_TRANSPORT_ERROR
;
309 us
->MS_Lib
.Phy2LogMap
[oldphy
] = MS_LB_NOT_USED_ERASED
;
310 MS_LibForceSetLogicalPair(us
, PhyBlockAddr
, newphy
);
317 offset
+= MS_BYTES_PER_PAGE
*len
;