devsd: Do not pass drive number as function argument
authorWill Sowerbutts <will@sowerbutts.com>
Fri, 6 Mar 2015 10:28:07 +0000 (10:28 +0000)
committerWill Sowerbutts <will@sowerbutts.com>
Fri, 6 Mar 2015 10:41:56 +0000 (10:41 +0000)
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
Kernel/dev/devsd.h
Kernel/dev/devsd_discard.c
Kernel/platform-msx2/devmegasd.c
Kernel/platform-n8vem-mark4/devsdspi.c
Kernel/platform-socz80/devsdspi.c

index 667447f..d508aa6 100644 (file)
 #include <stdbool.h>
 #include <blkdev.h>
 
+/* 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<n> is the command sequense of CMD55-CMD<n> */
         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 */
index aca45e6..f679c3f 100644 (file)
 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 */
index af145dc..0f694b4 100644 (file)
 
 void devsd_init(void)
 {
-    uint8_t d;
-
-    for(d=0; d<SD_DRIVE_COUNT; d++)
-        sd_init_drive(d);
+    for(sd_drive=0; sd_drive<SD_DRIVE_COUNT; sd_drive++)
+        sd_init_drive();
 }
 
-void sd_init_drive(uint8_t drive)
+void sd_init_drive(void)
 {
     blkdev_t *blk;
     unsigned char csd[16], n;
     uint8_t card_type;
 
-    kprintf("SD drive %d: ", drive);
-    card_type = sd_spi_init(drive);
+    kprintf("SD drive %d: ", sd_drive);
+    card_type = sd_spi_init();
 
     if(!(card_type & (~CT_BLOCK))){
         kprintf("no card found\n");
@@ -53,12 +51,12 @@ void sd_init_drive(uint8_t drive)
         return;
 
     blk->transfer = 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;
     }
 
index 23dacb5..7fd932d 100644 (file)
@@ -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
index 4fd88f3..1809082 100644 (file)
@@ -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 */
 }
index 8d75de0..4fe29c4 100644 (file)
@@ -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)