mirror of
https://git.FreeBSD.org/src.git
synced 2024-12-19 10:53:58 +00:00
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:
parent
66e845d8dc
commit
76db0ab017
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=74370
@ -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 */
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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) \
|
||||
|
Loading…
Reference in New Issue
Block a user