summaryrefslogtreecommitdiff
path: root/sys/dev
diff options
context:
space:
mode:
authoraugustss <augustss@NetBSD.org>2001-12-24 13:43:24 +0000
committeraugustss <augustss@NetBSD.org>2001-12-24 13:43:24 +0000
commitab7b323efa6fb8f38badd7f82de9e7aae613c3b2 (patch)
tree193e9b51b853a3ccfae3d964d7adbbfc47edd022 /sys/dev
parent45fc7e27e9d48128bf625205f9c3e8c0965dc1ac (diff)
Add a preliminary version of a driver for In-System Designs non-standard
ATA-over-BulkOnly protocol. The ISD chip can be found, e.g., in the Archos MP3 player. The driver still lacks real error handling.
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/usb/files.usb5
-rw-r--r--sys/dev/usb/umass.c17
-rw-r--r--sys/dev/usb/umass_isdata.c589
-rw-r--r--sys/dev/usb/umass_isdata.h40
-rw-r--r--sys/dev/usb/umass_quirks.c33
-rw-r--r--sys/dev/usb/umassvar.h3
6 files changed, 681 insertions, 6 deletions
diff --git a/sys/dev/usb/files.usb b/sys/dev/usb/files.usb
index f34f52b318f..20f8e833b47 100644
--- a/sys/dev/usb/files.usb
+++ b/sys/dev/usb/files.usb
@@ -1,4 +1,4 @@
-# $NetBSD: files.usb,v 1.34 2001/12/24 13:25:53 augustss Exp $
+# $NetBSD: files.usb,v 1.35 2001/12/24 13:43:25 augustss Exp $
#
# Config file and device description for machine-independent USB code.
# Included by ports that need it. Ports that use it must provide
@@ -79,9 +79,10 @@ file dev/usb/ulpt.c ulpt needs-flag
# Mass storage
-device umass: scsi, atapi
+device umass: scsi, atapi, ata
attach umass at uhub
file dev/usb/umass.c umass
+file dev/usb/umass_isdata.c umass & wd
file dev/usb/umass_quirks.c umass
file dev/usb/umass_scsipi.c umass & (scsibus | atapibus)
diff --git a/sys/dev/usb/umass.c b/sys/dev/usb/umass.c
index dd4df05e905..67116d72ed0 100644
--- a/sys/dev/usb/umass.c
+++ b/sys/dev/usb/umass.c
@@ -1,4 +1,4 @@
-/* $NetBSD: umass.c,v 1.79 2001/12/24 13:25:52 augustss Exp $ */
+/* $NetBSD: umass.c,v 1.80 2001/12/24 13:43:24 augustss Exp $ */
/*-
* Copyright (c) 1999 MAEKAWA Masahide <bishop@rr.iij4u.or.jp>,
* Nick Hibma <n_hibma@freebsd.org>
@@ -94,10 +94,11 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: umass.c,v 1.79 2001/12/24 13:25:52 augustss Exp $");
+__KERNEL_RCSID(0, "$NetBSD: umass.c,v 1.80 2001/12/24 13:43:24 augustss Exp $");
#include "atapibus.h"
#include "scsibus.h"
+#include "wd.h"
#include <sys/param.h>
#include <sys/systm.h>
@@ -124,6 +125,7 @@ __KERNEL_RCSID(0, "$NetBSD: umass.c,v 1.79 2001/12/24 13:25:52 augustss Exp $");
#include <dev/usb/umassvar.h>
#include <dev/usb/umass_quirks.h>
#include <dev/usb/umass_scsipi.h>
+#include <dev/usb/umass_isdata.h>
#ifdef UMASS_DEBUG
@@ -388,6 +390,9 @@ USB_ATTACH(umass)
case UMASS_CPROTO_ATAPI:
sCommand = "ATAPI";
break;
+ case UMASS_CPROTO_ISD_ATA:
+ sCommand = "ISD-ATA";
+ break;
default:
sCommand = "unknown";
break;
@@ -578,6 +583,14 @@ USB_ATTACH(umass)
#endif
break;
+ case UMASS_CPROTO_ISD_ATA:
+#if NWD > 0
+ error = umass_isdata_attach(sc);
+#else
+ printf("%s: isdata not configured\n", USBDEVNAME(sc->sc_dev));
+#endif
+ break;
+
default:
printf("%s: command protocol=0x%x not supported\n",
USBDEVNAME(sc->sc_dev), sc->sc_cmd);
diff --git a/sys/dev/usb/umass_isdata.c b/sys/dev/usb/umass_isdata.c
new file mode 100644
index 00000000000..bd5a73562dd
--- /dev/null
+++ b/sys/dev/usb/umass_isdata.c
@@ -0,0 +1,589 @@
+/* $NetBSD: umass_isdata.c,v 1.1 2001/12/24 13:43:25 augustss Exp $ */
+
+/*
+ * TODO:
+ * get ATA registers on any kind of error
+ * implement more commands (what is needed)
+ */
+
+/*
+ * 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 <sys/cdefs.h>
+__KERNEL_RCSID(0, "$NetBSD: umass_isdata.c,v 1.1 2001/12/24 13:43:25 augustss Exp $");
+
+#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/proc.h>
+#include <sys/disklabel.h>
+#include <sys/malloc.h>
+
+#include <dev/usb/usb.h>
+#include <dev/usb/usbdi.h>
+#include <dev/usb/usbdi_util.h>
+
+#include <dev/usb/umassvar.h>
+#include <dev/usb/umass_isdata.h>
+
+int umass_wd_attach(struct umass_softc *);
+
+#include <dev/ata/atareg.h>
+#include <dev/ata/atavar.h>
+#include <dev/ata/wdvar.h>
+#include <dev/ic/wdcreg.h>
+
+/* XXX move this */
+struct isd200_config {
+ uByte EventNotification;
+ uByte ExternalClock;
+ uByte ATAInitTimeout;
+ uByte ATAMisc1;
+#define ATATiming 0x0f
+#define ATAPIReset 0x10
+#define MasterSlaveSelection 0x20
+#define ATAPICommandBlockSize 0xc0
+ uByte ATAMajorCommand;
+ uByte ATAMinorCommand;
+ uByte ATAMisc2;
+#define LastLUNIdentifier 0x07
+#define DescriptOverride 0x08
+#define ATA3StateSuspend 0x10
+#define SkipDeviceBoot 0x20
+#define ConfigDescriptor2 0x40
+#define InitStatus 0x80
+ uByte ATAMisc3;
+#define SRSTEnable 0x01
+};
+
+struct uisdata_softc {
+ struct umassbus_softc base;
+
+ struct ata_drive_datas sc_drv_data;
+ struct isd200_config sc_isd_config;
+ void *sc_ata_bio;
+ u_long sc_skip;
+};
+
+#undef DPRINTF
+#undef DPRINTFN
+#ifdef UISDATA_DEBUG
+#define DPRINTF(x) if (uisdatadebug) logprintf x
+#define DPRINTFN(n,x) if (uisdatadebug>(n)) logprintf x
+int uisdatadebug = 0;
+#else
+#define DPRINTF(x)
+#define DPRINTFN(n,x)
+#endif
+
+int uisdata_bio(struct ata_drive_datas *, struct ata_bio *);
+int uisdata_bio1(struct ata_drive_datas *, struct ata_bio *);
+void uisdata_reset_channel(struct ata_drive_datas *);
+int uisdata_exec_command(struct ata_drive_datas *, struct wdc_command *);
+int uisdata_get_params(struct ata_drive_datas *, u_int8_t, struct ataparams *);
+int uisdata_addref(struct ata_drive_datas *);
+void uisdata_delref(struct ata_drive_datas *);
+void uisdata_kill_pending(struct ata_drive_datas *);
+
+void uisdata_bio_cb(struct umass_softc *, void *, int, int);
+void uisdata_exec_cb(struct umass_softc *, void *, int, int);
+int uwdprint(void *, const char *);
+
+const struct ata_bustype uisdata_bustype = {
+ SCSIPI_BUSTYPE_ATA,
+ uisdata_bio,
+ uisdata_reset_channel,
+ uisdata_exec_command,
+ uisdata_get_params,
+ uisdata_addref,
+ uisdata_delref,
+ uisdata_kill_pending,
+};
+
+struct ata_cmd {
+ u_int8_t ac_signature0;
+ u_int8_t ac_signature1;
+
+ u_int8_t ac_action_select;
+#define AC_ReadRegisterAccess 0x01
+#define AC_NoDeviceSelectionBit 0x02
+#define AC_NoBSYPollBit 0x04
+#define AC_IgnorePhaseErrorBit 0x08
+#define AC_IgnoreDeviceErrorBit 0x10
+
+ u_int8_t ac_register_select;
+#define AC_SelectAlternateStatus 0x01 /* R */
+#define AC_SelectDeviceControl 0x01 /* W */
+#define AC_SelectError 0x02 /* R */
+#define AC_SelectFeatures 0x02 /* W */
+#define AC_SelectSectorCount 0x04 /* RW */
+#define AC_SelectSectorNumber 0x08 /* RW */
+#define AC_SelectCylinderLow 0x10 /* RW */
+#define AC_SelectCylinderHigh 0x20 /* RW */
+#define AC_SelectDeviceHead 0x40 /* RW */
+#define AC_SelectStatus 0x80 /* R */
+#define AC_SelectCommand 0x80 /* W */
+
+ u_int8_t ac_transfer_blocksize;
+
+ u_int8_t ac_alternate_status;
+#define ac_device_control ac_alternate_status
+ u_int8_t ac_error;
+#define ac_features ac_error
+
+ u_int8_t ac_sector_count;
+ u_int8_t ac_sector_number;
+ u_int8_t ac_cylinder_low;
+ u_int8_t ac_cylinder_high;
+ u_int8_t ac_device_head;
+
+ u_int8_t ac_status;
+#define ac_command ac_status
+
+ u_int8_t ac_reserved[3];
+};
+
+#define ATA_DELAY 10000 /* 10s for a drive I/O */
+
+int
+umass_isdata_attach(struct umass_softc *sc)
+{
+ usb_device_request_t req;
+ usbd_status err;
+ struct ata_device adev;
+ struct uisdata_softc *scbus;
+ struct isd200_config *cf;
+
+ scbus = malloc(sizeof *scbus, M_DEVBUF, M_WAITOK | M_ZERO);
+ sc->bus = &scbus->base;
+ cf = &scbus->sc_isd_config;
+
+ req.bmRequestType = UT_READ_VENDOR_DEVICE;
+ req.bRequest = 0x02;
+ USETW(req.wValue, 0);
+ USETW(req.wIndex, 2);
+ USETW(req.wLength, sizeof *cf);
+
+ err = usbd_do_request(sc->sc_udev, &req, cf);
+ if (err)
+ return (EIO);
+ DPRINTF(("umass_wd_attach info:\n EventNotification=0x%02x "
+ "ExternalClock=0x%02x ATAInitTimeout=0x%02x\n"
+ " ATAMisc1=0x%02x ATAMajorCommand=0x%02x "
+ "ATAMinorCommand=0x%02x\n"
+ " ATAMisc2=0x%02x ATAMisc3=0x%02x\n",
+ cf->EventNotification, cf->ExternalClock, cf->ATAInitTimeout,
+ cf->ATAMisc1, cf->ATAMajorCommand, cf->ATAMinorCommand,
+ cf->ATAMisc2, cf->ATAMisc3));
+
+ memset(&adev, 0, sizeof(struct ata_device));
+ adev.adev_bustype = &uisdata_bustype;
+ adev.adev_channel = 1; /* XXX */
+ adev.adev_openings = 1;
+ adev.adev_drv_data = &scbus->sc_drv_data;
+ scbus->sc_drv_data.drive_flags = DRIVE_ATA;
+ scbus->sc_drv_data.chnl_softc = sc;
+ scbus->base.sc_child = config_found(&sc->sc_dev, &adev, uwdprint);
+
+ return (0);
+}
+
+
+void
+uisdata_bio_cb(struct umass_softc *sc, void *priv, int residue, int status)
+{
+ struct uisdata_softc *scbus = (struct uisdata_softc *)sc->bus;
+ struct ata_bio *ata_bio = priv;
+ int s;
+
+ DPRINTF(("%s: residue=%d status=%d\n", __FUNCTION__, residue, status));
+
+ s = splbio();
+ scbus->sc_ata_bio = NULL;
+ if (status != STATUS_CMD_OK)
+ ata_bio->error = ERR_DF; /* ??? */
+ else
+ ata_bio->error = NOERROR;
+ ata_bio->flags |= ATA_ITSDONE;
+
+ ata_bio->blkdone += ata_bio->nblks;
+ ata_bio->blkno += ata_bio->nblks;
+ ata_bio->bcount -= ata_bio->nbytes;
+ scbus->sc_skip += ata_bio->nbytes;
+ if (residue != 0) {
+ ata_bio->bcount += residue;
+ } else if (ata_bio->bcount > 0) {
+ DPRINTF(("%s: continue\n", __FUNCTION__));
+ (void)uisdata_bio1(&scbus->sc_drv_data, ata_bio); /*XXX save drv*/
+ splx(s);
+ return;
+ }
+
+ if (ata_bio->flags & ATA_POLL) {
+ DPRINTF(("%s: wakeup %p\n", __FUNCTION__, ata_bio));
+ wakeup(ata_bio);
+ } else {
+ wddone(scbus->sc_drv_data.drv_softc);
+ }
+ splx(s);
+}
+
+int
+uisdata_bio(struct ata_drive_datas *drv, struct ata_bio *ata_bio)
+{
+ struct umass_softc *sc = drv->chnl_softc;
+ struct uisdata_softc *scbus = (struct uisdata_softc *)sc->bus;
+
+ scbus->sc_skip = 0;
+ return (uisdata_bio1(drv, ata_bio));
+}
+
+int
+uisdata_bio1(struct ata_drive_datas *drv, struct ata_bio *ata_bio)
+{
+ struct umass_softc *sc = drv->chnl_softc;
+ struct uisdata_softc *scbus = (struct uisdata_softc *)sc->bus;
+ struct isd200_config *cf = &scbus->sc_isd_config;
+ struct ata_cmd ata;
+ u_int16_t cyl;
+ u_int8_t head, sect;
+ int dir;
+ long nbytes;
+ u_int nblks;
+
+ DPRINTF(("%s\n", __FUNCTION__));
+ /* XXX */
+
+ if (ata_bio->flags & ATA_NOSLEEP) {
+ printf("%s: ATA_NOSLEEP not supported\n", __FUNCTION__);
+ ata_bio->error = TIMEOUT;
+ ata_bio->flags |= ATA_ITSDONE;
+ return (WDC_COMPLETE);
+ }
+
+ if (scbus->sc_ata_bio != NULL) {
+ printf("%s: multiple uisdata_bio\n", __FUNCTION__);
+ return (WDC_TRY_AGAIN);
+ } else
+ scbus->sc_ata_bio = ata_bio;
+
+ if (ata_bio->flags & ATA_LBA) {
+ sect = (ata_bio->blkno >> 0) & 0xff;
+ cyl = (ata_bio->blkno >> 8) & 0xffff;
+ head = (ata_bio->blkno >> 24) & 0x0f;
+ head |= WDSD_LBA;
+ } else {
+ int blkno = ata_bio->blkno;
+ sect = blkno % ata_bio->lp->d_nsectors;
+ sect++; /* Sectors begin with 1, not 0. */
+ blkno /= ata_bio->lp->d_nsectors;
+ head = blkno % ata_bio->lp->d_ntracks;
+ blkno /= ata_bio->lp->d_ntracks;
+ cyl = blkno;
+ head |= WDSD_CHS;
+ }
+
+ nbytes = ata_bio->bcount;
+ if (ata_bio->flags & ATA_SINGLE)
+ nblks = 1;
+ else
+ nblks = min(ata_bio->multi, nbytes / ata_bio->lp->d_secsize);
+ nbytes = nblks * ata_bio->lp->d_secsize;
+ ata_bio->nblks = nblks;
+ ata_bio->nbytes = nbytes;
+
+ memset(&ata, 0, sizeof ata);
+ ata.ac_signature0 = cf->ATAMajorCommand;
+ ata.ac_signature1 = cf->ATAMinorCommand;
+ ata.ac_transfer_blocksize = 1;
+ ata.ac_sector_count = nblks;
+ ata.ac_sector_number = sect;
+ ata.ac_cylinder_high = cyl >> 8;
+ ata.ac_cylinder_low = cyl;
+ ata.ac_device_head = head;
+ ata.ac_register_select = AC_SelectSectorCount | AC_SelectSectorNumber |
+ AC_SelectCylinderLow | AC_SelectCylinderHigh | AC_SelectDeviceHead |
+ AC_SelectCommand;
+
+ dir = DIR_NONE;
+ if (ata_bio->bcount != 0) {
+ if (ata_bio->flags & ATA_READ)
+ dir = DIR_IN;
+ else
+ dir = DIR_OUT;
+ }
+
+ if (ata_bio->flags & ATA_READ) {
+ ata.ac_command = WDCC_READ;
+ } else {
+ ata.ac_command = WDCC_WRITE;
+ }
+ DPRINTF(("%s: bno=%d LBA=%d cyl=%d head=%d sect=%d count=%d multi=%d\n",
+ __FUNCTION__, ata_bio->blkno,
+ (ata_bio->flags & ATA_LBA) != 0, cyl, head, sect,
+ ata.ac_sector_count, ata_bio->multi));
+ DPRINTF((" data=%p bcount=%ld, drive=%d\n", ata_bio->databuf,
+ ata_bio->bcount, drv->drive));
+ sc->sc_methods->wire_xfer(sc, drv->drive, &ata, sizeof ata,
+ ata_bio->databuf + scbus->sc_skip, nbytes,
+ dir, ATA_DELAY, uisdata_bio_cb, ata_bio);
+
+ while (ata_bio->flags & ATA_POLL) {
+ DPRINTF(("%s: tsleep %p\n", __FUNCTION__, ata_bio));
+ if (tsleep(ata_bio, PZERO, "uisdatabl", 0)) {
+ ata_bio->error = TIMEOUT;
+ ata_bio->flags |= ATA_ITSDONE;
+ return (WDC_COMPLETE);
+ }
+ }
+
+ return (ata_bio->flags & ATA_ITSDONE) ? WDC_COMPLETE : WDC_QUEUED;
+}
+
+void
+uisdata_reset_channel(struct ata_drive_datas *drv)
+{
+ DPRINTFN(-1,("%s\n", __FUNCTION__));
+ /* XXX what? */
+}
+
+void
+uisdata_exec_cb(struct umass_softc *sc, void *priv, int residue, int status)
+{
+ struct wdc_command *cmd = priv;
+
+ DPRINTF(("%s: status=%d\n", __FUNCTION__, status));
+ if (status != STATUS_CMD_OK)
+ cmd->flags |= AT_DF; /* XXX */
+ cmd->flags |= AT_DONE;
+ if (cmd->flags & (AT_POLL | AT_WAIT)) {
+ DPRINTF(("%s: wakeup %p\n", __FUNCTION__, cmd));
+ wakeup(cmd);
+ }
+}
+
+int
+uisdata_exec_command(struct ata_drive_datas *drv, struct wdc_command *cmd)
+{
+ struct umass_softc *sc = drv->chnl_softc;
+ struct uisdata_softc *scbus = (struct uisdata_softc *)sc->bus;
+ struct isd200_config *cf = &scbus->sc_isd_config;
+ int dir;
+ struct ata_cmd ata;
+
+ DPRINTF(("%s\n", __FUNCTION__));
+ DPRINTF((" r_command=0x%02x timeout=%d flags=0x%x bcount=%d\n",
+ cmd->r_command, cmd->timeout, cmd->flags, cmd->bcount));
+
+ dir = DIR_NONE;
+ if (cmd->bcount != 0) {
+ if (cmd->flags & AT_READ)
+ dir = DIR_IN;
+ else
+ dir = DIR_OUT;
+ }
+
+ if (cmd->bcount > UMASS_MAX_TRANSFER_SIZE) {
+ printf("uisdata_exec_command: large datalen %d\n", cmd->bcount);
+ cmd->flags |= AT_ERROR;
+ goto done;
+ }
+
+ memset(&ata, 0, sizeof ata);
+ ata.ac_signature0 = cf->ATAMajorCommand;
+ ata.ac_signature1 = cf->ATAMinorCommand;
+ ata.ac_transfer_blocksize = 1;
+
+ switch (cmd->r_command) {
+ case WDCC_IDENTIFY:
+ ata.ac_register_select |= AC_SelectCommand;
+ ata.ac_command = WDCC_IDENTIFY;
+ break;
+ default:
+ printf("uisdata_exec_command: bad command 0x%02x\n",
+ cmd->r_command);
+ cmd->flags |= AT_ERROR;
+ goto done;
+ }
+
+ DPRINTF(("%s: execute ATA command 0x%02x, drive=%d\n", __FUNCTION__,
+ ata.ac_command, drv->drive));
+ sc->sc_methods->wire_xfer(sc, drv->drive, &ata,
+ sizeof ata, cmd->data, cmd->bcount, dir,
+ cmd->timeout, uisdata_exec_cb, cmd);
+ if (cmd->flags & (AT_POLL | AT_WAIT)) {
+#if 0
+ if (cmd->flags & AT_POLL)
+ printf("%s: AT_POLL not supported\n", __FUNCTION__);
+#endif
+ DPRINTF(("%s: tsleep %p\n", __FUNCTION__, cmd));
+ if (tsleep(cmd, PZERO, "uisdataex", 0)) {
+ cmd->flags |= AT_ERROR;
+ goto done;
+ }
+ }
+
+done:
+ return (WDC_COMPLETE);
+}
+
+int
+uisdata_addref(struct ata_drive_datas *drv)
+{
+ DPRINTF(("%s\n", __FUNCTION__));
+ /* Nothing to do */
+ return (0);
+}
+
+void
+uisdata_delref(struct ata_drive_datas *drv)
+{
+ DPRINTF(("%s\n", __FUNCTION__));
+ /* Nothing to do */
+}
+
+void
+uisdata_kill_pending(struct ata_drive_datas *drv)
+{
+ struct umass_softc *sc = drv->chnl_softc;
+ struct uisdata_softc *scbus = (struct uisdata_softc *)sc->bus;
+ struct ata_bio *ata_bio = scbus->sc_ata_bio;
+
+ DPRINTFN(-1,("%s\n", __FUNCTION__));
+
+ if (ata_bio == NULL)
+ return;
+ scbus->sc_ata_bio = NULL;
+ ata_bio->flags |= ATA_ITSDONE;
+ ata_bio->error = ERR_NODEV;
+ ata_bio->r_error = WDCE_ABRT;
+ wddone(scbus->sc_drv_data.drv_softc);
+}
+
+int
+uisdata_get_params(struct ata_drive_datas *drvp, u_int8_t flags,
+ struct ataparams *prms)
+{
+ char tb[DEV_BSIZE];
+ struct wdc_command wdc_c;
+
+#if BYTE_ORDER == LITTLE_ENDIAN
+ int i;
+ u_int16_t *p;
+#endif
+
+ DPRINTF(("%s\n", __FUNCTION__));
+
+ memset(tb, 0, DEV_BSIZE);
+ memset(prms, 0, sizeof(struct ataparams));
+ memset(&wdc_c, 0, sizeof(struct wdc_command));
+
+ wdc_c.r_command = WDCC_IDENTIFY;
+ wdc_c.timeout = 1000; /* 1s */
+ wdc_c.flags = AT_READ | flags;
+ wdc_c.data = tb;
+ wdc_c.bcount = DEV_BSIZE;
+ if (uisdata_exec_command(drvp, &wdc_c) != WDC_COMPLETE) {
+ DPRINTF(("uisdata_get_parms: wdc_exec_command failed\n"));
+ return (CMD_AGAIN);
+ }
+ if (wdc_c.flags & (AT_ERROR | AT_TIMEOU | AT_DF)) {
+ DPRINTF(("uisdata_get_parms: wdc_c.flags=0x%x\n",
+ wdc_c.flags));
+ return (CMD_ERR);
+ } else {
+ /* Read in parameter block. */
+ memcpy(prms, tb, sizeof(struct ataparams));
+#if BYTE_ORDER == LITTLE_ENDIAN
+ /* XXX copied from ata.c */
+ /*
+ * Shuffle string byte order.
+ * ATAPI Mitsumi and NEC drives don't need this.
+ */
+ if ((prms->atap_config & WDC_CFG_ATAPI_MASK) ==
+ WDC_CFG_ATAPI &&
+ ((prms->atap_model[0] == 'N' &&
+ prms->atap_model[1] == 'E') ||
+ (prms->atap_model[0] == 'F' &&
+ prms->atap_model[1] == 'X')))
+ return 0;
+ for (i = 0; i < sizeof(prms->atap_model); i += 2) {
+ p = (u_short *)(prms->atap_model + i);
+ *p = ntohs(*p);
+ }
+ for (i = 0; i < sizeof(prms->atap_serial); i += 2) {
+ p = (u_short *)(prms->atap_serial + i);
+ *p = ntohs(*p);
+ }
+ for (i = 0; i < sizeof(prms->atap_revision); i += 2) {
+ p = (u_short *)(prms->atap_revision + i);
+ *p = ntohs(*p);
+ }
+#endif
+ return CMD_OK;
+ }
+}
+
+
+/* XXX join with wdc.c routine? */
+int
+uwdprint(void *aux, const char *pnp)
+{
+ //struct ata_device *adev = aux;
+ if (pnp)
+ printf("wd at %s", pnp);
+#if 0
+ printf(" channel %d drive %d", adev->adev_channel,
+ adev->adev_drv_data->drive);
+#endif
+ return (UNCONF);
+}
+
+
+#if 0
+
+int umass_wd_attach(struct umass_softc *);
+
+#if NWD > 0
+ case UMASS_CPROTO_ISD_ATA:
+ return (umass_wd_attach(sc));
+#endif
+
+#endif
diff --git a/sys/dev/usb/umass_isdata.h b/sys/dev/usb/umass_isdata.h
new file mode 100644
index 00000000000..665922192a4
--- /dev/null
+++ b/sys/dev/usb/umass_isdata.h
@@ -0,0 +1,40 @@
+/* $NetBSD: umass_isdata.h,v 1.1 2001/12/24 13:43:25 augustss Exp $ */
+
+/*
+ * 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.
+ */
+
+int umass_isdata_attach(struct umass_softc *sc);
diff --git a/sys/dev/usb/umass_quirks.c b/sys/dev/usb/umass_quirks.c
index 3eba42de120..02a415e79a0 100644
--- a/sys/dev/usb/umass_quirks.c
+++ b/sys/dev/usb/umass_quirks.c
@@ -1,4 +1,4 @@
-/* $NetBSD: umass_quirks.c,v 1.3 2001/12/24 13:25:52 augustss Exp $ */
+/* $NetBSD: umass_quirks.c,v 1.4 2001/12/24 13:43:25 augustss Exp $ */
/*
* Copyright (c) 2001 The NetBSD Foundation, Inc.
@@ -149,6 +149,37 @@ Static const struct umass_quirk umass_quirks[] = {
NULL, umass_fixup_yedata
},
+ /* InSystem Design ATA over USB devices */
+ { { USB_VENDOR_ATI, USB_PRODUCT_ATI2_205 },
+ UMASS_WPROTO_BBB, UMASS_CPROTO_ISD_ATA,
+ 0,
+ UMATCH_VENDOR_PRODUCT,
+ NULL, NULL
+ },
+ { { USB_VENDOR_INSYSTEM, USB_PRODUCT_INSYSTEM_ATAPI },
+ UMASS_WPROTO_BBB, UMASS_CPROTO_ISD_ATA,
+ 0,
+ UMATCH_VENDOR_PRODUCT,
+ NULL, NULL
+ },
+ { { USB_VENDOR_INSYSTEM, USB_PRODUCT_INSYSTEM_DRIVEV2_5 },
+ UMASS_WPROTO_BBB, UMASS_CPROTO_ISD_ATA,
+ 0,
+ UMATCH_VENDOR_PRODUCT,
+ NULL, NULL
+ },
+ { { USB_VENDOR_INSYSTEM, USB_PRODUCT_INSYSTEM_ADAPTERV2 },
+ UMASS_WPROTO_BBB, UMASS_CPROTO_ISD_ATA,
+ 0,
+ UMATCH_VENDOR_PRODUCT,
+ NULL, NULL
+ },
+ { { USB_VENDOR_SONY, USB_PRODUCT_SONY_DRIVEV2 },
+ UMASS_WPROTO_BBB, UMASS_CPROTO_ISD_ATA,
+ 0,
+ UMATCH_VENDOR_PRODUCT,
+ NULL, NULL
+ },
};
const struct umass_quirk *
diff --git a/sys/dev/usb/umassvar.h b/sys/dev/usb/umassvar.h
index cd10f3892d7..9c5de1def07 100644
--- a/sys/dev/usb/umassvar.h
+++ b/sys/dev/usb/umassvar.h
@@ -1,4 +1,4 @@
-/* $NetBSD: umassvar.h,v 1.11 2001/12/24 13:25:53 augustss Exp $ */
+/* $NetBSD: umassvar.h,v 1.12 2001/12/24 13:43:25 augustss Exp $ */
/*-
* Copyright (c) 1999 MAEKAWA Masahide <bishop@rr.iij4u.or.jp>,
* Nick Hibma <n_hibma@freebsd.org>
@@ -182,6 +182,7 @@ struct umass_softc {
#define UMASS_CPROTO_ATAPI 2
#define UMASS_CPROTO_UFI 3
#define UMASS_CPROTO_RBC 4
+#define UMASS_CPROTO_ISD_ATA 5
u_int32_t sc_quirks;
#define UMASS_QUIRK_NO_TEST_UNIT_READY 0x00000001