Al Cho | 126bb03 | 2010-09-08 00:42:32 -0700 | [diff] [blame] | 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" |
Rui Miguel Silva | b7b1462 | 2014-04-12 01:33:11 +0100 | [diff] [blame] | 12 | #include "smil.h" |
Al Cho | 126bb03 | 2010-09-08 00:42:32 -0700 | [diff] [blame] | 13 | #include "init.h" |
| 14 | |
Al Cho | e93192a | 2010-11-26 19:06:39 +0800 | [diff] [blame] | 15 | /* |
| 16 | * ENE_InitMedia(): |
| 17 | */ |
Al Cho | 126bb03 | 2010-09-08 00:42:32 -0700 | [diff] [blame] | 18 | int ENE_InitMedia(struct us_data *us) |
| 19 | { |
| 20 | int result; |
Himangi Saraogi | 432f857 | 2014-03-16 03:14:57 +0530 | [diff] [blame] | 21 | u8 MiscReg03 = 0; |
Al Cho | 126bb03 | 2010-09-08 00:42:32 -0700 | [diff] [blame] | 22 | |
Laura Lawniczak | 29b3142 | 2013-06-06 18:10:47 +0200 | [diff] [blame] | 23 | dev_info(&us->pusb_dev->dev, "--- Init Media ---\n"); |
Katrina Prosise | 9799d12 | 2013-05-12 17:17:41 -0700 | [diff] [blame] | 24 | result = ene_read_byte(us, REG_CARD_STATUS, &MiscReg03); |
Al Cho | e93192a | 2010-11-26 19:06:39 +0800 | [diff] [blame] | 25 | if (result != USB_STOR_XFER_GOOD) { |
Laura Lawniczak | 6fbb90b | 2013-06-06 18:10:48 +0200 | [diff] [blame] | 26 | dev_err(&us->pusb_dev->dev, "Failed to read register\n"); |
Al Cho | 126bb03 | 2010-09-08 00:42:32 -0700 | [diff] [blame] | 27 | return USB_STOR_TRANSPORT_ERROR; |
| 28 | } |
Laura Lawniczak | 29b3142 | 2013-06-06 18:10:47 +0200 | [diff] [blame] | 29 | dev_info(&us->pusb_dev->dev, "MiscReg03 = %x\n", MiscReg03); |
Al Cho | 126bb03 | 2010-09-08 00:42:32 -0700 | [diff] [blame] | 30 | |
Al Cho | e93192a | 2010-11-26 19:06:39 +0800 | [diff] [blame] | 31 | if (MiscReg03 & 0x02) { |
| 32 | if (!us->SM_Status.Ready && !us->MS_Status.Ready) { |
Al Cho | 126bb03 | 2010-09-08 00:42:32 -0700 | [diff] [blame] | 33 | result = ENE_SMInit(us); |
William Blair | 383b7fc | 2012-06-10 15:10:33 -0400 | [diff] [blame] | 34 | if (result != USB_STOR_XFER_GOOD) |
Cho, Yu-Chen | 20c3d7f | 2011-07-07 11:27:14 +0800 | [diff] [blame] | 35 | return USB_STOR_TRANSPORT_ERROR; |
Al Cho | 126bb03 | 2010-09-08 00:42:32 -0700 | [diff] [blame] | 36 | } |
| 37 | |
| 38 | } |
| 39 | return result; |
| 40 | } |
| 41 | |
Al Cho | e93192a | 2010-11-26 19:06:39 +0800 | [diff] [blame] | 42 | /* |
Katrina Prosise | 9799d12 | 2013-05-12 17:17:41 -0700 | [diff] [blame] | 43 | * ene_read_byte() : |
Al Cho | e93192a | 2010-11-26 19:06:39 +0800 | [diff] [blame] | 44 | */ |
Himangi Saraogi | 432f857 | 2014-03-16 03:14:57 +0530 | [diff] [blame] | 45 | int ene_read_byte(struct us_data *us, u16 index, void *buf) |
Al Cho | 126bb03 | 2010-09-08 00:42:32 -0700 | [diff] [blame] | 46 | { |
| 47 | struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf; |
| 48 | int result; |
| 49 | |
Konstantin Katuev | 307ae1d | 2010-10-29 12:18:18 +1100 | [diff] [blame] | 50 | memset(bcb, 0, sizeof(struct bulk_cb_wrap)); |
Al Cho | 126bb03 | 2010-09-08 00:42:32 -0700 | [diff] [blame] | 51 | bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN); |
| 52 | bcb->DataTransferLength = 0x01; |
| 53 | bcb->Flags = 0x80; |
| 54 | bcb->CDB[0] = 0xED; |
Himangi Saraogi | 432f857 | 2014-03-16 03:14:57 +0530 | [diff] [blame] | 55 | bcb->CDB[2] = (u8)(index>>8); |
| 56 | bcb->CDB[3] = (u8)index; |
Al Cho | 126bb03 | 2010-09-08 00:42:32 -0700 | [diff] [blame] | 57 | |
| 58 | result = ENE_SendScsiCmd(us, FDIR_READ, buf, 0); |
| 59 | return result; |
| 60 | } |
| 61 | |
Al Cho | e93192a | 2010-11-26 19:06:39 +0800 | [diff] [blame] | 62 | /* |
Al Cho | e93192a | 2010-11-26 19:06:39 +0800 | [diff] [blame] | 63 | *ENE_SMInit() |
| 64 | */ |
Al Cho | 126bb03 | 2010-09-08 00:42:32 -0700 | [diff] [blame] | 65 | int ENE_SMInit(struct us_data *us) |
| 66 | { |
| 67 | struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf; |
| 68 | int result; |
Himangi Saraogi | 432f857 | 2014-03-16 03:14:57 +0530 | [diff] [blame] | 69 | u8 buf[0x200]; |
Al Cho | 126bb03 | 2010-09-08 00:42:32 -0700 | [diff] [blame] | 70 | |
Laura Lawniczak | 29b3142 | 2013-06-06 18:10:47 +0200 | [diff] [blame] | 71 | dev_dbg(&us->pusb_dev->dev, "transport --- ENE_SMInit\n"); |
Al Cho | 126bb03 | 2010-09-08 00:42:32 -0700 | [diff] [blame] | 72 | |
| 73 | result = ENE_LoadBinCode(us, SM_INIT_PATTERN); |
Al Cho | e93192a | 2010-11-26 19:06:39 +0800 | [diff] [blame] | 74 | if (result != USB_STOR_XFER_GOOD) { |
Laura Lawniczak | 6fbb90b | 2013-06-06 18:10:48 +0200 | [diff] [blame] | 75 | dev_info(&us->pusb_dev->dev, |
| 76 | "Failed to load SmartMedia init code\n: result= %x\n", |
| 77 | result); |
Al Cho | 126bb03 | 2010-09-08 00:42:32 -0700 | [diff] [blame] | 78 | return USB_STOR_TRANSPORT_ERROR; |
| 79 | } |
| 80 | |
Konstantin Katuev | 307ae1d | 2010-10-29 12:18:18 +1100 | [diff] [blame] | 81 | memset(bcb, 0, sizeof(struct bulk_cb_wrap)); |
Al Cho | 126bb03 | 2010-09-08 00:42:32 -0700 | [diff] [blame] | 82 | bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN); |
| 83 | bcb->DataTransferLength = 0x200; |
| 84 | bcb->Flags = 0x80; |
| 85 | bcb->CDB[0] = 0xF1; |
| 86 | bcb->CDB[1] = 0x01; |
| 87 | |
| 88 | result = ENE_SendScsiCmd(us, FDIR_READ, &buf, 0); |
Al Cho | e93192a | 2010-11-26 19:06:39 +0800 | [diff] [blame] | 89 | if (result != USB_STOR_XFER_GOOD) { |
Laura Lawniczak | 6fbb90b | 2013-06-06 18:10:48 +0200 | [diff] [blame] | 90 | dev_err(&us->pusb_dev->dev, |
| 91 | "Failed to load SmartMedia init code: result = %x\n", |
| 92 | result); |
Al Cho | 126bb03 | 2010-09-08 00:42:32 -0700 | [diff] [blame] | 93 | return USB_STOR_TRANSPORT_ERROR; |
| 94 | } |
| 95 | |
Johannes Schilling | 8be8804 | 2013-06-06 18:10:45 +0200 | [diff] [blame] | 96 | us->SM_Status = *(struct keucr_sm_status *)&buf[0]; |
Al Cho | 126bb03 | 2010-09-08 00:42:32 -0700 | [diff] [blame] | 97 | |
| 98 | us->SM_DeviceID = buf[1]; |
| 99 | us->SM_CardID = buf[2]; |
| 100 | |
Al Cho | e93192a | 2010-11-26 19:06:39 +0800 | [diff] [blame] | 101 | if (us->SM_Status.Insert && us->SM_Status.Ready) { |
Johannes Schilling | 0ea8a16 | 2013-06-06 18:10:50 +0200 | [diff] [blame] | 102 | dev_info(&us->pusb_dev->dev, "Insert = %x\n", |
| 103 | us->SM_Status.Insert); |
| 104 | dev_info(&us->pusb_dev->dev, "Ready = %x\n", |
| 105 | us->SM_Status.Ready); |
| 106 | dev_info(&us->pusb_dev->dev, "WtP = %x\n", |
| 107 | us->SM_Status.WtP); |
| 108 | dev_info(&us->pusb_dev->dev, "DeviceID = %x\n", |
| 109 | us->SM_DeviceID); |
| 110 | dev_info(&us->pusb_dev->dev, "CardID = %x\n", |
| 111 | us->SM_CardID); |
Al Cho | 126bb03 | 2010-09-08 00:42:32 -0700 | [diff] [blame] | 112 | MediaChange = 1; |
| 113 | Check_D_MediaFmt(us); |
Al Cho | e93192a | 2010-11-26 19:06:39 +0800 | [diff] [blame] | 114 | } else { |
Laura Lawniczak | 6fbb90b | 2013-06-06 18:10:48 +0200 | [diff] [blame] | 115 | dev_err(&us->pusb_dev->dev, |
| 116 | "SmartMedia Card Not Ready --- %x\n", buf[0]); |
Al Cho | 126bb03 | 2010-09-08 00:42:32 -0700 | [diff] [blame] | 117 | return USB_STOR_TRANSPORT_ERROR; |
| 118 | } |
| 119 | |
| 120 | return USB_STOR_TRANSPORT_GOOD; |
| 121 | } |
| 122 | |
Al Cho | e93192a | 2010-11-26 19:06:39 +0800 | [diff] [blame] | 123 | /* |
Al Cho | e93192a | 2010-11-26 19:06:39 +0800 | [diff] [blame] | 124 | * ENE_LoadBinCode() |
| 125 | */ |
Himangi Saraogi | 432f857 | 2014-03-16 03:14:57 +0530 | [diff] [blame] | 126 | int ENE_LoadBinCode(struct us_data *us, u8 flag) |
Al Cho | 126bb03 | 2010-09-08 00:42:32 -0700 | [diff] [blame] | 127 | { |
| 128 | struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf; |
| 129 | int result; |
Al Cho | e93192a | 2010-11-26 19:06:39 +0800 | [diff] [blame] | 130 | /* void *buf; */ |
Himangi Saraogi | 432f857 | 2014-03-16 03:14:57 +0530 | [diff] [blame] | 131 | u8 *buf; |
Al Cho | 126bb03 | 2010-09-08 00:42:32 -0700 | [diff] [blame] | 132 | |
Laura Lawniczak | 29b3142 | 2013-06-06 18:10:47 +0200 | [diff] [blame] | 133 | /* dev_info(&us->pusb_dev->dev, "transport --- ENE_LoadBinCode\n"); */ |
Al Cho | 126bb03 | 2010-09-08 00:42:32 -0700 | [diff] [blame] | 134 | if (us->BIN_FLAG == flag) |
| 135 | return USB_STOR_TRANSPORT_GOOD; |
| 136 | |
| 137 | buf = kmalloc(0x800, GFP_KERNEL); |
Vasiliy Kulikov | b1f5f54 | 2010-09-19 11:36:23 +0400 | [diff] [blame] | 138 | if (buf == NULL) |
| 139 | return USB_STOR_TRANSPORT_ERROR; |
Al Cho | e93192a | 2010-11-26 19:06:39 +0800 | [diff] [blame] | 140 | switch (flag) { |
Al Cho | e93192a | 2010-11-26 19:06:39 +0800 | [diff] [blame] | 141 | /* For SS */ |
| 142 | case SM_INIT_PATTERN: |
Laura Lawniczak | 29b3142 | 2013-06-06 18:10:47 +0200 | [diff] [blame] | 143 | dev_dbg(&us->pusb_dev->dev, "SM_INIT_PATTERN\n"); |
Al Cho | e93192a | 2010-11-26 19:06:39 +0800 | [diff] [blame] | 144 | memcpy(buf, SM_Init, 0x800); |
Al Cho | 126bb03 | 2010-09-08 00:42:32 -0700 | [diff] [blame] | 145 | break; |
Al Cho | e93192a | 2010-11-26 19:06:39 +0800 | [diff] [blame] | 146 | case SM_RW_PATTERN: |
Laura Lawniczak | 29b3142 | 2013-06-06 18:10:47 +0200 | [diff] [blame] | 147 | dev_dbg(&us->pusb_dev->dev, "SM_RW_PATTERN\n"); |
Al Cho | e93192a | 2010-11-26 19:06:39 +0800 | [diff] [blame] | 148 | memcpy(buf, SM_Rdwr, 0x800); |
Al Cho | 126bb03 | 2010-09-08 00:42:32 -0700 | [diff] [blame] | 149 | break; |
| 150 | } |
| 151 | |
Konstantin Katuev | 307ae1d | 2010-10-29 12:18:18 +1100 | [diff] [blame] | 152 | memset(bcb, 0, sizeof(struct bulk_cb_wrap)); |
Al Cho | 126bb03 | 2010-09-08 00:42:32 -0700 | [diff] [blame] | 153 | bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN); |
| 154 | bcb->DataTransferLength = 0x800; |
Al Cho | e93192a | 2010-11-26 19:06:39 +0800 | [diff] [blame] | 155 | bcb->Flags = 0x00; |
Al Cho | 126bb03 | 2010-09-08 00:42:32 -0700 | [diff] [blame] | 156 | bcb->CDB[0] = 0xEF; |
| 157 | |
| 158 | result = ENE_SendScsiCmd(us, FDIR_WRITE, buf, 0); |
| 159 | |
| 160 | kfree(buf); |
| 161 | us->BIN_FLAG = flag; |
| 162 | return result; |
| 163 | } |
| 164 | |
Al Cho | e93192a | 2010-11-26 19:06:39 +0800 | [diff] [blame] | 165 | /* |
| 166 | * ENE_SendScsiCmd(): |
| 167 | */ |
Himangi Saraogi | 432f857 | 2014-03-16 03:14:57 +0530 | [diff] [blame] | 168 | int ENE_SendScsiCmd(struct us_data *us, u8 fDir, void *buf, int use_sg) |
Al Cho | 126bb03 | 2010-09-08 00:42:32 -0700 | [diff] [blame] | 169 | { |
| 170 | struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf; |
| 171 | struct bulk_cs_wrap *bcs = (struct bulk_cs_wrap *) us->iobuf; |
| 172 | |
| 173 | int result; |
Al Cho | e93192a | 2010-11-26 19:06:39 +0800 | [diff] [blame] | 174 | unsigned int transfer_length = bcb->DataTransferLength, |
| 175 | cswlen = 0, partial = 0; |
Al Cho | 126bb03 | 2010-09-08 00:42:32 -0700 | [diff] [blame] | 176 | unsigned int residue; |
| 177 | |
Laura Lawniczak | 29b3142 | 2013-06-06 18:10:47 +0200 | [diff] [blame] | 178 | /* dev_dbg(&us->pusb_dev->dev, "transport --- ENE_SendScsiCmd\n"); */ |
Al Cho | e93192a | 2010-11-26 19:06:39 +0800 | [diff] [blame] | 179 | /* send cmd to out endpoint */ |
| 180 | result = usb_stor_bulk_transfer_buf(us, us->send_bulk_pipe, |
| 181 | bcb, US_BULK_CB_WRAP_LEN, NULL); |
| 182 | if (result != USB_STOR_XFER_GOOD) { |
Johannes Schilling | 0ea8a16 | 2013-06-06 18:10:50 +0200 | [diff] [blame] | 183 | dev_err(&us->pusb_dev->dev, |
| 184 | "send cmd to out endpoint fail ---\n"); |
Al Cho | 126bb03 | 2010-09-08 00:42:32 -0700 | [diff] [blame] | 185 | return USB_STOR_TRANSPORT_ERROR; |
| 186 | } |
| 187 | |
Al Cho | e93192a | 2010-11-26 19:06:39 +0800 | [diff] [blame] | 188 | if (buf) { |
Al Cho | 6efe04e | 2010-11-26 19:07:27 +0800 | [diff] [blame] | 189 | unsigned int pipe = fDir; |
| 190 | |
| 191 | if (fDir == FDIR_READ) |
| 192 | pipe = us->recv_bulk_pipe; |
| 193 | else |
| 194 | pipe = us->send_bulk_pipe; |
| 195 | |
Al Cho | e93192a | 2010-11-26 19:06:39 +0800 | [diff] [blame] | 196 | /* Bulk */ |
Al Cho | 126bb03 | 2010-09-08 00:42:32 -0700 | [diff] [blame] | 197 | if (use_sg) |
| 198 | result = usb_stor_bulk_srb(us, pipe, us->srb); |
| 199 | else |
Al Cho | e93192a | 2010-11-26 19:06:39 +0800 | [diff] [blame] | 200 | result = usb_stor_bulk_transfer_sg(us, pipe, buf, |
| 201 | transfer_length, 0, &partial); |
| 202 | if (result != USB_STOR_XFER_GOOD) { |
Laura Lawniczak | 29b3142 | 2013-06-06 18:10:47 +0200 | [diff] [blame] | 203 | dev_err(&us->pusb_dev->dev, "data transfer fail ---\n"); |
Al Cho | 126bb03 | 2010-09-08 00:42:32 -0700 | [diff] [blame] | 204 | return USB_STOR_TRANSPORT_ERROR; |
| 205 | } |
| 206 | } |
| 207 | |
Al Cho | e93192a | 2010-11-26 19:06:39 +0800 | [diff] [blame] | 208 | /* Get CSW for device status */ |
| 209 | result = usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe, bcs, |
| 210 | US_BULK_CS_WRAP_LEN, &cswlen); |
Al Cho | 126bb03 | 2010-09-08 00:42:32 -0700 | [diff] [blame] | 211 | |
Al Cho | e93192a | 2010-11-26 19:06:39 +0800 | [diff] [blame] | 212 | if (result == USB_STOR_XFER_SHORT && cswlen == 0) { |
Johannes Schilling | 0ea8a16 | 2013-06-06 18:10:50 +0200 | [diff] [blame] | 213 | dev_warn(&us->pusb_dev->dev, |
| 214 | "Received 0-length CSW; retrying...\n"); |
Al Cho | e93192a | 2010-11-26 19:06:39 +0800 | [diff] [blame] | 215 | result = usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe, |
| 216 | bcs, US_BULK_CS_WRAP_LEN, &cswlen); |
Al Cho | 126bb03 | 2010-09-08 00:42:32 -0700 | [diff] [blame] | 217 | } |
| 218 | |
Al Cho | e93192a | 2010-11-26 19:06:39 +0800 | [diff] [blame] | 219 | if (result == USB_STOR_XFER_STALLED) { |
Al Cho | 126bb03 | 2010-09-08 00:42:32 -0700 | [diff] [blame] | 220 | /* get the status again */ |
Johannes Schilling | 0ea8a16 | 2013-06-06 18:10:50 +0200 | [diff] [blame] | 221 | dev_warn(&us->pusb_dev->dev, |
| 222 | "Attempting to get CSW (2nd try)...\n"); |
Al Cho | e93192a | 2010-11-26 19:06:39 +0800 | [diff] [blame] | 223 | result = usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe, |
| 224 | bcs, US_BULK_CS_WRAP_LEN, NULL); |
Al Cho | 126bb03 | 2010-09-08 00:42:32 -0700 | [diff] [blame] | 225 | } |
| 226 | |
| 227 | if (result != USB_STOR_XFER_GOOD) |
| 228 | return USB_STOR_TRANSPORT_ERROR; |
| 229 | |
| 230 | /* check bulk status */ |
| 231 | residue = le32_to_cpu(bcs->Residue); |
| 232 | |
Al Cho | e93192a | 2010-11-26 19:06:39 +0800 | [diff] [blame] | 233 | /* |
| 234 | * try to compute the actual residue, based on how much data |
| 235 | * was really transferred and what the device tells us |
| 236 | */ |
| 237 | if (residue && !(us->fflags & US_FL_IGNORE_RESIDUE)) { |
Al Cho | 126bb03 | 2010-09-08 00:42:32 -0700 | [diff] [blame] | 238 | residue = min(residue, transfer_length); |
huajun li | 41e568d | 2011-03-04 10:56:18 +0800 | [diff] [blame] | 239 | if (us->srb) |
| 240 | scsi_set_resid(us->srb, max(scsi_get_resid(us->srb), |
| 241 | (int) residue)); |
Al Cho | 126bb03 | 2010-09-08 00:42:32 -0700 | [diff] [blame] | 242 | } |
| 243 | |
| 244 | if (bcs->Status != US_BULK_STAT_OK) |
| 245 | return USB_STOR_TRANSPORT_ERROR; |
| 246 | |
| 247 | return USB_STOR_TRANSPORT_GOOD; |
| 248 | } |
| 249 | |
Al Cho | e93192a | 2010-11-26 19:06:39 +0800 | [diff] [blame] | 250 | /* |
| 251 | * ENE_Read_Data() |
| 252 | */ |
Al Cho | 126bb03 | 2010-09-08 00:42:32 -0700 | [diff] [blame] | 253 | int ENE_Read_Data(struct us_data *us, void *buf, unsigned int length) |
| 254 | { |
| 255 | struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf; |
| 256 | struct bulk_cs_wrap *bcs = (struct bulk_cs_wrap *) us->iobuf; |
| 257 | int result; |
| 258 | |
Laura Lawniczak | 29b3142 | 2013-06-06 18:10:47 +0200 | [diff] [blame] | 259 | /* dev_dbg(&us->pusb_dev->dev, "transport --- ENE_Read_Data\n"); */ |
Al Cho | e93192a | 2010-11-26 19:06:39 +0800 | [diff] [blame] | 260 | /* set up the command wrapper */ |
Konstantin Katuev | 307ae1d | 2010-10-29 12:18:18 +1100 | [diff] [blame] | 261 | memset(bcb, 0, sizeof(struct bulk_cb_wrap)); |
Al Cho | 126bb03 | 2010-09-08 00:42:32 -0700 | [diff] [blame] | 262 | bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN); |
| 263 | bcb->DataTransferLength = length; |
Al Cho | e93192a | 2010-11-26 19:06:39 +0800 | [diff] [blame] | 264 | bcb->Flags = 0x80; |
Al Cho | 126bb03 | 2010-09-08 00:42:32 -0700 | [diff] [blame] | 265 | bcb->CDB[0] = 0xED; |
| 266 | bcb->CDB[2] = 0xFF; |
| 267 | bcb->CDB[3] = 0x81; |
| 268 | |
Al Cho | e93192a | 2010-11-26 19:06:39 +0800 | [diff] [blame] | 269 | /* send cmd to out endpoint */ |
| 270 | result = usb_stor_bulk_transfer_buf(us, us->send_bulk_pipe, bcb, |
| 271 | US_BULK_CB_WRAP_LEN, NULL); |
Al Cho | 126bb03 | 2010-09-08 00:42:32 -0700 | [diff] [blame] | 272 | if (result != USB_STOR_XFER_GOOD) |
| 273 | return USB_STOR_TRANSPORT_ERROR; |
| 274 | |
Al Cho | e93192a | 2010-11-26 19:06:39 +0800 | [diff] [blame] | 275 | /* R/W data */ |
| 276 | result = usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe, |
| 277 | buf, length, NULL); |
Al Cho | 126bb03 | 2010-09-08 00:42:32 -0700 | [diff] [blame] | 278 | if (result != USB_STOR_XFER_GOOD) |
| 279 | return USB_STOR_TRANSPORT_ERROR; |
| 280 | |
Al Cho | e93192a | 2010-11-26 19:06:39 +0800 | [diff] [blame] | 281 | /* Get CSW for device status */ |
| 282 | result = usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe, bcs, |
| 283 | US_BULK_CS_WRAP_LEN, NULL); |
Al Cho | 126bb03 | 2010-09-08 00:42:32 -0700 | [diff] [blame] | 284 | if (result != USB_STOR_XFER_GOOD) |
| 285 | return USB_STOR_TRANSPORT_ERROR; |
| 286 | if (bcs->Status != US_BULK_STAT_OK) |
| 287 | return USB_STOR_TRANSPORT_ERROR; |
| 288 | |
| 289 | return USB_STOR_TRANSPORT_GOOD; |
| 290 | } |
| 291 | |
Al Cho | e93192a | 2010-11-26 19:06:39 +0800 | [diff] [blame] | 292 | /* |
| 293 | * ENE_Write_Data(): |
| 294 | */ |
Al Cho | 126bb03 | 2010-09-08 00:42:32 -0700 | [diff] [blame] | 295 | int ENE_Write_Data(struct us_data *us, void *buf, unsigned int length) |
| 296 | { |
| 297 | struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf; |
| 298 | struct bulk_cs_wrap *bcs = (struct bulk_cs_wrap *) us->iobuf; |
| 299 | int result; |
| 300 | |
Al Cho | e93192a | 2010-11-26 19:06:39 +0800 | [diff] [blame] | 301 | /* printk("transport --- ENE_Write_Data\n"); */ |
| 302 | /* set up the command wrapper */ |
Konstantin Katuev | 307ae1d | 2010-10-29 12:18:18 +1100 | [diff] [blame] | 303 | memset(bcb, 0, sizeof(struct bulk_cb_wrap)); |
Al Cho | 126bb03 | 2010-09-08 00:42:32 -0700 | [diff] [blame] | 304 | bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN); |
| 305 | bcb->DataTransferLength = length; |
Al Cho | e93192a | 2010-11-26 19:06:39 +0800 | [diff] [blame] | 306 | bcb->Flags = 0x00; |
Al Cho | 126bb03 | 2010-09-08 00:42:32 -0700 | [diff] [blame] | 307 | bcb->CDB[0] = 0xEE; |
| 308 | bcb->CDB[2] = 0xFF; |
| 309 | bcb->CDB[3] = 0x81; |
| 310 | |
Al Cho | e93192a | 2010-11-26 19:06:39 +0800 | [diff] [blame] | 311 | /* send cmd to out endpoint */ |
| 312 | result = usb_stor_bulk_transfer_buf(us, us->send_bulk_pipe, bcb, |
| 313 | US_BULK_CB_WRAP_LEN, NULL); |
Al Cho | 126bb03 | 2010-09-08 00:42:32 -0700 | [diff] [blame] | 314 | if (result != USB_STOR_XFER_GOOD) |
| 315 | return USB_STOR_TRANSPORT_ERROR; |
| 316 | |
Al Cho | e93192a | 2010-11-26 19:06:39 +0800 | [diff] [blame] | 317 | /* R/W data */ |
| 318 | result = usb_stor_bulk_transfer_buf(us, us->send_bulk_pipe, |
| 319 | buf, length, NULL); |
Al Cho | 126bb03 | 2010-09-08 00:42:32 -0700 | [diff] [blame] | 320 | if (result != USB_STOR_XFER_GOOD) |
| 321 | return USB_STOR_TRANSPORT_ERROR; |
| 322 | |
Al Cho | e93192a | 2010-11-26 19:06:39 +0800 | [diff] [blame] | 323 | /* Get CSW for device status */ |
| 324 | result = usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe, bcs, |
| 325 | US_BULK_CS_WRAP_LEN, NULL); |
Al Cho | 126bb03 | 2010-09-08 00:42:32 -0700 | [diff] [blame] | 326 | if (result != USB_STOR_XFER_GOOD) |
| 327 | return USB_STOR_TRANSPORT_ERROR; |
| 328 | if (bcs->Status != US_BULK_STAT_OK) |
| 329 | return USB_STOR_TRANSPORT_ERROR; |
| 330 | |
| 331 | return USB_STOR_TRANSPORT_GOOD; |
| 332 | } |
| 333 | |