summaryrefslogtreecommitdiff
path: root/firmware/usbstack/usb_storage.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/usbstack/usb_storage.c')
-rw-r--r--firmware/usbstack/usb_storage.c59
1 files changed, 23 insertions, 36 deletions
diff --git a/firmware/usbstack/usb_storage.c b/firmware/usbstack/usb_storage.c
index 005697f6fa..1ff3b1ec4c 100644
--- a/firmware/usbstack/usb_storage.c
+++ b/firmware/usbstack/usb_storage.c
@@ -32,6 +32,8 @@
32#include "usb_storage.h" 32#include "usb_storage.h"
33#include "timefuncs.h" 33#include "timefuncs.h"
34 34
35/* For sector filter macro definitions */
36#include "usb-target.h"
35 37
36/* Enable the following define to export only the SD card slot. This 38/* Enable the following define to export only the SD card slot. This
37 * is useful for USBCV MSC tests, as those are destructive. 39 * is useful for USBCV MSC tests, as those are destructive.
@@ -47,6 +49,15 @@
47#define SECTOR_SIZE 512 49#define SECTOR_SIZE 512
48#endif 50#endif
49 51
52/* These defaults allow the operation */
53#ifndef USBSTOR_READ_SECTORS_FILTER
54#define USBSTOR_READ_SECTORS_FILTER() ({ 0; })
55#endif
56
57#ifndef USBSTOR_WRITE_SECTORS_FILTER
58#define USBSTOR_WRITE_SECTORS_FILTER() ({ 0; })
59#endif
60
50/* the ARC driver currently supports up to 64k USB transfers. This is 61/* the ARC driver currently supports up to 64k USB transfers. This is
51 * enough for efficient mass storage support, as commonly host OSes 62 * enough for efficient mass storage support, as commonly host OSes
52 * don't do larger SCSI transfers anyway, so larger USB transfers 63 * don't do larger SCSI transfers anyway, so larger USB transfers
@@ -342,23 +353,6 @@ static void yearday_to_daymonth(int yd, int y, int *d, int *m)
342 *m = i; 353 *m = i;
343} 354}
344 355
345#ifdef TOSHIBA_GIGABEAT_S
346
347/* The Gigabeat S factory partition table contains invalid values for the
348 "active" flag in the MBR. This prevents at least the Linux kernel from
349 accepting the partition table, so we fix it on-the-fly. */
350
351static void fix_mbr(unsigned char* mbr)
352{
353 unsigned char* p = mbr + 0x1be;
354
355 p[0x00] &= 0x80;
356 p[0x10] &= 0x80;
357 p[0x20] &= 0x80;
358 p[0x30] &= 0x80;
359}
360#endif
361
362static bool check_disk_present(IF_MD_NONVOID(int volume)) 356static bool check_disk_present(IF_MD_NONVOID(int volume))
363{ 357{
364#ifdef USB_USE_RAMDISK 358#ifdef USB_USE_RAMDISK
@@ -491,14 +485,7 @@ void usb_storage_init_connection(void)
491 485
492 int i; 486 int i;
493 for(i=0;i<storage_num_drives();i++) { 487 for(i=0;i<storage_num_drives();i++) {
494#ifdef TOSHIBA_GIGABEAT_S
495 /* As long as the Gigabeat S is a non-removable device, we need
496 to mark the device as locked to avoid usb_storage_try_release_ata()
497 to leave MSC mode while the device is in use */
498 locked[i] = true;
499#else
500 locked[i] = false; 488 locked[i] = false;
501#endif
502 ejected[i] = !check_disk_present(IF_MD(i)); 489 ejected[i] = !check_disk_present(IF_MD(i));
503 queue_broadcast(SYS_USB_LUN_LOCKED, (i<<16)+0); 490 queue_broadcast(SYS_USB_LUN_LOCKED, (i<<16)+0);
504 } 491 }
@@ -549,10 +536,15 @@ void usb_storage_transfer_complete(int ep,int dir,int status,int length)
549 cur_cmd.data[cur_cmd.data_select], 536 cur_cmd.data[cur_cmd.data_select],
550 MIN(WRITE_BUFFER_SIZE/SECTOR_SIZE, cur_cmd.count)*SECTOR_SIZE); 537 MIN(WRITE_BUFFER_SIZE/SECTOR_SIZE, cur_cmd.count)*SECTOR_SIZE);
551#else 538#else
552 int result = storage_write_sectors(IF_MD2(cur_cmd.lun,) 539 int result = USBSTOR_WRITE_SECTORS_FILTER();
540
541 if (result == 0) {
542 result = storage_write_sectors(IF_MD2(cur_cmd.lun,)
553 cur_cmd.sector, 543 cur_cmd.sector,
554 MIN(WRITE_BUFFER_SIZE/SECTOR_SIZE, cur_cmd.count), 544 MIN(WRITE_BUFFER_SIZE/SECTOR_SIZE, cur_cmd.count),
555 cur_cmd.data[cur_cmd.data_select]); 545 cur_cmd.data[cur_cmd.data_select]);
546 }
547
556 if(result != 0) { 548 if(result != 0) {
557 send_csw(UMS_STATUS_FAIL); 549 send_csw(UMS_STATUS_FAIL);
558 cur_sense_data.sense_key=SENSE_MEDIUM_ERROR; 550 cur_sense_data.sense_key=SENSE_MEDIUM_ERROR;
@@ -725,6 +717,11 @@ bool usb_storage_control_request(struct usb_ctrlrequest* req, unsigned char* des
725 717
726static void send_and_read_next(void) 718static void send_and_read_next(void)
727{ 719{
720 int result = USBSTOR_READ_SECTORS_FILTER();
721
722 if(result != 0 && cur_cmd.last_result == 0)
723 cur_cmd.last_result = result;
724
728 send_block_data(cur_cmd.data[cur_cmd.data_select], 725 send_block_data(cur_cmd.data[cur_cmd.data_select],
729 MIN(READ_BUFFER_SIZE,cur_cmd.count*SECTOR_SIZE)); 726 MIN(READ_BUFFER_SIZE,cur_cmd.count*SECTOR_SIZE));
730 727
@@ -742,7 +739,7 @@ static void send_and_read_next(void)
742 ramdisk_buffer + cur_cmd.sector*SECTOR_SIZE, 739 ramdisk_buffer + cur_cmd.sector*SECTOR_SIZE,
743 MIN(READ_BUFFER_SIZE/SECTOR_SIZE, cur_cmd.count)*SECTOR_SIZE); 740 MIN(READ_BUFFER_SIZE/SECTOR_SIZE, cur_cmd.count)*SECTOR_SIZE);
744#else 741#else
745 int result = storage_read_sectors(IF_MD2(cur_cmd.lun,) 742 result = storage_read_sectors(IF_MD2(cur_cmd.lun,)
746 cur_cmd.sector, 743 cur_cmd.sector,
747 MIN(READ_BUFFER_SIZE/SECTOR_SIZE, cur_cmd.count), 744 MIN(READ_BUFFER_SIZE/SECTOR_SIZE, cur_cmd.count),
748 cur_cmd.data[cur_cmd.data_select]); 745 cur_cmd.data[cur_cmd.data_select]);
@@ -1104,12 +1101,6 @@ static void handle_scsi(struct command_block_wrapper* cbw)
1104 cur_cmd.sector, 1101 cur_cmd.sector,
1105 MIN(READ_BUFFER_SIZE/SECTOR_SIZE, cur_cmd.count), 1102 MIN(READ_BUFFER_SIZE/SECTOR_SIZE, cur_cmd.count),
1106 cur_cmd.data[cur_cmd.data_select]); 1103 cur_cmd.data[cur_cmd.data_select]);
1107
1108#ifdef TOSHIBA_GIGABEAT_S
1109 if(cur_cmd.sector == 0) {
1110 fix_mbr(cur_cmd.data[cur_cmd.data_select]);
1111 }
1112#endif
1113#endif 1104#endif
1114 send_and_read_next(); 1105 send_and_read_next();
1115 } 1106 }
@@ -1262,9 +1253,5 @@ static void fill_inquiry(IF_MD_NONVOID(int lun))
1262 tb.inquiry->Versions = 4; /* SPC-2 */ 1253 tb.inquiry->Versions = 4; /* SPC-2 */
1263 tb.inquiry->Format = 2; /* SPC-2/3 inquiry format */ 1254 tb.inquiry->Format = 2; /* SPC-2/3 inquiry format */
1264 1255
1265#ifdef TOSHIBA_GIGABEAT_S
1266 tb.inquiry->DeviceTypeModifier = 0;
1267#else
1268 tb.inquiry->DeviceTypeModifier = DEVICE_REMOVABLE; 1256 tb.inquiry->DeviceTypeModifier = DEVICE_REMOVABLE;
1269#endif
1270} 1257}