00001 #include <usb-msc-bulk.h>
00002 #include <usb-api.h>
00003 #include <usb-core.h>
00004 #include <sys/process.h>
00005 #include <stdio.h>
00006 #include <rbc_const.h>
00007 #include <rbc_struct.h>
00008 #include <string.h>
00009
00010 #ifdef DEBUG
00011 #define PRINTF(...) printf(__VA_ARGS__)
00012 #else
00013 #define PRINTF(...)
00014 #endif
00015
00016 #ifndef USB_RBC_NUM_BLOCKS
00017 #define USB_RBC_NUM_BLOCKS 32
00018 #endif
00019
00020 static struct spc2_sense_data sense_data =
00021 {
00022 SCSI_SENSE_CURRENT_ERROR,
00023 0,
00024 0,
00025 {0},
00026 (sizeof(struct spc2_sense_data)
00027 - offsetof(struct spc2_sense_data, command_specific))
00028 };
00029
00030 static void
00031 scsi_error(unsigned int sense_key, unsigned int asc, int32_t info)
00032 {
00033 sense_data.response_code = SCSI_SENSE_INFORMATION_VALID | SCSI_SENSE_CURRENT_ERROR;
00034 sense_data.information[0] = (info >> 24) & 0xff;
00035 sense_data.information[1] = (info >> 16) & 0xff;
00036 sense_data.information[2] = (info >> 8) & 0xff;
00037 sense_data.information[3] = info & 0xff;
00038 sense_data.sense_key = sense_key;
00039 sense_data.asc = (asc >> 8) & 0xff;
00040 sense_data.ascq = asc & 0xff;
00041 }
00042
00043 static void
00044 scsi_ok()
00045 {
00046 sense_data.response_code = SCSI_SENSE_CURRENT_ERROR;
00047 sense_data.sense_key = SCSI_SENSE_KEY_NO_SENSE;
00048 sense_data.asc = 0x00;
00049 sense_data.ascq = 0x00;
00050 };
00051
00052 static const struct spc2_std_inquiry_data std_inquiry_data =
00053 {
00054 SCSI_STD_INQUIRY_CONNECTED | SCSI_STD_INQUIRY_TYPE_RBC,
00055 0,
00056 SCSI_STD_INQUIRY_VERSION_SPC2,
00057 0,
00058 (sizeof(struct spc2_std_inquiry_data)
00059 - offsetof(struct spc2_std_inquiry_data, flags3)),
00060 0,
00061 0,
00062 0,
00063 {'F','l','u','f','w','a','r','e'},
00064 {'T','e','s','t',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' '},
00065 {'0','.','1',' '}
00066 };
00067
00068 #define UNIT_NAME {'F','l','u','f','f','w','a','r','e',' ', \
00069 'P','s','e','u','d','o',' ','D','i','s','k'}
00070 #define UNIT_NAME_LENGTH 21
00071
00072 static const struct
00073 {
00074 struct spc2_vital_product_data_head head;
00075 struct {
00076 struct spc2_vital_product_data_head head;
00077 char unit_name[UNIT_NAME_LENGTH];
00078 } descriptor;
00079 } CC_BYTE_ALIGNED device_identification_data =
00080 {
00081 {
00082 SCSI_STD_INQUIRY_CONNECTED | SCSI_STD_INQUIRY_TYPE_RBC,
00083 SCSI_PAGE_DEVICE_IDENTIFICATION,
00084 0,
00085 sizeof(device_identification_data.descriptor),
00086 },
00087 {
00088 {
00089 SCSI_CODE_SET_ACSII,
00090 SCSI_IDENTIFIER_TYPE_NON_UNIQUE,
00091 0,
00092 sizeof(device_identification_data.descriptor.unit_name)
00093 },
00094 UNIT_NAME
00095 }
00096 };
00097
00098
00099 static const struct
00100 {
00101 struct spc2_vital_product_data_head head;
00102 uint8_t supported[3];
00103 } CC_BYTE_ALIGNED supported_pages_data =
00104 {
00105 {
00106 SCSI_STD_INQUIRY_CONNECTED | SCSI_STD_INQUIRY_TYPE_RBC,
00107 SCSI_PAGE_SUPPORTED_PAGES,
00108 0,
00109 sizeof(supported_pages_data.supported),
00110 },
00111 {SCSI_PAGE_SUPPORTED_PAGES, SCSI_PAGE_UNIT_SERIAL_NUMBER,
00112 SCSI_PAGE_DEVICE_IDENTIFICATION}
00113 };
00114
00115 static const struct
00116 {
00117 struct spc2_vital_product_data_head head;
00118 uint8_t serial_number[8];
00119 } CC_BYTE_ALIGNED unit_serial_number_data = {
00120 {
00121 SCSI_STD_INQUIRY_CONNECTED | SCSI_STD_INQUIRY_TYPE_RBC,
00122 SCSI_PAGE_SUPPORTED_PAGES,
00123 0,
00124 sizeof(unit_serial_number_data.serial_number)
00125 },
00126 {'1','2','3','4','5','6','7','8'}
00127 };
00128
00129 static usb_msc_handler_status
00130 handle_inquiry_cmd(struct usb_msc_command_state *state)
00131 {
00132 struct spc2_inquiry_cmd *cmd = (struct spc2_inquiry_cmd*)state->command;
00133 if (cmd->flags & SCSI_INQUIRY_FLAG_CMDDT) {
00134 scsi_error(SCSI_SENSE_KEY_ILLEGAL_REQUEST,SCSI_ASC_INVALID_FIELD_IN_CDB,
00135 cmd->allocation_length);
00136 return USB_MSC_HANDLER_FAILED;
00137 }
00138 if (cmd->flags & SCSI_INQUIRY_FLAG_EVPD) {
00139 PRINTF("Requested page %02x\n", cmd->page);
00140 switch (cmd->page) {
00141 case SCSI_PAGE_SUPPORTED_PAGES:
00142 usb_msc_send_data((uint8_t *)&supported_pages_data,
00143 sizeof(supported_pages_data),
00144 USB_MSC_DATA_SEND | USB_MSC_DATA_LAST);
00145 break;
00146 case SCSI_PAGE_DEVICE_IDENTIFICATION:
00147 usb_msc_send_data((uint8_t *)&device_identification_data,
00148 sizeof(device_identification_data),
00149 USB_MSC_DATA_SEND | USB_MSC_DATA_LAST);
00150 break;
00151 case SCSI_PAGE_UNIT_SERIAL_NUMBER:
00152 usb_msc_send_data((uint8_t *)&unit_serial_number_data,
00153 sizeof(unit_serial_number_data),
00154 USB_MSC_DATA_SEND | USB_MSC_DATA_LAST);
00155 break;
00156 default:
00157 scsi_error(SCSI_SENSE_KEY_ILLEGAL_REQUEST,SCSI_ASC_INVALID_FIELD_IN_CDB,
00158 cmd->allocation_length);
00159 return USB_MSC_HANDLER_FAILED;
00160 }
00161 return USB_MSC_HANDLER_OK;
00162 } else {
00163 if (cmd->page != 0) {
00164 scsi_error(SCSI_SENSE_KEY_ILLEGAL_REQUEST,SCSI_ASC_INVALID_FIELD_IN_CDB,
00165 cmd->allocation_length);
00166 return USB_MSC_HANDLER_FAILED;
00167 }
00168 usb_msc_send_data((uint8_t *)&std_inquiry_data,
00169 sizeof(std_inquiry_data),
00170 USB_MSC_DATA_SEND | USB_MSC_DATA_LAST);
00171 }
00172 return USB_MSC_HANDLER_OK;
00173 }
00174
00175 static usb_msc_handler_status
00176 handle_request_sense_cmd(struct usb_msc_command_state *state)
00177 {
00178 usb_msc_send_data((uint8_t *)&sense_data,
00179 sizeof(sense_data),
00180 USB_MSC_DATA_SEND | USB_MSC_DATA_LAST);
00181 return USB_MSC_HANDLER_OK;
00182 }
00183
00184 static usb_msc_handler_status
00185 handle_test_unit_ready_cmd(struct usb_msc_command_state *state)
00186 {
00187 scsi_ok();
00188 return USB_MSC_HANDLER_OK;
00189 }
00190
00191 static const struct rbc_read_capacity_data read_capacity_data =
00192 {
00193 HOST32_TO_BE_BYTES(USB_RBC_NUM_BLOCKS-1),
00194 HOST32_TO_BE_BYTES(512)
00195 };
00196
00197 static usb_msc_handler_status
00198 handle_read_capacity(struct usb_msc_command_state *state)
00199 {
00200 usb_msc_send_data((uint8_t *)&read_capacity_data,
00201 sizeof(read_capacity_data),
00202 USB_MSC_DATA_SEND | USB_MSC_DATA_LAST);
00203 return USB_MSC_HANDLER_OK;
00204 }
00205
00206 static const struct mode_sense_data {
00207 struct spc2_mode_parameter_header_6 header;
00208 struct rbc_device_parameters_page page;
00209 } CC_BYTE_ALIGNED mode_sense_data =
00210 {
00211 {
00212 (sizeof(mode_sense_data)
00213 - offsetof(struct mode_sense_data, header.medium_type)),
00214 0,0,0
00215 },
00216 {
00217 {SCSI_MODE_RBC_DEVICE_PAGE | SCSI_MODE_PAGE_SP,
00218 sizeof(mode_sense_data) - offsetof(struct mode_sense_data, page.flags1)},
00219 SCSI_MODE_WCD,
00220 HOST16_TO_BE_BYTES(512),
00221 HOST40_TO_BE_BYTES((long long)USB_RBC_NUM_BLOCKS),
00222 0x80,
00223 (SCSI_MODE_FORMATD | SCSI_MODE_LOCKD),
00224 0
00225 }
00226 };
00227
00228 static usb_msc_handler_status
00229 handle_mode_sense(struct usb_msc_command_state *state)
00230 {
00231 struct spc2_mode_sence_6_cmd *cmd =
00232 (struct spc2_mode_sence_6_cmd*)state->command;
00233 PRINTF("%ld - %ld - %ld\n", sizeof(struct mode_sense_data), offsetof(struct mode_sense_data, page.flags1),offsetof(struct mode_sense_data, page.reserved));
00234 switch(cmd->page_code) {
00235 case SCSI_MODE_RBC_DEVICE_PAGE:
00236 case SCSI_MODE_SENSE_ALL_PAGES:
00237 usb_msc_send_data((uint8_t *)&mode_sense_data,
00238 sizeof(mode_sense_data),
00239 USB_MSC_DATA_SEND | USB_MSC_DATA_LAST);
00240 break;
00241 default:
00242 scsi_error(SCSI_SENSE_KEY_ILLEGAL_REQUEST,SCSI_ASC_INVALID_FIELD_IN_CDB,
00243 cmd->allocation_length);
00244 return USB_MSC_HANDLER_FAILED;
00245 }
00246 return USB_MSC_HANDLER_OK;
00247 }
00248
00249 static usb_msc_handler_status
00250 handle_mode_select(struct usb_msc_command_state *state)
00251 {
00252
00253 return USB_MSC_HANDLER_OK;
00254 }
00255 static uint8_t disk_blocks[USB_RBC_NUM_BLOCKS][512];
00256
00257 static usb_msc_handler_status
00258 handle_read(struct usb_msc_command_state *state)
00259 {
00260 struct rbc_read_cmd *cmd = (struct rbc_read_cmd*)state->command;
00261 unsigned long lba = be32_to_host(cmd->logical_block_address);
00262 unsigned long blocks = be16_to_host(cmd->transfer_length);
00263 PRINTF("Requested %ld blocks at %ld\n", blocks, lba);
00264 if (lba >= USB_RBC_NUM_BLOCKS || lba + blocks > USB_RBC_NUM_BLOCKS) {
00265 scsi_error(SCSI_SENSE_KEY_ILLEGAL_REQUEST,SCSI_ASC_INVALID_FIELD_IN_CDB,
00266 blocks);
00267 return USB_MSC_HANDLER_FAILED;
00268 }
00269 usb_msc_send_data((uint8_t *)&disk_blocks[lba], blocks * 512,
00270 USB_MSC_DATA_SEND | USB_MSC_DATA_LAST);
00271 scsi_ok();
00272 return USB_MSC_HANDLER_OK;
00273 }
00274
00275 static void
00276 handle_write_done(struct usb_msc_command_state *state)
00277 {
00278 PRINTF("Wrote data\n");
00279 state->status = MASS_BULK_CSW_STATUS_PASSED;
00280 scsi_ok();
00281 }
00282
00283 static usb_msc_handler_status
00284 handle_write(struct usb_msc_command_state *state)
00285 {
00286 struct rbc_write_cmd *cmd = (struct rbc_write_cmd*)state->command;
00287 unsigned long lba = be32_to_host(cmd->logical_block_address);
00288 unsigned long blocks = be16_to_host(cmd->transfer_length);
00289 if (lba >= USB_RBC_NUM_BLOCKS || lba + blocks > USB_RBC_NUM_BLOCKS) {
00290 scsi_error(SCSI_SENSE_KEY_ILLEGAL_REQUEST,SCSI_ASC_INVALID_FIELD_IN_CDB,
00291 blocks);
00292 return USB_MSC_HANDLER_FAILED;
00293 }
00294 PRINTF("Writing %ld blocks at %ld\n", blocks, lba);
00295 usb_msc_receive_data(disk_blocks[lba], blocks * 512,
00296 USB_MSC_DATA_RECEIVE | USB_MSC_DATA_LAST
00297 | USB_MSC_DATA_DO_CALLBACK);
00298 state->data_cb = handle_write_done;
00299 return USB_MSC_HANDLER_DELAYED;
00300 }
00301
00302 static usb_msc_handler_status
00303 handle_start_stop_unit(struct usb_msc_command_state *state)
00304 {
00305 scsi_ok();
00306 return USB_MSC_HANDLER_OK;
00307 }
00308
00309 static usb_msc_handler_status
00310 handle_verify(struct usb_msc_command_state *state)
00311 {
00312 scsi_ok();
00313 return USB_MSC_HANDLER_OK;
00314 }
00315
00316 usb_msc_handler_status
00317 usb_msc_handle_command(struct usb_msc_command_state *state)
00318 {
00319
00320 usb_msc_handler_status ret;
00321 PRINTF("Got CBW %02x\n", state->command[0]);
00322 switch(state->command[0]) {
00323 case SCSI_CMD_INQUIRY:
00324 ret = handle_inquiry_cmd(state);
00325 break;
00326 case SCSI_CMD_REQUEST_SENSE:
00327 ret = handle_request_sense_cmd(state);
00328 break;
00329 case SCSI_CMD_TEST_UNIT_READY:
00330 ret = handle_test_unit_ready_cmd(state);
00331 break;
00332 case SCSI_CMD_READ_CAPACITY:
00333 ret = handle_read_capacity(state);
00334 break;
00335 case SCSI_CMD_MODE_SENSE_6:
00336 ret = handle_mode_sense(state);
00337 break;
00338 case SCSI_CMD_MODE_SELECT_6:
00339 ret = handle_mode_select(state);
00340 break;
00341 case SCSI_CMD_READ_10:
00342 ret = handle_read(state);
00343 break;
00344 case SCSI_CMD_WRITE_10:
00345 ret = handle_write(state);
00346 break;
00347 case SCSI_CMD_VERIFY_10:
00348 ret = handle_verify(state);
00349 break;
00350 case SCSI_CMD_START_STOP_UNIT:
00351 ret = handle_start_stop_unit(state);
00352 break;
00353 default:
00354 printf("Unhandled request: %02x\n", state->command[0]);
00355 scsi_error(SCSI_SENSE_KEY_ILLEGAL_REQUEST,
00356 SCSI_ASC_INVALID_COMMAND_OPERATION,0);
00357 return USB_MSC_HANDLER_FAILED;
00358 }
00359 return ret;
00360 }
00361
00362 void
00363 usb_msc_command_handler_init()
00364 {
00365 }