cleanup
This commit is contained in:
129
src/usb_msc.c
129
src/usb_msc.c
@@ -193,17 +193,22 @@ static void set_scsi_sense_data(uint8_t sense_key, uint8_t asc) {
|
|||||||
|
|
||||||
static uint8_t buf[512];
|
static uint8_t buf[512];
|
||||||
|
|
||||||
static uint8_t media_available;
|
static uint8_t contingent_allegiance;
|
||||||
static uint8_t media_changed;
|
static uint8_t keep_contingent_allegiance;
|
||||||
|
|
||||||
|
uint8_t media_available;
|
||||||
|
|
||||||
void msc_media_insert_change (int available)
|
void msc_media_insert_change (int available)
|
||||||
{
|
{
|
||||||
|
contingent_allegiance = 1;
|
||||||
media_available = available;
|
media_available = available;
|
||||||
media_changed = 1;
|
|
||||||
if (available)
|
if (available)
|
||||||
set_scsi_sense_data (0x06, 0x28); /* UNIT_ATTENTION */
|
set_scsi_sense_data (0x06, 0x28); /* UNIT_ATTENTION */
|
||||||
else
|
else
|
||||||
set_scsi_sense_data (0x02, 0x3a); /* NOT_READY */
|
{
|
||||||
|
set_scsi_sense_data (0x02, 0x3a); /* NOT_READY */
|
||||||
|
keep_contingent_allegiance = 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -222,22 +227,6 @@ static struct CBW CBW;
|
|||||||
|
|
||||||
static struct CSW CSW;
|
static struct CSW CSW;
|
||||||
|
|
||||||
int msc_recv_cbw (void)
|
|
||||||
{
|
|
||||||
msg_t msg;
|
|
||||||
|
|
||||||
chSysLock();
|
|
||||||
msc_state = MSC_IDLE;
|
|
||||||
the_thread = chThdSelf ();
|
|
||||||
usb_start_receive ((uint8_t *)&CBW, sizeof CBW);
|
|
||||||
chSchGoSleepTimeoutS (THD_STATE_SUSPENDED, MS2ST (1000));
|
|
||||||
msg = chThdSelf ()->p_u.rdymsg;
|
|
||||||
chSysUnlock ();
|
|
||||||
if (msg == RDY_OK)
|
|
||||||
return 0;
|
|
||||||
else
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int msc_recv_data (void)
|
static int msc_recv_data (void)
|
||||||
{
|
{
|
||||||
@@ -291,36 +280,42 @@ static void msc_send_result (const uint8_t *p, size_t n)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void msc_handle_err (int err)
|
void msc_handle_command (void)
|
||||||
{
|
|
||||||
if (err == 0)
|
|
||||||
{
|
|
||||||
msc_state = MSC_ERROR;
|
|
||||||
chSysLock ();
|
|
||||||
usb_stall_receive ();
|
|
||||||
chSysUnlock ();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
msc_state = MSC_ERROR;
|
|
||||||
chSysLock ();
|
|
||||||
usb_stall_transmit ();
|
|
||||||
usb_stall_receive ();
|
|
||||||
chSysUnlock ();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int msc_handle_cbw (void)
|
|
||||||
{
|
{
|
||||||
size_t n;
|
size_t n;
|
||||||
uint32_t nblocks, secsize;
|
uint32_t nblocks, secsize;
|
||||||
uint8_t lun;
|
|
||||||
uint32_t lba;
|
uint32_t lba;
|
||||||
|
int r;
|
||||||
|
msg_t msg;
|
||||||
|
|
||||||
|
chSysLock();
|
||||||
|
msc_state = MSC_IDLE;
|
||||||
|
the_thread = chThdSelf ();
|
||||||
|
usb_start_receive ((uint8_t *)&CBW, sizeof CBW);
|
||||||
|
chSchGoSleepTimeoutS (THD_STATE_SUSPENDED, MS2ST (1000));
|
||||||
|
msg = chThdSelf ()->p_u.rdymsg;
|
||||||
|
chSysUnlock ();
|
||||||
|
|
||||||
|
if (msg != RDY_OK)
|
||||||
|
{
|
||||||
|
/* Error occured, ignore the request and go into error state */
|
||||||
|
msc_state = MSC_ERROR;
|
||||||
|
chSysLock ();
|
||||||
|
usb_stall_receive ();
|
||||||
|
chSysUnlock ();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
n = ep7_out.rxcnt;
|
n = ep7_out.rxcnt;
|
||||||
|
|
||||||
if ((n != sizeof (struct CBW)) || (CBW.dCBWSignature != MSC_CBW_SIGNATURE))
|
if ((n != sizeof (struct CBW)) || (CBW.dCBWSignature != MSC_CBW_SIGNATURE))
|
||||||
return 0;
|
{
|
||||||
|
msc_state = MSC_ERROR;
|
||||||
|
chSysLock ();
|
||||||
|
usb_stall_receive ();
|
||||||
|
chSysUnlock ();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
CSW.dCSWTag = CBW.dCBWTag;
|
CSW.dCSWTag = CBW.dCBWTag;
|
||||||
switch (CBW.CBWCB[0]) {
|
switch (CBW.CBWCB[0]) {
|
||||||
@@ -331,12 +326,13 @@ int msc_handle_cbw (void)
|
|||||||
else
|
else
|
||||||
msc_send_result ((uint8_t *)&scsi_sense_data_fixed,
|
msc_send_result ((uint8_t *)&scsi_sense_data_fixed,
|
||||||
sizeof scsi_sense_data_fixed);
|
sizeof scsi_sense_data_fixed);
|
||||||
if (media_changed && media_available)
|
/* After the error is reported, clear it, if it's . */
|
||||||
|
if (!keep_contingent_allegiance)
|
||||||
{
|
{
|
||||||
media_changed = 0;
|
contingent_allegiance = 0;
|
||||||
set_scsi_sense_data (0x00, 0x00);
|
set_scsi_sense_data (0x00, 0x00);
|
||||||
}
|
}
|
||||||
return 1;
|
return;
|
||||||
case SCSI_INQUIRY:
|
case SCSI_INQUIRY:
|
||||||
if (CBW.CBWCB[1] & 0x01) /* EVPD */
|
if (CBW.CBWCB[1] & 0x01) /* EVPD */
|
||||||
/* assume page 00 */
|
/* assume page 00 */
|
||||||
@@ -345,7 +341,7 @@ int msc_handle_cbw (void)
|
|||||||
else
|
else
|
||||||
msc_send_result ((uint8_t *)&scsi_inquiry_data,
|
msc_send_result ((uint8_t *)&scsi_inquiry_data,
|
||||||
sizeof scsi_inquiry_data);
|
sizeof scsi_inquiry_data);
|
||||||
return 1;
|
return;
|
||||||
case SCSI_READ_FORMAT_CAPACITIES:
|
case SCSI_READ_FORMAT_CAPACITIES:
|
||||||
buf[8] = scsi_read_format_capacities (&nblocks, &secsize);
|
buf[8] = scsi_read_format_capacities (&nblocks, &secsize);
|
||||||
buf[0] = buf[1] = buf[2] = 0;
|
buf[0] = buf[1] = buf[2] = 0;
|
||||||
@@ -358,14 +354,14 @@ int msc_handle_cbw (void)
|
|||||||
buf[10] = (uint8_t)(secsize >> 8);
|
buf[10] = (uint8_t)(secsize >> 8);
|
||||||
buf[11] = (uint8_t)(secsize >> 0);
|
buf[11] = (uint8_t)(secsize >> 0);
|
||||||
msc_send_result (buf, 12);
|
msc_send_result (buf, 12);
|
||||||
return 1;
|
return;
|
||||||
case SCSI_TEST_UNIT_READY:
|
case SCSI_TEST_UNIT_READY:
|
||||||
if (media_available == 0 || media_changed)
|
if (contingent_allegiance)
|
||||||
{
|
{
|
||||||
CSW.bCSWStatus = MSC_CSW_STATUS_FAILED;
|
CSW.bCSWStatus = MSC_CSW_STATUS_FAILED;
|
||||||
CSW.dCSWDataResidue = 0;
|
CSW.dCSWDataResidue = 0;
|
||||||
msc_send_result (NULL, 0);
|
msc_send_result (NULL, 0);
|
||||||
return 1;
|
return;
|
||||||
}
|
}
|
||||||
/* fall through */
|
/* fall through */
|
||||||
case SCSI_SYNCHRONIZE_CACHE:
|
case SCSI_SYNCHRONIZE_CACHE:
|
||||||
@@ -375,12 +371,12 @@ int msc_handle_cbw (void)
|
|||||||
CSW.bCSWStatus = MSC_CSW_STATUS_PASSED;
|
CSW.bCSWStatus = MSC_CSW_STATUS_PASSED;
|
||||||
CSW.dCSWDataResidue = CBW.dCBWDataTransferLength;
|
CSW.dCSWDataResidue = CBW.dCBWDataTransferLength;
|
||||||
msc_send_result (NULL, 0);
|
msc_send_result (NULL, 0);
|
||||||
return 1;
|
return;
|
||||||
case SCSI_MODE_SENSE6:
|
case SCSI_MODE_SENSE6:
|
||||||
buf[0] = 0x03;
|
buf[0] = 0x03;
|
||||||
buf[1] = buf[2] = buf[3] = 0;
|
buf[1] = buf[2] = buf[3] = 0;
|
||||||
msc_send_result (buf, 4);
|
msc_send_result (buf, 4);
|
||||||
return 1;
|
return;
|
||||||
case SCSI_READ_CAPACITY10:
|
case SCSI_READ_CAPACITY10:
|
||||||
scsi_read_format_capacities (&nblocks, &secsize);
|
scsi_read_format_capacities (&nblocks, &secsize);
|
||||||
buf[0] = (uint8_t)((nblocks - 1) >> 24);
|
buf[0] = (uint8_t)((nblocks - 1) >> 24);
|
||||||
@@ -392,7 +388,7 @@ int msc_handle_cbw (void)
|
|||||||
buf[6] = (uint8_t)(secsize >> 8);
|
buf[6] = (uint8_t)(secsize >> 8);
|
||||||
buf[7] = (uint8_t)(secsize >> 0);
|
buf[7] = (uint8_t)(secsize >> 0);
|
||||||
msc_send_result (buf, 8);
|
msc_send_result (buf, 8);
|
||||||
return 1;
|
return;
|
||||||
case SCSI_READ10:
|
case SCSI_READ10:
|
||||||
case SCSI_WRITE10:
|
case SCSI_WRITE10:
|
||||||
break;
|
break;
|
||||||
@@ -402,12 +398,19 @@ int msc_handle_cbw (void)
|
|||||||
CSW.bCSWStatus = MSC_CSW_STATUS_FAILED;
|
CSW.bCSWStatus = MSC_CSW_STATUS_FAILED;
|
||||||
CSW.dCSWDataResidue = 0;
|
CSW.dCSWDataResidue = 0;
|
||||||
msc_send_result (NULL, 0);
|
msc_send_result (NULL, 0);
|
||||||
return 1;
|
return;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
msc_state = MSC_ERROR;
|
||||||
|
chSysLock ();
|
||||||
|
usb_stall_transmit ();
|
||||||
|
usb_stall_receive ();
|
||||||
|
chSysUnlock ();
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
lun = CBW.bCBWLUN;
|
|
||||||
lba = (CBW.CBWCB[2] << 24) | (CBW.CBWCB[3] << 16)
|
lba = (CBW.CBWCB[2] << 24) | (CBW.CBWCB[3] << 16)
|
||||||
| (CBW.CBWCB[4] << 8) | CBW.CBWCB[5];
|
| (CBW.CBWCB[4] << 8) | CBW.CBWCB[5];
|
||||||
|
|
||||||
@@ -429,7 +432,7 @@ int msc_handle_cbw (void)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((p = msc_scsi_read (lun, lba)))
|
if ((r = msc_scsi_read (lba, &p)) == 0)
|
||||||
{
|
{
|
||||||
msc_send_data (p, 512);
|
msc_send_data (p, 512);
|
||||||
if (++CBW.CBWCB[5] == 0)
|
if (++CBW.CBWCB[5] == 0)
|
||||||
@@ -443,6 +446,11 @@ int msc_handle_cbw (void)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
CSW.bCSWStatus = MSC_CSW_STATUS_FAILED;
|
CSW.bCSWStatus = MSC_CSW_STATUS_FAILED;
|
||||||
|
contingent_allegiance = 1;
|
||||||
|
if (r == SCSI_ERROR_NOT_READY)
|
||||||
|
set_scsi_sense_data (SCSI_ERROR_NOT_READY, 0x3a);
|
||||||
|
else
|
||||||
|
set_scsi_sense_data (r, 0x00);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -466,7 +474,7 @@ int msc_handle_cbw (void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
msc_recv_data ();
|
msc_recv_data ();
|
||||||
if (msc_scsi_write (lun, lba, buf, 512))
|
if ((r = msc_scsi_write (lba, buf, 512)) == 0)
|
||||||
{
|
{
|
||||||
if (++CBW.CBWCB[5] == 0)
|
if (++CBW.CBWCB[5] == 0)
|
||||||
if (++CBW.CBWCB[4] == 0)
|
if (++CBW.CBWCB[4] == 0)
|
||||||
@@ -479,6 +487,11 @@ int msc_handle_cbw (void)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
CSW.bCSWStatus = MSC_CSW_STATUS_FAILED;
|
CSW.bCSWStatus = MSC_CSW_STATUS_FAILED;
|
||||||
|
contingent_allegiance = 1;
|
||||||
|
if (r == SCSI_ERROR_NOT_READY)
|
||||||
|
set_scsi_sense_data (SCSI_ERROR_NOT_READY, 0x3a);
|
||||||
|
else
|
||||||
|
set_scsi_sense_data (r, 0x00);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -486,6 +499,4 @@ int msc_handle_cbw (void)
|
|||||||
msc_send_result (NULL, 0);
|
msc_send_result (NULL, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -43,3 +43,10 @@ struct CSW {
|
|||||||
uint32_t dCSWDataResidue;
|
uint32_t dCSWDataResidue;
|
||||||
uint8_t bCSWStatus;
|
uint8_t bCSWStatus;
|
||||||
} __attribute__((packed));
|
} __attribute__((packed));
|
||||||
|
|
||||||
|
#define SCSI_ERROR_NOT_READY 2
|
||||||
|
#define SCSI_ERROR_ILLEAGAL_REQUEST 5
|
||||||
|
#define SCSI_ERROR_UNIT_ATTENTION 6
|
||||||
|
#define SCSI_ERROR_DATA_PROTECT 7
|
||||||
|
|
||||||
|
extern uint8_t media_available;
|
||||||
|
|||||||
@@ -6,6 +6,8 @@
|
|||||||
|
|
||||||
extern Thread *main_thread;
|
extern Thread *main_thread;
|
||||||
|
|
||||||
|
#define TOTAL_SECTOR 68
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
||||||
blk=0: master boot record sector
|
blk=0: master boot record sector
|
||||||
@@ -17,7 +19,7 @@ blk=4: fat cluster #2
|
|||||||
blk=4+63: fat cluster #2+63
|
blk=4+63: fat cluster #2+63
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static const uint8_t d0_0_sector[512] = {
|
static const uint8_t d0_0_sector[] = {
|
||||||
0xeb, 0x3c, /* Jump instruction */
|
0xeb, 0x3c, /* Jump instruction */
|
||||||
0x90, /* NOP */
|
0x90, /* NOP */
|
||||||
|
|
||||||
@@ -29,7 +31,7 @@ static const uint8_t d0_0_sector[512] = {
|
|||||||
0x01, 0x00, /* reserved sector count: 1 */
|
0x01, 0x00, /* reserved sector count: 1 */
|
||||||
0x02, /* Number of FATs: 2 */
|
0x02, /* Number of FATs: 2 */
|
||||||
0x10, 0x00, /* Max. root directory entries: 16 (1 sector) */
|
0x10, 0x00, /* Max. root directory entries: 16 (1 sector) */
|
||||||
0x44, 0x00, /* total sectors: 68 */
|
TOTAL_SECTOR, 0x00, /* total sectors: 68 */
|
||||||
0xf8, /* media descriptor: fixed disk */
|
0xf8, /* media descriptor: fixed disk */
|
||||||
0x01, 0x00, /* sectors per FAT: 1 */
|
0x01, 0x00, /* sectors per FAT: 1 */
|
||||||
0x04, 0x00, /* sectors per track: 4 */
|
0x04, 0x00, /* sectors per track: 4 */
|
||||||
@@ -46,14 +48,24 @@ static const uint8_t d0_0_sector[512] = {
|
|||||||
|
|
||||||
0x46, 0x41, 0x54, 0x31, 0x32, 0x20, 0x20, 0x20, /* FAT12 */
|
0x46, 0x41, 0x54, 0x31, 0x32, 0x20, 0x20, 0x20, /* FAT12 */
|
||||||
|
|
||||||
0x0e, 0x1f,
|
0x0e, /* push cs */
|
||||||
0xbe, 0x5b, 0x7c, 0xac, 0x22, 0xc0, 0x74, 0x0b,
|
0x1f, /* pop ds */
|
||||||
0x56, 0xb4, 0x0e, 0xbb, 0x07, 0x00, 0xcd, 0x10,
|
0xbe, 0x5b, 0x7c, /* mov si, offset message_txt */
|
||||||
0x5e, 0xeb, 0xf0, 0x32, 0xe4, 0xcd, 0x16, 0xcd,
|
0xac, /* 1: lodsb */
|
||||||
0x19,
|
0x22, 0xc0, /* and al, al */
|
||||||
0xeb, 0xfe, /* loop: jmp loop */
|
0x74, 0x0b, /* jz 2f */
|
||||||
|
0x56, /* push si */
|
||||||
|
0xb4, 0x0e, /* mov ah, 0eh */
|
||||||
|
0xbb, 0x07, 0x00, /* mov bx, 0007h */
|
||||||
|
0xcd, 0x10, /* int 10h ; output char color=white */
|
||||||
|
0x5e, /* pop si */
|
||||||
|
0xeb, 0xf0, /* jmp 1b */
|
||||||
|
0x32, 0xe4, /* 2: xor ah, ah */
|
||||||
|
0xcd, 0x16, /* int 16h; key input */
|
||||||
|
0xcd, 0x19, /* int 19h; load OS */
|
||||||
|
0xeb, 0xfe, /* 3: jmp 3b */
|
||||||
|
|
||||||
/* "Thisis not a bootable disk... \r\n" */
|
/* "This is not a bootable disk... \r\n" */
|
||||||
0x54, 0x68, 0x69, 0x73, 0x20,
|
0x54, 0x68, 0x69, 0x73, 0x20,
|
||||||
0x69, 0x73, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x61,
|
0x69, 0x73, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x61,
|
||||||
0x20, 0x62, 0x6f, 0x6f, 0x74, 0x61, 0x62, 0x6c,
|
0x20, 0x62, 0x6f, 0x6f, 0x74, 0x61, 0x62, 0x6c,
|
||||||
@@ -67,61 +79,16 @@ static const uint8_t d0_0_sector[512] = {
|
|||||||
0x6b, 0x65, 0x79, 0x20, 0x74, 0x6f, 0x20, 0x74,
|
0x6b, 0x65, 0x79, 0x20, 0x74, 0x6f, 0x20, 0x74,
|
||||||
0x72, 0x79, 0x20, 0x61, 0x67, 0x61, 0x69, 0x6e,
|
0x72, 0x79, 0x20, 0x61, 0x67, 0x61, 0x69, 0x6e,
|
||||||
0x20, 0x2e, 0x2e, 0x2e, 0x20, 0x0d, 0x0a, 0x00,
|
0x20, 0x2e, 0x2e, 0x2e, 0x20, 0x0d, 0x0a, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0xaa
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static const uint8_t d0_fat0_sector[512] = {
|
static const uint8_t d0_fat0_sector[] = {
|
||||||
0xf8, 0xff, 0xff, /* Media descriptor: fixed disk */ /* EOC */
|
0xf8, 0xff, 0xff, /* Media descriptor: fixed disk */ /* EOC */
|
||||||
0xff, 0xff, 0xff, /* cluster 2: used */ /* cluster 3: used */
|
0xff, 0xff, 0xff, /* cluster 2: used */ /* cluster 3: used */
|
||||||
0xff, 0xff, 0xff, /* cluster 4: used */ /* cluster 5: used */
|
0xff, 0xff, 0xff, /* cluster 4: used */ /* cluster 5: used */
|
||||||
0xff, 0xff, 0xff, /* cluster 6: used */ /* cluster 7: used */
|
0xff, 0xff, 0xff, /* cluster 6: used */ /* cluster 7: used */
|
||||||
0xff, 0x0f, 0x00, /* cluster 8: used */ /* cluster 9: free */
|
0xff, 0x0f, 0x00, /* cluster 8: used */ /* cluster 9: free */
|
||||||
0x00,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static const uint8_t zero_sector[512] = {
|
|
||||||
0x00,
|
|
||||||
};
|
|
||||||
|
|
||||||
static uint8_t the_sector[512];
|
static uint8_t the_sector[512];
|
||||||
|
|
||||||
struct folder {
|
struct folder {
|
||||||
@@ -157,14 +124,13 @@ static uint8_t *fill_file_entry (uint8_t *p, const uint8_t *filename,
|
|||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const uint8_t *build_directory_sector (uint8_t *p, uint8_t index)
|
static void build_directory_sector (uint8_t *p, uint8_t index)
|
||||||
{
|
{
|
||||||
uint16_t cluster_no = FOLDER_INDEX_TO_CLUSTER_NO (index);
|
uint16_t cluster_no = FOLDER_INDEX_TO_CLUSTER_NO (index);
|
||||||
int i;
|
int i;
|
||||||
uint8_t filename[11] = { 0x2e, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
uint8_t filename[11] = { 0x2e, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||||
0x20, 0x20, 0x20 };
|
0x20, 0x20, 0x20 };
|
||||||
uint8_t child;
|
uint8_t child;
|
||||||
uint8_t *p_orig = p;
|
|
||||||
|
|
||||||
memset (p, 0, 512);
|
memset (p, 0, 512);
|
||||||
|
|
||||||
@@ -184,20 +150,33 @@ static const uint8_t *build_directory_sector (uint8_t *p, uint8_t index)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
break;
|
break;
|
||||||
|
|
||||||
return p_orig;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const uint8_t *
|
int
|
||||||
msc_scsi_read (uint8_t lun, uint32_t lba)
|
msc_scsi_read (uint32_t lba, const uint8_t **sector_p)
|
||||||
{
|
{
|
||||||
|
if (!media_available)
|
||||||
|
return SCSI_ERROR_NOT_READY;
|
||||||
|
|
||||||
|
if (lba >= TOTAL_SECTOR)
|
||||||
|
return SCSI_ERROR_ILLEAGAL_REQUEST;
|
||||||
|
|
||||||
switch (lba)
|
switch (lba)
|
||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
return d0_0_sector;
|
*sector_p = the_sector;
|
||||||
|
memcpy (the_sector, d0_0_sector, sizeof d0_0_sector);
|
||||||
|
memset (the_sector + sizeof d0_0_sector, 0, 512 - sizeof d0_0_sector);
|
||||||
|
the_sector[510] = 0x55;
|
||||||
|
the_sector[511] = 0xaa;
|
||||||
|
return 0;
|
||||||
case 1:
|
case 1:
|
||||||
case 2:
|
case 2:
|
||||||
return d0_fat0_sector;
|
*sector_p = the_sector;
|
||||||
|
memcpy (the_sector, d0_fat0_sector, sizeof d0_fat0_sector);
|
||||||
|
memset (the_sector + sizeof d0_fat0_sector, 0,
|
||||||
|
512 - sizeof d0_fat0_sector);
|
||||||
|
return 0;
|
||||||
case 3:
|
case 3:
|
||||||
case 4:
|
case 4:
|
||||||
case 5:
|
case 5:
|
||||||
@@ -206,9 +185,13 @@ msc_scsi_read (uint8_t lun, uint32_t lba)
|
|||||||
case 8:
|
case 8:
|
||||||
case 9:
|
case 9:
|
||||||
case 10:
|
case 10:
|
||||||
return build_directory_sector (the_sector, LBA_TO_FOLDER_INDEX (lba));
|
*sector_p = the_sector;
|
||||||
|
build_directory_sector (the_sector, LBA_TO_FOLDER_INDEX (lba));
|
||||||
|
return 0;
|
||||||
default:
|
default:
|
||||||
return zero_sector;
|
*sector_p = the_sector;
|
||||||
|
memset (the_sector, 0, 512);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -258,14 +241,19 @@ static void parse_directory_sector (const uint8_t *p, uint8_t index)
|
|||||||
int
|
int
|
||||||
msc_scsi_write (uint8_t lun, uint32_t lba, const uint8_t *buf, size_t size)
|
msc_scsi_write (uint8_t lun, uint32_t lba, const uint8_t *buf, size_t size)
|
||||||
{
|
{
|
||||||
if (lba <= 2)
|
if (!media_available)
|
||||||
return 1; /* error */
|
return SCSI_ERROR_NOT_READY;
|
||||||
|
|
||||||
|
if (lba >= TOTAL_SECTOR)
|
||||||
|
return SCSI_ERROR_ILLEAGAL_REQUEST;
|
||||||
|
|
||||||
|
if (lba <= 2 || lba >= 11)
|
||||||
|
return SCSI_ERROR_DATA_PROTECT;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
uint8_t index = LBA_TO_FOLDER_INDEX (lba);
|
uint8_t index = LBA_TO_FOLDER_INDEX (lba);
|
||||||
|
|
||||||
parse_directory_sector (buf, index);
|
parse_directory_sector (buf, index);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user