patch-2.1.57 linux/drivers/scsi/ncr53c8xx.c

Next file: linux/drivers/scsi/ncr53c8xx.h
Previous file: linux/drivers/scsi/ChangeLog.ncr53c8xx
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.1.56/linux/drivers/scsi/ncr53c8xx.c linux/drivers/scsi/ncr53c8xx.c
@@ -67,7 +67,7 @@
 */
 
 /*
-**	23 August 1997, version 2.5a
+**	20 September 1997, version 2.5c
 **
 **	Supported SCSI-II features:
 **	    Synchronous negotiation
@@ -457,9 +457,9 @@
 /*
 **	Head of list of NCR boards
 **
-**	Host is retrieved by its irq level.
-**	If interrupts are shared, the internal host control block 
-**	address (struct ncb) is used as device id.
+**	For kernel version < 1.3.70, host is retrieved by its irq level.
+**	For later kernels, the internal host control block address 
+**	(struct ncb) is used as device id parameter of the irq stuff.
 */
 
 static struct Scsi_Host		*first_host	= NULL;
@@ -528,6 +528,9 @@
 #ifdef	SCSI_NCR_BOOT_COMMAND_LINE_SUPPORT
 static struct ncr_driver_setup
 	driver_safe_setup __initdata	= SCSI_NCR_DRIVER_SAFE_SETUP;
+#ifdef	MODULE
+char *ncr53c8xx = 0;	/* command line passed by insmod */
+#endif
 #endif
 
 /*
@@ -4579,7 +4582,7 @@
 			SA_INTERRUPT|SA_SHIRQ, "ncr53c8xx", np)) {
 #else
 	if (request_irq(device->slot.irq, ncr53c8xx_intr,
-			SA_INTERRUPT, "ncr53c8xx", NULL)) {
+			SA_INTERRUPT, "ncr53c8xx", np)) {
 #endif
 #else
 	if (request_irq(device->slot.irq, ncr53c8xx_intr,
@@ -4736,7 +4739,9 @@
 
 	/*---------------------------------------------------
 	**
-	**	Assign a ccb / bind cmd
+	**	Assign a ccb / bind cmd.
+	**	If resetting, shorten settle_time if necessary
+	**	in order to avoid spurious timeouts.
 	**	If resetting or no free ccb,
 	**	insert cmd into the waiting list.
 	**
@@ -4744,6 +4749,11 @@
 	*/
 	save_flags(flags); cli();
 
+	if (np->settle_time && cmd->timeout_per_command >= HZ &&
+		np->settle_time > jiffies + cmd->timeout_per_command - HZ) {
+		np->settle_time = jiffies + cmd->timeout_per_command - HZ;
+	}
+
         if (np->settle_time || !(cp=ncr_get_ccb (np, cmd->target, cmd->lun))) {
 		insert_into_waiting_list(np, cmd);
 		restore_flags(flags);
@@ -5234,7 +5244,7 @@
  * Commands will now be queued in the waiting list until a settle 
  * delay of 2 seconds will be completed.
  */
-	ncr_start_reset(np, 2);
+	ncr_start_reset(np, driver_setup.settle_delay);
 /*
  * First, look in the wakeup list
  */
@@ -5382,7 +5392,7 @@
 */
 
 #ifdef MODULE
-static int ncr_detach(ncb_p np, int irq)
+static int ncr_detach(ncb_p np)
 {
 	ccb_p cp;
 	tcb_p tp;
@@ -5421,16 +5431,12 @@
 */
 
 #ifdef DEBUG_NCR53C8XX
-	printf("%s: freeing irq %d\n", ncr_name(np), irq);
+	printf("%s: freeing irq %d\n", ncr_name(np), np->irq);
 #endif
 #if LINUX_VERSION_CODE >= LinuxVersionCode(1,3,70)
-#   ifdef SCSI_NCR_SHARE_IRQ
-	free_irq(irq, np);
-#   else
-	free_irq(irq, NULL);
-#   endif
+	free_irq(np->irq, np);
 #else
-	free_irq(irq);
+	free_irq(np->irq);
 #endif
 
 	/*
@@ -6786,14 +6792,20 @@
 		script_base	= (u_char *) np->script;
 		script_name	= "script";
 	}
-	else {
+	else if (np->p_scripth < dsp && 
+		 dsp <= np->p_scripth + sizeof(struct scripth)) {
 		script_ofs	= dsp - np->p_scripth;
 		script_size	= sizeof(struct scripth);
 		script_base	= (u_char *) np->scripth;
 		script_name	= "scripth";
+	} else {
+		script_ofs	= dsp;
+		script_size	= 0;
+		script_base	= 0;
+		script_name	= "mem";
 	}
 
-	printf ("%s:%d: ERROR (%x:%x) (%x-%x-%x) (%x/%x) @ %s (%x:%08x).\n",
+	printf ("%s:%d: ERROR (%x:%x) (%x-%x-%x) (%x/%x) @ (%s %x:%08x).\n",
 		ncr_name (np), (unsigned)INB (nc_ctest0)&0x0f, dstat, sist,
 		(unsigned)INB (nc_socl), (unsigned)INB (nc_sbcl), (unsigned)INB (nc_sbdl),
 		(unsigned)INB (nc_sxfer),(unsigned)INB (nc_scntl3), script_name, script_ofs,
@@ -6978,13 +6990,13 @@
 
 	if ((sist & (SGE)) ||
 		(dstat & (MDPE|BF|ABORT|IID))) {
-		ncr_start_reset(np, 2);
+		ncr_start_reset(np, driver_setup.settle_delay);
 		return;
 	};
 
 	if (sist & HTH) {
 		printf ("%s: handshake timeout\n", ncr_name(np));
-		ncr_start_reset(np, 2);
+		ncr_start_reset(np, driver_setup.settle_delay);
 		return;
 	};
 
@@ -6994,7 +7006,7 @@
 			OUTB (nc_scr1, HS_UNEXPECTED);
 			OUTL (nc_dsp, NCB_SCRIPT_PHYS (np, cleanup));
 		};
-		ncr_start_reset(np, 2);
+		ncr_start_reset(np, driver_setup.settle_delay);
 		return;
 	};
 
@@ -7085,7 +7097,7 @@
 		ncr_name(np), np->scsi_mode, scsi_mode);
 
 	np->scsi_mode = scsi_mode;
-	ncr_start_reset(np, 2);
+	ncr_start_reset(np, driver_setup.settle_delay);
 
 	return 1;
 }
@@ -8913,7 +8925,11 @@
 		else
 			printf("ncr53c8xx_setup: unexpected boot option '%.*s' ignored\n", (int)(pc-cur+1), cur);
 
+#ifdef MODULE
+		if ((cur = strchr(cur, ' ')) != NULL)
+#else
 		if ((cur = strchr(cur, ',')) != NULL)
+#endif
 			++cur;
 	}
 #endif /* SCSI_NCR_BOOT_COMMAND_LINE_SUPPORT */
@@ -9089,6 +9105,11 @@
 # endif
 #endif
 
+#if	defined(SCSI_NCR_BOOT_COMMAND_LINE_SUPPORT) && defined(MODULE)
+if (ncr53c8xx)
+	ncr53c8xx_setup(ncr53c8xx, (int *) 0);
+#endif
+
 	/* 
 	** Detect all 53c8xx hosts and then attach them.
 	**
@@ -9248,6 +9269,28 @@
 		return -1;
 	}
 
+#ifdef __powerpc__
+	/*
+	 *	Severall fix-up for power/pc.
+	 *	Should not be performed by the driver.
+	 */
+	if ((command &
+		(PCI_COMMAND_MASTER|PCI_COMMAND_IO|PCI_COMMAND_MEMORY)) !=
+		(PCI_COMMAND_MASTER|PCI_COMMAND_IO|PCI_COMMAND_MEMORY)) {
+		printk("ncr53c8xx : setting PCI master/io/command bit\n");
+		command |= PCI_COMMAND_MASTER|PCI_COMMAND_IO|PCI_COMMAND_MEMORY;
+		pcibios_write_config_word(bus, device_fn, PCI_COMMAND, command);
+	}
+       if (io_port >= 0x10000000) {
+		io_port = (io_port & 0x00FFFFFF) | 0x01000000;
+		pcibios_write_config_dword(bus, device_fn, PCI_BASE_ADDRESS_0, io_port);
+       }
+	if (base >= 0x10000000) {
+		base = (base & 0x00FFFFFF) | 0x01000000;
+		pcibios_write_config_dword(bus, device_fn, PCI_BASE_ADDRESS_1, base);
+	}
+#endif
+
 	/*
 	 * Check availability of IO space, memory space and master capability.
 	 */
@@ -9510,47 +9553,41 @@
 }
 
 /*
-**   Linux entry point of the interrupt handler
+**   Linux entry point of the interrupt handler.
+**   Fort linux versions > 1.3.70, we trust the kernel for 
+**   passing the internal host descriptor as 'dev_id'.
+**   Otherwise, we scan the host list and call the interrupt 
+**   routine for each host that uses this IRQ.
 */
 
 #if LINUX_VERSION_CODE >= LinuxVersionCode(1,3,70)
 static void ncr53c8xx_intr(int irq, void *dev_id, struct pt_regs * regs)
+{
+#ifdef DEBUG_NCR53C8XX
+     printk("ncr53c8xx : interrupt received\n");
+#endif
+
+     if (DEBUG_FLAGS & DEBUG_TINY) printf ("[");
+     ncr_exception((ncb_p) dev_id);
+     if (DEBUG_FLAGS & DEBUG_TINY) printf ("]\n");
+}
+
 #else
 static void ncr53c8xx_intr(int irq, struct pt_regs * regs)
-#endif
 {
      struct Scsi_Host *host;
      struct host_data *host_data;
-#if 0
-     u_long flags;
-
-     save_flags(flags); cli();
-#endif
-
-#ifdef DEBUG_NCR53C8XX
-printk("ncr53c8xx : interrupt received\n");
-#endif
 
      for (host = first_host; host; host = host->next) {
 	  if (host->hostt == the_template && host->irq == irq) {
 	       host_data = (struct host_data *) host->hostdata;
-#if LINUX_VERSION_CODE >= LinuxVersionCode(1,3,70)
-#   ifdef SCSI_NCR_SHARE_IRQ
-               if (dev_id == host_data->ncb) {
-#else
-               if (1) {
-#   endif
-#endif
-                    if (DEBUG_FLAGS & DEBUG_TINY) printf ("[");
-	            ncr_exception(host_data->ncb);
-                    if (DEBUG_FLAGS & DEBUG_TINY) printf ("]\n");
-               }
+               if (DEBUG_FLAGS & DEBUG_TINY) printf ("[");
+               ncr_exception(host_data->ncb);
+               if (DEBUG_FLAGS & DEBUG_TINY) printf ("]\n");
 	  }
      }
-#if 0
-     restore_flags(flags);
-#endif
 }
+#endif
 
 /*
 **   Linux entry point of the timer handler
@@ -9656,17 +9693,10 @@
 #ifdef MODULE
 int ncr53c8xx_release(struct Scsi_Host *host)
 {
-     struct host_data *host_data;
 #ifdef DEBUG_NCR53C8XX
 printk("ncr53c8xx : release\n");
 #endif
-
-     for (host = first_host; host; host = host->next) {
-	  if (host->hostt == the_template) {
-	       host_data = (struct host_data *) host->hostdata;
-	       ncr_detach(host_data->ncb, host->irq);
-	  }
-     }
+     ncr_detach(((struct host_data *) host->hostdata)->ncb);
 
      return 1;
 }

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov