From owner-freebsd-bugs Sun Nov 18 5:10:17 2001 Delivered-To: freebsd-bugs@freebsd.org Received: from salmon.maths.tcd.ie (salmon.maths.tcd.ie [134.226.81.11]) by hub.freebsd.org (Postfix) with SMTP id 4B71137B416 for ; Sun, 18 Nov 2001 05:09:50 -0800 (PST) Received: from walton.maths.tcd.ie by salmon.maths.tcd.ie with SMTP id ; 18 Nov 2001 13:09:49 +0000 (GMT) To: John Merryweather Cooper Cc: freebsd-bugs@freebsd.org Subject: Re: kern/23314: aic driver fails to detect Adaptec 1520B unless PnP is disabled on the adapter Date: Sun, 18 Nov 2001 13:09:49 +0000 From: Ian Dowse Message-ID: <200111181309.aa66368@salmon.maths.tcd.ie> Sender: owner-freebsd-bugs@FreeBSD.ORG Precedence: bulk List-ID: List-Archive: (Web Archive) List-Help: (List Instructions) List-Subscribe: List-Unsubscribe: X-Loop: FreeBSD.org 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 #include -#include -#include #include -#include #include +#include +#include /* for struct devstat */ #include #include @@ -43,6 +42,7 @@ #include #include #include +#include #include @@ -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 -#include #include #include #include @@ -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 -#include #include #include #include @@ -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 -#include #include #include #include @@ -37,7 +36,6 @@ #include #include -#include #include 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