From 919676039fea5653a8a9e8705cd2d60adb68400a Mon Sep 17 00:00:00 2001 From: Will Sowerbutts Date: Fri, 6 Mar 2015 10:28:07 +0000 Subject: [PATCH] devsd: Do not pass drive number as function argument None of our existing platforms support multiple cards. This change moves the SD drive number into a global variable which platform drivers can access if required. This change reduces code size by just over 200 bytes. --- Kernel/dev/devsd.c | 72 ++++++++++++++------------ Kernel/dev/devsd.h | 27 +++++----- Kernel/dev/devsd_discard.c | 50 +++++++++--------- Kernel/platform-msx2/devmegasd.c | 27 +++------- Kernel/platform-n8vem-mark4/devsdspi.c | 21 +++----- Kernel/platform-socz80/devsdspi.c | 26 ++++------ 6 files changed, 101 insertions(+), 122 deletions(-) diff --git a/Kernel/dev/devsd.c b/Kernel/dev/devsd.c index 667447f1..d508aa67 100644 --- a/Kernel/dev/devsd.c +++ b/Kernel/dev/devsd.c @@ -20,36 +20,40 @@ #include #include +/* for platforms with multiple SD card slots, this variable contains + * the current operation's drive number */ +uint8_t sd_drive; + uint8_t devsd_transfer_sector(void) { - uint8_t attempt, drive; + uint8_t attempt; bool success; - drive = blk_op.blkdev->driver_data & DRIVE_NR_MASK; + sd_drive = blk_op.blkdev->driver_data & DRIVE_NR_MASK; for(attempt=0; attempt<8; attempt++){ - if(sd_send_command(drive, blk_op.is_read ? CMD17 : CMD24, + if(sd_send_command(blk_op.is_read ? CMD17 : CMD24, /* for byte addressed cards, shift LBA to convert to byte address */ (blk_op.blkdev->driver_data & CT_BLOCK) ? blk_op.lba : (blk_op.lba << 9) ) == 0){ if(blk_op.is_read){ - success = (sd_spi_wait(drive, false) == 0xFE); + success = (sd_spi_wait(false) == 0xFE); if(success) - sd_spi_receive_sector(drive); + sd_spi_receive_sector(); }else{ success = false; - if(sd_spi_wait(drive, true) == 0xFF){ - sd_spi_transmit_byte(drive, 0xFE); - sd_spi_transmit_sector(drive); - sd_spi_transmit_byte(drive, 0xFF); /* dummy CRC */ - sd_spi_transmit_byte(drive, 0xFF); - success = ((sd_spi_wait(drive, false) & 0x1F) == 0x05); + if(sd_spi_wait(true) == 0xFF){ + sd_spi_transmit_byte(0xFE); + sd_spi_transmit_sector(); + sd_spi_transmit_byte(0xFF); /* dummy CRC */ + sd_spi_transmit_byte(0xFF); + success = ((sd_spi_wait(false) & 0x1F) == 0x05); } } }else success = false; - sd_spi_release(drive); + sd_spi_release(); if(success) return 1; @@ -61,13 +65,13 @@ uint8_t devsd_transfer_sector(void) return 0; } -void sd_spi_release(uint8_t drive) +void sd_spi_release(void) { - sd_spi_raise_cs(drive); - sd_spi_receive_byte(drive); + sd_spi_raise_cs(); + sd_spi_receive_byte(); } -uint8_t sd_spi_wait(uint8_t drive, bool want_ff) +uint8_t sd_spi_wait(bool want_ff) { unsigned int timer; unsigned char b; @@ -75,7 +79,7 @@ uint8_t sd_spi_wait(uint8_t drive, bool want_ff) timer = set_timer_ms(500); while(true){ - b = sd_spi_receive_byte(drive); + b = sd_spi_receive_byte(); if(want_ff){ if(b == 0xFF) break; @@ -92,50 +96,50 @@ uint8_t sd_spi_wait(uint8_t drive, bool want_ff) return b; } -int sd_send_command(uint8_t drive, unsigned char cmd, uint32_t arg) +int sd_send_command(unsigned char cmd, uint32_t arg) { unsigned char n, res, *p; if (cmd & 0x80) { /* ACMD is the command sequense of CMD55-CMD */ cmd &= 0x7F; - res = sd_send_command(drive, CMD55, 0); + res = sd_send_command(CMD55, 0); if (res > 1) return res; } /* Select the card and wait for ready */ - sd_spi_release(drive); /* raise CS, then sends 8 clocks (some cards require this) */ - sd_spi_lower_cs(drive); - if(sd_spi_wait(drive, true) != 0xFF) + sd_spi_release(); /* raise CS, then sends 8 clocks (some cards require this) */ + sd_spi_lower_cs(); + if(sd_spi_wait(true) != 0xFF) return 0xFF; /* Send command packet */ - sd_spi_transmit_byte(drive, cmd); /* Start + Command index */ + sd_spi_transmit_byte(cmd); /* Start + Command index */ #if 0 - sd_spi_transmit_byte(drive, (unsigned char)(arg >> 24)); /* Argument[31..24] */ - sd_spi_transmit_byte(drive, (unsigned char)(arg >> 16)); /* Argument[23..16] */ - sd_spi_transmit_byte(drive, (unsigned char)(arg >> 8)); /* Argument[15..8] */ - sd_spi_transmit_byte(drive, (unsigned char)arg); /* Argument[7..0] */ + sd_spi_transmit_byte((unsigned char)(arg >> 24)); /* Argument[31..24] */ + sd_spi_transmit_byte((unsigned char)(arg >> 16)); /* Argument[23..16] */ + sd_spi_transmit_byte((unsigned char)(arg >> 8)); /* Argument[15..8] */ + sd_spi_transmit_byte((unsigned char)arg); /* Argument[7..0] */ #else /* sdcc sadly unable to figure this out for itself yet */ p = ((unsigned char *)&arg)+3; - sd_spi_transmit_byte(drive, *(p--)); /* Argument[31..24] */ - sd_spi_transmit_byte(drive, *(p--)); /* Argument[23..16] */ - sd_spi_transmit_byte(drive, *(p--)); /* Argument[15..8] */ - sd_spi_transmit_byte(drive, *p); /* Argument[7..0] */ + sd_spi_transmit_byte(*(p--)); /* Argument[31..24] */ + sd_spi_transmit_byte(*(p--)); /* Argument[23..16] */ + sd_spi_transmit_byte(*(p--)); /* Argument[15..8] */ + sd_spi_transmit_byte(*p); /* Argument[7..0] */ #endif /* there's only a few commands (in native mode) that need correct CRCs */ n = 0x01; /* Dummy CRC + Stop */ if (cmd == CMD0) n = 0x95; /* Valid CRC for CMD0(0) */ if (cmd == CMD8) n = 0x87; /* Valid CRC for CMD8(0x1AA) */ - sd_spi_transmit_byte(drive, n); + sd_spi_transmit_byte(n); /* Receive command response */ if (cmd == CMD12) - sd_spi_receive_byte(drive); /* Skip a stuff byte when stop reading */ + sd_spi_receive_byte(); /* Skip a stuff byte when stop reading */ n = 20; /* Wait for a valid response */ do{ - res = sd_spi_receive_byte(drive); + res = sd_spi_receive_byte(); }while ((res & 0x80) && --n); return res; /* Return with the response value */ diff --git a/Kernel/dev/devsd.h b/Kernel/dev/devsd.h index aca45e63..f679c3f0 100644 --- a/Kernel/dev/devsd.h +++ b/Kernel/dev/devsd.h @@ -33,22 +33,25 @@ void devsd_init(void); /* platform-specific SPI functions */ -void sd_spi_clock(uint8_t drive, bool go_fast); -void sd_spi_raise_cs(uint8_t drive); -void sd_spi_lower_cs(uint8_t drive); -void sd_spi_transmit_byte(uint8_t drive, uint8_t byte); -uint8_t sd_spi_receive_byte(uint8_t drive); -bool sd_spi_receive_sector(uint8_t drive); -bool sd_spi_transmit_sector(uint8_t drive); +void sd_spi_clock(bool go_fast); +void sd_spi_raise_cs(void); +void sd_spi_lower_cs(void); +void sd_spi_transmit_byte(uint8_t byte); +uint8_t sd_spi_receive_byte(void); +bool sd_spi_receive_sector(void); +bool sd_spi_transmit_sector(void); + +/* for platforms which support multiple SD cards */ +extern uint8_t sd_drive; /* current card/drive number */ #ifdef _SD_PRIVATE /* internal functions */ -void sd_spi_release(uint8_t drive); -int sd_send_command(uint8_t drive, unsigned char cmd, uint32_t arg); -uint8_t sd_spi_wait(uint8_t drive, bool want_ff); -void sd_init_drive(uint8_t drive); -int sd_spi_init(uint8_t drive); +void sd_spi_release(void); +int sd_send_command(unsigned char cmd, uint32_t arg); +uint8_t sd_spi_wait(bool want_ff); +void sd_init_drive(void); +int sd_spi_init(void); uint8_t devsd_transfer_sector(void); /* Definitions for MMC/SDC command */ diff --git a/Kernel/dev/devsd_discard.c b/Kernel/dev/devsd_discard.c index af145dcd..0f694b4e 100644 --- a/Kernel/dev/devsd_discard.c +++ b/Kernel/dev/devsd_discard.c @@ -28,20 +28,18 @@ void devsd_init(void) { - uint8_t d; - - for(d=0; dtransfer = devsd_transfer_sector; - blk->driver_data = (drive & DRIVE_NR_MASK) | card_type; + blk->driver_data = (sd_drive & DRIVE_NR_MASK) | card_type; /* read and compute card size */ - if(sd_send_command(drive, CMD9, 0) == 0 && sd_spi_wait(drive, false) == 0xFE){ + if(sd_send_command(CMD9, 0) == 0 && sd_spi_wait(false) == 0xFE){ for(n=0; n<16; n++) - csd[n] = sd_spi_receive_byte(drive); + csd[n] = sd_spi_receive_byte(); if ((csd[0] >> 6) == 1) { /* SDC ver 2.00 */ blk->drive_lba_count = ((uint32_t)csd[9] @@ -71,43 +69,43 @@ void sd_init_drive(uint8_t drive) blk->drive_lba_count <<= (n-9); } } - sd_spi_release(drive); + sd_spi_release(); blkdev_scan(blk, 0); } -int sd_spi_init(uint8_t drive) +int sd_spi_init(void) { unsigned char n, cmd, card_type, ocr[4]; timer_t timer; - sd_spi_raise_cs(drive); + sd_spi_raise_cs(); - sd_spi_clock(drive, false); + sd_spi_clock(false); for (n = 20; n; n--) - sd_spi_receive_byte(drive); /* send dummy clocks -- at least 80 required; we send 160 */ + sd_spi_receive_byte(); /* send dummy clocks -- at least 80 required; we send 160 */ card_type = CT_NONE; /* Enter Idle state */ - if (sd_send_command(drive, CMD0, 0) == 1) { + if (sd_send_command(CMD0, 0) == 1) { /* initialisation timeout 2 seconds */ timer = set_timer_sec(2); - if (sd_send_command(drive, CMD8, (uint32_t)0x1AA) == 1) { /* SDHC */ + if (sd_send_command(CMD8, (uint32_t)0x1AA) == 1) { /* SDHC */ /* Get trailing return value of R7 resp */ - for (n = 0; n < 4; n++) ocr[n] = sd_spi_receive_byte(drive); + for (n = 0; n < 4; n++) ocr[n] = sd_spi_receive_byte(); /* The card can work at vdd range of 2.7-3.6V */ if (ocr[2] == 0x01 && ocr[3] == 0xAA) { /* Wait for leaving idle state (ACMD41 with HCS bit) */ - while(!timer_expired(timer) && sd_send_command(drive, ACMD41, (uint32_t)1 << 30)); + while(!timer_expired(timer) && sd_send_command(ACMD41, (uint32_t)1 << 30)); /* Check CCS bit in the OCR */ - if (!timer_expired(timer) && sd_send_command(drive, CMD58, 0) == 0) { - for (n = 0; n < 4; n++) ocr[n] = sd_spi_receive_byte(drive); + if (!timer_expired(timer) && sd_send_command(CMD58, 0) == 0) { + for (n = 0; n < 4; n++) ocr[n] = sd_spi_receive_byte(); card_type = (ocr[0] & 0x40) ? CT_SD2 | CT_BLOCK : CT_SD2; /* SDv2 */ } } } else { /* SDSC or MMC */ - if (sd_send_command(drive, ACMD41, 0) <= 1) { + if (sd_send_command(ACMD41, 0) <= 1) { /* SDv1 */ card_type = CT_SD1; cmd = ACMD41; @@ -117,16 +115,16 @@ int sd_spi_init(uint8_t drive) cmd = CMD1; } /* Wait for leaving idle state */ - while(!timer_expired(timer) && sd_send_command(drive, cmd, 0)); + while(!timer_expired(timer) && sd_send_command(cmd, 0)); /* Set R/W block length to 512 */ - if(timer_expired(timer) || sd_send_command(drive, CMD16, 512) != 0) + if(timer_expired(timer) || sd_send_command(CMD16, 512) != 0) card_type = CT_NONE; } } - sd_spi_release(drive); + sd_spi_release(); if (card_type) { - sd_spi_clock(drive, true); /* up to 20MHz should be OK */ + sd_spi_clock(true); /* up to 20MHz should be OK */ return card_type; } diff --git a/Kernel/platform-msx2/devmegasd.c b/Kernel/platform-msx2/devmegasd.c index 23dacb57..7fd932db 100644 --- a/Kernel/platform-msx2/devmegasd.c +++ b/Kernel/platform-msx2/devmegasd.c @@ -74,18 +74,15 @@ void sd_spi_unmap_interface() mapslot_bank1(slotram); } -void sd_spi_clock(uint8_t drive, bool go_fast) +void sd_spi_clock(bool go_fast) { - drive; /* not used */ go_fast; } -void sd_spi_raise_cs(uint8_t drive) +void sd_spi_raise_cs(void) { - drive; /* not used */ - sd_spi_map_interface(); - writeb(drive, MSD_DEVSEL); + writeb(0, MSD_DEVSEL); /* reading from MSD_CS raises CS for all cards */ @@ -94,17 +91,13 @@ void sd_spi_raise_cs(uint8_t drive) sd_spi_unmap_interface(); } -void sd_spi_lower_cs(uint8_t drive) +void sd_spi_lower_cs(void) { - drive; /* not used */ - /* happens automatically when sending */ } -void sd_spi_transmit_byte(uint8_t drive, unsigned char byte) +void sd_spi_transmit_byte(unsigned char byte) { - drive; /* not used */ - sd_spi_map_interface(); writeb(byte, MSD_RDWR); @@ -112,10 +105,9 @@ void sd_spi_transmit_byte(uint8_t drive, unsigned char byte) sd_spi_unmap_interface(); } -uint8_t sd_spi_receive_byte(uint8_t drive) +uint8_t sd_spi_receive_byte(void) { unsigned char c; - drive; /* not used */ sd_spi_map_interface(); @@ -131,7 +123,7 @@ uint8_t sd_spi_receive_byte(uint8_t drive) * Target page is always mapped to slot_page2, and the target address offset accordingly. * */ -bool sd_spi_receive_sector(uint8_t drive) __naked +bool sd_spi_receive_sector(void) __naked { __asm @@ -171,11 +163,9 @@ starttx: ld bc,#512 jp looptxrx __endasm; - - drive; /* silence compiler warning */ } -bool sd_spi_transmit_sector(uint8_t drive) __naked +bool sd_spi_transmit_sector(void) __naked { __asm @@ -244,7 +234,6 @@ looptxrx: ret z jp _map_kernel __endasm; - drive; /* silence compiler warning */ } #endif diff --git a/Kernel/platform-n8vem-mark4/devsdspi.c b/Kernel/platform-n8vem-mark4/devsdspi.c index 4fd88f36..18090827 100644 --- a/Kernel/platform-n8vem-mark4/devsdspi.c +++ b/Kernel/platform-n8vem-mark4/devsdspi.c @@ -55,10 +55,9 @@ reverse_byte_a: byte; /* squelch compiler warning */ } -void sd_spi_clock(uint8_t drive, bool go_fast) +void sd_spi_clock(bool go_fast) { unsigned char c; - drive; /* not used */ c = CSIO_CNTR & 0xf8; /* clear low three bits, gives fastest rate (clk/20) */ if(!go_fast) @@ -66,26 +65,23 @@ void sd_spi_clock(uint8_t drive, bool go_fast) CSIO_CNTR = c; } -void sd_spi_raise_cs(uint8_t drive) +void sd_spi_raise_cs(void) { - drive; /* not used */ /* wait for idle */ while(CSIO_CNTR & (CSIO_CNTR_TE | CSIO_CNTR_RE)); MARK4_SD = MARK4_SD & (~MARK4_SD_CS); } -void sd_spi_lower_cs(uint8_t drive) +void sd_spi_lower_cs(void) { - drive; /* not used */ /* wait for idle */ while(CSIO_CNTR & (CSIO_CNTR_TE | CSIO_CNTR_RE)); MARK4_SD = MARK4_SD | MARK4_SD_CS; } -void sd_spi_transmit_byte(uint8_t drive, unsigned char byte) +void sd_spi_transmit_byte(unsigned char byte) { unsigned char c; - drive; /* not used */ /* reverse the bits before we busywait */ byte = reverse_byte(byte); @@ -100,10 +96,9 @@ void sd_spi_transmit_byte(uint8_t drive, unsigned char byte) CSIO_CNTR = c | CSIO_CNTR_TE; } -uint8_t sd_spi_receive_byte(uint8_t drive) +uint8_t sd_spi_receive_byte(void) { unsigned char c; - drive; /* not used */ /* wait for any current transmit or receive operation to complete */ do{ @@ -129,7 +124,7 @@ COMMON_MEMORY /* WRS: measured byte transfer time as approx 5.66us with Z180 @ 36.864MHz, three times faster. Main change is to start the next receive operation as soon as possible and overlap the loop housekeeping with the receive. */ -bool sd_spi_receive_sector(uint8_t drive) __naked +bool sd_spi_receive_sector(void) __naked { __asm waitrx: @@ -183,10 +178,9 @@ waitrx3: jr nz, rxnextbyte ; go again if not yet done jr transferdone ; we are done __endasm; - drive; /* squelch compiler warnings */ } -bool sd_spi_transmit_sector(uint8_t drive) __naked +bool sd_spi_transmit_sector(void) __naked { __asm ; load parameters @@ -235,5 +229,4 @@ transferdone: ; note this code is shared with sd_spi_receive_b ret z ; return if kernel still mapped jp map_kernel ; else map kernel and return __endasm; - drive; /* squelch compiler warnings */ } diff --git a/Kernel/platform-socz80/devsdspi.c b/Kernel/platform-socz80/devsdspi.c index 8d75de03..4fe29c41 100644 --- a/Kernel/platform-socz80/devsdspi.c +++ b/Kernel/platform-socz80/devsdspi.c @@ -26,16 +26,14 @@ __sfr __at 0x36 sd_spi_mode; /* only on later VHDL */ #define SD_SPI_TX 0x32 #define SD_SPI_RX 0x33 -void sd_spi_mode0(uint8_t drive) +void sd_spi_mode0(void) { - used(drive); sd_spi_mode = 0; } -void sd_spi_clock(uint8_t drive, bool go_fast) +void sd_spi_clock(bool go_fast) { - used(drive); -// sd_spi_mode0(drive); +// sd_spi_mode0(); /* Currently the sd driver just uses 'slow' and 'fast'. That's ok for sd but mmc really needs to be 16MHz */ if (go_fast) @@ -44,28 +42,24 @@ void sd_spi_clock(uint8_t drive, bool go_fast) sd_spi_divisor = 255; } -void sd_spi_raise_cs(uint8_t drive) +void sd_spi_raise_cs(void) { - used(drive); sd_spi_chipselect = 0xFF; } -void sd_spi_lower_cs(uint8_t drive) +void sd_spi_lower_cs(void) { - used(drive); sd_spi_chipselect = 0xFE; } -void sd_spi_transmit_byte(uint8_t drive, unsigned char byte) +void sd_spi_transmit_byte(unsigned char byte) { - used(drive); sd_spi_tx = byte; } -uint8_t sd_spi_receive_byte(uint8_t drive) +uint8_t sd_spi_receive_byte(void) { uint8_t r; - used(drive); sd_spi_tx = 0xFF; r = sd_spi_rx; return r; @@ -73,9 +67,8 @@ uint8_t sd_spi_receive_byte(uint8_t drive) COMMON_MEMORY -bool sd_spi_receive_sector(uint8_t drive) __naked +bool sd_spi_receive_sector(void) __naked { - used(drive); __asm ld a, (_blk_op+BLKPARAM_IS_USER_OFFSET); ld hl, (_blk_op+BLKPARAM_ADDR_OFFSET); @@ -99,9 +92,8 @@ rx256_1: __endasm; } -bool sd_spi_transmit_sector(uint8_t drive) __naked +bool sd_spi_transmit_sector(void) __naked { - used(drive); __asm ld a, (_blk_op+BLKPARAM_IS_USER_OFFSET) ld hl, (_blk_op+BLKPARAM_ADDR_OFFSET) -- 2.34.1