1 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
3 #include <linux/sched.h>
4 #include <linux/errno.h>
5 #include <linux/slab.h>
8 #include <scsi/scsi_eh.h>
9 #include <scsi/scsi_device.h>
13 #include "transport.h"
16 * MS_SCSI_Test_Unit_Ready()
18 int MS_SCSI_Test_Unit_Ready(struct us_data
*us
, struct scsi_cmnd
*srb
)
20 /* pr_info("MS_SCSI_Test_Unit_Ready\n"); */
21 if (us
->MS_Status
.Insert
&& us
->MS_Status
.Ready
)
22 return USB_STOR_TRANSPORT_GOOD
;
25 return USB_STOR_TRANSPORT_GOOD
;
28 return USB_STOR_TRANSPORT_GOOD
;
34 int MS_SCSI_Inquiry(struct us_data
*us
, struct scsi_cmnd
*srb
)
36 /* pr_info("MS_SCSI_Inquiry\n"); */
37 BYTE data_ptr
[36] = {0x00, 0x80, 0x02, 0x00, 0x1F, 0x00,
38 0x00, 0x00, 0x55, 0x53, 0x42, 0x32,
39 0x2E, 0x30, 0x20, 0x20, 0x43, 0x61,
40 0x72, 0x64, 0x52, 0x65, 0x61, 0x64,
41 0x65, 0x72, 0x20, 0x20, 0x20, 0x20,
42 0x20, 0x20, 0x30, 0x31, 0x30, 0x30};
44 usb_stor_set_xfer_buf(us
, data_ptr
, 36, srb
, TO_XFER_BUF
);
45 return USB_STOR_TRANSPORT_GOOD
;
49 * MS_SCSI_Mode_Sense()
51 int MS_SCSI_Mode_Sense(struct us_data
*us
, struct scsi_cmnd
*srb
)
53 BYTE mediaNoWP
[12] = {0x0b, 0x00, 0x00, 0x08, 0x00, 0x00,
54 0x71, 0xc0, 0x00, 0x00, 0x02, 0x00};
55 BYTE mediaWP
[12] = {0x0b, 0x00, 0x80, 0x08, 0x00, 0x00,
56 0x71, 0xc0, 0x00, 0x00, 0x02, 0x00};
58 if (us
->MS_Status
.WtP
)
59 usb_stor_set_xfer_buf(us
, mediaWP
, 12, srb
, TO_XFER_BUF
);
61 usb_stor_set_xfer_buf(us
, mediaNoWP
, 12, srb
, TO_XFER_BUF
);
64 return USB_STOR_TRANSPORT_GOOD
;
68 * MS_SCSI_Read_Capacity()
70 int MS_SCSI_Read_Capacity(struct us_data
*us
, struct scsi_cmnd
*srb
)
72 unsigned int offset
= 0;
73 struct scatterlist
*sg
= NULL
;
78 pr_info("MS_SCSI_Read_Capacity\n");
81 if (us
->MS_Status
.IsMSPro
)
82 bl_num
= us
->MSP_TotalBlock
- 1;
84 bl_num
= us
->MS_Lib
.NumberOfLogBlock
*
85 us
->MS_Lib
.blockSize
* 2 - 1;
88 pr_info("bl_len = %x\n", bl_len
);
89 pr_info("bl_num = %x\n", bl_num
);
91 /* srb->request_bufflen = 8; */
92 buf
[0] = (bl_num
>> 24) & 0xff;
93 buf
[1] = (bl_num
>> 16) & 0xff;
94 buf
[2] = (bl_num
>> 8) & 0xff;
95 buf
[3] = (bl_num
>> 0) & 0xff;
96 buf
[4] = (bl_len
>> 24) & 0xff;
97 buf
[5] = (bl_len
>> 16) & 0xff;
98 buf
[6] = (bl_len
>> 8) & 0xff;
99 buf
[7] = (bl_len
>> 0) & 0xff;
101 usb_stor_access_xfer_buf(us
, buf
, 8, srb
, &sg
, &offset
, TO_XFER_BUF
);
102 /* usb_stor_set_xfer_buf(us, buf, srb->request_bufflen,
103 srb, TO_XFER_BUF); */
105 return USB_STOR_TRANSPORT_GOOD
;
111 int MS_SCSI_Read(struct us_data
*us
, struct scsi_cmnd
*srb
)
113 struct bulk_cb_wrap
*bcb
= (struct bulk_cb_wrap
*) us
->iobuf
;
115 PBYTE Cdb
= srb
->cmnd
;
116 DWORD bn
= ((Cdb
[2] << 24) & 0xff000000) |
117 ((Cdb
[3] << 16) & 0x00ff0000) |
118 ((Cdb
[4] << 8) & 0x0000ff00) |
119 ((Cdb
[5] << 0) & 0x000000ff);
120 WORD blen
= ((Cdb
[7] << 8) & 0xff00) | ((Cdb
[8] << 0) & 0x00ff);
121 DWORD blenByte
= blen
* 0x200;
123 /* pr_info("SCSIOP_READ --- bn = %X, blen = %X, srb->use_sg = %X\n",
124 bn, blen, srb->use_sg); */
127 return USB_STOR_TRANSPORT_ERROR
;
129 if (us
->MS_Status
.IsMSPro
) {
130 result
= ENE_LoadBinCode(us
, MSP_RW_PATTERN
);
131 if (result
!= USB_STOR_XFER_GOOD
) {
132 pr_info("Load MSP RW pattern Fail !!\n");
133 return USB_STOR_TRANSPORT_ERROR
;
136 /* set up the command wrapper */
137 memset(bcb
, 0, sizeof(struct bulk_cb_wrap
));
138 bcb
->Signature
= cpu_to_le32(US_BULK_CB_SIGN
);
139 bcb
->DataTransferLength
= blenByte
;
143 bcb
->CDB
[5] = (BYTE
)(bn
);
144 bcb
->CDB
[4] = (BYTE
)(bn
>>8);
145 bcb
->CDB
[3] = (BYTE
)(bn
>>16);
146 bcb
->CDB
[2] = (BYTE
)(bn
>>24);
148 result
= ENE_SendScsiCmd(us
, FDIR_READ
, scsi_sglist(srb
), 1);
157 buf
= kmalloc(blenByte
, GFP_KERNEL
);
159 return USB_STOR_TRANSPORT_ERROR
;
161 result
= ENE_LoadBinCode(us
, MS_RW_PATTERN
);
162 if (result
!= USB_STOR_XFER_GOOD
) {
163 pr_info("Load MS RW pattern Fail !!\n");
164 result
= USB_STOR_TRANSPORT_ERROR
;
168 logblk
= (WORD
)(bn
/ us
->MS_Lib
.PagesPerBlock
);
169 PageNum
= (BYTE
)(bn
% us
->MS_Lib
.PagesPerBlock
);
172 if (blen
> (us
->MS_Lib
.PagesPerBlock
-PageNum
))
173 len
= us
->MS_Lib
.PagesPerBlock
-PageNum
;
177 phyblk
= MS_LibConv2Physical(us
, logblk
);
178 blkno
= phyblk
* 0x20 + PageNum
;
180 /* set up the command wrapper */
181 memset(bcb
, 0, sizeof(struct bulk_cb_wrap
));
182 bcb
->Signature
= cpu_to_le32(US_BULK_CB_SIGN
);
183 bcb
->DataTransferLength
= 0x200 * len
;
187 bcb
->CDB
[5] = (BYTE
)(blkno
);
188 bcb
->CDB
[4] = (BYTE
)(blkno
>>8);
189 bcb
->CDB
[3] = (BYTE
)(blkno
>>16);
190 bcb
->CDB
[2] = (BYTE
)(blkno
>>24);
192 result
= ENE_SendScsiCmd(us
, FDIR_READ
, buf
+offset
, 0);
193 if (result
!= USB_STOR_XFER_GOOD
) {
194 pr_info("MS_SCSI_Read --- result = %x\n",
196 result
= USB_STOR_TRANSPORT_ERROR
;
205 offset
+= MS_BYTES_PER_PAGE
*len
;
207 usb_stor_set_xfer_buf(us
, buf
, blenByte
, srb
, TO_XFER_BUF
);
217 int MS_SCSI_Write(struct us_data
*us
, struct scsi_cmnd
*srb
)
219 struct bulk_cb_wrap
*bcb
= (struct bulk_cb_wrap
*) us
->iobuf
;
221 PBYTE Cdb
= srb
->cmnd
;
222 DWORD bn
= ((Cdb
[2] << 24) & 0xff000000) |
223 ((Cdb
[3] << 16) & 0x00ff0000) |
224 ((Cdb
[4] << 8) & 0x0000ff00) |
225 ((Cdb
[5] << 0) & 0x000000ff);
226 WORD blen
= ((Cdb
[7] << 8) & 0xff00) | ((Cdb
[8] << 0) & 0x00ff);
227 DWORD blenByte
= blen
* 0x200;
230 return USB_STOR_TRANSPORT_ERROR
;
232 if (us
->MS_Status
.IsMSPro
) {
233 result
= ENE_LoadBinCode(us
, MSP_RW_PATTERN
);
234 if (result
!= USB_STOR_XFER_GOOD
) {
235 pr_info("Load MSP RW pattern Fail !!\n");
236 return USB_STOR_TRANSPORT_ERROR
;
239 /* set up the command wrapper */
240 memset(bcb
, 0, sizeof(struct bulk_cb_wrap
));
241 bcb
->Signature
= cpu_to_le32(US_BULK_CB_SIGN
);
242 bcb
->DataTransferLength
= blenByte
;
246 bcb
->CDB
[5] = (BYTE
)(bn
);
247 bcb
->CDB
[4] = (BYTE
)(bn
>>8);
248 bcb
->CDB
[3] = (BYTE
)(bn
>>16);
249 bcb
->CDB
[2] = (BYTE
)(bn
>>24);
251 result
= ENE_SendScsiCmd(us
, FDIR_WRITE
, scsi_sglist(srb
), 1);
258 WORD len
, oldphy
, newphy
;
260 buf
= kmalloc(blenByte
, GFP_KERNEL
);
262 return USB_STOR_TRANSPORT_ERROR
;
263 usb_stor_set_xfer_buf(us
, buf
, blenByte
, srb
, FROM_XFER_BUF
);
265 result
= ENE_LoadBinCode(us
, MS_RW_PATTERN
);
266 if (result
!= USB_STOR_XFER_GOOD
) {
267 pr_info("Load MS RW pattern Fail !!\n");
268 result
= USB_STOR_TRANSPORT_ERROR
;
272 PhyBlockAddr
= (WORD
)(bn
/ us
->MS_Lib
.PagesPerBlock
);
273 PageNum
= (BYTE
)(bn
% us
->MS_Lib
.PagesPerBlock
);
276 if (blen
> (us
->MS_Lib
.PagesPerBlock
-PageNum
))
277 len
= us
->MS_Lib
.PagesPerBlock
-PageNum
;
281 oldphy
= MS_LibConv2Physical(us
, PhyBlockAddr
);
282 newphy
= MS_LibSearchBlockFromLogical(us
, PhyBlockAddr
);
284 result
= MS_ReaderCopyBlock(us
, oldphy
, newphy
,
285 PhyBlockAddr
, PageNum
,
287 if (result
!= USB_STOR_XFER_GOOD
) {
288 pr_info("MS_SCSI_Write --- result = %x\n",
290 result
= USB_STOR_TRANSPORT_ERROR
;
294 us
->MS_Lib
.Phy2LogMap
[oldphy
] = MS_LB_NOT_USED_ERASED
;
295 MS_LibForceSetLogicalPair(us
, PhyBlockAddr
, newphy
);
302 offset
+= MS_BYTES_PER_PAGE
*len
;
313 int MS_SCSIIrp(struct us_data
*us
, struct scsi_cmnd
*srb
)
317 us
->SrbStatus
= SS_SUCCESS
;
318 switch (srb
->cmnd
[0]) {
319 case TEST_UNIT_READY
:
320 result
= MS_SCSI_Test_Unit_Ready(us
, srb
);
323 result
= MS_SCSI_Inquiry(us
, srb
);
326 result
= MS_SCSI_Mode_Sense(us
, srb
);
329 result
= MS_SCSI_Read_Capacity(us
, srb
);
332 result
= MS_SCSI_Read(us
, srb
);
335 result
= MS_SCSI_Write(us
, srb
);
338 us
->SrbStatus
= SS_ILLEGAL_REQUEST
;
339 result
= USB_STOR_TRANSPORT_FAILED
;