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

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

diff -u --recursive --new-file v2.2.2/linux/drivers/scsi/ncr53c8xx.c linux/drivers/scsi/ncr53c8xx.c
@@ -73,7 +73,7 @@
 */
 
 /*
-**	January 16 1998, version 3.1f
+**	March 6 1999, version 3.1h
 **
 **	Supported SCSI-II features:
 **	    Synchronous negotiation
@@ -2081,6 +2081,7 @@
 	ncrcmd  msg_ext_3	[ 10];
 	ncrcmd	msg_sdtr	[ 14];
 	ncrcmd	send_sdtr	[  7];
+	ncrcmd	nego_bad_phase	[  4];
 	ncrcmd	msg_out_abort	[ 10];
 	ncrcmd  hdata_in	[MAX_SCATTERH * 4];
 	ncrcmd  hdata_in2	[  2];
@@ -3185,16 +3186,15 @@
 	/*
 	**	If a negotiation was in progress,
 	**	negotiation failed.
+	**	Otherwise, let the C code print 
+	**	some message.
 	*/
 	SCR_FROM_REG (HS_REG),
 		0,
-	SCR_INT ^ IFTRUE (DATA (HS_NEGOTIATE)),
-		SIR_NEGO_FAILED,
-	/*
-	**	else make host log this message
-	*/
 	SCR_INT ^ IFFALSE (DATA (HS_NEGOTIATE)),
 		SIR_REJECT_RECEIVED,
+	SCR_INT ^ IFTRUE (DATA (HS_NEGOTIATE)),
+		SIR_NEGO_FAILED,
 	SCR_JUMP,
 		PADDR (clrack),
 
@@ -3304,10 +3304,9 @@
 		0,
 	SCR_CLR (SCR_ACK),
 		0,
+	SCR_JUMP ^ IFFALSE (WHEN (SCR_MSG_OUT)),
+		PADDRH (nego_bad_phase),
 
-/* CHECK THE SOURCE FOR 'send_wdtr' IF YOU INTEND TO CHANGE SOMETHING HERE */
-	SCR_INT ^ IFFALSE (WHEN (SCR_MSG_OUT)),
-		SIR_NEGO_PROTO,
 }/*-------------------------< SEND_WDTR >----------------*/,{
 	/*
 	**	Send the M_X_WIDE_REQ
@@ -3360,10 +3359,9 @@
 		0,
 	SCR_CLR (SCR_ACK),
 		0,
+	SCR_JUMP ^ IFFALSE (WHEN (SCR_MSG_OUT)),
+		PADDRH (nego_bad_phase),
 
-/* CHECK THE SOURCE FOR 'send_sdtr' IF YOU INTEND TO CHANGE SOMETHING HERE */
-	SCR_INT ^ IFFALSE (WHEN (SCR_MSG_OUT)),
-		SIR_NEGO_PROTO,
 }/*-------------------------< SEND_SDTR >-------------*/,{
 	/*
 	**	Send the M_X_SYNC_REQ
@@ -3376,6 +3374,12 @@
 	SCR_JUMP,
 		PADDR (msg_out_done),
 
+}/*-------------------------< NEGO_BAD_PHASE >------------*/,{
+	SCR_INT,
+		SIR_NEGO_PROTO,
+	SCR_JUMP,
+		PADDR (dispatch),
+
 }/*-------------------------< MSG_OUT_ABORT >-------------*/,{
 	/*
 	**	After ABORT message,
@@ -4274,7 +4278,7 @@
 	/*
 	**	Set irq mode.
 	*/
-	switch(driver_setup.irqm) {
+	switch(driver_setup.irqm & 3) {
 	case 2:
 		np->rv_dcntl	|= IRQM;
 		break;
@@ -4665,21 +4669,11 @@
 	/*
 	**	Install the interrupt handler.
 	*/
-#ifdef	SCSI_NCR_SHARE_IRQ
-#define	NCR_SA_INTERRUPT_FLAGS (SA_INTERRUPT | SA_SHIRQ)
-	if (bootverbose > 1)
-#ifdef __sparc__
-		printk(KERN_INFO "%s: requesting shared irq %s (dev_id=0x%lx)\n",
-		        ncr_name(np), __irq_itoa(device->slot.irq), (u_long) np);
-#else
-		printk(KERN_INFO "%s: requesting shared irq %d (dev_id=0x%lx)\n",
-		        ncr_name(np), device->slot.irq, (u_long) np);
-#endif
-#else
-#define	NCR_SA_INTERRUPT_FLAGS SA_INTERRUPT
-#endif
+
 	if (request_irq(device->slot.irq, ncr53c8xx_intr,
-			NCR_SA_INTERRUPT_FLAGS, "ncr53c8xx", np)) {
+			((driver_setup.irqm & 0x10) ? 0 : SA_SHIRQ) |
+			((driver_setup.irqm & 0x20) ? 0 : SA_INTERRUPT),
+			"ncr53c8xx", np)) {
 #ifdef __sparc__
 		printk(KERN_ERR "%s: request irq %s failure\n",
 			ncr_name(np), __irq_itoa(device->slot.irq));
@@ -4689,6 +4683,7 @@
 #endif
 		goto attach_error;
 	}
+
 	np->irq = device->slot.irq;
 
 	/*
@@ -4956,9 +4951,8 @@
 				nego = NS_SYNC;
 			} else {
 				tp->period  =0xffff;
-				tp->sval = 0xe0;
 				PRINT_TARGET(np, cmd->target);
-				printk ("SYNC transfers not supported.\n");
+				printk ("device did not report SYNC.\n");
 			};
 		};
 
@@ -5824,7 +5818,7 @@
 		**	announced capabilities (we need the 1rst 7 bytes).
 		*/
 		if (cmd->cmnd[0] == 0x12 && !(cmd->cmnd[1] & 0x3) &&
-		    cmd->cmnd[4] >= 7) {
+		    cmd->cmnd[4] >= 7 && !cmd->use_sg) {
 			ncr_setup_lcb (np, cmd->target, cmd->lun,
 				       (char *) cmd->request_buffer);
 		}
@@ -7051,7 +7045,7 @@
 	OUTONB (nc_ctest3, CLF);
 
 	if ((sist & (SGE)) ||
-		(dstat & (MDPE|BF|ABORT|IID))) {
+		(dstat & (MDPE|BF|ABRT|IID))) {
 		ncr_start_reset(np);
 		return;
 	};
@@ -7528,7 +7522,7 @@
 		}
 		else if	(dsp == NCB_SCRIPTH_PHYS (np, send_wdtr) ||
 			 dsp == NCB_SCRIPTH_PHYS (np, send_sdtr)) {
-			nxtdsp = dsp - 8; /* Should raise SIR_NEGO_PROTO */
+			nxtdsp = NCB_SCRIPTH_PHYS (np, nego_bad_phase);
 		}
 		break;
 #if 0
@@ -7882,9 +7876,7 @@
 		np->msgin [0] = M_NOOP;
 		np->msgout[0] = M_NOOP;
 		cp->nego_status = 0;
-		OUTL (nc_dsp, NCB_SCRIPT_PHYS (np, dispatch));
-		return;
-/*		break;	*/
+		break;
 
 	case SIR_NEGO_SYNC:
 		/*
@@ -8657,10 +8649,15 @@
 	**	Evaluate trustable target/unit capabilities.
 	**	We only believe device version >= SCSI-2 that 
 	**	use appropriate response data format (2).
+	**	But it seems that some CCS devices also 
+	**	support SYNC and I donnot want to frustrate 
+	**	anybody. ;-)
 	*/
 	inq_byte7 = 0;
-	if ((inq_data[2] & 0x7) >= 2 && (inq_data[3] & 0xf) == 2)
+	if	((inq_data[2] & 0x7) >= 2 && (inq_data[3] & 0xf) == 2)
 		inq_byte7 = inq_data[7];
+	else if ((inq_data[2] & 0x7) == 1 && (inq_data[3] & 0xf) == 1)
+		inq_byte7 = INQ7_SYNC;
 
 	/*
 	**	Throw away announced LUN capabilities if we are told 
@@ -9586,6 +9583,50 @@
 }
 
 /*
+**   Generically read a base address from the PCI configuration space.
+**   Return the offset immediately after the base address that has 
+**   been read. Btw, we blindly assume that the high 32 bits of 64 bit 
+**   base addresses are set to zero on 32 bit architectures.
+**
+*/
+#if LINUX_VERSION_CODE <= LinuxVersionCode(2,1,92)
+__initfunc(
+static int 
+pci_read_base_address(u_char bus, u_char device_fn, int offset, u_long *base)
+)
+{
+	u_int32 tmp;
+
+	pcibios_read_config_dword(bus, device_fn, offset, &tmp);
+	*base = tmp;
+	offset += sizeof(u_int32);
+	if ((tmp & 0x7) == 0x4) {
+#if BITS_PER_LONG > 32
+		pcibios_read_config_dword(bus, device_fn, offset, &tmp);
+		*base |= (((u_long)tmp) << 32);
+#endif
+		offset += sizeof(u_int32);
+	}
+	return offset;
+}
+#else	/* LINUX_VERSION_CODE > LinuxVersionCode(2,1,92) */
+__initfunc(
+static int 
+pci_get_base_address(struct pci_dev *pdev, int index, u_long *base)
+)
+{
+	*base = pdev->base_address[index++];
+	if ((*base & 0x7) == 0x4) {
+#if BITS_PER_LONG > 32
+		*base |= (((u_long)pdev->base_address[index]) << 32);
+#endif
+		++index;
+	}
+	return index;
+}
+#endif
+
+/*
 **   Read and check the PCI configuration for any detected NCR 
 **   boards and save data for attaching after all boards have 
 **   been detected.
@@ -9601,61 +9642,46 @@
 	uchar revision;
 #if LINUX_VERSION_CODE > LinuxVersionCode(2,1,92)
 	struct pci_dev *pdev;
-	ulong base, base_2, io_port; 
 	uint irq;
 #else
 	uchar irq;
-	uint base, base_2, io_port; 
 #endif
+	ulong base, base_2, io_port; 
 	int i;
-
 #ifdef SCSI_NCR_NVRAM_SUPPORT
 	ncr_nvram *nvram = device->nvram;
 #endif
 	ncr_chip *chip;
 
 	/*
-	 * Read info from the PCI config space.
-	 * pcibios_read_config_xxx() functions are assumed to be used for 
-	 * successfully detected PCI devices.
-	 * Expecting error conditions from them is just paranoia,
-	 * thus void cast.
-	 */
-	(void) pcibios_read_config_word(bus, device_fn,
-					PCI_VENDOR_ID, &vendor_id);
-	(void) pcibios_read_config_word(bus, device_fn,
-					PCI_DEVICE_ID, &device_id);
-	(void) pcibios_read_config_word(bus, device_fn,
-					PCI_COMMAND, &command);
+	**    Read info from the PCI config space.
+	**    pcibios_read_config_xxx() functions are assumed to be used for 
+	**    successfully detected PCI devices.
+	*/
 #if LINUX_VERSION_CODE > LinuxVersionCode(2,1,92)
 	pdev = pci_find_slot(bus, device_fn);
-	io_port = pdev->base_address[0];
-	base = pdev->base_address[1];
-	base_2 = pdev->base_address[2];
+	vendor_id = pdev->vendor;
+	device_id = pdev->device;
 	irq = pdev->irq;
-	if ((base & PCI_BASE_ADDRESS_MEM_TYPE_MASK) == PCI_BASE_ADDRESS_MEM_TYPE_64)
-		base_2 = pdev->base_address[3];
+	i =	0;
+	i =	pci_get_base_address(pdev, i, &io_port);
+	i =	pci_get_base_address(pdev, i, &base);
+	(void)	pci_get_base_address(pdev, i, &base_2);
 #else
-	(void) pcibios_read_config_dword(bus, device_fn,
-					PCI_BASE_ADDRESS_0, &io_port);	
-	(void) pcibios_read_config_dword(bus, device_fn,
-					PCI_BASE_ADDRESS_1, &base);
-	(void) pcibios_read_config_dword(bus, device_fn,
-					PCI_BASE_ADDRESS_2, &base_2);
-
-	/* Handle 64bit base addresses for 53C896. */
-	if ((base & PCI_BASE_ADDRESS_MEM_TYPE_MASK) == PCI_BASE_ADDRESS_MEM_TYPE_64)
-		(void) pcibios_read_config_dword(bus, device_fn,
-						 PCI_BASE_ADDRESS_3, &base_2);
-	(void) pcibios_read_config_byte(bus, device_fn,
-					PCI_INTERRUPT_LINE, &irq);
-#endif
-	(void) pcibios_read_config_byte(bus, device_fn,
-					PCI_CLASS_REVISION,&revision);	
-	(void) pcibios_read_config_byte(bus, device_fn,
-					PCI_CACHE_LINE_SIZE, &cache_line_size);
-	(void) pcibios_read_config_byte(bus, device_fn,
-					PCI_LATENCY_TIMER, &latency_timer);
+	pcibios_read_config_word(bus, device_fn, PCI_VENDOR_ID, &vendor_id);
+	pcibios_read_config_word(bus, device_fn, PCI_DEVICE_ID, &device_id);
+	pcibios_read_config_byte(bus, device_fn, PCI_INTERRUPT_LINE, &irq);
+	i =	PCI_BASE_ADDRESS_0;
+	i =	pci_read_base_address(bus, device_fn, i, &io_port);
+	i =	pci_read_base_address(bus, device_fn, i, &base);
+	(void)	pci_read_base_address(bus, device_fn, i, &base_2);
+#endif
+	pcibios_read_config_word(bus, device_fn, PCI_COMMAND, &command);
+	pcibios_read_config_byte(bus, device_fn, PCI_CLASS_REVISION, &revision);
+	pcibios_read_config_byte(bus, device_fn, PCI_CACHE_LINE_SIZE,
+				 &cache_line_size);
+	pcibios_read_config_byte(bus, device_fn, PCI_LATENCY_TIMER,
+				 &latency_timer);
 
 	/*
 	 *	Check if the chip is supported

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)