Contiki 2.6
|
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 /* Can't change anything */ 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 }