diff options
-rw-r--r-- | sys/dev/ic/twe.c | 40 | ||||
-rw-r--r-- | sys/dev/ic/twereg.h | 78 |
2 files changed, 94 insertions, 24 deletions
diff --git a/sys/dev/ic/twe.c b/sys/dev/ic/twe.c index a10cbc03a8f..123434dcea0 100644 --- a/sys/dev/ic/twe.c +++ b/sys/dev/ic/twe.c @@ -1,4 +1,4 @@ -/* $OpenBSD: twe.c,v 1.5 2000/11/08 20:44:56 mickey Exp $ */ +/* $OpenBSD: twe.c,v 1.6 2001/01/07 20:27:46 mickey Exp $ */ /* * Copyright (c) 2000 Michael Shalayeff. All rights reserved. @@ -86,7 +86,6 @@ static __inline void twe_put_ccb __P((struct twe_ccb *ccb)); void twe_dispose __P((struct twe_softc *sc)); int twe_cmd __P((struct twe_ccb *ccb, int flags, int wait)); int twe_start __P((struct twe_ccb *ccb, int wait)); -void twe_exec_cmd __P((void *v)); int twe_complete __P((struct twe_ccb *ccb)); int twe_done __P((struct twe_softc *sc, int idx)); void twe_copy_internal_data __P((struct scsi_xfer *xs, void *v, size_t size)); @@ -240,7 +239,7 @@ twe_attach(sc) cmd = ccb->ccb_cmd; cmd->cmd_unit_host = TWE_UNITHOST(0, 0); cmd->cmd_op = TWE_CMD_GPARAM; - cmd->cmd_count = 1; + cmd->cmd_param.count = 1; pb->table_id = TWE_PARAM_AEN; pb->param_id = 2; @@ -308,7 +307,7 @@ twe_attach(sc) cmd = ccb->ccb_cmd; cmd->cmd_unit_host = TWE_UNITHOST(0, 0); cmd->cmd_op = TWE_CMD_GPARAM; - cmd->cmd_count = 1; + cmd->cmd_param.count = 1; pb->table_id = TWE_PARAM_UC; pb->param_id = TWE_PARAM_UC; @@ -339,7 +338,7 @@ twe_attach(sc) cmd = ccb->ccb_cmd; cmd->cmd_unit_host = TWE_UNITHOST(0, 0); cmd->cmd_op = TWE_CMD_GPARAM; - cmd->cmd_count = 1; + cmd->cmd_param.count = 1; cap->table_id = TWE_PARAM_UI + i; cap->param_id = 4; @@ -487,7 +486,6 @@ twe_start(ccb, wait) int i; cmd->cmd_op = htole16(cmd->cmd_op); - cmd->cmd_count = htole16(cmd->cmd_count); if (!wait) { @@ -567,14 +565,13 @@ twe_done(sc, idx) struct twe_softc *sc; int idx; { - struct scsi_xfer *xs; struct twe_ccb *ccb = &sc->sc_ccbs[idx]; struct twe_cmd *cmd = ccb->ccb_cmd; + struct scsi_xfer *xs = ccb->ccb_xs; + twe_lock_t lock; TWE_DPRINTF(TWE_D_CMD, ("done(%d) ", idx)); - xs = ccb->ccb_xs; - if (ccb->ccb_state != TWE_CCB_QUEUED) { printf("%s: unqueued ccb %d ready\n", sc->sc_dev.dv_xname, idx); @@ -616,8 +613,10 @@ twe_done(sc, idx) ccb->ccb_realdata = NULL; } + lock = TWE_LOCK_TWE(sc); TAILQ_REMOVE(&sc->sc_ccbq, ccb, ccb_link); twe_put_ccb(ccb); + TWE_UNLOCK_TWE(sc, lock); if (xs) { xs->resid = 0; @@ -647,7 +646,7 @@ twe_copy_internal_data(xs, v, size) TWE_DPRINTF(TWE_D_MISC, ("twe_copy_internal_data ")); if (!xs->datalen) - printf("uio move not yet supported\n"); + printf("uio move is not yet supported\n"); else { copy_cnt = MIN(size, xs->datalen); bcopy(v, xs->data, copy_cnt); @@ -674,7 +673,7 @@ twe_scsi_cmd(xs) u_int32_t blockno, blockcnt; struct scsi_rw *rw; struct scsi_rw_big *rwb; - int error, op; + int error, op, flags; twe_lock_t lock; @@ -781,6 +780,7 @@ twe_scsi_cmd(xs) case SYNCHRONIZE_CACHE: lock = TWE_LOCK_TWE(sc); + flags = 0; if (xs->cmd->opcode != SYNCHRONIZE_CACHE) { /* A read or write operation. */ if (xs->cmdlen == 6) { @@ -792,6 +792,10 @@ twe_scsi_cmd(xs) rwb = (struct scsi_rw_big *)xs->cmd; blockno = _4btol(rwb->addr); blockcnt = _2btol(rwb->length); + /* reflect DPO & FUA flags */ + if (xs->cmd->opcode == WRITE_BIG && + rwb->byte2 & 0x18) + flags = TWE_FLAGS_CACHEDISABLE; } if (blockno >= sc->sc_hdr[target].hd_size || blockno + blockcnt > sc->sc_hdr[target].hd_size) { @@ -799,8 +803,8 @@ twe_scsi_cmd(xs) printf("%s: out of bounds %u-%u >= %u\n", sc->sc_dev.dv_xname, blockno, blockcnt, sc->sc_hdr[target].hd_size); - scsi_done(xs); xs->error = XS_DRIVER_STUFFUP; + scsi_done(xs); return (COMPLETE); } } @@ -814,8 +818,8 @@ twe_scsi_cmd(xs) } if ((ccb = twe_get_ccb(sc)) == NULL) { - scsi_done(xs); xs->error = XS_DRIVER_STUFFUP; + scsi_done(xs); return (COMPLETE); } @@ -826,7 +830,8 @@ twe_scsi_cmd(xs) cmd = ccb->ccb_cmd; cmd->cmd_unit_host = TWE_UNITHOST(target, 0); /* XXX why 0? */ cmd->cmd_op = op; - cmd->cmd_count = blockcnt; + cmd->cmd_flags = flags; + cmd->cmd_io.count = htole16(blockcnt); cmd->cmd_io.lba = blockno; if ((error = twe_cmd(ccb, ((xs->flags & SCSI_NOSLEEP)? @@ -838,8 +843,8 @@ twe_scsi_cmd(xs) xs->error = XS_TIMEOUT; return (TRY_AGAIN_LATER); } else { - scsi_done(xs); xs->error = XS_DRIVER_STUFFUP; + scsi_done(xs); return (COMPLETE); } } @@ -912,7 +917,6 @@ twe_intr(v) if (status & TWE_STAT_RDYI) { - lock = TWE_LOCK_TWE(sc); while (!(status & TWE_STAT_RQE)) { u_int32_t ready; @@ -933,7 +937,6 @@ twe_intr(v) TWE_DPRINTF(TWE_D_INTR, ("twe_intr stat=%b ", status & TWE_STAT_FLAGS, TWE_STAT_BITS)); } - TWE_UNLOCK_TWE(sc, lock); } if (status & TWE_STAT_ATTNI) { @@ -963,7 +966,8 @@ twe_intr(v) cmd = ccb->ccb_cmd; cmd->cmd_unit_host = TWE_UNITHOST(0, 0); cmd->cmd_op = TWE_CMD_GPARAM; - cmd->cmd_count = 1; + cmd->cmd_flags = 0; + cmd->cmd_param.count = 1; pb->table_id = TWE_PARAM_AEN; pb->param_id = 2; diff --git a/sys/dev/ic/twereg.h b/sys/dev/ic/twereg.h index ba2968d85c6..8fc16a3cbfc 100644 --- a/sys/dev/ic/twereg.h +++ b/sys/dev/ic/twereg.h @@ -1,4 +1,4 @@ -/* $OpenBSD: twereg.h,v 1.3 2000/11/06 23:56:18 mickey Exp $ */ +/* $OpenBSD: twereg.h,v 1.4 2001/01/07 20:27:46 mickey Exp $ */ /* * Copyright (c) 2000 Michael Shalayeff @@ -78,6 +78,7 @@ #define TWE_STAT_FLAGS 0x00fff000 /* mask out other stuff */ #define TWE_STAT_BITS "\020\015cqr\016cpurdy\017rqe\20cqf" \ "\021rdyi\022cmdi\023attni\024hosti\025pciabr\026cpuerr\027queuee\030pcipar" + #define TWE_COMMANDQUEUE 0x08 /* * the segs offset is encoded into upper 3 bits of the opcode. @@ -88,18 +89,50 @@ #define TWE_CMD_INIT 0x0301 #define TWE_CMD_READ 0x0362 #define TWE_CMD_WRITE 0x0363 -#define TWE_CMD_VERIFY 0x0364 +#define TWE_CMD_RDVRFY 0x0364 +#define TWE_CMD_VERIFY 0x0365 +#define TWE_CMD_ZRFUNIT 0x0208 +#define TWE_CMD_RPLUNIT 0x0209 +#define TWE_CMD_HOTSWAP 0x020a +#define TWE_CMD_SETATA 0x020c +#define TWE_CMD_FLUSH 0x020e +#define TWE_CMD_ABORT 0x020f +#define TWE_CMD_QSTAT 0x0210 #define TWE_CMD_GPARAM 0x0252 #define TWE_CMD_SPARAM 0x0253 +#define TWE_CMD_NEWUNIT 0x0214 +#define TWE_CMD_DELUNIT 0x0215 +#define TWE_CMD_RBLUNIT 0x0217 /* rebuild */ #define TWE_CMD_SECINF 0x021a #define TWE_CMD_AEN 0x021c +#define TWE_CMD_CMDPK 0x021d #define TWE_READYQUEUE 0x0c #define TWE_READYID(u) (((u) >> 4) & 0xff) +/* + * From 3ware's documentation: + * + * All parameters maintained by the controller are grouped into related + * tables. Tables are are accessed indirectly via get and set parameter + * commands. To access a specific parameter in a table, the table ID and + * parameter index are used to uniquely identify a parameter. Table + * 0xffff is the directory table and provides a list of the table IDs and + * sizes of all other tables. Index zero in each table specifies the + * entire table, and index one specifies the size of the table. An entire + * table can be read or set by using index zero. + */ + /* get/set param table ids */ +#define TWE_PARAM_ALL 0x000 /* everything */ +#define TWE_PARAM_DSUM 0x002 /* drive summary */ #define TWE_PARAM_UC 0x003 /* unit config */ +#define TWE_PARAM_DC 0x200 /* + 15 -- drive config (doc says 0x100) */ #define TWE_PARAM_UI 0x300 /* + 16 -- unit information */ #define TWE_PARAM_AEN 0x401 +#define TWE_PARAM_VER 0x402 /* version info */ +#define TWE_PARAM_CTRL 0x403 /* controller info */ +#define TWE_PARAM_FTRS 0x404 /* features */ +#define TWE_PARAM_DIR 0xffff /* param table directory */ #define TWE_AEN_QEMPTY 0x0000 #define TWE_AEN_SRST 0x0001 @@ -111,13 +144,15 @@ #define TWE_AEN_QFULL 0x00ff #define TWE_AEN_TUN 0x0015 /* table undefined */ +#pragma pack(1) + /* struct definitions */ struct twe_param { u_int16_t table_id; u_int8_t param_id; u_int8_t param_size; u_int8_t data[1]; -} __attribute__ ((packed)); +}; struct twe_segs { u_int32_t twes_addr; @@ -132,22 +167,53 @@ struct twe_cmd { u_int8_t cmd_status; u_int8_t cmd_flags; #define TWE_FLAGS_CACHEDISABLE 0x01 - u_int16_t cmd_count; union { struct { + u_int16_t count; u_int32_t lba; struct twe_segs segs[TWE_MAXOFFSETS]; u_int32_t pad; } _cmd_io; #define cmd_io _._cmd_io struct { + u_int16_t count; struct twe_segs segs[TWE_MAXOFFSETS]; } _cmd_param; #define cmd_param _._cmd_param struct { - u_int32_t rdy_q_ptr; + u_int16_t msgcr; + u_int32_t rdy_q_ptr; } _cmd_init; #define cmd_init _._cmd_init + struct { + u_int8_t action; +#define TWE_HSWAP_REMOVE 0 +#define TWE_HSWAP_ADDCBOD 1 +#define TWE_HSWAP_ADDSPARE 2 + u_int8_t port; + } _cmd_aport; +#define cmd_hswap _._cmd_hswap + struct { + u_int8_t feature; +#define TWE_ATA_WCE 0x02 +#define TWE_ATA_NWCE 0x82 + u_int8_t mode; + u_int16_t units; + u_int16_t persist; + } _cmd_ata; +#define cmd_ata _._cmd_ata + u_int16_t cmd_status; + struct { + u_int8_t action; +#define TWE_REBUILD_NOP 0 +#define TWE_REBUILD_STOP 2 +#define TWE_REBUILD_START 4 +#define TWE_REBUILD_STARTU 5 +#define TWE_REBUILD_CS 0x80 + u_int8_t subunit; /* raid10 lu rebuild */ + } _cmd_rebuild; +#define cmd_rebuild _._cmd_rebuild } _; -} __attribute__ ((packed)); /* 512 bytes */ +}; /* 512 bytes */ +#pragma pack() |