diff options
author | Theo de Raadt <deraadt@cvs.openbsd.org> | 1995-12-19 17:49:33 +0000 |
---|---|---|
committer | Theo de Raadt <deraadt@cvs.openbsd.org> | 1995-12-19 17:49:33 +0000 |
commit | c0747b2cbefcefe8e470831688ff4b9fab5446b0 (patch) | |
tree | a2d57d5d99870e756e6d2e6b17aacdc8ce7c599f /sys/arch/atari | |
parent | 4488a95a5a301834f856cc4f86df4cb752610511 (diff) |
from netbsd:
Fixes for devices that don't support linked commands. (Paul Goyette)
Diffstat (limited to 'sys/arch/atari')
-rw-r--r-- | sys/arch/atari/dev/ncr5380.c | 83 | ||||
-rw-r--r-- | sys/arch/atari/dev/ncr5380reg.h | 3 |
2 files changed, 73 insertions, 13 deletions
diff --git a/sys/arch/atari/dev/ncr5380.c b/sys/arch/atari/dev/ncr5380.c index e3e63eef9a4..04df451db32 100644 --- a/sys/arch/atari/dev/ncr5380.c +++ b/sys/arch/atari/dev/ncr5380.c @@ -1,4 +1,4 @@ -/* $NetBSD: ncr5380.c,v 1.12 1995/11/30 00:57:56 jtc Exp $ */ +/* $NetBSD: ncr5380.c,v 1.13 1995/12/18 20:37:51 leo Exp $ */ /* * Copyright (c) 1995 Leo Weppelman. @@ -68,6 +68,17 @@ u_char dbg_target_mask = 0x7f; */ u_char ncr5380_no_parchk = 0xff; +#ifdef AUTO_SENSE + +/* + * Bit masks of targets that accept linked commands, and those + * that we've already checked out + */ +u_char ncr_will_link = 0x00; +u_char ncr_test_link = 0x00; + +#endif /* AUTO_SENSE */ + /* * This is the default sense-command we send. */ @@ -191,7 +202,6 @@ extern __inline__ void finish_req(SC_REQ *reqp) if (reqp->xs->error != 0) show_request(reqp, "ERR_RET"); #endif - /* * Return request to free-q */ @@ -201,7 +211,8 @@ extern __inline__ void finish_req(SC_REQ *reqp) splx(sps); xs->flags |= ITSDONE; - scsi_done(xs); + if (!(reqp->dr_flag & DRIVER_LINKCHK)) + scsi_done(xs); } /* @@ -306,7 +317,7 @@ static int ncr5380_scsi_cmd(struct scsi_xfer *xs) { int sps; - SC_REQ *reqp; + SC_REQ *reqp, *link, *tmp; int flags = xs->flags; /* @@ -375,27 +386,59 @@ ncr5380_scsi_cmd(struct scsi_xfer *xs) * Interrupts are disabled while we are fiddling with the issue-queue. */ sps = splbio(); + link = NULL; if ((issue_q == NULL) || (reqp->xcmd.opcode == REQUEST_SENSE)) { reqp->next = issue_q; issue_q = reqp; } else { - SC_REQ *tmp, *link; - tmp = issue_q; - link = NULL; do { if (!link && (tmp->targ_id == reqp->targ_id) && !tmp->link) link = tmp; } while (tmp->next && (tmp = tmp->next)); tmp->next = reqp; #ifdef AUTO_SENSE - if (link) { + if (link && (ncr_will_link & (1<<reqp->targ_id))) { link->link = reqp; link->xcmd.bytes[link->xs->cmdlen-2] |= 1; } #endif } +#ifdef AUTO_SENSE + /* + * If we haven't already, check the target for link support. + * Do this by prefixing the current command with a dummy + * Request_Sense command, link the dummy to the current + * command, and insert the dummy command at the head of the + * issue queue. Set the DRIVER_LINKCHK flag so that we'll + * ignore the results of the dummy command, since we only + * care about whether it was accepted or not. + */ + if (!link && !(ncr_test_link & (1<<reqp->targ_id)) && + (tmp = free_head) && !(reqp->dr_flag & DRIVER_NOINT)) { + free_head = tmp->next; + tmp->dr_flag = (reqp->dr_flag & ~DRIVER_DMAOK) | DRIVER_LINKCHK; + tmp->phase = NR_PHASE; + tmp->msgout = MSG_NOOP; + tmp->status = SCSGOOD; + tmp->xs = reqp->xs; + tmp->targ_id = reqp->targ_id; + tmp->targ_lun = reqp->targ_lun; + bcopy(sense_cmd, &tmp->xcmd, sizeof(sense_cmd)); + tmp->xdata_ptr = (u_char *)&tmp->xs->sense; + tmp->xdata_len = sizeof(tmp->xs->sense); + ncr_test_link |= 1<<tmp->targ_id; + tmp->link = reqp; + tmp->xcmd.bytes[sizeof(sense_cmd)-2] |= 1; + tmp->next = issue_q; + issue_q = tmp; +#ifdef DBG_REQ + if (dbg_target_mask & (1 << tmp->targ_id)) + show_request(tmp, "LINKCHK"); +#endif + } +#endif splx(sps); #ifdef DBG_REQ @@ -844,6 +887,8 @@ SC_REQ *reqp; reqp->xs->error = code ? code : XS_SELTIMEOUT; DBG_SELPRINT ("Target %d not responding to sel\n", reqp->targ_id); + if (reqp->dr_flag & DRIVER_LINKCHK) + ncr_test_link &= ~(1<<reqp->targ_id); finish_req(reqp); PID("scsi_select8"); return (0); @@ -1270,7 +1315,8 @@ struct ncr_softc *sc; phase = PH_MSGOUT; SET_5380_REG(NCR5380_ICOM, SC_A_ATN); - transfer_pio(&phase, &msg, &len, 0); + if (transfer_pio(&phase, &msg, &len, 0) || len) + scsi_reset(sc); } else { connected = tmp; @@ -1532,6 +1578,18 @@ int linked; int sps; /* + * If this is the driver's Link Check for this target, ignore + * the results of the command. All we care about is whether we + * got here from a LINK_CMD_COMPLETE or CMD_COMPLETE message. + */ + PID("linkcheck"); + if (reqp->dr_flag & DRIVER_LINKCHK) { + if (linked) + ncr_will_link |= 1<<reqp->targ_id; + else ncr_tprint(reqp, "Does not support linked commands\n"); + return (0); + } + /* * If we not executing an auto-sense and the status code * is request-sense, we automatically issue a request * sense command. @@ -1551,7 +1609,7 @@ int linked; issue_q = reqp; splx(sps); } - else reqp->xcmd.bytes[4] |= 1; + else reqp->xcmd.bytes[sizeof(sense_cmd)-2] |= 1; #ifdef DBG_REQ bzero(reqp->xdata_ptr, reqp->xdata_len); @@ -1875,10 +1933,11 @@ show_request(reqp, qtxt) SC_REQ *reqp; char *qtxt; { - printf("REQ-%s: %d %x[%d] cmd[0]=%x S=%x M=%x R=%x resid=%d %s\n", + printf("REQ-%s: %d %x[%d] cmd[0]=%x S=%x M=%x R=%x resid=%d dr_flag=%x %s\n", qtxt, reqp->targ_id, reqp->xdata_ptr, reqp->xdata_len, reqp->xcmd.opcode, reqp->status, reqp->message, - reqp->xs->error, reqp->xs->resid, reqp->link ? "L":""); + reqp->xs->error, reqp->xs->resid, reqp->dr_flag, + reqp->link ? "L":""); if (reqp->status == SCSCHKC) show_data_sense(reqp->xs); } diff --git a/sys/arch/atari/dev/ncr5380reg.h b/sys/arch/atari/dev/ncr5380reg.h index 717434ff81d..e563e16c854 100644 --- a/sys/arch/atari/dev/ncr5380reg.h +++ b/sys/arch/atari/dev/ncr5380reg.h @@ -1,4 +1,4 @@ -/* $NetBSD: ncr5380reg.h,v 1.5 1995/10/05 08:53:00 leo Exp $ */ +/* $NetBSD: ncr5380reg.h,v 1.6 1995/12/18 20:37:54 leo Exp $ */ /* * Copyright (c) 1995 Leo Weppelman. @@ -219,6 +219,7 @@ typedef struct req_q { #define DRIVER_NOINT 0x04 /* We are booting: no interrupts */ #define DRIVER_DMAOK 0x08 /* DMA can be used on this request */ #define DRIVER_BOUNCING 0x10 /* Using the bounce buffer */ +#define DRIVER_LINKCHK 0x20 /* Doing the linked command check */ /* XXX: Should go to ncr5380var.h */ static SC_REQ *issue_q = NULL; /* Commands waiting to be issued*/ |