diff options
Diffstat (limited to 'firmware')
-rw-r--r-- | firmware/usbstack/usb_storage.c | 215 |
1 files changed, 104 insertions, 111 deletions
diff --git a/firmware/usbstack/usb_storage.c b/firmware/usbstack/usb_storage.c index cee2f7700e..73464cf608 100644 --- a/firmware/usbstack/usb_storage.c +++ b/firmware/usbstack/usb_storage.c | |||
@@ -179,17 +179,19 @@ struct format_capacity { | |||
179 | unsigned int block_size; | 179 | unsigned int block_size; |
180 | } __attribute__ ((packed)); | 180 | } __attribute__ ((packed)); |
181 | 181 | ||
182 | static unsigned char* transfer_buffer; | 182 | |
183 | 183 | static union { | |
184 | static struct inquiry_data* inquiry; | 184 | unsigned char* transfer_buffer; |
185 | static struct capacity* capacity_data; | 185 | struct inquiry_data* inquiry; |
186 | static struct format_capacity* format_capacity_data; | 186 | struct capacity* capacity_data; |
187 | static struct sense_data *sense_data; | 187 | struct format_capacity* format_capacity_data; |
188 | static struct mode_sense_data_6 *mode_sense_data_6; | 188 | struct sense_data *sense_data; |
189 | static struct mode_sense_data_10 *mode_sense_data_10; | 189 | struct mode_sense_data_6 *mode_sense_data_6; |
190 | static struct report_lun_data *lun_data; | 190 | struct mode_sense_data_10 *mode_sense_data_10; |
191 | static struct command_status_wrapper* csw; | 191 | struct report_lun_data *lun_data; |
192 | static char *max_lun; | 192 | struct command_status_wrapper* csw; |
193 | char *max_lun; | ||
194 | } tb; | ||
193 | 195 | ||
194 | static struct { | 196 | static struct { |
195 | unsigned int sector; | 197 | unsigned int sector; |
@@ -229,23 +231,14 @@ void usb_storage_init(void) | |||
229 | size_t bufsize; | 231 | size_t bufsize; |
230 | unsigned char * audio_buffer = audio_get_buffer(false,&bufsize); | 232 | unsigned char * audio_buffer = audio_get_buffer(false,&bufsize); |
231 | /* TODO : check if bufsize is at least 32K ? */ | 233 | /* TODO : check if bufsize is at least 32K ? */ |
232 | transfer_buffer = (void *)UNCACHED_ADDR((unsigned int)(audio_buffer + 31) & 0xffffffe0); | 234 | tb.transfer_buffer = (void *)UNCACHED_ADDR((unsigned int)(audio_buffer + 31) & 0xffffffe0); |
233 | inquiry = (void*)transfer_buffer; | ||
234 | capacity_data = (void*)transfer_buffer; | ||
235 | format_capacity_data = (void*)transfer_buffer; | ||
236 | sense_data = (void*)transfer_buffer; | ||
237 | mode_sense_data_6 = (void*)transfer_buffer; | ||
238 | mode_sense_data_10 = (void*)transfer_buffer; | ||
239 | lun_data = (void*)transfer_buffer; | ||
240 | max_lun = (void*)transfer_buffer; | ||
241 | csw = (void*)transfer_buffer; | ||
242 | logf("usb_storage_init done"); | 235 | logf("usb_storage_init done"); |
243 | } | 236 | } |
244 | 237 | ||
245 | /* called by usb_core_transfer_complete() */ | 238 | /* called by usb_core_transfer_complete() */ |
246 | void usb_storage_transfer_complete(bool in,int status,int length) | 239 | void usb_storage_transfer_complete(bool in,int status,int length) |
247 | { | 240 | { |
248 | struct command_block_wrapper* cbw = (void*)transfer_buffer; | 241 | struct command_block_wrapper* cbw = (void*)tb.transfer_buffer; |
249 | 242 | ||
250 | //logf("transfer result %X %d", status, length); | 243 | //logf("transfer result %X %d", status, length); |
251 | switch(state) { | 244 | switch(state) { |
@@ -319,7 +312,7 @@ void usb_storage_transfer_complete(bool in,int status,int length) | |||
319 | } | 312 | } |
320 | //logf("csw sent, now go back to idle"); | 313 | //logf("csw sent, now go back to idle"); |
321 | state = WAITING_FOR_COMMAND; | 314 | state = WAITING_FOR_COMMAND; |
322 | usb_drv_recv(EP_MASS_STORAGE, transfer_buffer, 1024); | 315 | usb_drv_recv(EP_MASS_STORAGE, tb.transfer_buffer, 1024); |
323 | break; | 316 | break; |
324 | case SENDING_RESULT: | 317 | case SENDING_RESULT: |
325 | if(in==false) { | 318 | if(in==false) { |
@@ -371,12 +364,12 @@ bool usb_storage_control_request(struct usb_ctrlrequest* req) | |||
371 | switch (req->bRequest) { | 364 | switch (req->bRequest) { |
372 | case USB_BULK_GET_MAX_LUN: { | 365 | case USB_BULK_GET_MAX_LUN: { |
373 | #ifdef ONLY_EXPOSE_CARD_SLOT | 366 | #ifdef ONLY_EXPOSE_CARD_SLOT |
374 | *max_lun = 0; | 367 | *tb.max_lun = 0; |
375 | #else | 368 | #else |
376 | *max_lun = NUM_VOLUMES - 1; | 369 | *tb.max_lun = NUM_VOLUMES - 1; |
377 | #endif | 370 | #endif |
378 | logf("ums: getmaxlun"); | 371 | logf("ums: getmaxlun"); |
379 | usb_drv_send(EP_CONTROL, UNCACHED_ADDR(max_lun), 1); | 372 | usb_drv_send(EP_CONTROL, UNCACHED_ADDR(tb.max_lun), 1); |
380 | usb_drv_recv(EP_CONTROL, NULL, 0); /* ack */ | 373 | usb_drv_recv(EP_CONTROL, NULL, 0); /* ack */ |
381 | handled = true; | 374 | handled = true; |
382 | break; | 375 | break; |
@@ -401,7 +394,7 @@ bool usb_storage_control_request(struct usb_ctrlrequest* req) | |||
401 | logf("ums: set config"); | 394 | logf("ums: set config"); |
402 | /* prime rx endpoint. We only need room for commands */ | 395 | /* prime rx endpoint. We only need room for commands */ |
403 | state = WAITING_FOR_COMMAND; | 396 | state = WAITING_FOR_COMMAND; |
404 | usb_drv_recv(EP_MASS_STORAGE, transfer_buffer, 1024); | 397 | usb_drv_recv(EP_MASS_STORAGE, tb.transfer_buffer, 1024); |
405 | handled = true; | 398 | handled = true; |
406 | break; | 399 | break; |
407 | } | 400 | } |
@@ -496,16 +489,16 @@ static void handle_scsi(struct command_block_wrapper* cbw) | |||
496 | allocation_length|=(cbw->command_block[7]<<16); | 489 | allocation_length|=(cbw->command_block[7]<<16); |
497 | allocation_length|=(cbw->command_block[8]<<8); | 490 | allocation_length|=(cbw->command_block[8]<<8); |
498 | allocation_length|=(cbw->command_block[9]); | 491 | allocation_length|=(cbw->command_block[9]); |
499 | memset(lun_data,0,sizeof(struct report_lun_data)); | 492 | memset(tb.lun_data,0,sizeof(struct report_lun_data)); |
500 | #ifdef HAVE_HOTSWAP | 493 | #ifdef HAVE_HOTSWAP |
501 | lun_data->lun_list_length=htobe32(16); | 494 | tb.lun_data->lun_list_length=htobe32(16); |
502 | lun_data->lun1[1]=1; | 495 | tb.lun_data->lun1[1]=1; |
503 | #else | 496 | #else |
504 | lun_data->lun_list_length=htobe32(8); | 497 | tb.lun_data->lun_list_length=htobe32(8); |
505 | #endif | 498 | #endif |
506 | lun_data->lun0[1]=0; | 499 | tb.lun_data->lun0[1]=0; |
507 | 500 | ||
508 | send_command_result(lun_data, MIN(sizeof(struct report_lun_data), length)); | 501 | send_command_result(tb.lun_data, MIN(sizeof(struct report_lun_data), length)); |
509 | break; | 502 | break; |
510 | } | 503 | } |
511 | 504 | ||
@@ -513,22 +506,22 @@ static void handle_scsi(struct command_block_wrapper* cbw) | |||
513 | logf("scsi inquiry %d",lun); | 506 | logf("scsi inquiry %d",lun); |
514 | identify2inquiry(lun); | 507 | identify2inquiry(lun); |
515 | length = MIN(length, cbw->command_block[4]); | 508 | length = MIN(length, cbw->command_block[4]); |
516 | send_command_result(inquiry, MIN(sizeof(struct inquiry_data), length)); | 509 | send_command_result(tb.inquiry, MIN(sizeof(struct inquiry_data), length)); |
517 | break; | 510 | break; |
518 | 511 | ||
519 | case SCSI_REQUEST_SENSE: { | 512 | case SCSI_REQUEST_SENSE: { |
520 | sense_data->ResponseCode=0x70;/*current error*/ | 513 | tb.sense_data->ResponseCode=0x70;/*current error*/ |
521 | sense_data->filemark_eom_ili_sensekey=cur_sense_data.sense_key&0x0f; | 514 | tb.sense_data->filemark_eom_ili_sensekey=cur_sense_data.sense_key&0x0f; |
522 | sense_data->Information=cur_sense_data.information; | 515 | tb.sense_data->Information=cur_sense_data.information; |
523 | sense_data->AdditionalSenseLength=10; | 516 | tb.sense_data->AdditionalSenseLength=10; |
524 | sense_data->CommandSpecificInformation=0; | 517 | tb.sense_data->CommandSpecificInformation=0; |
525 | sense_data->AdditionalSenseCode=cur_sense_data.asc; | 518 | tb.sense_data->AdditionalSenseCode=cur_sense_data.asc; |
526 | sense_data->AdditionalSenseCodeQualifier=0; | 519 | tb.sense_data->AdditionalSenseCodeQualifier=0; |
527 | sense_data->FieldReplaceableUnitCode=0; | 520 | tb.sense_data->FieldReplaceableUnitCode=0; |
528 | sense_data->SKSV=0; | 521 | tb.sense_data->SKSV=0; |
529 | sense_data->SenseKeySpecific=0; | 522 | tb.sense_data->SenseKeySpecific=0; |
530 | logf("scsi request_sense %d",lun); | 523 | logf("scsi request_sense %d",lun); |
531 | send_command_result(sense_data, sizeof(struct sense_data)); | 524 | send_command_result(tb.sense_data, sizeof(struct sense_data)); |
532 | break; | 525 | break; |
533 | } | 526 | } |
534 | 527 | ||
@@ -545,24 +538,24 @@ static void handle_scsi(struct command_block_wrapper* cbw) | |||
545 | logf("scsi mode_sense_10 %d %X",lun,page_code); | 538 | logf("scsi mode_sense_10 %d %X",lun,page_code); |
546 | switch(page_code) { | 539 | switch(page_code) { |
547 | case 0x3f: | 540 | case 0x3f: |
548 | mode_sense_data_10->mode_data_length=sizeof(struct mode_sense_data_10); | 541 | tb.mode_sense_data_10->mode_data_length=sizeof(struct mode_sense_data_10); |
549 | mode_sense_data_10->medium_type=0; | 542 | tb.mode_sense_data_10->medium_type=0; |
550 | mode_sense_data_10->device_specific=0; | 543 | tb.mode_sense_data_10->device_specific=0; |
551 | mode_sense_data_10->reserved=0; | 544 | tb.mode_sense_data_10->reserved=0; |
552 | mode_sense_data_10->longlba=1; | 545 | tb.mode_sense_data_10->longlba=1; |
553 | mode_sense_data_10->block_descriptor_length=sizeof(struct mode_sense_block_descriptor_longlba); | 546 | tb.mode_sense_data_10->block_descriptor_length=sizeof(struct mode_sense_block_descriptor_longlba); |
554 | memset(mode_sense_data_10->block_descriptor.reserved,0,4); | 547 | memset(tb.mode_sense_data_10->block_descriptor.reserved,0,4); |
555 | memset(mode_sense_data_10->block_descriptor.number_of_blocks,0,8); | 548 | memset(tb.mode_sense_data_10->block_descriptor.number_of_blocks,0,8); |
556 | mode_sense_data_10->block_descriptor.number_of_blocks[4]=((block_count/block_size_mult) & 0xff000000)>>24; | 549 | tb.mode_sense_data_10->block_descriptor.number_of_blocks[4]=((block_count/block_size_mult) & 0xff000000)>>24; |
557 | mode_sense_data_10->block_descriptor.number_of_blocks[5]=((block_count/block_size_mult) & 0x00ff0000)>>16; | 550 | tb.mode_sense_data_10->block_descriptor.number_of_blocks[5]=((block_count/block_size_mult) & 0x00ff0000)>>16; |
558 | mode_sense_data_10->block_descriptor.number_of_blocks[6]=((block_count/block_size_mult) & 0x0000ff00)>>8; | 551 | tb.mode_sense_data_10->block_descriptor.number_of_blocks[6]=((block_count/block_size_mult) & 0x0000ff00)>>8; |
559 | mode_sense_data_10->block_descriptor.number_of_blocks[7]=((block_count/block_size_mult) & 0x000000ff); | 552 | tb.mode_sense_data_10->block_descriptor.number_of_blocks[7]=((block_count/block_size_mult) & 0x000000ff); |
560 | 553 | ||
561 | mode_sense_data_10->block_descriptor.block_size[0]=((block_size*block_size_mult) & 0xff000000)>>24; | 554 | tb.mode_sense_data_10->block_descriptor.block_size[0]=((block_size*block_size_mult) & 0xff000000)>>24; |
562 | mode_sense_data_10->block_descriptor.block_size[1]=((block_size*block_size_mult) & 0x00ff0000)>>16; | 555 | tb.mode_sense_data_10->block_descriptor.block_size[1]=((block_size*block_size_mult) & 0x00ff0000)>>16; |
563 | mode_sense_data_10->block_descriptor.block_size[2]=((block_size*block_size_mult) & 0x0000ff00)>>8; | 556 | tb.mode_sense_data_10->block_descriptor.block_size[2]=((block_size*block_size_mult) & 0x0000ff00)>>8; |
564 | mode_sense_data_10->block_descriptor.block_size[3]=((block_size*block_size_mult) & 0x000000ff); | 557 | tb.mode_sense_data_10->block_descriptor.block_size[3]=((block_size*block_size_mult) & 0x000000ff); |
565 | send_command_result(mode_sense_data_10, | 558 | send_command_result(tb.mode_sense_data_10, |
566 | MIN(sizeof(struct mode_sense_data_10), length)); | 559 | MIN(sizeof(struct mode_sense_data_10), length)); |
567 | break; | 560 | break; |
568 | default: | 561 | default: |
@@ -588,26 +581,26 @@ static void handle_scsi(struct command_block_wrapper* cbw) | |||
588 | switch(page_code) { | 581 | switch(page_code) { |
589 | case 0x3f: | 582 | case 0x3f: |
590 | /* All supported pages Since we support only one this is easy*/ | 583 | /* All supported pages Since we support only one this is easy*/ |
591 | mode_sense_data_6->mode_data_length=sizeof(struct mode_sense_data_6); | 584 | tb.mode_sense_data_6->mode_data_length=sizeof(struct mode_sense_data_6); |
592 | mode_sense_data_6->medium_type=0; | 585 | tb.mode_sense_data_6->medium_type=0; |
593 | mode_sense_data_6->device_specific=0; | 586 | tb.mode_sense_data_6->device_specific=0; |
594 | mode_sense_data_6->block_descriptor_length=sizeof(struct mode_sense_block_descriptor_shortlba); | 587 | tb.mode_sense_data_6->block_descriptor_length=sizeof(struct mode_sense_block_descriptor_shortlba); |
595 | mode_sense_data_6->block_descriptor.density_code=0; | 588 | tb.mode_sense_data_6->block_descriptor.density_code=0; |
596 | mode_sense_data_6->block_descriptor.reserved=0; | 589 | tb.mode_sense_data_6->block_descriptor.reserved=0; |
597 | if(block_count/block_size_mult > 0xffffff){ | 590 | if(block_count/block_size_mult > 0xffffff){ |
598 | mode_sense_data_6->block_descriptor.number_of_blocks[0]=0xff; | 591 | tb.mode_sense_data_6->block_descriptor.number_of_blocks[0]=0xff; |
599 | mode_sense_data_6->block_descriptor.number_of_blocks[1]=0xff; | 592 | tb.mode_sense_data_6->block_descriptor.number_of_blocks[1]=0xff; |
600 | mode_sense_data_6->block_descriptor.number_of_blocks[2]=0xff; | 593 | tb.mode_sense_data_6->block_descriptor.number_of_blocks[2]=0xff; |
601 | } | 594 | } |
602 | else { | 595 | else { |
603 | mode_sense_data_6->block_descriptor.number_of_blocks[0]=((block_count/block_size_mult) & 0xff0000)>>16; | 596 | tb.mode_sense_data_6->block_descriptor.number_of_blocks[0]=((block_count/block_size_mult) & 0xff0000)>>16; |
604 | mode_sense_data_6->block_descriptor.number_of_blocks[1]=((block_count/block_size_mult) & 0x00ff00)>>8; | 597 | tb.mode_sense_data_6->block_descriptor.number_of_blocks[1]=((block_count/block_size_mult) & 0x00ff00)>>8; |
605 | mode_sense_data_6->block_descriptor.number_of_blocks[2]=((block_count/block_size_mult) & 0x0000ff); | 598 | tb.mode_sense_data_6->block_descriptor.number_of_blocks[2]=((block_count/block_size_mult) & 0x0000ff); |
606 | } | 599 | } |
607 | mode_sense_data_6->block_descriptor.block_size[0]=((block_size*block_size_mult) & 0xff0000)>>16; | 600 | tb.mode_sense_data_6->block_descriptor.block_size[0]=((block_size*block_size_mult) & 0xff0000)>>16; |
608 | mode_sense_data_6->block_descriptor.block_size[1]=((block_size*block_size_mult) & 0x00ff00)>>8; | 601 | tb.mode_sense_data_6->block_descriptor.block_size[1]=((block_size*block_size_mult) & 0x00ff00)>>8; |
609 | mode_sense_data_6->block_descriptor.block_size[2]=((block_size*block_size_mult) & 0x0000ff); | 602 | tb.mode_sense_data_6->block_descriptor.block_size[2]=((block_size*block_size_mult) & 0x0000ff); |
610 | send_command_result(mode_sense_data_6, | 603 | send_command_result(tb.mode_sense_data_6, |
611 | MIN(sizeof(struct mode_sense_data_6), length)); | 604 | MIN(sizeof(struct mode_sense_data_6), length)); |
612 | break; | 605 | break; |
613 | default: | 606 | default: |
@@ -633,13 +626,13 @@ static void handle_scsi(struct command_block_wrapper* cbw) | |||
633 | case SCSI_READ_FORMAT_CAPACITY: { | 626 | case SCSI_READ_FORMAT_CAPACITY: { |
634 | logf("scsi read_format_capacity %d",lun); | 627 | logf("scsi read_format_capacity %d",lun); |
635 | if(lun_present) { | 628 | if(lun_present) { |
636 | format_capacity_data->following_length=htobe32(8); | 629 | tb.format_capacity_data->following_length=htobe32(8); |
637 | /* Careful: "block count" actually means "number of last block" */ | 630 | /* Careful: "block count" actually means "number of last block" */ |
638 | format_capacity_data->block_count = htobe32(block_count/block_size_mult - 1); | 631 | tb.format_capacity_data->block_count = htobe32(block_count/block_size_mult - 1); |
639 | format_capacity_data->block_size = htobe32(block_size*block_size_mult); | 632 | tb.format_capacity_data->block_size = htobe32(block_size*block_size_mult); |
640 | format_capacity_data->block_size |= SCSI_FORMAT_CAPACITY_FORMATTED_MEDIA; | 633 | tb.format_capacity_data->block_size |= SCSI_FORMAT_CAPACITY_FORMATTED_MEDIA; |
641 | 634 | ||
642 | send_command_result(format_capacity_data, | 635 | send_command_result(tb.format_capacity_data, |
643 | MIN(sizeof(struct format_capacity), length)); | 636 | MIN(sizeof(struct format_capacity), length)); |
644 | } | 637 | } |
645 | else | 638 | else |
@@ -656,10 +649,10 @@ static void handle_scsi(struct command_block_wrapper* cbw) | |||
656 | 649 | ||
657 | if(lun_present) { | 650 | if(lun_present) { |
658 | /* Careful: "block count" actually means "number of last block" */ | 651 | /* Careful: "block count" actually means "number of last block" */ |
659 | capacity_data->block_count = htobe32(block_count/block_size_mult - 1); | 652 | tb.capacity_data->block_count = htobe32(block_count/block_size_mult - 1); |
660 | capacity_data->block_size = htobe32(block_size*block_size_mult); | 653 | tb.capacity_data->block_size = htobe32(block_size*block_size_mult); |
661 | 654 | ||
662 | send_command_result(capacity_data, MIN(sizeof(struct capacity), length)); | 655 | send_command_result(tb.capacity_data, MIN(sizeof(struct capacity), length)); |
663 | } | 656 | } |
664 | else | 657 | else |
665 | { | 658 | { |
@@ -680,8 +673,8 @@ static void handle_scsi(struct command_block_wrapper* cbw) | |||
680 | cur_sense_data.asc=ASC_MEDIUM_NOT_PRESENT; | 673 | cur_sense_data.asc=ASC_MEDIUM_NOT_PRESENT; |
681 | break; | 674 | break; |
682 | } | 675 | } |
683 | current_cmd.data[0] = transfer_buffer; | 676 | current_cmd.data[0] = tb.transfer_buffer; |
684 | current_cmd.data[1] = &transfer_buffer[BUFFER_SIZE]; | 677 | current_cmd.data[1] = &tb.transfer_buffer[BUFFER_SIZE]; |
685 | current_cmd.data_select=0; | 678 | current_cmd.data_select=0; |
686 | current_cmd.sector = block_size_mult * | 679 | current_cmd.sector = block_size_mult * |
687 | (cbw->command_block[2] << 24 | | 680 | (cbw->command_block[2] << 24 | |
@@ -717,8 +710,8 @@ static void handle_scsi(struct command_block_wrapper* cbw) | |||
717 | cur_sense_data.asc=ASC_MEDIUM_NOT_PRESENT; | 710 | cur_sense_data.asc=ASC_MEDIUM_NOT_PRESENT; |
718 | break; | 711 | break; |
719 | } | 712 | } |
720 | current_cmd.data[0] = transfer_buffer; | 713 | current_cmd.data[0] = tb.transfer_buffer; |
721 | current_cmd.data[1] = &transfer_buffer[BUFFER_SIZE]; | 714 | current_cmd.data[1] = &tb.transfer_buffer[BUFFER_SIZE]; |
722 | current_cmd.data_select=0; | 715 | current_cmd.data_select=0; |
723 | current_cmd.sector = block_size_mult * | 716 | current_cmd.sector = block_size_mult * |
724 | (cbw->command_block[2] << 24 | | 717 | (cbw->command_block[2] << 24 | |
@@ -770,12 +763,12 @@ static void receive_block_data(void *data,int size) | |||
770 | 763 | ||
771 | static void send_csw(int status) | 764 | static void send_csw(int status) |
772 | { | 765 | { |
773 | csw->signature = htole32(CSW_SIGNATURE); | 766 | tb.csw->signature = htole32(CSW_SIGNATURE); |
774 | csw->tag = current_cmd.tag; | 767 | tb.csw->tag = current_cmd.tag; |
775 | csw->data_residue = 0; | 768 | tb.csw->data_residue = 0; |
776 | csw->status = status; | 769 | tb.csw->status = status; |
777 | 770 | ||
778 | usb_drv_send_nonblocking(EP_MASS_STORAGE, csw, sizeof(struct command_status_wrapper)); | 771 | usb_drv_send_nonblocking(EP_MASS_STORAGE, tb.csw, sizeof(struct command_status_wrapper)); |
779 | state = SENDING_CSW; | 772 | state = SENDING_CSW; |
780 | //logf("CSW: %X",status); | 773 | //logf("CSW: %X",status); |
781 | 774 | ||
@@ -791,14 +784,14 @@ static void identify2inquiry(int lun) | |||
791 | { | 784 | { |
792 | #ifdef HAVE_FLASH_STORAGE | 785 | #ifdef HAVE_FLASH_STORAGE |
793 | if(lun==0) { | 786 | if(lun==0) { |
794 | memcpy(&inquiry->VendorId,"Rockbox ",8); | 787 | memcpy(&tb.inquiry->VendorId,"Rockbox ",8); |
795 | memcpy(&inquiry->ProductId,"Internal Storage",16); | 788 | memcpy(&tb.inquiry->ProductId,"Internal Storage",16); |
796 | memcpy(&inquiry->ProductRevisionLevel,"0.00",4); | 789 | memcpy(&tb.inquiry->ProductRevisionLevel,"0.00",4); |
797 | } | 790 | } |
798 | else { | 791 | else { |
799 | memcpy(&inquiry->VendorId,"Rockbox ",8); | 792 | memcpy(&tb.inquiry->VendorId,"Rockbox ",8); |
800 | memcpy(&inquiry->ProductId,"SD Card Slot ",16); | 793 | memcpy(&tb.inquiry->ProductId,"SD Card Slot ",16); |
801 | memcpy(&inquiry->ProductRevisionLevel,"0.00",4); | 794 | memcpy(&tb.inquiry->ProductRevisionLevel,"0.00",4); |
802 | } | 795 | } |
803 | #else | 796 | #else |
804 | unsigned int i; | 797 | unsigned int i; |
@@ -806,33 +799,33 @@ static void identify2inquiry(int lun) | |||
806 | unsigned short* src; | 799 | unsigned short* src; |
807 | unsigned short* identify = ata_get_identify(); | 800 | unsigned short* identify = ata_get_identify(); |
808 | (void)lun; | 801 | (void)lun; |
809 | memset(inquiry, 0, sizeof(struct inquiry_data)); | 802 | memset(tb.inquiry, 0, sizeof(struct inquiry_data)); |
810 | 803 | ||
811 | if (identify[82] & 4) | 804 | if (identify[82] & 4) |
812 | inquiry->DeviceTypeModifier = DEVICE_REMOVABLE; | 805 | tb.inquiry->DeviceTypeModifier = DEVICE_REMOVABLE; |
813 | 806 | ||
814 | /* ATA only has a 'model' field, so we copy the | 807 | /* ATA only has a 'model' field, so we copy the |
815 | first 8 bytes to 'vendor' and the rest to 'product' (they are | 808 | first 8 bytes to 'vendor' and the rest to 'product' (they are |
816 | consecutive in the inquiry struct) */ | 809 | consecutive in the inquiry struct) */ |
817 | src = (unsigned short*)&identify[27]; | 810 | src = (unsigned short*)&identify[27]; |
818 | dest = (unsigned short*)&inquiry->VendorId; | 811 | dest = (unsigned short*)&tb.inquiry->VendorId; |
819 | for (i=0;i<12;i++) | 812 | for (i=0;i<12;i++) |
820 | dest[i] = htobe16(src[i]); | 813 | dest[i] = htobe16(src[i]); |
821 | 814 | ||
822 | src = (unsigned short*)&identify[23]; | 815 | src = (unsigned short*)&identify[23]; |
823 | dest = (unsigned short*)&inquiry->ProductRevisionLevel; | 816 | dest = (unsigned short*)&tb.inquiry->ProductRevisionLevel; |
824 | for (i=0;i<2;i++) | 817 | for (i=0;i<2;i++) |
825 | dest[i] = htobe16(src[i]); | 818 | dest[i] = htobe16(src[i]); |
826 | #endif | 819 | #endif |
827 | 820 | ||
828 | inquiry->DeviceType = DIRECT_ACCESS_DEVICE; | 821 | tb.inquiry->DeviceType = DIRECT_ACCESS_DEVICE; |
829 | inquiry->AdditionalLength = 0x1f; | 822 | tb.inquiry->AdditionalLength = 0x1f; |
830 | inquiry->Versions = 4; /* SPC-2 */ | 823 | tb.inquiry->Versions = 4; /* SPC-2 */ |
831 | inquiry->Format = 2; /* SPC-2/3 inquiry format */ | 824 | tb.inquiry->Format = 2; /* SPC-2/3 inquiry format */ |
832 | 825 | ||
833 | #ifdef HAVE_HOTSWAP | 826 | #ifdef HAVE_HOTSWAP |
834 | if(lun>0) | 827 | if(lun>0) |
835 | inquiry->DeviceTypeModifier = DEVICE_REMOVABLE; | 828 | tb.inquiry->DeviceTypeModifier = DEVICE_REMOVABLE; |
836 | #endif | 829 | #endif |
837 | 830 | ||
838 | } | 831 | } |