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.
This commit is contained in:
Kenneth D. Merry 2001-03-16 22:20:19 +00:00
parent 66e845d8dc
commit 76db0ab017
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=74370
4 changed files with 48 additions and 8 deletions

View file

@ -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))
aic->flags |= AIC_DWIO_ENABLE;
/*
* 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 */

View file

@ -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)

View file

@ -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);
}

View file

@ -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) \