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"
15 int MS_SCSI_Test_Unit_Ready (struct us_data
*us
, struct scsi_cmnd
*srb
);
16 int MS_SCSI_Inquiry (struct us_data
*us
, struct scsi_cmnd
*srb
);
17 int MS_SCSI_Mode_Sense (struct us_data
*us
, struct scsi_cmnd
*srb
);
18 int MS_SCSI_Start_Stop (struct us_data
*us
, struct scsi_cmnd
*srb
);
19 int MS_SCSI_Read_Capacity (struct us_data
*us
, struct scsi_cmnd
*srb
);
20 int MS_SCSI_Read (struct us_data
*us
, struct scsi_cmnd
*srb
);
21 int MS_SCSI_Write (struct us_data
*us
, struct scsi_cmnd
*srb
);
23 //----- MS_SCSIIrp() --------------------------------------------------
24 int MS_SCSIIrp(struct us_data
*us
, struct scsi_cmnd
*srb
)
28 us
->SrbStatus
= SS_SUCCESS
;
31 case TEST_UNIT_READY
: result
= MS_SCSI_Test_Unit_Ready (us
, srb
); break; //0x00
32 case INQUIRY
: result
= MS_SCSI_Inquiry (us
, srb
); break; //0x12
33 case MODE_SENSE
: result
= MS_SCSI_Mode_Sense (us
, srb
); break; //0x1A
34 case READ_CAPACITY
: result
= MS_SCSI_Read_Capacity (us
, srb
); break; //0x25
35 case READ_10
: result
= MS_SCSI_Read (us
, srb
); break; //0x28
36 case WRITE_10
: result
= MS_SCSI_Write (us
, srb
); break; //0x2A
39 us
->SrbStatus
= SS_ILLEGAL_REQUEST
;
40 result
= USB_STOR_TRANSPORT_FAILED
;
46 //----- MS_SCSI_Test_Unit_Ready() --------------------------------------------------
47 int MS_SCSI_Test_Unit_Ready(struct us_data
*us
, struct scsi_cmnd
*srb
)
49 /* pr_info("MS_SCSI_Test_Unit_Ready\n"); */
50 if (us
->MS_Status
.Insert
&& us
->MS_Status
.Ready
)
51 return USB_STOR_TRANSPORT_GOOD
;
55 return USB_STOR_TRANSPORT_GOOD
;
58 return USB_STOR_TRANSPORT_GOOD
;
61 //----- MS_SCSI_Inquiry() --------------------------------------------------
62 int MS_SCSI_Inquiry(struct us_data
*us
, struct scsi_cmnd
*srb
)
64 /* pr_info("MS_SCSI_Inquiry\n"); */
65 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};
67 usb_stor_set_xfer_buf(us
, data_ptr
, 36, srb
, TO_XFER_BUF
);
68 return USB_STOR_TRANSPORT_GOOD
;
72 //----- MS_SCSI_Mode_Sense() --------------------------------------------------
73 int MS_SCSI_Mode_Sense(struct us_data
*us
, struct scsi_cmnd
*srb
)
75 BYTE mediaNoWP
[12] = {0x0b,0x00,0x00,0x08,0x00,0x00,0x71,0xc0,0x00,0x00,0x02,0x00};
76 BYTE mediaWP
[12] = {0x0b,0x00,0x80,0x08,0x00,0x00,0x71,0xc0,0x00,0x00,0x02,0x00};
78 if (us
->MS_Status
.WtP
)
79 usb_stor_set_xfer_buf(us
, mediaWP
, 12, srb
, TO_XFER_BUF
);
81 usb_stor_set_xfer_buf(us
, mediaNoWP
, 12, srb
, TO_XFER_BUF
);
84 return USB_STOR_TRANSPORT_GOOD
;
87 //----- MS_SCSI_Read_Capacity() --------------------------------------------------
88 int MS_SCSI_Read_Capacity(struct us_data
*us
, struct scsi_cmnd
*srb
)
90 unsigned int offset
= 0;
91 struct scatterlist
*sg
= NULL
;
96 pr_info("MS_SCSI_Read_Capacity\n");
99 if ( us
->MS_Status
.IsMSPro
)
100 bl_num
= us
->MSP_TotalBlock
- 1;
102 bl_num
= us
->MS_Lib
.NumberOfLogBlock
* us
->MS_Lib
.blockSize
* 2 - 1;
105 pr_info("bl_len = %x\n", bl_len
);
106 pr_info("bl_num = %x\n", bl_num
);
108 //srb->request_bufflen = 8;
109 buf
[0] = (bl_num
>>24) & 0xff;
110 buf
[1] = (bl_num
>>16) & 0xff;
111 buf
[2] = (bl_num
>> 8) & 0xff;
112 buf
[3] = (bl_num
>> 0) & 0xff;
113 buf
[4] = (bl_len
>>24) & 0xff;
114 buf
[5] = (bl_len
>>16) & 0xff;
115 buf
[6] = (bl_len
>> 8) & 0xff;
116 buf
[7] = (bl_len
>> 0) & 0xff;
118 usb_stor_access_xfer_buf(us
, buf
, 8, srb
, &sg
, &offset
, TO_XFER_BUF
);
119 //usb_stor_set_xfer_buf(us, buf, srb->request_bufflen, srb, TO_XFER_BUF);
121 return USB_STOR_TRANSPORT_GOOD
;
124 //----- MS_SCSI_Read() --------------------------------------------------
125 int MS_SCSI_Read(struct us_data
*us
, struct scsi_cmnd
*srb
)
127 struct bulk_cb_wrap
*bcb
= (struct bulk_cb_wrap
*) us
->iobuf
;
129 PBYTE Cdb
= srb
->cmnd
;
130 DWORD bn
= ((Cdb
[2]<<24) & 0xff000000) | ((Cdb
[3]<<16) & 0x00ff0000) |
131 ((Cdb
[4]<< 8) & 0x0000ff00) | ((Cdb
[5]<< 0) & 0x000000ff);
132 WORD blen
= ((Cdb
[7]<< 8) & 0xff00) | ((Cdb
[8]<< 0) & 0x00ff);
133 DWORD blenByte
= blen
* 0x200;
135 /* pr_info("SCSIOP_READ --- bn = %X, blen = %X, srb->use_sg = %X\n",
136 bn, blen, srb->use_sg); */
139 return USB_STOR_TRANSPORT_ERROR
;
141 if (us
->MS_Status
.IsMSPro
)
143 result
= ENE_LoadBinCode(us
, MSP_RW_PATTERN
);
144 if (result
!= USB_STOR_XFER_GOOD
)
146 pr_info("Load MSP RW pattern Fail !!\n");
147 return USB_STOR_TRANSPORT_ERROR
;
150 // set up the command wrapper
151 memset(bcb
, 0, sizeof(struct bulk_cb_wrap
));
152 bcb
->Signature
= cpu_to_le32(US_BULK_CB_SIGN
);
153 bcb
->DataTransferLength
= blenByte
;
157 bcb
->CDB
[5] = (BYTE
)(bn
);
158 bcb
->CDB
[4] = (BYTE
)(bn
>>8);
159 bcb
->CDB
[3] = (BYTE
)(bn
>>16);
160 bcb
->CDB
[2] = (BYTE
)(bn
>>24);
162 result
= ENE_SendScsiCmd(us
, FDIR_READ
, scsi_sglist(srb
), 1);
173 buf
= kmalloc(blenByte
, GFP_KERNEL
);
175 return USB_STOR_TRANSPORT_ERROR
;
177 result
= ENE_LoadBinCode(us
, MS_RW_PATTERN
);
178 if (result
!= USB_STOR_XFER_GOOD
)
180 pr_info("Load MS RW pattern Fail !!\n");
181 result
= USB_STOR_TRANSPORT_ERROR
;
185 logblk
= (WORD
)(bn
/ us
->MS_Lib
.PagesPerBlock
);
186 PageNum
= (BYTE
)(bn
% us
->MS_Lib
.PagesPerBlock
);
190 if (blen
> (us
->MS_Lib
.PagesPerBlock
-PageNum
) )
191 len
= us
->MS_Lib
.PagesPerBlock
-PageNum
;
195 phyblk
= MS_LibConv2Physical(us
, logblk
);
196 blkno
= phyblk
* 0x20 + PageNum
;
198 // set up the command wrapper
199 memset(bcb
, 0, sizeof(struct bulk_cb_wrap
));
200 bcb
->Signature
= cpu_to_le32(US_BULK_CB_SIGN
);
201 bcb
->DataTransferLength
= 0x200 * len
;
205 bcb
->CDB
[5] = (BYTE
)(blkno
);
206 bcb
->CDB
[4] = (BYTE
)(blkno
>>8);
207 bcb
->CDB
[3] = (BYTE
)(blkno
>>16);
208 bcb
->CDB
[2] = (BYTE
)(blkno
>>24);
210 result
= ENE_SendScsiCmd(us
, FDIR_READ
, buf
+offset
, 0);
211 if (result
!= USB_STOR_XFER_GOOD
)
213 pr_info("MS_SCSI_Read --- result = %x\n",
215 result
= USB_STOR_TRANSPORT_ERROR
;
224 offset
+= MS_BYTES_PER_PAGE
*len
;
226 usb_stor_set_xfer_buf(us
, buf
, blenByte
, srb
, TO_XFER_BUF
);
233 //----- MS_SCSI_Write() --------------------------------------------------
234 int MS_SCSI_Write(struct us_data
*us
, struct scsi_cmnd
*srb
)
236 struct bulk_cb_wrap
*bcb
= (struct bulk_cb_wrap
*) us
->iobuf
;
238 PBYTE Cdb
= srb
->cmnd
;
239 DWORD bn
= ((Cdb
[2]<<24) & 0xff000000) | ((Cdb
[3]<<16) & 0x00ff0000) |
240 ((Cdb
[4]<< 8) & 0x0000ff00) | ((Cdb
[5]<< 0) & 0x000000ff);
241 WORD blen
= ((Cdb
[7]<< 8) & 0xff00) | ((Cdb
[8]<< 0) & 0x00ff);
242 DWORD blenByte
= blen
* 0x200;
245 return USB_STOR_TRANSPORT_ERROR
;
247 if (us
->MS_Status
.IsMSPro
)
249 result
= ENE_LoadBinCode(us
, MSP_RW_PATTERN
);
250 if (result
!= USB_STOR_XFER_GOOD
)
252 pr_info("Load MSP RW pattern Fail !!\n");
253 return USB_STOR_TRANSPORT_ERROR
;
256 // set up the command wrapper
257 memset(bcb
, 0, sizeof(struct bulk_cb_wrap
));
258 bcb
->Signature
= cpu_to_le32(US_BULK_CB_SIGN
);
259 bcb
->DataTransferLength
= blenByte
;
263 bcb
->CDB
[5] = (BYTE
)(bn
);
264 bcb
->CDB
[4] = (BYTE
)(bn
>>8);
265 bcb
->CDB
[3] = (BYTE
)(bn
>>16);
266 bcb
->CDB
[2] = (BYTE
)(bn
>>24);
268 result
= ENE_SendScsiCmd(us
, FDIR_WRITE
, scsi_sglist(srb
), 1);
277 WORD len
, oldphy
, newphy
;
279 buf
= kmalloc(blenByte
, GFP_KERNEL
);
281 return USB_STOR_TRANSPORT_ERROR
;
282 usb_stor_set_xfer_buf(us
, buf
, blenByte
, srb
, FROM_XFER_BUF
);
284 result
= ENE_LoadBinCode(us
, MS_RW_PATTERN
);
285 if (result
!= USB_STOR_XFER_GOOD
)
287 pr_info("Load MS RW pattern Fail !!\n");
288 result
= USB_STOR_TRANSPORT_ERROR
;
292 PhyBlockAddr
= (WORD
)(bn
/ us
->MS_Lib
.PagesPerBlock
);
293 PageNum
= (BYTE
)(bn
% us
->MS_Lib
.PagesPerBlock
);
297 if (blen
> (us
->MS_Lib
.PagesPerBlock
-PageNum
) )
298 len
= us
->MS_Lib
.PagesPerBlock
-PageNum
;
302 oldphy
= MS_LibConv2Physical(us
, PhyBlockAddr
);
303 newphy
= MS_LibSearchBlockFromLogical(us
, PhyBlockAddr
);
305 result
= MS_ReaderCopyBlock(us
, oldphy
, newphy
, PhyBlockAddr
, PageNum
, buf
+offset
, len
);
306 if (result
!= USB_STOR_XFER_GOOD
)
308 pr_info("MS_SCSI_Write --- result = %x\n",
310 result
= USB_STOR_TRANSPORT_ERROR
;
314 us
->MS_Lib
.Phy2LogMap
[oldphy
] = MS_LB_NOT_USED_ERASED
;
315 MS_LibForceSetLogicalPair(us
, PhyBlockAddr
, newphy
);
322 offset
+= MS_BYTES_PER_PAGE
*len
;