Module Name: src Committed By: jdolecek Date: Thu Apr 20 20:14:42 UTC 2017
Modified Files: src/sys/dev/ata [jdolecek-ncq]: TODO.ncq atavar.h src/sys/dev/usb [jdolecek-ncq]: umass_isdata.c Log Message: 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 To generate a diff of this commit: cvs rdiff -u -r1.1.2.3 -r1.1.2.4 src/sys/dev/ata/TODO.ncq cvs rdiff -u -r1.92.8.6 -r1.92.8.7 src/sys/dev/ata/atavar.h cvs rdiff -u -r1.33.4.1 -r1.33.4.2 src/sys/dev/usb/umass_isdata.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/dev/ata/TODO.ncq diff -u src/sys/dev/ata/TODO.ncq:1.1.2.3 src/sys/dev/ata/TODO.ncq:1.1.2.4 --- src/sys/dev/ata/TODO.ncq:1.1.2.3 Wed Apr 19 22:02:32 2017 +++ src/sys/dev/ata/TODO.ncq Thu Apr 20 20:14:42 2017 @@ -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? Index: src/sys/dev/ata/atavar.h diff -u src/sys/dev/ata/atavar.h:1.92.8.6 src/sys/dev/ata/atavar.h:1.92.8.7 --- src/sys/dev/ata/atavar.h:1.92.8.6 Wed Apr 19 21:42:39 2017 +++ src/sys/dev/ata/atavar.h Thu Apr 20 20:14:42 2017 @@ -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 @@ struct ata_drive_datas { 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 */ Index: src/sys/dev/usb/umass_isdata.c diff -u src/sys/dev/usb/umass_isdata.c:1.33.4.1 src/sys/dev/usb/umass_isdata.c:1.33.4.2 --- src/sys/dev/usb/umass_isdata.c:1.33.4.1 Sat Apr 15 12:01:24 2017 +++ src/sys/dev/usb/umass_isdata.c Thu Apr 20 20:14:42 2017 @@ -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 uisdata_softc { 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_bio(struct ata_drive_datas 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 @@ umass_isdata_attach(struct umass_softc * 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 @@ uisdata_bio_cb(struct umass_softc *sc, v 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 @@ uisdata_bio_cb(struct umass_softc *sc, v 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 @@ uisdata_bio(struct ata_drive_datas *drv, 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 @@ uisdata_bio1(struct ata_drive_datas *drv 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 @@ uisdata_exec_cb(struct umass_softc *sc, } 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 @@ uisdata_delref(struct ata_drive_datas *d 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 @@ uisdata_kill_pending(struct ata_drive_da 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 @@ uisdata_get_params(struct ata_drive_data 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 @@ uisdata_get_params(struct ata_drive_data memset(tb, 0, DEV_BSIZE); memset(prms, 0, sizeof(struct ataparams)); - memset(&ata_c, 0, sizeof(struct ata_command)); - 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) { + ata_xfer_init(&xfer, true); + + 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); - } -#endif - return CMD_OK; + /* 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 + rv = CMD_OK; + +out: + ata_xfer_destroy(&xfer); + return rv; }