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/c6bafe7ae799
branches: jdolecek-ncq
changeset: 352636:c6bafe7ae799
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 bbfa00d891cf -r c6bafe7ae799 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 bbfa00d891cf -r c6bafe7ae799 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 bbfa00d891cf -r c6bafe7ae799 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