00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00036 #include "mast.h"
00037 #include "cmds.h"
00038 #include <bool.h>
00039 #include <errno.h>
00040 #include <str_error.h>
00041 #include <usb/debug.h>
00042 #include <usb/dev/request.h>
00043
00044 bool usb_mast_verbose = true;
00045
00046 #define MASTLOG(format, ...) \
00047 do { \
00048 if (usb_mast_verbose) { \
00049 usb_log_debug("USB cl08: " format, ##__VA_ARGS__); \
00050 } \
00051 } while (false)
00052
00066 int usb_massstor_data_in(usb_device_t *dev,
00067 size_t bulk_in_pipe_index, size_t bulk_out_pipe_index,
00068 uint32_t tag, uint8_t lun, void *cmd, size_t cmd_size,
00069 void *in_buffer, size_t in_buffer_size, size_t *received_size)
00070 {
00071 int rc;
00072 size_t act_size;
00073 usb_pipe_t *bulk_in_pipe = dev->pipes[bulk_in_pipe_index].pipe;
00074 usb_pipe_t *bulk_out_pipe = dev->pipes[bulk_out_pipe_index].pipe;
00075
00076
00077 usb_massstor_cbw_t cbw;
00078 usb_massstor_cbw_prepare(&cbw, tag, in_buffer_size,
00079 USB_DIRECTION_IN, lun, cmd_size, cmd);
00080
00081
00082 rc = usb_pipe_write(bulk_out_pipe, &cbw, sizeof(cbw));
00083 MASTLOG("CBW '%s' sent: %s.\n",
00084 usb_debug_str_buffer((uint8_t *) &cbw, sizeof(cbw), 0),
00085 str_error(rc));
00086 if (rc != EOK) {
00087 return rc;
00088 }
00089
00090
00091 act_size = 0;
00092 rc = usb_pipe_read(bulk_in_pipe, in_buffer, in_buffer_size, &act_size);
00093 MASTLOG("Received %zuB (%s): %s.\n", act_size,
00094 usb_debug_str_buffer((uint8_t *) in_buffer, act_size, 0),
00095 str_error(rc));
00096 if (rc != EOK) {
00097 return rc;
00098 }
00099
00100
00101 usb_massstor_csw_t csw;
00102 size_t csw_size;
00103 rc = usb_pipe_read(bulk_in_pipe, &csw, sizeof(csw), &csw_size);
00104 MASTLOG("CSW '%s' received (%zuB): %s.\n",
00105 usb_debug_str_buffer((uint8_t *) &csw, csw_size, 0), csw_size,
00106 str_error(rc));
00107 if (rc != EOK) {
00108 return rc;
00109 }
00110 if (csw_size != sizeof(csw)) {
00111 return ERANGE;
00112 }
00113
00114 if (csw.dCSWTag != tag) {
00115 return EBADCHECKSUM;
00116 }
00117
00118
00119
00120
00121 if (csw.dCSWStatus != 0) {
00122
00123
00124 return EXDEV;
00125 }
00126
00127 size_t residue = (size_t) uint32_usb2host(csw.dCSWDataResidue);
00128 if (residue > in_buffer_size) {
00129 return ERANGE;
00130 }
00131 if (act_size != in_buffer_size - residue) {
00132 return ERANGE;
00133 }
00134 if (received_size != NULL) {
00135 *received_size = in_buffer_size - residue;
00136 }
00137
00138 return EOK;
00139 }
00140
00146 int usb_massstor_reset(usb_device_t *dev)
00147 {
00148 return usb_control_request_set(&dev->ctrl_pipe,
00149 USB_REQUEST_TYPE_CLASS, USB_REQUEST_RECIPIENT_INTERFACE,
00150 0xFF, 0, dev->interface_no, NULL, 0);
00151 }
00152
00162 void usb_massstor_reset_recovery(usb_device_t *dev,
00163 size_t bulk_in_idx, size_t bulk_out_idx)
00164 {
00165
00166
00167
00168 usb_massstor_reset(dev);
00169 usb_pipe_clear_halt(&dev->ctrl_pipe, dev->pipes[bulk_in_idx].pipe);
00170 usb_pipe_clear_halt(&dev->ctrl_pipe, dev->pipes[bulk_out_idx].pipe);
00171 }
00172
00184 int usb_massstor_get_max_lun(usb_device_t *dev)
00185 {
00186 uint8_t max_lun;
00187 size_t data_recv_len;
00188 int rc = usb_control_request_get(&dev->ctrl_pipe,
00189 USB_REQUEST_TYPE_CLASS, USB_REQUEST_RECIPIENT_INTERFACE,
00190 0xFE, 0, dev->interface_no, &max_lun, 1, &data_recv_len);
00191 if (rc != EOK) {
00192 return rc;
00193 }
00194 if (data_recv_len != 1) {
00195 return EEMPTY;
00196 }
00197 return (int) max_lun;
00198 }
00199
00208 size_t usb_masstor_get_lun_count(usb_device_t *dev)
00209 {
00210 int max_lun = usb_massstor_get_max_lun(dev);
00211 if (max_lun < 0) {
00212 max_lun = 1;
00213 } else {
00214 max_lun++;
00215 }
00216
00217 return (size_t) max_lun;
00218 }
00219