Changeset 00c2de63 in mainline for uspace/drv/bus/usb/usbmast/bo_trans.c
- Timestamp:
- 2011-07-29T14:50:22Z (13 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- b6759f4
- Parents:
- 6c69d19 (diff), 7ae249d (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/bus/usb/usbmast/bo_trans.c
r6c69d19 r00c2de63 58 58 * @param tag Command block wrapper tag (automatically compared 59 59 * with answer) 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 60 * @param cmd SCSI command 66 61 * 67 62 * @return Error code 68 63 */ 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) 64 int usb_massstor_cmd(usbmast_fun_t *mfun, uint32_t tag, scsi_cmd_t *cmd) 72 65 { 73 66 int rc; 67 int retval = EOK; 74 68 size_t act_size; 75 69 usb_pipe_t *bulk_in_pipe = mfun->mdev->usb_dev->pipes[BULK_IN_EP].pipe; 76 70 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 } 77 86 78 87 /* Prepare CBW - command block wrapper */ 79 88 usb_massstor_cbw_t cbw; 80 89 usb_massstor_cbw_prepare(&cbw, tag, dbuf_size, ddir, mfun->lun, 81 cmd _size, cmd);90 cmd->cdb_size, cmd->cdb); 82 91 83 92 /* Send the CBW. */ 93 MASTLOG("Sending CBW.\n"); 84 94 rc = usb_pipe_write(bulk_out_pipe, &cbw, sizeof(cbw)); 85 95 MASTLOG("CBW '%s' sent: %s.\n", 86 96 usb_debug_str_buffer((uint8_t *) &cbw, sizeof(cbw), 0), 87 97 str_error(rc)); 88 if (rc != EOK) {89 return rc;90 } 91 98 if (rc != EOK) 99 return EIO; 100 101 MASTLOG("Transferring data.\n"); 92 102 if (ddir == USB_DIRECTION_IN) { 93 103 /* Recieve data from the device. */ … … 104 114 } 105 115 106 if (rc != EOK) { 107 /* 108 * XXX If the pipe is stalled, we should clear it 109 * and read CSW. 110 */ 111 return rc; 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; 112 127 } 113 128 … … 115 130 usb_massstor_csw_t csw; 116 131 size_t csw_size; 132 MASTLOG("Reading CSW.\n"); 117 133 rc = usb_pipe_read(bulk_in_pipe, &csw, sizeof(csw), &csw_size); 118 134 MASTLOG("CSW '%s' received (%zu bytes): %s.\n", … … 121 137 if (rc != EOK) { 122 138 MASTLOG("rc != EOK\n"); 123 return rc;139 return EIO; 124 140 } 125 141 126 142 if (csw_size != sizeof(csw)) { 127 143 MASTLOG("csw_size != sizeof(csw)\n"); 128 return E RANGE;144 return EIO; 129 145 } 130 146 131 147 if (csw.dCSWTag != tag) { 132 148 MASTLOG("csw.dCSWTag != tag\n"); 133 return E BADCHECKSUM;149 return EIO; 134 150 } 135 151 … … 137 153 * Determine the actual return value from the CSW. 138 154 */ 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; 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; 144 170 } 145 171 … … 147 173 if (residue > dbuf_size) { 148 174 MASTLOG("residue > dbuf_size\n"); 149 return E RANGE;175 return EIO; 150 176 } 151 177 … … 158 184 */ 159 185 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); 186 if (ddir == USB_DIRECTION_IN) 187 cmd->rcvd_size = dbuf_size - residue; 188 189 return retval; 204 190 } 205 191
Note:
See TracChangeset
for help on using the changeset viewer.