patch-2.3.32 linux/drivers/block/icside.c
Next file: linux/drivers/block/ide-cd.c
Previous file: linux/drivers/block/hd.c
Back to the patch index
Back to the overall index
- Lines: 162
- Date:
Mon Dec 13 16:26:27 1999
- Orig file:
v2.3.31/linux/drivers/block/icside.c
- Orig date:
Sun Nov 7 16:37:34 1999
diff -u --recursive --new-file v2.3.31/linux/drivers/block/icside.c linux/drivers/block/icside.c
@@ -210,24 +210,11 @@
/*
* SG-DMA support.
*
- * Similar to the BM-DMA, but we use the RiscPCs IOMD
- * DMA controllers. There is only one DMA controller
- * per card, which means that only one drive can be
- * accessed at one time. NOTE! We do not inforce that
- * here, but we rely on the main IDE driver spotting
- * that both interfaces use the same IRQ, which should
- * guarantee this.
- *
- * We are limited by the drives IOR/IOW pulse time.
- * The closest that we can get to the requirements is
- * a type C cycle for both mode 1 and mode 2. However,
- * this does give a burst of 8MB/s.
- *
- * This has been tested with a couple of Conner
- * Peripherals 1080MB CFS1081A drives, one on each
- * interface, which deliver about 2MB/s each. I
- * believe that this is limited by the lack of
- * on-board drive cache.
+ * Similar to the BM-DMA, but we use the RiscPCs IOMD DMA controllers.
+ * There is only one DMA controller per card, which means that only
+ * one drive can be accessed at one time. NOTE! We do not enforce that
+ * here, but we rely on the main IDE driver spotting that both
+ * interfaces use the same IRQ, which should guarantee this.
*/
#define TABLE_SIZE 2048
@@ -286,27 +273,43 @@
}
static int
-icside_config_drive(ide_drive_t *drive, int mode)
+icside_config_if(ide_drive_t *drive, int xfer_mode)
{
- int speed, err;
+ int func = ide_dma_off;
- if (mode == 2) {
- speed = XFER_MW_DMA_2;
+ switch (xfer_mode) {
+ case XFER_MW_DMA_2:
+ /*
+ * The cycle time is limited to 250ns by the r/w
+ * pulse width (90ns), however we should still
+ * have a maximum burst transfer rate of 8MB/s.
+ */
drive->drive_data = 250;
- } else {
- speed = XFER_MW_DMA_1;
+ break;
+
+ case XFER_MW_DMA_1:
drive->drive_data = 250;
- }
+ break;
- err = ide_config_drive_speed(drive, (byte) speed);
+ case XFER_MW_DMA_0:
+ drive->drive_data = 480;
+ break;
- if (err == 0) {
- drive->id->dma_mword &= 0x00ff;
- drive->id->dma_mword |= 256 << mode;
- } else
+ default:
drive->drive_data = 0;
+ break;
+ }
- return err;
+ if (drive->drive_data &&
+ ide_config_drive_speed(drive, (byte) xfer_mode) == 0)
+ func = ide_dma_on;
+ else
+ drive->drive_data = 480;
+
+ printk("%s: %s selected (peak %dMB/s)\n", drive->name,
+ ide_xfer_verbose(xfer_mode), 2000 / drive->drive_data);
+
+ return func;
}
static int
@@ -315,34 +318,51 @@
struct hd_driveid *id = drive->id;
ide_hwif_t *hwif = HWIF(drive);
int autodma = hwif->autodma;
+ int xfer_mode = XFER_PIO_2;
+ int func = ide_dma_off_quietly;
- if (id && (id->capability & 1) && autodma) {
- int dma_mode = 0;
-
- /* Consult the list of known "bad" drives */
- if (ide_dmaproc(ide_dma_bad_drive, drive))
- return hwif->dmaproc(ide_dma_off, drive);
+ if (!id || !(id->capability & 1) || !autodma)
+ goto out;
- /* Enable DMA on any drive that has
- * UltraDMA (mode 0/1/2) enabled
- */
- if (id->field_valid & 4 && id->dma_ultra & 7)
- dma_mode = 2;
-
- /* Enable DMA on any drive that has mode1
- * or mode2 multiword DMA enabled
- */
- if (id->field_valid & 2 && id->dma_mword & 6)
- dma_mode = id->dma_mword & 4 ? 2 : 1;
+ /*
+ * Consult the list of known "bad" drives
+ */
+ if (ide_dmaproc(ide_dma_bad_drive, drive)) {
+ func = ide_dma_off;
+ goto out;
+ }
- /* Consult the list of known "good" drives */
- if (ide_dmaproc(ide_dma_good_drive, drive))
- dma_mode = 1;
+ /*
+ * Enable DMA on any drive that has multiword DMA
+ */
+ if (id->field_valid & 2) {
+ if (id->dma_mword & 4) {
+ xfer_mode = XFER_MW_DMA_2;
+ func = ide_dma_on;
+ } else if (id->dma_mword & 2) {
+ xfer_mode = XFER_MW_DMA_1;
+ func = ide_dma_on;
+ } else if (id->dma_mword & 1) {
+ xfer_mode = XFER_MW_DMA_0;
+ func = ide_dma_on;
+ }
+ goto out;
+ }
- if (dma_mode && icside_config_drive(drive, dma_mode) == 0)
- return hwif->dmaproc(ide_dma_on, drive);
+ /*
+ * Consult the list of known "good" drives
+ */
+ if (ide_dmaproc(ide_dma_good_drive, drive)) {
+ if (id->eide_dma_time > 150)
+ goto out;
+ xfer_mode = XFER_MW_DMA_1;
+ func = ide_dma_on;
}
- return hwif->dmaproc(ide_dma_off_quietly, drive);
+
+out:
+ func = icside_config_if(drive, xfer_mode);
+
+ return hwif->dmaproc(func, drive);
}
static int
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)