Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/jdolecek-ncq]: src/sys/dev use a fake ata_channel struct in umass_isdata...



details:   https://anonhg.NetBSD.org/src/rev/5e911e2abb22
branches:  jdolecek-ncq
changeset: 822887:5e911e2abb22
user:      jdolecek <jdolecek%NetBSD.org@localhost>
date:      Thu Apr 20 20:14:42 2017 +0000

description:
use a fake ata_channel struct in umass_isdata.c so that the wd(4) calls
to ata_{get,free}_xfer() can work, adjust to ata interface changes

compile tested only

diffstat:

 sys/dev/ata/TODO.ncq       |    8 +-
 sys/dev/ata/atavar.h       |    4 +-
 sys/dev/usb/umass_isdata.c |  132 ++++++++++++++++++++++++--------------------
 3 files changed, 78 insertions(+), 66 deletions(-)

diffs (285 lines):

diff -r 82aefc1ba777 -r 5e911e2abb22 sys/dev/ata/TODO.ncq
--- a/sys/dev/ata/TODO.ncq      Thu Apr 20 19:24:25 2017 +0000
+++ b/sys/dev/ata/TODO.ncq      Thu Apr 20 20:14:42 2017 +0000
@@ -1,10 +1,12 @@
-ahci with NCQ gets frequent timeouts, something's amiss
+ahci with NCQ gets frequent timeouts, something's amiss; improve message
+to use dev for the drive, not the controller
 
 under QEMU, the mounted AHCI drive doesn't show directories for ls,
 but cd, mkdir, stat and creating files wroks just fine - what do?
 
-ata_xfer_*() uses wd->drvp->chnl_softc as ata_channel, but it's umass
-softc for wd? at umass*
+test wd* at umass?, confirm the ata_channel kludge works
+
+set PRIO/ICC for NCQ transfers for BPRIO_TIMECRITICAL/BPRIO_TIMELIMITED
 
 protect more of wddone() with mutex?
 
diff -r 82aefc1ba777 -r 5e911e2abb22 sys/dev/ata/atavar.h
--- a/sys/dev/ata/atavar.h      Thu Apr 20 19:24:25 2017 +0000
+++ b/sys/dev/ata/atavar.h      Thu Apr 20 20:14:42 2017 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: atavar.h,v 1.92.8.6 2017/04/19 21:42:39 jdolecek Exp $ */
+/*     $NetBSD: atavar.h,v 1.92.8.7 2017/04/20 20:14:42 jdolecek Exp $ */
 
 /*
  * Copyright (c) 1998, 2001 Manuel Bouyer.
@@ -288,7 +288,7 @@
        void    (*drv_done)(void *, struct ata_xfer *); /* transfer is done */
 
        device_t drv_softc;             /* ATA drives softc, if any */
-       void *chnl_softc;               /* channel softc */
+       struct ata_channel *chnl_softc; /* channel softc */
 
        /* Context used for I/O */
        struct disklabel *lp;   /* pointer to drive's label info */
diff -r 82aefc1ba777 -r 5e911e2abb22 sys/dev/usb/umass_isdata.c
--- a/sys/dev/usb/umass_isdata.c        Thu Apr 20 19:24:25 2017 +0000
+++ b/sys/dev/usb/umass_isdata.c        Thu Apr 20 20:14:42 2017 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: umass_isdata.c,v 1.33.4.1 2017/04/15 12:01:24 jdolecek Exp $   */
+/*     $NetBSD: umass_isdata.c,v 1.33.4.2 2017/04/20 20:14:42 jdolecek Exp $   */
 
 /*
  * TODO:
@@ -37,7 +37,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: umass_isdata.c,v 1.33.4.1 2017/04/15 12:01:24 jdolecek Exp $");
+__KERNEL_RCSID(0, "$NetBSD: umass_isdata.c,v 1.33.4.2 2017/04/20 20:14:42 jdolecek Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_usb.h"
@@ -92,11 +92,13 @@
        struct umassbus_softc   base;
 
        struct ata_drive_datas  sc_drv_data;
+       struct ata_channel      sc_channel;
        struct isd200_config    sc_isd_config;
-       struct ata_xfer         *sc_ata_xfer;
        u_long                  sc_skip;
 };
 
+#define CH2SELF(chnl_softc)    ((void *)chnl_softc->atabus)
+
 #undef DPRINTF
 #undef DPRINTFN
 #ifdef UISDATA_DEBUG
@@ -112,7 +114,7 @@
 int  uisdata_bio1(struct ata_drive_datas *, struct ata_xfer *);
 void uisdata_reset_drive(struct ata_drive_datas *, int, uint32_t *);
 void uisdata_reset_channel(struct ata_channel *, int);
-int  uisdata_exec_command(struct ata_drive_datas *, struct ata_command *);
+int  uisdata_exec_command(struct ata_drive_datas *, struct ata_xfer *);
 int  uisdata_get_params(struct ata_drive_datas *, uint8_t, struct ataparams *);
 int  uisdata_addref(struct ata_drive_datas *);
 void uisdata_delref(struct ata_drive_datas *);
@@ -216,11 +218,15 @@
        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;
+
+       /* Fake ATA channel so wd(4) ata_{get,free}_xfer() work */
+       scbus->sc_channel.atabus = (device_t)scbus;
+       scbus->sc_channel.ch_queue = ata_queue_alloc(1);
+
        scbus->sc_drv_data.drive_type = ATA_DRIVET_ATA;
-       scbus->sc_drv_data.chnl_softc = sc;
-#error chnl_softc is used by ata_get_xfer() as ata_channel
+       scbus->sc_drv_data.chnl_softc = &scbus->sc_channel;
+
        scbus->base.sc_child = config_found(sc->sc_dev, &adev, uwdprint);
 
        return 0;
@@ -238,7 +244,6 @@
        DPRINTF(("%s: residue=%d status=%d\n", __func__, residue, status));
 
        s = splbio();
-       scbus->sc_ata_xfer = NULL;
        if (status != STATUS_CMD_OK)
                ata_bio->error = ERR_DF; /* ??? */
        else
@@ -271,7 +276,7 @@
 int
 uisdata_bio(struct ata_drive_datas *drv, struct ata_xfer *xfer)
 {
-       struct umass_softc *sc = drv->chnl_softc;
+       struct umass_softc *sc = CH2SELF(drv->chnl_softc);
        struct uisdata_softc *scbus = (struct uisdata_softc *)sc->bus;
 
        scbus->sc_skip = 0;
@@ -281,7 +286,7 @@
 int
 uisdata_bio1(struct ata_drive_datas *drv, struct ata_xfer *xfer)
 {
-       struct umass_softc *sc = drv->chnl_softc;
+       struct umass_softc *sc = CH2SELF(drv->chnl_softc);
        struct uisdata_softc *scbus = (struct uisdata_softc *)sc->bus;
        struct isd200_config *cf = &scbus->sc_isd_config;
        struct ata_bio *ata_bio = &xfer->c_bio;
@@ -302,12 +307,6 @@
                return ATACMD_COMPLETE;
        }
 
-       if (scbus->sc_ata_xfer != NULL) {
-               printf("%s: multiple uisdata_bio\n", __func__);
-               return ATACMD_TRY_AGAIN;
-       } else
-               scbus->sc_ata_xfer = xfer;
-
        if (ata_bio->flags & ATA_LBA) {
                sect = (ata_bio->blkno >> 0) & 0xff;
                cyl = (ata_bio->blkno >> 8) & 0xffff;
@@ -416,12 +415,13 @@
 }
 
 int
-uisdata_exec_command(struct ata_drive_datas *drv, struct ata_command *cmd)
+uisdata_exec_command(struct ata_drive_datas *drv, struct ata_xfer *xfer)
 {
-       struct umass_softc *sc = drv->chnl_softc;
+       struct umass_softc *sc = CH2SELF(drv->chnl_softc);
        struct uisdata_softc *scbus = (struct uisdata_softc *)sc->bus;
        struct isd200_config *cf = &scbus->sc_isd_config;
        int dir;
+       struct ata_command *cmd = &xfer->c_ata_c;
        struct ata_cmd ata;
 
        DPRINTF(("%s\n", __func__));
@@ -498,9 +498,10 @@
 void
 uisdata_kill_pending(struct ata_drive_datas *drv)
 {
-       struct umass_softc *sc = drv->chnl_softc;
+       struct ata_channel *chp = drv->chnl_softc;
+       struct umass_softc *sc = CH2SELF(chp);
        struct uisdata_softc *scbus = (struct uisdata_softc *)sc->bus;
-       struct ata_xfer *xfer = scbus->sc_ata_xfer;
+       struct ata_xfer *xfer = ata_queue_hwslot_to_xfer(chp->ch_queue, 0);
        struct ata_bio *ata_bio = &xfer->c_bio;
 
        DPRINTFN(-1,("%s\n", __func__));
@@ -508,7 +509,6 @@
        if (xfer == NULL)
                return;
 
-       scbus->sc_ata_xfer = NULL;
        ata_bio->flags |= ATA_ITSDONE;
        ata_bio->error = ERR_NODEV;
        ata_bio->r_error = WDCE_ABRT;
@@ -520,7 +520,8 @@
                struct ataparams *prms)
 {
        char tb[DEV_BSIZE];
-       struct ata_command ata_c;
+       struct ata_xfer xfer;
+       int rv;
 
 #if BYTE_ORDER == LITTLE_ENDIAN
        int i;
@@ -531,52 +532,61 @@
 
        memset(tb, 0, DEV_BSIZE);
        memset(prms, 0, sizeof(struct ataparams));
-       memset(&ata_c, 0, sizeof(struct ata_command));
+
+       ata_xfer_init(&xfer, true);
 
-       ata_c.r_command = WDCC_IDENTIFY;
-       ata_c.timeout = 1000; /* 1s */
-       ata_c.flags = AT_READ | flags;
-       ata_c.data = tb;
-       ata_c.bcount = DEV_BSIZE;
-       if (uisdata_exec_command(drvp, &ata_c) != ATACMD_COMPLETE) {
+       xfer.c_ata_c.r_command = WDCC_IDENTIFY;
+       xfer.c_ata_c.timeout = 1000; /* 1s */
+       xfer.c_ata_c.flags = AT_READ | flags;
+       xfer.c_ata_c.data = tb;
+       xfer.c_ata_c.bcount = DEV_BSIZE;
+       if (uisdata_exec_command(drvp, &xfer) != ATACMD_COMPLETE) {
                DPRINTF(("uisdata_get_parms: wdc_exec_command failed\n"));
-               return CMD_AGAIN;
+               rv = CMD_AGAIN;
+               goto out;
        }
-       if (ata_c.flags & (AT_ERROR | AT_TIMEOU | AT_DF)) {
+       if (xfer.c_ata_c.flags & (AT_ERROR | AT_TIMEOU | AT_DF)) {
                DPRINTF(("uisdata_get_parms: ata_c.flags=0x%x\n",
                         ata_c.flags));
-               return CMD_ERR;
-       } else {
-               /* Read in parameter block. */
-               memcpy(prms, tb, sizeof(struct ataparams));
+               rv = CMD_ERR;
+               goto out;
+       }
+
+       /* 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_CFA_MAGIC &&
-                   (prms->atap_config & 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);
-               }
+       /* XXX copied from ata.c */
+       /*
+        * Shuffle string byte order.
+        * ATAPI Mitsumi and NEC drives don't need this.
+        */
+       if (prms->atap_config != WDC_CFG_CFA_MAGIC &&
+           (prms->atap_config & WDC_CFG_ATAPI) &&
+           ((prms->atap_model[0] == 'N' &&
+               prms->atap_model[1] == 'E') ||
+            (prms->atap_model[0] == 'F' &&
+                prms->atap_model[1] == 'X'))) {
+               rv = 0;
+               goto out;
+       }
+       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;
-       }
+       rv = CMD_OK;
+
+out:
+       ata_xfer_destroy(&xfer);
+       return rv;
 }
 
 



Home | Main Index | Thread Index | Old Index