From 8d74e08df53b4e20f79a31d6950d4faf882e0983 Mon Sep 17 00:00:00 2001 From: ken Date: Fri, 16 Mar 2001 22:20:19 +0000 Subject: Fix a few things in the aic(4) driver: - enable 10MHz (fast SCSI) operation on boards that support it. (only aic6360 boards with fast SCSI enabled can do it) - bounds check sync periods and offsets passed in from the transport layer - tell the user which resource allocation failed (for the ISA probe) if we weren't able to allocate an IRQ, DRQ or I/O port. --- sys/dev/aic/aic.c | 40 ++++++++++++++++++++++++++++++++++------ sys/dev/aic/aic6360reg.h | 2 ++ sys/dev/aic/aic_isa.c | 6 +++++- sys/dev/aic/aicvar.h | 6 ++++++ 4 files changed, 47 insertions(+), 7 deletions(-) (limited to 'sys/dev/aic') diff --git a/sys/dev/aic/aic.c b/sys/dev/aic/aic.c index 634373e..6282cda 100644 --- a/sys/dev/aic/aic.c +++ b/sys/dev/aic/aic.c @@ -196,16 +196,26 @@ aic_action(struct cam_sim *sim, union ccb *ccb) 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); @@ -1427,9 +1437,25 @@ aic_init(struct aic_softc *aic) 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]; @@ -1445,7 +1471,7 @@ aic_init(struct aic_softc *aic) 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; } @@ -1513,6 +1539,8 @@ aic_attach(struct aic_softc *aic) 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 */ diff --git a/sys/dev/aic/aic6360reg.h b/sys/dev/aic/aic6360reg.h index 7dafac4..7e14f14 100644 --- a/sys/dev/aic/aic6360reg.h +++ b/sys/dev/aic/aic6360reg.h @@ -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) diff --git a/sys/dev/aic/aic_isa.c b/sys/dev/aic/aic_isa.c index b89edc2..e35dcc9 100644 --- a/sys/dev/aic/aic_isa.c +++ b/sys/dev/aic/aic_isa.c @@ -68,14 +68,17 @@ aic_isa_alloc_resources(device_t dev) 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); } @@ -86,6 +89,7 @@ aic_isa_alloc_resources(device_t dev) 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); } diff --git a/sys/dev/aic/aicvar.h b/sys/dev/aic/aicvar.h index 9b3c979..d86e49f 100644 --- a/sys/dev/aic/aicvar.h +++ b/sys/dev/aic/aicvar.h @@ -91,6 +91,9 @@ struct aic_softc { 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 @@ struct aic_softc { #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 @@ struct aic_softc { #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) \ -- cgit v1.1