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;
 }
 
 

Reply via email to