summaryrefslogtreecommitdiffstats
path: root/sys/dev/aha/aha.c
diff options
context:
space:
mode:
authorimp <imp@FreeBSD.org>1999-01-20 06:21:27 +0000
committerimp <imp@FreeBSD.org>1999-01-20 06:21:27 +0000
commit00736ae9131bddd05cf204fdd53a52aaf79adf63 (patch)
tree4c9e30ee3ffad6a0847cf82407827b9e244d9e38 /sys/dev/aha/aha.c
parent0b91534f2d2280f6af9d8d1f3067a9540ea4ffcc (diff)
downloadFreeBSD-src-00736ae9131bddd05cf204fdd53a52aaf79adf63.zip
FreeBSD-src-00736ae9131bddd05cf204fdd53a52aaf79adf63.tar.gz
o enable plug and play support for the aha driver. Given the cumbersome
pnp system in freebsd, I'm not sure how useful this will be, but my 1542CP seems to work well in plug and play mode and does seem to probe correctly at all the oddball addresses/irq/drqs that I tried. [[ I was unable to get /kernel.conf or /kernel.config to read in, so I wasn't able to verify that this method of userconfig works. that's one thing that makes pnp so hard to use in the current scheme. Pointers to the right new way of doing this accepted. ]] o Add some kludges to maybe bring support for 1540A/1542A into the driver. Since I have no 154xA cards, and the only person I know that has them hasn't given me feedback, I'm making this commit blind. o Honor unit numbers that are in the config file now. This allows one to hard wire the unit numbers (and have high unit numbers for plug and pray devices, which can't seem to be hardwired) and have the cards not migrate from aha1 -> aha0 should aha0 go on the fritz. I didn't verify that hard wired scsi busses would work, but did verify that hard wired aha addresses did work to a limited extent. Both aha0 and aha1 must be hardwired, or when the card that was in aha0 goes away, the probe for aha0 might pick up the card that otherwise would have been aha1.
Diffstat (limited to 'sys/dev/aha/aha.c')
-rw-r--r--sys/dev/aha/aha.c39
1 files changed, 30 insertions, 9 deletions
diff --git a/sys/dev/aha/aha.c b/sys/dev/aha/aha.c
index b213adc..dcabdea 100644
--- a/sys/dev/aha/aha.c
+++ b/sys/dev/aha/aha.c
@@ -55,9 +55,11 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: aha.c,v 1.17 1998/12/22 18:14:50 gibbs Exp $
+ * $Id: aha.c,v 1.18 1998/12/22 22:31:06 imp Exp $
*/
+#include "pnp.h"
+
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/malloc.h>
@@ -79,10 +81,15 @@
#include <vm/vm.h>
#include <vm/pmap.h>
+
+#if NPNP > 0
+#include <i386/isa/isa_device.h>
+#include <i386/isa/pnp.h> /* XXX pnp isn't x86 only */
+#endif
#include <dev/aha/ahareg.h>
-struct aha_softc *aha_softcs[NAHA];
+struct aha_softc *aha_softcs[NAHATOT];
#define MIN(a, b) ((a) < (b) ? (a) : (b))
#define PRVERB(x) if (bootverbose) printf x
@@ -209,7 +216,7 @@ aha_alloc(int unit, bus_space_tag_t tag, bus_space_handle_t bsh)
struct aha_softc *aha;
if (unit != AHA_TEMP_UNIT) {
- if (unit >= NAHA) {
+ if (unit >= NAHATOT) {
printf("aha: unit number (%d) too high\n", unit);
return NULL;
}
@@ -235,6 +242,8 @@ aha_alloc(int unit, bus_space_tag_t tag, bus_space_handle_t bsh)
aha->unit = unit;
aha->tag = tag;
aha->bsh = bsh;
+ aha->ccb_sg_opcode = INITIATOR_SG_CCB_WRESID;
+ aha->ccb_ccb_opcode = INITIATOR_CCB_WRESID;
if (aha->unit != AHA_TEMP_UNIT) {
aha_softcs[unit] = aha;
@@ -902,7 +911,7 @@ ahaaction(struct cam_sim *sim, union ccb *ccb)
csio = &ccb->csio;
ccbh = &csio->ccb_h;
- hccb->opcode = INITIATOR_CCB_WRESID;
+ hccb->opcode = aha->ccb_ccb_opcode;
hccb->datain = (ccb->ccb_h.flags & CAM_DIR_IN) != 0;
hccb->dataout = (ccb->ccb_h.flags & CAM_DIR_OUT) != 0;
hccb->cmd_len = csio->cdb_len;
@@ -1169,7 +1178,7 @@ ahaexecuteccb(void *arg, bus_dma_segment_t *dm_segs, int nseg, int error)
}
if (nseg > 1) {
- accb->hccb.opcode = INITIATOR_SG_CCB_WRESID;
+ accb->hccb.opcode = aha->ccb_sg_opcode;
ahautoa24((sizeof(aha_sg_t) * nseg),
accb->hccb.data_len);
ahautoa24(accb->sg_list_phys, accb->hccb.data_addr);
@@ -1360,7 +1369,10 @@ ahadone(struct aha_softc *aha, struct aha_ccb *accb, aha_mbi_comp_code_t comp_co
case AMBI_ABORT:
case AMBI_ERROR:
/* An error occured */
- csio->resid = aha_a24tou(accb->hccb.data_len);
+ if (accb->hccb.opcode < INITIATOR_CCB_WRESID)
+ csio->resid = 0;
+ else
+ csio->resid = aha_a24tou(accb->hccb.data_len);
switch(accb->hccb.ahastat) {
case AHASTAT_DATARUN_ERROR:
{
@@ -1406,8 +1418,16 @@ ahadone(struct aha_softc *aha, struct aha_ccb *accb, aha_mbi_comp_code_t comp_co
panic("%s: Inavlid Action code", aha_name(aha));
break;
case AHASTAT_INVALID_OPCODE:
- panic("%s: Invalid CCB Opcode code %x hccb = %p",
- aha_name(aha), accb->hccb.opcode, &accb->hccb);
+ if (accb->hccb.opcode < INITIATOR_CCB_WRESID)
+ panic("%s: Invalid CCB Opcode %x hccb = %p",
+ aha_name(aha), accb->hccb.opcode,
+ &accb->hccb);
+ printf("%s: AHA-1540A detected, compensating\n",
+ aha_name(aha));
+ aha->ccb_sg_opcode = INITIATOR_SG_CCB;
+ aha->ccb_ccb_opcode = INITIATOR_CCB;
+ xpt_freeze_devq(ccb->ccb_h.path, /*count*/1);
+ csio->ccb_h.status = CAM_REQUEUE_REQ;
break;
case AHASTAT_LINKED_CCB_LUN_MISMATCH:
/* We don't even support linked commands... */
@@ -1418,7 +1438,7 @@ ahadone(struct aha_softc *aha, struct aha_ccb *accb, aha_mbi_comp_code_t comp_co
break;
case AHASTAT_HA_SCSI_BUS_RESET:
if ((csio->ccb_h.status & CAM_STATUS_MASK)
- != CAM_CMD_TIMEOUT)
+ != CAM_CMD_TIMEOUT)
csio->ccb_h.status = CAM_SCSI_BUS_RESET;
break;
case AHASTAT_HA_BDR:
@@ -1440,6 +1460,7 @@ ahadone(struct aha_softc *aha, struct aha_ccb *accb, aha_mbi_comp_code_t comp_co
case AMBI_OK:
/* All completed without incident */
/* XXX DO WE NEED TO COPY SENSE BYTES HERE???? XXX */
+ /* I don't think so since it works???? */
ccb->ccb_h.status |= CAM_REQ_CMP;
if ((accb->flags & ACCB_RELEASE_SIMQ) != 0)
ccb->ccb_h.status |= CAM_RELEASE_SIMQ;
OpenPOWER on IntegriCloud