patch-1.3.92 linux/drivers/block/promise.c

Next file: linux/drivers/char/ChangeLog
Previous file: linux/drivers/block/ide.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v1.3.91/linux/drivers/block/promise.c linux/drivers/block/promise.c
@@ -1,5 +1,5 @@
-/*
- *  linux/drivers/block/promise.c	Version 0.04  Mar 15, 1996
+/*  -*- linux-c -*-
+ *  linux/drivers/block/promise.c	Version 0.07  Mar 26, 1996
  *
  *  Copyright (C) 1995-1996  Linus Torvalds & authors (see below)
  */
@@ -26,16 +26,11 @@
  *                      Changed initialization strategy
  *  Version 0.05	Kernel integration.  -ml
  *  Version 0.06	Ooops. Add hwgroup to direct call of ide_intr() -ml
+ *  Version 0.07	Added support for DC4030 variants
+ *			Secondary interface autodetection
  */
 
-
 /*
- * From:  'peterd@pnd-pc.demon.co.uk'
- *
- * Here's another version of the Promise driver for DC4030VL2 cards.
- * There have been few substantive changes to the code, but it is now in
- * line with the more recent ide.c changes, and is somewhat more configurable.
- *
  * Once you've compiled it in, you'll have to also enable the interface
  * setup routine from the kernel command line, as in 
  *
@@ -155,12 +150,14 @@
 	}
 	ide_input_data(drive,&ident,SECTOR_WORDS);
 	if(ident.id[1] != 'P' || ident.id[0] != 'T') {
-	    return 0;
+            return 0;
 	}
 	printk("%s: Promise caching controller, ",hwif->name);
 	switch(ident.type) {
-            case 0x43:	printk("DC4030VL, "); break;
-            default:	printk("unknown - type 0x%02x - please report!, "
+            case 0x43:	printk("DC4030VL-2, "); break;
+            case 0x41:	printk("DC4030VL-1, "); break;
+	    case 0x40:	printk("DC4030VL, "); break;
+            default:	printk("unknown - type 0x%02x - please report!\n"
 			       ,ident.type);
 			return 0;
 	}
@@ -173,16 +170,23 @@
 	printk("on IRQ %d\n",hwif->irq);
 	hwif->chipset    = second_hwif->chipset    = ide_promise;
 	hwif->selectproc = second_hwif->selectproc = &promise_selectproc;
+/* Shift the remaining interfaces down by one */
+	for (i=MAX_HWIFS-1 ; i > hwif->index+1 ; i--) {
+		printk("Shifting i/f %d values to i/f %d\n",i-1,i);
+		ide_hwifs[i].io_base = ide_hwifs[i-1].io_base;
+		ide_hwifs[i].ctl_port = ide_hwifs[i-1].ctl_port;
+		ide_hwifs[i].noprobe = ide_hwifs[i-1].noprobe;
+	}
 	second_hwif->is_promise2 = 1;
 	second_hwif->io_base = hwif->io_base;
 	second_hwif->ctl_port = hwif->ctl_port;	
 	second_hwif->irq = hwif->irq;
 	for (i=0; i<2 ; i++) {
-	    hwif->drives[i].io_32bit = 3;
+            hwif->drives[i].io_32bit = 3;
 	    second_hwif->drives[i].io_32bit = 3;
 	    if(!ident.current_tm[i+2].cyl) second_hwif->drives[i].noprobe=1;
 	}
-	return 1;
+        return 1;
 }
 
 /*
@@ -298,9 +302,9 @@
 }
 
 /*
- * do_promise_rw_disk() issues READ and WRITE commands to a
- * disk on a promise controller, using LBA to address sectors.  It also
- * takes care of issuing special DRIVE_CMDs.
+ * do_promise_io() is called from do_rw_disk, having had the block number
+ * already set up. It issues a READ or WRITE command to the Promise
+ * controller, assuming LBA has been used to set up the block number.
  */
 void do_promise_io (ide_drive_t *drive, struct request *rq)
 {
@@ -311,27 +315,30 @@
 	if (rq->cmd == READ) {
 	    ide_set_handler(drive, &promise_read_intr, WAIT_CMD);
 	    OUT_BYTE(PROMISE_READ, io_base+IDE_COMMAND_OFFSET);
-	    /* The card's behaviour is odd at this point. If the data is
-	       available, DRQ will be true, and no interrupt will be
-	       generated by the card. If this is the case, we need to simulate
-	       an interrupt. Ugh! Otherwise, if an interrupt will occur, bit0
-	       of the SELECT register will be high, so we can just return and
-	       be interrupted.*/
+/* The card's behaviour is odd at this point. If the data is
+   available, DRQ will be true, and no interrupt will be
+   generated by the card. If this is the case, we need to simulate
+   an interrupt. Ugh! Otherwise, if an interrupt will occur, bit0
+   of the SELECT register will be high, so we can just return and
+   be interrupted.*/
 	    timeout = jiffies + HZ/20; /* 50ms wait */
 	    do {
 		stat=GET_STAT();
 		if(stat & DRQ_STAT) {
-                    unsigned long flags;
+/*                    unsigned long flags;
                     save_flags(flags);
                     cli();
                     disable_irq(HWIF(drive)->irq);
+*/
 		    ide_intr(HWIF(drive)->irq,HWGROUP(drive),NULL);
-                    enable_irq(HWIF(drive)->irq);
+/*                    enable_irq(HWIF(drive)->irq);
                     restore_flags(flags);
+*/
 		    return;
 		}
 		if(IN_BYTE(io_base+IDE_SELECT_OFFSET) & 0x01)
 		    return;
+		udelay(1);
 	    } while (jiffies < timeout);
 	    printk("%s: reading: No DRQ and not waiting - Odd!\n",
 		   drive->name);

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov with Sam's (original) version
of this