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>
