lkml.org 
[lkml]   [2001]   [Apr]   [24]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patches in this message
/
Date
From
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
\
 
 \ /
  Last update: 2005-03-22 13:17    [W:0.037 / U:0.692 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site