summaryrefslogtreecommitdiff
path: root/sys/dev/usb/umass_scsi.c
diff options
context:
space:
mode:
authorNathan Binkert <nate@cvs.openbsd.org>2002-05-07 18:29:20 +0000
committerNathan Binkert <nate@cvs.openbsd.org>2002-05-07 18:29:20 +0000
commite3500453ce2b94b39af2ef626169742ebc17530c (patch)
treed3c1ce90d9ae11b43948c86e7276f9595b6ee08d /sys/dev/usb/umass_scsi.c
parent98e3a0a3b6a5b0271467c9f199a555d22161f072 (diff)
Meant to commit only ulpt and committed everything. Most things weren't ready
Diffstat (limited to 'sys/dev/usb/umass_scsi.c')
-rw-r--r--sys/dev/usb/umass_scsi.c488
1 files changed, 0 insertions, 488 deletions
diff --git a/sys/dev/usb/umass_scsi.c b/sys/dev/usb/umass_scsi.c
deleted file mode 100644
index 2c1f1c2ba50..00000000000
--- a/sys/dev/usb/umass_scsi.c
+++ /dev/null
@@ -1,488 +0,0 @@
-/* $OpenBSD: umass_scsi.c,v 1.1 2002/05/07 18:08:04 nate Exp $ */
-/*
- * Copyright (c) 2001 Nathan L. Binkert
- * All rights reserved.
- *
- * Permission to redistribute, use, copy, and modify this software
- * without fee is hereby granted, provided that the following
- * conditions are met:
- *
- * 1. This entire notice is included in all source code copies of any
- * software which is or includes a copy or modification of this
- * software.
- * 2. The name of the author may not be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
- * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-/*
- * Copyright (c) 2001 The NetBSD Foundation, Inc.
- * All rights reserved.
- *
- * This code is derived from software contributed to The NetBSD Foundation
- * by Lennart Augustsson (lennart@augustsson.net) at
- * Carlstedt Research & Technology.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the NetBSD
- * Foundation, Inc. and its contributors.
- * 4. Neither the name of The NetBSD Foundation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
- * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "atapiscsi.h"
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/kernel.h>
-#include <sys/conf.h>
-#include <sys/buf.h>
-#include <sys/device.h>
-#include <sys/ioctl.h>
-#include <sys/malloc.h>
-
-#include <dev/usb/usb.h>
-#include <dev/usb/usbdi.h>
-#include <dev/usb/usbdi_util.h>
-#include <dev/usb/usbdevs.h>
-
-#include <dev/usb/umassvar.h>
-#include <dev/usb/umass_scsi.h>
-
-#include <scsi/scsi_all.h>
-#include <scsi/scsiconf.h>
-#include <scsi/scsi_disk.h>
-#include <machine/bus.h>
-
-struct umass_scsi_softc {
- struct umassbus_softc base;
- struct scsi_link sc_link;
- struct scsi_adapter sc_adapter;
-
- usbd_status sc_sync_status;
- struct scsi_sense sc_sense_cmd;
-};
-
-
-#define SHORT_INQUIRY_LENGTH 36 /* XXX */
-
-#define UMASS_SCSIID_HOST 0x00
-#define UMASS_SCSIID_DEVICE 0x01
-
-#define UMASS_ATAPI_DRIVE 0
-
-int umass_scsi_cmd(struct scsi_xfer *);
-void umass_scsi_minphys(struct buf *);
-int umass_scsi_ioctl(struct scsi_link *, u_long cmd, caddr_t addrp, int flag,
- struct proc *p);
-
-void umass_scsi_cb(struct umass_softc *sc, void *priv, int residue,
- int status);
-void umass_scsi_sense_cb(struct umass_softc *sc, void *priv, int residue,
- int status);
-struct umass_scsi_softc *umass_scsi_setup(struct umass_softc *);
-
-struct scsi_device umass_scsi_dev = { NULL, NULL, NULL, NULL, };
-
-int
-umass_scsi_attach(struct umass_softc *sc)
-{
- struct umass_scsi_softc *scbus;
-
- scbus = umass_scsi_setup(sc);
- scbus->sc_link.adapter_target = UMASS_SCSIID_HOST;
- scbus->sc_link.luns = sc->maxlun + 1;
-
- scbus->sc_adapter.scsi_cmd = umass_scsi_cmd;
- scbus->sc_adapter.scsi_minphys = umass_scsi_minphys;
- scbus->sc_adapter.ioctl = umass_scsi_ioctl;
-
- DPRINTF(UDMASS_USB, ("%s: umass_attach_bus: SCSI\n"
- "sc = 0x%x, scbus = 0x%x\n",
- USBDEVNAME(sc->sc_dev), sc, scbus));
-
- scbus->base.sc_child =
- config_found((struct device *)sc, &scbus->sc_link, scsiprint);
-
- return (0);
-}
-
-#if NATAPISCSI > 0
-int
-umass_atapi_attach(struct umass_softc *sc)
-{
- struct umass_scsi_softc *scbus;
-
- scbus = umass_scsi_setup(sc);
- scbus->sc_link.adapter_target = UMASS_SCSIID_HOST;
- scbus->sc_link.luns = 1;
-
- scbus->sc_adapter.scsi_cmd = umass_scsi_cmd;
- scbus->sc_adapter.scsi_minphys = umass_scsi_minphys;
- scbus->sc_adapter.ioctl = umass_scsi_ioctl;
-
- DPRINTF(UDMASS_USB, ("%s: umass_attach_bus: ATAPI\n"
- "sc = 0x%x, scbus = 0x%x\n",
- USBDEVNAME(sc->sc_dev), sc, scbus));
-
- scbus->base.sc_child =
- config_found((struct device *)sc, &scbus->sc_link, scsiprint);
-
- return (0);
-}
-#endif
-
-struct umass_scsi_softc *
-umass_scsi_setup(struct umass_softc *sc)
-{
- struct umass_scsi_softc *scbus;
-
- scbus = malloc(sizeof(struct umass_scsi_softc), M_DEVBUF, M_WAITOK);
- memset(&scbus->sc_link, 0, sizeof(struct scsi_link));
- memset(&scbus->sc_adapter, 0, sizeof(struct scsi_adapter));
-
- sc->bus = (struct umassbus_softc *)scbus;
-
- scbus->sc_link.adapter_buswidth = 2;
- scbus->sc_link.openings = 1;
- scbus->sc_link.flags &= ~SDEV_ATAPI;
- scbus->sc_link.device = &umass_scsi_dev;
- scbus->sc_link.adapter = &scbus->sc_adapter;
- scbus->sc_link.adapter_softc = sc;
- scbus->sc_link.openings = 1;
-
- return (scbus);
-}
-
-int
-umass_scsi_cmd(struct scsi_xfer *xs)
-{
- struct scsi_link *sc_link = xs->sc_link;
- struct umass_softc *sc = sc_link->adapter_softc;
- struct umass_scsi_softc *scbus = (struct umass_scsi_softc *)sc->bus;
-
- struct scsi_generic *cmd, trcmd;
- int cmdlen, dir;
-
-#ifdef UMASS_DEBUG
- microtime(&sc->tv);
-#endif
-
- memset(&trcmd, 0, sizeof(trcmd));
-
- DIF(UDMASS_UPPER, sc_link->flags |= SCSIDEBUG_LEVEL);
-
- DPRINTF(UDMASS_CMD, ("%s: umass_scsi_cmd: at %lu.%06lu: %d:%d "
- "xs=%p cmd=0x%02x datalen=%d (quirks=0x%x, poll=%d)\n",
- USBDEVNAME(sc->sc_dev), sc->tv.tv_sec, sc->tv.tv_usec,
- sc_link->target, sc_link->lun, xs, xs->cmd->opcode,
- xs->datalen, sc_link->quirks, xs->flags & SCSI_POLL));
-
-#if defined(USB_DEBUG) && defined(SCSIDEBUG)
- if (umassdebug & UDMASS_SCSI)
- show_scsi_xs(xs);
- else if (umassdebug & ~UDMASS_CMD)
- show_scsi_cmd(xs);
-#endif
-
- if (sc->sc_dying) {
- xs->error = XS_DRIVER_STUFFUP;
- goto done;
- }
-
-#if defined(UMASS_DEBUG)
- if (sc_link->target != UMASS_SCSIID_DEVICE) {
- DPRINTF(UDMASS_SCSI, ("%s: wrong SCSI ID %d\n",
- USBDEVNAME(sc->sc_dev), sc_link->target));
- xs->error = XS_DRIVER_STUFFUP;
- goto done;
- }
-#endif
-
- cmd = xs->cmd;
- cmdlen = xs->cmdlen;
-
- if (cmd->opcode == MODE_SENSE &&
- (sc_link->quirks & SDEV_NOMODESENSE)) {
- xs->error = XS_TIMEOUT;
- goto done;
- }
-
- if (cmd->opcode == START_STOP &&
- (sc->sc_quirks & UMASS_QUIRK_NO_START_STOP)) {
- xs->error = XS_NOERROR;
- goto done;
- }
-
- if (cmd->opcode == INQUIRY &&
- (sc->sc_quirks & UMASS_QUIRK_FORCE_SHORT_INQUIRY)) {
- memcpy(&trcmd, cmd, sizeof(trcmd));
- trcmd.bytes[4] = SHORT_INQUIRY_LENGTH;
- cmd = &trcmd;
- }
-
- dir = DIR_NONE;
- if (xs->datalen) {
- switch (xs->flags & (SCSI_DATA_IN | SCSI_DATA_OUT)) {
- case SCSI_DATA_IN:
- dir = DIR_IN;
- break;
- case SCSI_DATA_OUT:
- dir = DIR_OUT;
- break;
- }
- }
-
- if (xs->datalen > UMASS_MAX_TRANSFER_SIZE) {
- printf("umass_cmd: large datalen, %d\n", xs->datalen);
- xs->error = XS_DRIVER_STUFFUP;
- goto done;
- }
-
- if (xs->flags & SCSI_POLL) {
- /* Use sync transfer. XXX Broken! */
- DPRINTF(UDMASS_SCSI, ("umass_scsi_cmd: sync dir=%d\n", dir));
- sc->sc_xfer_flags = USBD_SYNCHRONOUS;
- scbus->sc_sync_status = USBD_INVAL;
- sc->sc_methods->wire_xfer(sc, sc_link->lun, cmd, cmdlen,
- xs->data, xs->datalen, dir,
- xs->timeout, 0, xs);
- sc->sc_xfer_flags = 0;
- DPRINTF(UDMASS_SCSI, ("umass_scsi_cmd: done err=%d\n",
- scbus->sc_sync_status));
- switch (scbus->sc_sync_status) {
- case USBD_NORMAL_COMPLETION:
- xs->error = XS_NOERROR;
- break;
- case USBD_TIMEOUT:
- xs->error = XS_TIMEOUT;
- break;
- default:
- xs->error = XS_DRIVER_STUFFUP;
- break;
- }
- goto done;
- } else {
- DPRINTF(UDMASS_SCSI,
- ("umass_scsi_cmd: async dir=%d, cmdlen=%d"
- " datalen=%d\n",
- dir, cmdlen, xs->datalen));
- sc->sc_methods->wire_xfer(sc, sc_link->lun, cmd, cmdlen,
- xs->data, xs->datalen, dir,
- xs->timeout, umass_scsi_cb, xs);
- return (SUCCESSFULLY_QUEUED);
- }
-
- /* Return if command finishes early. */
- done:
- xs->flags |= ITSDONE;
-
- scsi_done(xs);
- if (xs->flags & SCSI_POLL)
- return (COMPLETE);
- else
- return (SUCCESSFULLY_QUEUED);
-}
-
-void
-umass_scsi_minphys(struct buf *bp)
-{
- if (bp->b_bcount > UMASS_MAX_TRANSFER_SIZE)
- bp->b_bcount = UMASS_MAX_TRANSFER_SIZE;
-
- minphys(bp);
-}
-
-int
-umass_scsi_ioctl(struct scsi_link *link, u_long cmd, caddr_t arg, int flag,
- struct proc *p)
-{
-#if 0
- struct umass_softc *sc = link->adapter_softc;
-#endif
-
- switch (cmd) {
-#if 0
- case SCBUSIORESET:
- ccb->ccb_h.status = CAM_REQ_INPROG;
- umass_reset(sc, umass_cam_cb, (void *) ccb);
- return (0);
-#endif
- default:
- return (ENOTTY);
- }
-}
-
-void
-umass_scsi_cb(struct umass_softc *sc, void *priv, int residue, int status)
-{
- struct umass_scsi_softc *scbus = (struct umass_scsi_softc *)sc->bus;
- struct scsi_xfer *xs = priv;
- struct scsi_link *link = xs->sc_link;
- int cmdlen;
- int s;
-#ifdef UMASS_DEBUG
- struct timeval tv;
- u_int delta;
- microtime(&tv);
- delta = (tv.tv_sec - sc->tv.tv_sec) * 1000000 +
- tv.tv_usec - sc->tv.tv_usec;
-#endif
-
- DPRINTF(UDMASS_CMD,
- ("umass_scsi_cb: at %lu.%06lu, delta=%u: xs=%p residue=%d"
- " status=%d\n", tv.tv_sec, tv.tv_usec, delta, xs, residue,
- status));
-
- xs->resid = residue;
-
- switch (status) {
- case STATUS_CMD_OK:
- xs->error = XS_NOERROR;
- break;
-
- case STATUS_CMD_UNKNOWN:
- /* we can't issue REQUEST SENSE */
- if (xs->sc_link->quirks & PQUIRK_NOSENSE) {
- /*
- * If no residue and no other USB error,
- * command succeeded.
- */
- if (residue == 0) {
- xs->error = XS_NOERROR;
- break;
- }
-
- /*
- * Some devices return a short INQUIRY
- * response, omitting response data from the
- * "vendor specific data" on...
- */
- if (xs->cmd->opcode == INQUIRY &&
- residue < xs->datalen) {
- xs->error = XS_NOERROR;
- break;
- }
-
- xs->error = XS_DRIVER_STUFFUP;
- break;
- }
- /* FALLTHROUGH */
- case STATUS_CMD_FAILED:
- /* fetch sense data */
- memset(&scbus->sc_sense_cmd, 0, sizeof(scbus->sc_sense_cmd));
- scbus->sc_sense_cmd.opcode = REQUEST_SENSE;
- scbus->sc_sense_cmd.byte2 = link->lun << SCSI_CMD_LUN_SHIFT;
- scbus->sc_sense_cmd.length = sizeof(xs->sense);
-
- cmdlen = sizeof(scbus->sc_sense_cmd);
- if (sc->sc_cmd == UMASS_CPROTO_UFI) /* XXX */
- cmdlen = UFI_COMMAND_LENGTH;
- sc->sc_methods->wire_xfer(sc, link->lun,
- &scbus->sc_sense_cmd, cmdlen,
- &xs->sense, sizeof(xs->sense),
- DIR_IN, xs->timeout,
- umass_scsi_sense_cb, xs);
- return;
-
- case STATUS_WIRE_FAILED:
- xs->error = XS_RESET;
- break;
-
- default:
- panic("%s: Unknown status %d in umass_scsi_cb\n",
- USBDEVNAME(sc->sc_dev), status);
- }
-
- DPRINTF(UDMASS_CMD,("umass_scsi_cb: at %lu.%06lu: return error=%d, "
- "status=0x%x resid=%d\n",
- tv.tv_sec, tv.tv_usec,
- xs->error, xs->status, xs->resid));
-
- s = splbio();
- scsi_done(xs);
- splx(s);
-}
-
-/*
- * Finalise a completed autosense operation
- */
-void
-umass_scsi_sense_cb(struct umass_softc *sc, void *priv, int residue,
- int status)
-{
- struct scsi_xfer *xs = priv;
- int s;
-
- DPRINTF(UDMASS_CMD,("umass_scsi_sense_cb: xs=%p residue=%d "
- "status=%d\n", xs, residue, status));
-
- switch (status) {
- case STATUS_CMD_OK:
- case STATUS_CMD_UNKNOWN:
- /* getting sense data succeeded */
- if (xs->cmd->opcode == INQUIRY && (xs->resid < xs->datalen ||
- (sc->sc_quirks & UMASS_QUIRK_RS_NO_CLEAR_UA /* XXX */))) {
- /*
- * Some drivers return SENSE errors even after INQUIRY.
- * The upper layer doesn't like that.
- */
- xs->error = XS_NOERROR;
- break;
- }
- /* XXX look at residue */
- if (residue == 0 || residue == 14)/* XXX */
- xs->error = XS_SENSE;
- else
- xs->error = XS_SHORTSENSE;
- break;
- default:
- DPRINTF(UDMASS_SCSI, ("%s: Autosense failed, status %d\n",
- USBDEVNAME(sc->sc_dev), status));
- xs->error = XS_DRIVER_STUFFUP;
- break;
- }
-
- xs->status |= ITSDONE;
-
- DPRINTF(UDMASS_CMD,("umass_scsi_sense_cb: return xs->error=%d, "
- "xs->status=0x%x xs->resid=%d\n", xs->error, xs->status,
- xs->resid));
-
- s = splbio();
- scsi_done(xs);
- splx(s);
-}