Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 18 Nov 2001 13:09:49 +0000
From:      Ian Dowse <iedowse@maths.tcd.ie>
To:        John Merryweather Cooper <jmcoopr@webmail.bmi.net>
Cc:        freebsd-bugs@freebsd.org
Subject:   Re: kern/23314: aic driver fails to detect Adaptec 1520B unless PnP is disabled on the adapter
Message-ID:   <200111181309.aa66368@salmon.maths.tcd.ie>

next in thread | raw e-mail | index | archive | help

Hi, could you try the following patch in sys/dev/aic/ to see if it
solves this problem? This is a backport to RELENG_4 of what I think
are all the relevent revisions that went into -current but haven't
been MFC'd. If it works, I'm sure there will be no problem getting
someone to commit it.

Ian

Index: aic.c
===================================================================
RCS file: /home/iedowse/CVS/src/sys/dev/aic/aic.c,v
retrieving revision 1.8
diff -u -r1.8 aic.c
--- aic.c	2000/01/14 23:42:35	1.8
+++ aic.c	2001/11/18 12:58:59
@@ -28,11 +28,10 @@
 
 #include <sys/param.h>
 #include <sys/systm.h>
-#include <sys/malloc.h>
-#include <sys/buf.h>   
 #include <sys/kernel.h>
-#include <sys/sysctl.h>
 #include <sys/bus.h>
+#include <sys/malloc.h>
+#include <sys/devicestat.h>	/* for struct devstat */
 
 #include <machine/bus_pio.h>
 #include <machine/bus.h>
@@ -43,6 +42,7 @@
 #include <cam/cam_sim.h>
 #include <cam/cam_xpt_sim.h>
 #include <cam/cam_debug.h>
+#include <cam/cam_periph.h>
 
 #include <cam/scsi/scsi_message.h>
 
@@ -69,6 +69,9 @@
 static void aic_scsi_reset __P((struct aic_softc *aic));
 static void aic_chip_reset __P((struct aic_softc *aic));
 static void aic_reset __P((struct aic_softc *aic, int initiate_reset));
+static void aic_cam_rescan_callback __P((struct cam_periph *periph,
+					union ccb *ccb));
+static void aic_cam_rescan __P((struct aic_softc *aic));
 
 devclass_t aic_devclass;
 
@@ -194,16 +197,26 @@
 
 		if ((cts->valid & CCB_TRANS_SYNC_RATE_VALID) != 0) {
 			ti->goal.period = cts->sync_period;
-			if (ti->goal.period != ti->current.period)
-				ti->flags |= TINFO_SDTR_NEGO;
+
+			if (ti->goal.period > aic->min_period) {
+				ti->goal.period = 0;
+				ti->goal.offset = 0;
+			} else if (ti->goal.period < aic->max_period)
+				ti->goal.period = aic->max_period;
 		}
 
 		if ((cts->valid & CCB_TRANS_SYNC_OFFSET_VALID) != 0) {
 			ti->goal.offset = cts->sync_offset;
-			if (ti->goal.offset != ti->current.offset)
-				ti->flags |= TINFO_SDTR_NEGO;
+			if (ti->goal.offset == 0)
+				ti->goal.period = 0;
+			else if (ti->goal.offset > AIC_SYNC_OFFSET)
+				ti->goal.offset = AIC_SYNC_OFFSET;
 		}
 
+		if ((ti->goal.period != ti->current.period)
+		 || (ti->goal.offset != ti->current.offset))
+			ti->flags |= TINFO_SDTR_NEGO;
+
 		splx(s);
 		ccb->ccb_h.status = CAM_REQ_CMP;
 		xpt_done(ccb);
@@ -1425,9 +1438,25 @@
 		aic->flags |= AIC_DISC_ENABLE;
 	if (PORTB_DMA(portb))
 		aic->flags |= AIC_DMA_ENABLE;
-	if (aic_inb(aic, REV))
+
+	/*
+	 * We can do fast SCSI (10MHz clock rate) if bit 4 of portb
+	 * is set and we've got a 6360.  The 6260 can only do standard
+	 * 5MHz SCSI.
+	 */
+	if (aic_inb(aic, REV)) {
+		if (PORTB_FSYNC(portb)) {
+			aic->max_period = AIC_FAST_SYNC_PERIOD;
+			aic->flags |= AIC_FAST_ENABLE;
+		} else
+			aic->max_period = AIC_SYNC_PERIOD;
+
 		aic->flags |= AIC_DWIO_ENABLE;
+	} else
+		aic->max_period = AIC_SYNC_PERIOD;
 
+	aic->min_period = AIC_MIN_SYNC_PERIOD;
+	
 	free_scbs = NULL;
 	for (i = 255; i >= 0; i--) {
 		scb = &aic->scbs[i];
@@ -1443,7 +1472,7 @@
 		ti->flags = TINFO_TAG_ENB;
 		if (aic->flags & AIC_DISC_ENABLE)
 			ti->flags |= TINFO_DISC_ENB;
-		ti->user.period = AIC_SYNC_PERIOD;
+		ti->user.period = aic->max_period;
 		ti->user.offset = AIC_SYNC_OFFSET;
 		ti->scsirate = 0;
 	}
@@ -1501,14 +1530,6 @@
 		return (ENXIO);
 	}
 
-	if (xpt_create_path(&aic->path, /*periph*/NULL,
-			    cam_sim_path(aic->sim), CAM_TARGET_WILDCARD,
-			    CAM_LUN_WILDCARD) != CAM_REQ_CMP) {
-		xpt_bus_deregister(cam_sim_path(aic->sim));
-		cam_sim_free(aic->sim, /*free_devq*/TRUE);
-		return (ENXIO);
-	}
-
 	aic_init(aic);
 
 	printf("aic%d: %s", aic->unit,
@@ -1519,7 +1540,12 @@
 		printf(", disconnection");
 	if (aic->flags & AIC_PARITY_ENABLE)
 		printf(", parity check");
+	if (aic->flags & AIC_FAST_ENABLE)
+		printf(", fast SCSI");
 	printf("\n");
+
+	aic_cam_rescan(aic);	/* have CAM rescan the bus */
+
 	return (0);
 }
 
@@ -1531,4 +1557,30 @@
 	xpt_bus_deregister(cam_sim_path(aic->sim));
 	cam_sim_free(aic->sim, /*free_devq*/TRUE);
 	return (0);
+}
+
+static void
+aic_cam_rescan_callback(struct cam_periph *periph, union ccb *ccb)
+{
+	free(ccb, M_TEMP);
+}
+
+static void
+aic_cam_rescan(struct aic_softc *aic)
+{
+	union ccb *ccb = malloc(sizeof(union ccb), M_TEMP, M_WAITOK | M_ZERO);
+
+	if (xpt_create_path(&aic->path, xpt_periph, cam_sim_path(aic->sim), 0, 0)
+	    != CAM_REQ_CMP) {
+		/* A failure is benign as the user can do a manual rescan */
+		return;
+	}
+
+	xpt_setup_ccb(&ccb->ccb_h, aic->path, 5/*priority (low)*/);
+	ccb->ccb_h.func_code = XPT_SCAN_BUS;
+	ccb->ccb_h.cbfcnp = aic_cam_rescan_callback;
+	ccb->crcn.flags = CAM_FLAG_NONE;
+	xpt_action(ccb);
+
+	/* The scan is in progress now. */
 }
Index: aic6360reg.h
===================================================================
RCS file: /home/iedowse/CVS/src/sys/dev/aic/aic6360reg.h,v
retrieving revision 1.1
diff -u -r1.1 aic6360reg.h
--- aic6360reg.h	1999/10/21 08:56:52	1.1
+++ aic6360reg.h	2001/11/18 12:59:13
@@ -320,8 +320,10 @@
 #define PORTA_PARITY(a)	((a) & 0x80)
 
 /* PORTB */
+#define PORTB_EXTTRAN(b)((b) & 1)
 #define PORTB_DISC(b)	((b) & 4)
 #define PORTB_SYNC(b)	((b) & 8)
+#define PORTB_FSYNC(b)	((b) & 0x10)
 #define PORTB_BOOT(b)	((b) & 0x40)
 #define PORTB_DMA(b)	((b) & 0x80)
 
Index: aic_cbus.c
===================================================================
RCS file: /home/iedowse/CVS/src/sys/dev/aic/aic_cbus.c,v
retrieving revision 1.1.2.2
diff -u -r1.1.2.2 aic_cbus.c
--- aic_cbus.c	2000/06/21 09:37:09	1.1.2.2
+++ aic_cbus.c	2001/11/18 13:01:25
@@ -27,7 +27,6 @@
  */
 
 #include <sys/param.h>
-#include <sys/systm.h>
 #include <sys/kernel.h>
 #include <sys/module.h>
 #include <sys/bus.h>
@@ -79,12 +78,12 @@
 	0x20, 0x22, 0x24, 0x26, 0x28, 0x2a, 0x2c, 0x2e,
 	0x30, 0x32, 0x34, 0x36, 0x38, 0x3a, 0x3c, 0x3e,
 };
+#endif
 
 static struct isa_pnp_id aic_ids[] = {
-        { 0xa180a3b8,   "NEC PC9801-100"},
-        {0}
+	{ 0xa180a3b8, "NEC PC9801-100" },
+ 	{ 0 }
 };
-#endif
 
 static int
 aic_isa_alloc_resources(device_t dev)
@@ -111,8 +110,10 @@
 	sc->sc_port = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid,
 					0ul, ~0ul, AIC_ISA_PORTSIZE, RF_ACTIVE);
 #endif
-	if (!sc->sc_port)
+	if (!sc->sc_port) {
+		device_printf(dev, "I/O port allocation failed\n");
 		return (ENOMEM);
+	}
 #ifdef PC98
 	isa_load_resourcev(sc->sc_port, bs_iat, AIC_ISA_PORTSIZE);
 #endif
@@ -122,6 +123,7 @@
 		sc->sc_irq = bus_alloc_resource(dev, SYS_RES_IRQ, &rid,
 						0ul, ~0ul, 1, RF_ACTIVE);
 		if (!sc->sc_irq) {
+			device_printf(dev, "IRQ allocation failed\n");
 			aic_isa_release_resources(dev);
 			return (ENOMEM);
 		}
@@ -132,6 +134,7 @@
 		sc->sc_drq = bus_alloc_resource(dev, SYS_RES_DRQ, &rid,
 						0ul, ~0ul, 1, RF_ACTIVE);
 		if (!sc->sc_drq) {
+			device_printf(dev, "DRQ allocation failed\n");
 			aic_isa_release_resources(dev);
 			return (ENOMEM);
 		}
@@ -166,11 +169,7 @@
 	u_int port, *ports;
 	u_int8_t porta;
 
-#ifdef PC98
 	if (ISA_PNP_PROBE(device_get_parent(dev), dev, aic_ids) == ENXIO)
-#else
-	if (isa_get_vendorid(dev))
-#endif
 		return (ENXIO);
 
 	port = isa_get_port(dev);
Index: aic_isa.c
===================================================================
RCS file: /home/iedowse/CVS/src/sys/dev/aic/aic_isa.c,v
retrieving revision 1.3
diff -u -r1.3 aic_isa.c
--- aic_isa.c	2000/01/14 23:42:35	1.3
+++ aic_isa.c	2001/11/18 13:01:02
@@ -27,7 +27,6 @@
  */
 
 #include <sys/param.h>
-#include <sys/systm.h>
 #include <sys/kernel.h>
 #include <sys/module.h>
 #include <sys/bus.h>
@@ -58,6 +57,12 @@
 #define	AIC_ISA_NUMPORTS (sizeof(aic_isa_ports) / sizeof(aic_isa_ports[0]))
 #define	AIC_ISA_PORTSIZE 0x20
 
+static struct isa_pnp_id aic_ids[] = {
+	{ 0x15309004, "Adaptec AHA-1530P" },
+	{ 0x15209004, "Adaptec AHA-1520P" },
+ 	{ 0 }
+};
+
 static int
 aic_isa_alloc_resources(device_t dev)
 {
@@ -69,14 +74,17 @@
 	rid = 0;
 	sc->sc_port = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid,
 					0ul, ~0ul, AIC_ISA_PORTSIZE, RF_ACTIVE);
-	if (!sc->sc_port)
+	if (!sc->sc_port) {
+		device_printf(dev, "I/O port allocation failed\n");
 		return (ENOMEM);
+	}
 
 	if (isa_get_irq(dev) != -1) {
 		rid = 0;
 		sc->sc_irq = bus_alloc_resource(dev, SYS_RES_IRQ, &rid,
 						0ul, ~0ul, 1, RF_ACTIVE);
 		if (!sc->sc_irq) {
+			device_printf(dev, "IRQ allocation failed\n");
 			aic_isa_release_resources(dev);
 			return (ENOMEM);
 		}
@@ -87,6 +95,7 @@
 		sc->sc_drq = bus_alloc_resource(dev, SYS_RES_DRQ, &rid,
 						0ul, ~0ul, 1, RF_ACTIVE);
 		if (!sc->sc_drq) {
+			device_printf(dev, "DRQ allocation failed\n");
 			aic_isa_release_resources(dev);
 			return (ENOMEM);
 		}
@@ -121,7 +130,7 @@
 	u_int port, *ports;
 	u_int8_t porta;
 
-	if (isa_get_vendorid(dev))
+	if (ISA_PNP_PROBE(device_get_parent(dev), dev, aic_ids) == ENXIO)
 		return (ENXIO);
 
 	port = isa_get_port(dev);
Index: aic_pccard.c
===================================================================
RCS file: /home/iedowse/CVS/src/sys/dev/aic/aic_pccard.c,v
retrieving revision 1.1
diff -u -r1.1 aic_pccard.c
--- aic_pccard.c	2000/01/14 23:42:36	1.1
+++ aic_pccard.c	2001/11/18 12:53:57
@@ -27,7 +27,6 @@
  */
 
 #include <sys/param.h>
-#include <sys/systm.h>
 #include <sys/kernel.h>
 #include <sys/module.h>
 #include <sys/bus.h>
@@ -37,7 +36,6 @@
 #include <machine/resource.h>
 #include <sys/rman.h>
  
-#include <dev/aic/aic6360reg.h>
 #include <dev/aic/aicvar.h>
 
 struct aic_pccard_softc {
Index: aicvar.h
===================================================================
RCS file: /home/iedowse/CVS/src/sys/dev/aic/aicvar.h,v
retrieving revision 1.2.2.1
diff -u -r1.2.2.1 aicvar.h
--- aicvar.h	2000/08/08 23:51:23	1.2.2.1
+++ aicvar.h	2001/11/18 12:59:29
@@ -91,6 +91,9 @@
 
 	struct aic_tinfo	tinfo[8];
 	struct aic_scb		scbs[256];
+
+	int			min_period;
+	int			max_period;
 };
 
 #define	AIC_DISC_ENABLE		0x01
@@ -100,6 +103,7 @@
 #define	AIC_RESOURCE_SHORTAGE	0x10
 #define	AIC_DROP_MSGIN		0x20
 #define	AIC_BUSFREE_OK		0x40
+#define	AIC_FAST_ENABLE		0x80
 
 #define	AIC_IDLE		0x00
 #define	AIC_SELECTING		0x01
@@ -114,6 +118,8 @@
 #define	AIC_MSG_MSGBUF		0x80
 
 #define	AIC_SYNC_PERIOD		(200 / 4)
+#define	AIC_FAST_SYNC_PERIOD	(100 / 4)
+#define	AIC_MIN_SYNC_PERIOD	112
 #define	AIC_SYNC_OFFSET		8
 
 #define	aic_inb(aic, port) \

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-bugs" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi? <200111181309.aa66368>