Changes in uspace/drv/bus/usb/usbmast/bo_trans.c [de3432b:2aceec5] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/bus/usb/usbmast/bo_trans.c
rde3432b r2aceec5 58 58 * @param tag Command block wrapper tag (automatically compared 59 59 * with answer) 60 * @param cmd SCSI command 60 * @param cmd Command block 61 * @param cmd_size Command block size in bytes 62 * @param ddir Direction in which data will be transferred 63 * @param dbuf Data send/receive buffer 64 * @param dbuf_size Size of the data buffer 65 * @param xferred_size Number of bytes actually transferred 61 66 * 62 67 * @return Error code 63 68 */ 64 int usb_massstor_cmd(usbmast_fun_t *mfun, uint32_t tag, scsi_cmd_t *cmd) 69 static int usb_massstor_cmd(usbmast_fun_t *mfun, uint32_t tag, const void *cmd, 70 size_t cmd_size, usb_direction_t ddir, void *dbuf, size_t dbuf_size, 71 size_t *xferred_size) 65 72 { 66 73 int rc; 67 int retval = EOK;68 74 size_t act_size; 69 75 usb_pipe_t *bulk_in_pipe = mfun->mdev->usb_dev->pipes[BULK_IN_EP].pipe; 70 76 usb_pipe_t *bulk_out_pipe = mfun->mdev->usb_dev->pipes[BULK_OUT_EP].pipe; 71 usb_direction_t ddir;72 void *dbuf;73 size_t dbuf_size;74 75 if (cmd->data_out != NULL && cmd->data_in == NULL) {76 ddir = USB_DIRECTION_OUT;77 dbuf = (void *)cmd->data_out;78 dbuf_size = cmd->data_out_size;79 } else if (cmd->data_out == NULL && cmd->data_in != NULL) {80 ddir = USB_DIRECTION_IN;81 dbuf = cmd->data_in;82 dbuf_size = cmd->data_in_size;83 } else {84 assert(false);85 }86 77 87 78 /* Prepare CBW - command block wrapper */ 88 79 usb_massstor_cbw_t cbw; 89 80 usb_massstor_cbw_prepare(&cbw, tag, dbuf_size, ddir, mfun->lun, 90 cmd ->cdb_size, cmd->cdb);81 cmd_size, cmd); 91 82 92 83 /* Send the CBW. */ 93 MASTLOG("Sending CBW.\n");94 84 rc = usb_pipe_write(bulk_out_pipe, &cbw, sizeof(cbw)); 95 85 MASTLOG("CBW '%s' sent: %s.\n", 96 86 usb_debug_str_buffer((uint8_t *) &cbw, sizeof(cbw), 0), 97 87 str_error(rc)); 98 if (rc != EOK) 99 return EIO;100 101 MASTLOG("Transferring data.\n"); 88 if (rc != EOK) { 89 return rc; 90 } 91 102 92 if (ddir == USB_DIRECTION_IN) { 103 93 /* Recieve data from the device. */ … … 114 104 } 115 105 116 if (rc == ESTALL) { 117 /* Clear stall condition and continue below to read CSW. */ 118 if (ddir == USB_DIRECTION_IN) { 119 usb_pipe_clear_halt(&mfun->mdev->usb_dev->ctrl_pipe, 120 mfun->mdev->usb_dev->pipes[BULK_IN_EP].pipe); 121 } else { 122 usb_pipe_clear_halt(&mfun->mdev->usb_dev->ctrl_pipe, 123 mfun->mdev->usb_dev->pipes[BULK_OUT_EP].pipe); 124 } 125 } else if (rc != EOK) { 126 return EIO; 106 if (rc != EOK) { 107 /* 108 * XXX If the pipe is stalled, we should clear it 109 * and read CSW. 110 */ 111 return rc; 127 112 } 128 113 … … 130 115 usb_massstor_csw_t csw; 131 116 size_t csw_size; 132 MASTLOG("Reading CSW.\n");133 117 rc = usb_pipe_read(bulk_in_pipe, &csw, sizeof(csw), &csw_size); 134 118 MASTLOG("CSW '%s' received (%zu bytes): %s.\n", … … 137 121 if (rc != EOK) { 138 122 MASTLOG("rc != EOK\n"); 139 return EIO;123 return rc; 140 124 } 141 125 142 126 if (csw_size != sizeof(csw)) { 143 127 MASTLOG("csw_size != sizeof(csw)\n"); 144 return E IO;128 return ERANGE; 145 129 } 146 130 147 131 if (csw.dCSWTag != tag) { 148 132 MASTLOG("csw.dCSWTag != tag\n"); 149 return E IO;133 return EBADCHECKSUM; 150 134 } 151 135 … … 153 137 * Determine the actual return value from the CSW. 154 138 */ 155 switch (csw.dCSWStatus) { 156 case cbs_passed: 157 cmd->status = CMDS_GOOD; 158 break; 159 case cbs_failed: 160 MASTLOG("Command failed\n"); 161 cmd->status = CMDS_FAILED; 162 break; 163 case cbs_phase_error: 164 MASTLOG("Phase error\n"); 165 retval = EIO; 166 break; 167 default: 168 retval = EIO; 169 break; 139 if (csw.dCSWStatus != 0) { 140 MASTLOG("csw.dCSWStatus != 0\n"); 141 // FIXME: better error code 142 // FIXME: distinguish 0x01 and 0x02 143 return EXDEV; 170 144 } 171 145 … … 173 147 if (residue > dbuf_size) { 174 148 MASTLOG("residue > dbuf_size\n"); 175 return E IO;149 return ERANGE; 176 150 } 177 151 … … 184 158 */ 185 159 186 if (ddir == USB_DIRECTION_IN) 187 cmd->rcvd_size = dbuf_size - residue; 188 189 return retval; 160 if (xferred_size != NULL) 161 *xferred_size = dbuf_size - residue; 162 163 return EOK; 164 } 165 166 /** Perform data-in command. 167 * 168 * @param mfun Mass storage function 169 * @param tag Command block wrapper tag (automatically compared with 170 * answer) 171 * @param cmd CDB (Command Descriptor) 172 * @param cmd_size CDB length in bytes 173 * @param dbuf Data receive buffer 174 * @param dbuf_size Data receive buffer size in bytes 175 * @param proc_size Number of bytes actually processed by device 176 * 177 * @return Error code 178 */ 179 int usb_massstor_data_in(usbmast_fun_t *mfun, uint32_t tag, const void *cmd, 180 size_t cmd_size, void *dbuf, size_t dbuf_size, size_t *proc_size) 181 { 182 return usb_massstor_cmd(mfun, tag, cmd, cmd_size, USB_DIRECTION_IN, 183 dbuf, dbuf_size, proc_size); 184 } 185 186 /** Perform data-out command. 187 * 188 * @param mfun Mass storage function 189 * @param tag Command block wrapper tag (automatically compared with 190 * answer) 191 * @param cmd CDB (Command Descriptor) 192 * @param cmd_size CDB length in bytes 193 * @param data Command data 194 * @param data_size Size of @a data in bytes 195 * @param proc_size Number of bytes actually processed by device 196 * 197 * @return Error code 198 */ 199 int usb_massstor_data_out(usbmast_fun_t *mfun, uint32_t tag, const void *cmd, 200 size_t cmd_size, const void *data, size_t data_size, size_t *proc_size) 201 { 202 return usb_massstor_cmd(mfun, tag, cmd, cmd_size, USB_DIRECTION_OUT, 203 (void *) data, data_size, proc_size); 190 204 } 191 205
Note:
See TracChangeset
for help on using the changeset viewer.