Messages in this thread Patches in this message | | | Date | Tue, 24 Apr 2001 14:29:44 +0200 (CEST) | From | Bjorn Wesen <> | Subject | [PATCH] drivers/ide/ide.c to work with more IDE controllers |
| |
Hi!
Problem description:
* drivers/ide/ide.c assumes the IDE controller is mapped in such a way that it can access it by "hardcoded" I/O commands (IN_BYTE/OUT_BYTE)
* drivers/ide/ide.c assumes that polled ide/atapi transfers should be done the way a PC would
* drivers/ide/Makefile assumes that all IDE DMA controllers are PCI
This makes it impossible to use for example the IDE-driver for the Etrax controller (arch/cris) which is not memory-mapped and is not PCI-based.
The following trivial patches (against 2.4.4-pre6 but are probably appliable to any 2.4.3-ac as well) fix the problem:
* In include/linux/ide.h, do #ifdef HAVE_ARCH_IN_BYTE etc. around the definitions of IN_BYTE and OUT_BYTE (allowing include/asm/ide.h to bypass the standard definition - see asm-cris/ide.h for an example)
* Add the "ideproc" entry in the HW driver structure, and let ide_input_bytes and friends in ide.c test that first. If it exists, it uses it, otherwise just do the normal PC transfer
* In the Makefile, let ide-dma.c (which is really PCI DMA only) be included by CONFIG_BLK_DEV_IDEDMA_PCI instead of just CONFIG_BLK_DEV_IDEDMA
* (Un)related addition: add ide_etrax100 as a chipset enum and an init call to the etrax IDE driver under #ifdef CONFIG_ETRAX_IDE
Please comment. It should all be trivial but there is one thing I'm unsure about and that is if it's guaranteed that the HWIF's structures are nulled upon creation (or maybe, if the primordial HWIF is nulled when copies are made). Obviously the above patch depends on any HWIF to have NULL as 'ideproc' if it does not need any alternative function there.
Regards, Bjorn
--- /home/bjornw/tmp/linux/drivers/ide/ide.c Tue Apr 24 13:30:46 2001 +++ linux/drivers/ide/ide.c Wed Apr 4 13:20:53 2001 @@ -374,7 +374,19 @@ */ void ide_input_data (ide_drive_t *drive, void *buffer, unsigned int wcount) { - byte io_32bit = drive->io_32bit; + byte io_32bit; + + /* first check if this controller has defined a special function + * for handling polled ide transfers + */ + + if(HWIF(drive)->ideproc) { + HWIF(drive)->ideproc(ideproc_ide_input_data, + drive, buffer, wcount); + return; + } + + io_32bit = drive->io_32bit; if (io_32bit) { #if SUPPORT_VLB_SYNC @@ -407,7 +419,15 @@ */ void ide_output_data (ide_drive_t *drive, void *buffer, unsigned int wcount) { - byte io_32bit = drive->io_32bit; + byte io_32bit; + + if(HWIF(drive)->ideproc) { + HWIF(drive)->ideproc(ideproc_ide_output_data, + drive, buffer, wcount); + return; + } + + io_32bit = drive->io_32bit; if (io_32bit) { #if SUPPORT_VLB_SYNC @@ -444,6 +464,12 @@ */ void atapi_input_bytes (ide_drive_t *drive, void *buffer, unsigned int bytecount) { + if(HWIF(drive)->ideproc) { + HWIF(drive)->ideproc(ideproc_atapi_input_bytes, + drive, buffer, bytecount); + return; + } + ++bytecount; #if defined(CONFIG_ATARI) || defined(CONFIG_Q40) if (MACH_IS_ATARI || MACH_IS_Q40) { @@ -459,6 +485,12 @@ void atapi_output_bytes (ide_drive_t *drive, void *buffer, unsigned int bytecount) { + if(HWIF(drive)->ideproc) { + HWIF(drive)->ideproc(ideproc_atapi_output_bytes, + drive, buffer, bytecount); + return; + } + ++bytecount; #if defined(CONFIG_ATARI) || defined(CONFIG_Q40) if (MACH_IS_ATARI || MACH_IS_Q40) { @@ -2092,6 +2123,7 @@ hwif->maskproc = old_hwif.maskproc; hwif->quirkproc = old_hwif.quirkproc; hwif->rwproc = old_hwif.rwproc; + hwif->ideproc = old_hwif.ideproc; hwif->dmaproc = old_hwif.dmaproc; hwif->dma_base = old_hwif.dma_base; hwif->dma_extra = old_hwif.dma_extra; @@ -3193,6 +3225,12 @@ } #endif /* CONFIG_PCI */ +#ifdef CONFIG_ETRAX_IDE + { + extern void init_e100_ide(void); + init_e100_ide(); + } +#endif /* CONFIG_ETRAX_IDE */ #ifdef CONFIG_BLK_DEV_CMD640 { extern void ide_probe_for_cmd640x(void);--- /home/bjornw/tmp/linux/include/linux/ide.h Thu Jan 4 23:51:21 2001 +++ linux/include/linux/ide.h Wed Apr 18 13:49:54 2001 @@ -133,14 +133,6 @@ #define IDE_BCOUNTL_REG IDE_LCYL_REG #define IDE_BCOUNTH_REG IDE_HCYL_REG -#ifdef REALLY_FAST_IO -#define OUT_BYTE(b,p) outb((b),(p)) -#define IN_BYTE(p) (byte)inb(p) -#else -#define OUT_BYTE(b,p) outb_p((b),(p)) -#define IN_BYTE(p) (byte)inb_p(p) -#endif /* REALLY_FAST_IO */ - #define GET_ERR() IN_BYTE(IDE_ERROR_REG) #define GET_STAT() IN_BYTE(IDE_STATUS_REG) #define GET_ALTSTAT() IN_BYTE(IDE_CONTROL_REG) @@ -255,6 +247,27 @@ #include <asm/ide.h> /* + * If the arch-dependant ide.h did not declare/define any OUT_BYTE + * or IN_BYTE functions, we make some defaults here. + */ + +#ifndef HAVE_ARCH_OUT_BYTE +#ifdef REALLY_FAST_IO +#define OUT_BYTE(b,p) outb((b),(p)) +#else +#define OUT_BYTE(b,p) outb_p((b),(p)) +#endif +#endif + +#ifndef HAVE_ARCH_IN_BYTE +#ifdef REALLY_FAST_IO +#define IN_BYTE(p) (byte)inb_p(p) +#else +#define IN_BYTE(p) (byte)inb(p) +#endif +#endif + +/* * Now for the data we need to maintain per-drive: ide_drive_t */ @@ -373,6 +386,23 @@ typedef int (ide_dmaproc_t)(ide_dma_action_t, ide_drive_t *); /* + * An ide_ideproc_t() performs CPU-polled transfers to/from a drive. + * Arguments are: the drive, the buffer pointer, and the length (in bytes or + * words depending on if it's an IDE or ATAPI call). + * + * If it is not defined for a controller, standard-code is used from ide.c. + * + * Controllers which are not memory-mapped in the standard way need to + * override that mechanism using this function to work. + * + */ +typedef enum { ideproc_ide_input_data, ideproc_ide_output_data, + ideproc_atapi_input_bytes, ideproc_atapi_output_bytes +} ide_ide_action_t; + +typedef void (ide_ideproc_t)(ide_ide_action_t, ide_drive_t *, void *, unsigned int); + +/* * An ide_tuneproc_t() is used to set the speed of an IDE interface * to a particular PIO mode. The "byte" parameter is used * to select the PIO mode by number (0,1,2,3,4,5), and a value of 255 @@ -405,7 +435,7 @@ ide_qd6580, ide_umc8672, ide_ht6560b, ide_pdc4030, ide_rz1000, ide_trm290, ide_cmd646, ide_cy82c693, ide_4drives, - ide_pmac + ide_pmac, ide_etrax100 } hwif_chipset_t; #ifdef CONFIG_BLK_DEV_IDEPCI @@ -433,6 +463,7 @@ ide_maskproc_t *maskproc; /* special host masking for drive selection */ ide_quirkproc_t *quirkproc; /* check host's drive quirk list */ ide_rw_proc_t *rwproc; /* adjust timing based upon rq->cmd direction */ + ide_ideproc_t *ideproc; /* CPU-polled transfer routine */ ide_dmaproc_t *dmaproc; /* dma read/write/abort routine */ unsigned int *dmatable_cpu; /* dma physical region descriptor table (cpu view) */ dma_addr_t dmatable_dma; /* dma physical region descriptor table (dma view) */--- /home/bjornw/tmp/linux/drivers/ide/Makefile Fri Dec 29 23:07:22 2000 +++ linux/drivers/ide/Makefile Wed Jan 10 20:34:15 2001 @@ -42,7 +42,7 @@ ide-obj-$(CONFIG_BLK_DEV_HPT366) += hpt366.o ide-obj-$(CONFIG_BLK_DEV_HT6560B) += ht6560b.o ide-obj-$(CONFIG_BLK_DEV_IDE_ICSIDE) += icside.o -ide-obj-$(CONFIG_BLK_DEV_IDEDMA) += ide-dma.o +ide-obj-$(CONFIG_BLK_DEV_IDEDMA_PCI) += ide-dma.o ide-obj-$(CONFIG_BLK_DEV_IDEPCI) += ide-pci.o ide-obj-$(CONFIG_BLK_DEV_ISAPNP) += ide-pnp.o ide-obj-$(CONFIG_BLK_DEV_IDE_PMAC) += ide-pmac.o | |