summaryrefslogtreecommitdiffstats
path: root/sys/dev/aic
diff options
context:
space:
mode:
authorken <ken@FreeBSD.org>2001-03-16 22:20:19 +0000
committerken <ken@FreeBSD.org>2001-03-16 22:20:19 +0000
commit8d74e08df53b4e20f79a31d6950d4faf882e0983 (patch)
treecc8c210e3d9f6f59b2fe6fe54f961fb48f74174b /sys/dev/aic
parent4265a70a5f8db0542b59be3797c042d4e5698fef (diff)
downloadFreeBSD-src-8d74e08df53b4e20f79a31d6950d4faf882e0983.zip
FreeBSD-src-8d74e08df53b4e20f79a31d6950d4faf882e0983.tar.gz
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.
Diffstat (limited to 'sys/dev/aic')
-rw-r--r--sys/dev/aic/aic.c40
-rw-r--r--sys/dev/aic/aic6360reg.h2
-rw-r--r--sys/dev/aic/aic_isa.c6
-rw-r--r--sys/dev/aic/aicvar.h6
4 files changed, 47 insertions, 7 deletions
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) \
OpenPOWER on IntegriCloud