From: Alan Cox Date: Fri, 9 Oct 2015 13:23:11 +0000 (+0100) Subject: dragon-nx-32: wire up the probing and mpi logic X-Git-Url: https://git.ndcode.org/public/gitweb.cgi?a=commitdiff_plain;h=15326233c20dd557ed411f23ad619a54a7080462;p=FUZIX.git dragon-nx-32: wire up the probing and mpi logic First cut at this. We make the IDE base a variable Allow for a platform private header for IDE (needed for stuff like ide_base) Issue select/deselect commands passing the drive number This in theory also gives us all that is needed for multiple IDE controllers, while not paying a cost for them on simple platforms (they can define the selectors into nothingness) --- diff --git a/Kernel/dev/devide.c b/Kernel/dev/devide.c index 54e5f9c8..63833579 100644 --- a/Kernel/dev/devide.c +++ b/Kernel/dev/devide.c @@ -49,8 +49,11 @@ uint8_t devide_transfer_sector(void) uint8_t *p; #endif + drive = blk_op.blkdev->driver_data & DRIVE_NR_MASK; + ide_select(drive); + #if defined(__SDCC_z80) || defined(__SDCC_z180) || defined(__SDCC_gbz80) || defined(__SDCC_r2k) || defined(__SDCC_r3k) /* sdcc sadly unable to figure this out for itself yet */ p = ((uint8_t *)&blk_op.lba)+3; @@ -65,25 +68,30 @@ uint8_t devide_transfer_sector(void) devide_writeb(ide_reg_lba_0, blk_op.lba); #endif - if(!devide_wait(IDE_STATUS_READY)) - return 0; + if (!devide_wait(IDE_STATUS_READY)) + goto fail; devide_writeb(ide_reg_sec_count, 1); devide_writeb(ide_reg_command, blk_op.is_read ? IDE_CMD_READ_SECTOR : IDE_CMD_WRITE_SECTOR); if(!devide_wait(IDE_STATUS_DATAREQUEST)) - return 0; + goto fail; - if(blk_op.is_read) + if (blk_op.is_read) devide_read_data(); - else{ + else { devide_write_data(); if(!devide_wait(IDE_STATUS_READY)) - return 0; + goto fail; blk_op.blkdev->driver_data |= FLAG_CACHE_DIRTY; } + ide_deselect(); + return 1; +fail: + ide_deselect(); + return 0; } int devide_flush_cache(void) @@ -92,28 +100,31 @@ int devide_flush_cache(void) drive = blk_op.blkdev->driver_data & DRIVE_NR_MASK; + ide_select(drive); + /* check drive has a cache and was written to since the last flush */ if((blk_op.blkdev->driver_data & (FLAG_WRITE_CACHE | FLAG_CACHE_DIRTY)) == (FLAG_WRITE_CACHE | FLAG_CACHE_DIRTY)){ - devide_writeb(ide_reg_lba_3, ((drive == 0) ? 0xE0 : 0xF0)); // select drive + devide_writeb(ide_reg_lba_3, (((drive & 1) == 0) ? 0xE0 : 0xF0)); // select drive - if(!devide_wait(IDE_STATUS_READY)){ - udata.u_error = EIO; - return -1; - } + if (!devide_wait(IDE_STATUS_READY)) + goto fail; devide_writeb(ide_reg_command, IDE_CMD_FLUSH_CACHE); - if(!devide_wait(IDE_STATUS_READY)){ - udata.u_error = EIO; - return -1; - } + if (!devide_wait(IDE_STATUS_READY)) + goto fail; /* drive cache is now clean */ blk_op.blkdev->driver_data &= ~FLAG_CACHE_DIRTY; } - + ide_deselect(); return 0; + +fail: + udata.u_error = EIO; + ide_deselect(); + return -1; } /****************************************************************************/ diff --git a/Kernel/dev/devide.h b/Kernel/dev/devide.h index c4c2f436..101b5cbf 100644 --- a/Kernel/dev/devide.h +++ b/Kernel/dev/devide.h @@ -2,6 +2,7 @@ #define __DEVIDE_DOT_H__ #include "config.h" +#include "platform_ide.h" /* IDE Drive Configuration (in config.h) @@ -89,20 +90,26 @@ void devide_writeb(uint8_t regaddr, uint8_t value); #ifdef _IDE_PRIVATE -#define DRIVE_COUNT 2 /* at most 2 drives without adjusting DRIVE_NR_MASK */ +#ifndef DRIVE_COUNT +#define DRIVE_COUNT 2 /* at most 16 drives without adjusting DRIVE_NR_MASK */ +#endif /* we use the bits in the driver_data field of blkdev_t as follows: */ -#define DRIVE_NR_MASK 0x01 /* low bit used to select the drive number -- extend if more required */ +#define DRIVE_NR_MASK 0x0F /* low bit used to select master/slave */ #define FLAG_CACHE_DIRTY 0x40 #define FLAG_WRITE_CACHE 0x80 extern bool devide_wait(uint8_t bits); -extern void devide_read_data(void); extern uint8_t devide_transfer_sector(void); extern int devide_flush_cache(void); +/* Platform provided, or may be defaults */ extern void devide_write_data(void); -extern void devde_read_data(void); +extern void devide_read_data(void); + +/* Platform provided */ +extern void ide_select(uint8_t drive); +extern void ide_deselect(void); #ifndef IDE_REG_INDIRECT #ifdef IDE_IS_MMIO diff --git a/Kernel/dev/devide_discard.c b/Kernel/dev/devide_discard.c index 8f0852b8..271870a6 100644 --- a/Kernel/dev/devide_discard.c +++ b/Kernel/dev/devide_discard.c @@ -54,7 +54,7 @@ void devide_init_drive(uint8_t drive) blkdev_t *blk; uint8_t *buffer, select; - switch(drive){ + switch(drive & 1){ case 0: select = 0xE0; break; case 1: select = 0xF0; break; default: return; @@ -62,19 +62,21 @@ void devide_init_drive(uint8_t drive) kprintf("IDE drive %d: ", drive); + ide_select(drive); + #ifdef IDE_8BIT_ONLY /* set 8-bit mode -- mostly only supported by CF cards */ devide_writeb(ide_reg_devhead, select); - if(!devide_wait(IDE_STATUS_READY)) - return; + if (!devide_wait(IDE_STATUS_READY)) + goto out; devide_writeb(ide_reg_features, 0x01); /* Enable 8-bit PIO transfer mode (CFA feature set only) */ devide_writeb(ide_reg_command, IDE_CMD_SET_FEATURES); #endif /* confirm drive has LBA support */ - if(!devide_wait(IDE_STATUS_READY)) - return; + if (!devide_wait(IDE_STATUS_READY)) + goto out; /* send identify command */ devide_writeb(ide_reg_devhead, select); @@ -83,7 +85,7 @@ void devide_init_drive(uint8_t drive) /* allocate temporary sector buffer memory */ buffer = (uint8_t *)tmpbuf(); - if(!devide_wait(IDE_STATUS_DATAREQUEST)) + if (!devide_wait(IDE_STATUS_DATAREQUEST)) goto failout; blk_op.is_user = false; @@ -91,7 +93,7 @@ void devide_init_drive(uint8_t drive) blk_op.nblock = 1; devide_read_data(); - if(!(buffer[99] & 0x02)){ + if(!(buffer[99] & 0x02)) { kputs("LBA unsupported.\n"); goto failout; } @@ -119,12 +121,18 @@ void devide_init_drive(uint8_t drive) /* done with our temporary memory */ brelse((bufptr)buffer); + /* Deselect the IDE, as we will re-select it in the partition scan and + it may not recursively stack de-selections */ + ide_deselect(); + /* scan partitions */ blkdev_scan(blk, SWAPSCAN); return; failout: brelse((bufptr)buffer); +out: + ide_deselect(); return; } @@ -136,6 +144,6 @@ void devide_init(void) devide_reset(); #endif - for(d=0; d #include #include +#include struct devsw dev_tab[] = /* The device driver switch table */ { @@ -46,9 +47,35 @@ bool validdev(uint16_t dev) return true; } +uint16_t ide_base = 0xFF50; +uint8_t ide_slot = 3; /* Disk in slot 3 by convention */ + +static uint8_t old_slot; + +void ide_select(void) +{ + if (cartslots > 1) + old_slot = mpi_set_slot(ide_slot); +} + +void ide_deselect(void) +{ + if (cartslots > 1) + mpi_set_slot(old_slot); +} + +/* This can move to discard... */ + void device_init(void) { + int i; + if (spi_setup()) devsd_init(); + i = cart_find(CART_IDE); + if (i >= 0) { + ide_base = cartaddr[i] ? cartaddr[i]: ide_base; + ide_slot = i; + } devide_init(); }