diff options
| author | thorpej <thorpej@NetBSD.org> | 2003-09-25 22:26:40 +0000 |
|---|---|---|
| committer | thorpej <thorpej@NetBSD.org> | 2003-09-25 22:26:40 +0000 |
| commit | abcd16ecc6cea7528f2d4a735e5bc7e3abfbcd3a (patch) | |
| tree | 528503520ca24b76e92d3a52a31c857b7788f384 /sys/dev | |
| parent | 2deb8b2e7b348ed26685cc4c1693f377bcc32180 (diff) | |
Fix up the TWEIO_COMMAND code to actually work. The 3ware management API
library can now communicate with the card.
Diffstat (limited to 'sys/dev')
| -rw-r--r-- | sys/dev/pci/twe.c | 63 |
1 files changed, 38 insertions, 25 deletions
diff --git a/sys/dev/pci/twe.c b/sys/dev/pci/twe.c index 92c29e2fabe..2e0f0e87d7f 100644 --- a/sys/dev/pci/twe.c +++ b/sys/dev/pci/twe.c @@ -1,4 +1,4 @@ -/* $NetBSD: twe.c,v 1.50 2003/09/25 01:35:25 thorpej Exp $ */ +/* $NetBSD: twe.c,v 1.51 2003/09/25 22:26:40 thorpej Exp $ */ /*- * Copyright (c) 2000, 2001, 2002, 2003 The NetBSD Foundation, Inc. @@ -70,7 +70,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: twe.c,v 1.50 2003/09/25 01:35:25 thorpej Exp $"); +__KERNEL_RCSID(0, "$NetBSD: twe.c,v 1.51 2003/09/25 22:26:40 thorpej Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -1642,19 +1642,15 @@ int tweioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) { struct twe_softc *twe; -#if 0 struct twe_ccb *ccb; -#endif struct twe_param *param; struct twe_usercommand *tu; struct twe_paramcommand *tp; struct twe_drivecommand *td; union twe_statrequest *ts; void *pdata = NULL; - int rv, s, error = 0; -#if 0 + int s, error = 0; u_int8_t cmdid; -#endif if (securelevel >= 2) return (EPERM); @@ -1665,35 +1661,41 @@ tweioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) td = (struct twe_drivecommand *)data; ts = (union twe_statrequest *)data; - /* Hmm, compatible with FreeBSD */ + /* This is intended to be compatible with the FreeBSD interface. */ switch (cmd) { case TWEIO_COMMAND: -#if 0 - /* XXXJRT This whole path needs to be cleaned up. */ if (tu->tu_size > 0) { - if (tu->tu_size > TWE_SECTOR_SIZE) + /* + * XXX Handle > TWE_SECTOR_SIZE? Let's see if + * it's really necessary, first. + */ + if (tu->tu_size > TWE_SECTOR_SIZE) { +#ifdef TWE_DEBUG + printf("%s: TWEIO_COMMAND: tu_size = %d\n", + twe->sc_dv.dv_xname, tu->tu_size); +#endif return EINVAL; + } pdata = malloc(tu->tu_size, M_DEVBUF, M_WAITOK); error = copyin(tu->tu_data, pdata, tu->tu_size); if (error != 0) goto done; - error = twe_ccb_alloc(twe, &ccb, TWE_CCB_PARAM | + ccb = twe_ccb_alloc_wait(twe, TWE_CCB_DATA_IN | TWE_CCB_DATA_OUT); - } else { - error = twe_ccb_alloc(twe, &ccb, 0); - } - if (rv != 0) - goto done; - cmdid = ccb->ccb_cmdid; - memcpy(ccb->ccb_cmd, &tu->tu_cmd, sizeof(struct twe_cmd)); - ccb->ccb_cmdid = cmdid; - if (ccb->ccb_flags & TWE_CCB_PARAM) { + KASSERT(ccb != NULL); ccb->ccb_data = pdata; ccb->ccb_datasize = TWE_SECTOR_SIZE; ccb->ccb_tx.tx_handler = 0; ccb->ccb_tx.tx_context = pdata; ccb->ccb_tx.tx_dv = &twe->sc_dv; + } else { + ccb = twe_ccb_alloc_wait(twe, 0); + KASSERT(ccb != NULL); } + cmdid = ccb->ccb_cmdid; + memcpy(ccb->ccb_cmd, &tu->tu_cmd, sizeof(struct twe_cmd)); + ccb->ccb_cmd->tc_cmdid = cmdid; + /* Map the transfer. */ if ((error = twe_ccb_map(twe, ccb)) != 0) { twe_ccb_free(twe, ccb); @@ -1701,17 +1703,28 @@ tweioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) } /* Submit the command and wait. */ + /* XXX Should use a callback and sleep, instead. */ s = splbio(); - rv = twe_ccb_poll(twe, ccb, 5); + if (twe_ccb_poll(twe, ccb, 5)) + printf("%s: TWEIO_COMMAND: CCB timed out\n", + twe->sc_dv.dv_xname); twe_ccb_unmap(twe, ccb); + splx(s); + + /* Copy the command back to the ioctl argument. */ + memcpy(&tu->tu_cmd, ccb->ccb_cmd, sizeof(struct twe_cmd)); +#ifdef TWE_DEBUG + printf("%s: TWEIO_COMMAND: tc_opcode = 0x%02x, " + "tc_status = 0x%02x\n", twe->sc_dv.dv_xname, + tu->tu_cmd.tc_opcode, tu->tu_cmd.tc_status); +#endif + + s = splbio(); twe_ccb_free(twe, ccb); splx(s); if (tu->tu_size > 0) error = copyout(pdata, tu->tu_data, tu->tu_size); -#else - rv = EOPNOTSUPP; -#endif goto done; case TWEIO_STATS: |
