PERFORCE change 158381 for review

John Baldwin jhb at FreeBSD.org
Fri Feb 27 07:52:29 PST 2009


http://perforce.freebsd.org/chv.cgi?CH=158381

Change 158381 by jhb at jhb_jhbbsd on 2009/02/27 15:51:33

	More sync.

Affected files ...

.. //depot/projects/smpng/sys/dev/ata/ata-usb.c#9 integrate
.. //depot/projects/smpng/sys/dev/sound/usb/uaudio.c#21 integrate
.. //depot/projects/smpng/sys/dev/sound/usb/uaudio.h#7 integrate
.. //depot/projects/smpng/sys/dev/sound/usb/uaudio_pcm.c#18 integrate
.. //depot/projects/smpng/sys/dev/sound/usb/uaudioreg.h#5 integrate

Differences ...

==== //depot/projects/smpng/sys/dev/ata/ata-usb.c#9 (text) ====

@@ -2,6 +2,9 @@
  * Copyright (c) 2006 - 2008 Søren Schmidt <sos at FreeBSD.org>
  * All rights reserved.
  *
+ * Copyright (c) 2006 Hans Petter Selasky
+ * All rights reserved.
+ *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * are met:
@@ -25,945 +28,1074 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/dev/ata/ata-usb.c,v 1.10 2009/02/19 12:47:24 mav Exp $");
+__FBSDID("$FreeBSD: src/sys/dev/ata/ata-usb.c,v 1.12 2009/02/23 21:19:18 thompsa Exp $");
+
+#include "usbdevs.h"
+#include <dev/usb/usb.h>
+#include <dev/usb/usb_mfunc.h>
+#include <dev/usb/usb_error.h>
+
+#include <dev/usb/usb_core.h>
+#include <dev/usb/usb_util.h>
+#include <dev/usb/usb_busdma.h>
+#include <dev/usb/usb_request.h>
+#include <dev/usb/usb_debug.h>
+#include <dev/usb/usb_process.h>
+#include <dev/usb/usb_transfer.h>
 
-#include "opt_ata.h"
-#include <sys/param.h>
-#include <sys/conf.h>
-#include <sys/systm.h>
-#include <sys/kernel.h>
-#include <sys/mutex.h>
 #include <sys/ata.h>
-#include <sys/bus.h>
-#include <sys/endian.h>
-#include <sys/malloc.h>
-#include <sys/module.h>
+#include <sys/bio.h>
 #include <sys/sema.h>
 #include <sys/taskqueue.h>
 #include <vm/uma.h>
-#include <machine/resource.h>
-#include <machine/bus.h>
-#include <sys/rman.h>
-#include <dev/usb/usb_port.h>
-#include <dev/usb/usb.h>
-#include <dev/usb/usbdi.h>
-#include <dev/usb/usbdi_util.h>
-#include <dev/usb/usbdivar.h>
+
 #include <dev/ata/ata-all.h>
 #include <ata_if.h>
 
+#define	ATAUSB_BULK_SIZE (1<<17)
+
 /* Command Block Wrapper */
 struct bbb_cbw {
-    u_int8_t	signature[4];
-#define		CBWSIGNATURE		0x43425355
+	uint8_t	signature[4];
+#define	CBWSIGNATURE		0x43425355
 
-    u_int8_t	tag[4];
-    u_int8_t	transfer_length[4];
-    u_int8_t	flags;
-#define		CBWFLAGS_OUT  		0x00
-#define		CBWFLAGS_IN  		0x80
+	uint8_t	tag[4];
+	uint8_t	transfer_length[4];
+	uint8_t	flags;
+#define	CBWFLAGS_OUT  		0x00
+#define	CBWFLAGS_IN  		0x80
 
-    u_int8_t	lun;
-    u_int8_t	length;
-#define		CBWCDBLENGTH     	16
+	uint8_t	lun;
+	uint8_t	length;
+#define	CBWCDBLENGTH     	16
 
-    u_int8_t	cdb[CBWCDBLENGTH];
-};
+	uint8_t	cdb[CBWCDBLENGTH];
+} __packed;
 
 /* Command Status Wrapper */
 struct bbb_csw {
-    u_int8_t	signature[4];
-#define		CSWSIGNATURE     	0x53425355
+	uint8_t	signature[4];
+#define	CSWSIGNATURE     	0x53425355
 
-    u_int8_t	tag[4];
-    u_int8_t	residue[4];
-    u_int8_t    status;
-#define 	CSWSTATUS_GOOD   	0x0
-#define		CSWSTATUS_FAILED 	0x1
-#define		CSWSTATUS_PHASE  	0x2
-};
+	uint8_t	tag[4];
+	uint8_t	residue[4];
+	uint8_t	status;
+#define	CSWSTATUS_GOOD   	0x0
+#define	CSWSTATUS_FAILED 	0x1
+#define	CSWSTATUS_PHASE  	0x2
+} __packed;
 
 /* USB-ATA 'controller' softc */
-struct atausb_softc {
-    device_t		dev;		/* base device */
-    usbd_interface_handle iface;	/* interface */
-    int			ifaceno;	/* interface number */
-    u_int8_t		bulkin;		/* endpoint address's */
-    u_int8_t		bulkout;	
-    u_int8_t		bulkirq;	
-    usbd_pipe_handle	bulkin_pipe;	/* pipe handle's */
-    usbd_pipe_handle	bulkout_pipe;
-    usbd_pipe_handle	bulkirq_pipe;
-    int			maxlun;
-    int			timeout;
-    struct ata_request	*ata_request;
-    usb_device_request_t usb_request;
-    struct bbb_cbw	cbw;
-    struct bbb_csw	csw;
+struct atausb2_softc {
+	struct bbb_cbw cbw;
+	struct bbb_csw csw;
+	struct mtx locked_mtx;
+
+	struct ata_channel *locked_ch;
+	struct ata_channel *restart_ch;
+	struct ata_request *ata_request;
+
+#define	ATAUSB_T_BBB_RESET1        0
+#define	ATAUSB_T_BBB_RESET2        1
+#define	ATAUSB_T_BBB_RESET3        2
+#define	ATAUSB_T_BBB_COMMAND       3
+#define	ATAUSB_T_BBB_DATA_READ     4
+#define	ATAUSB_T_BBB_DATA_RD_CS    5
+#define	ATAUSB_T_BBB_DATA_WRITE    6
+#define	ATAUSB_T_BBB_DATA_WR_CS    7
+#define	ATAUSB_T_BBB_STATUS        8
+#define	ATAUSB_T_BBB_MAX           9
+
+#define	ATAUSB_T_MAX ATAUSB_T_BBB_MAX
 
-#define ATAUSB_T_BBB_CBW		0
-#define ATAUSB_T_BBB_DATA		1
-#define ATAUSB_T_BBB_DCLEAR		2
-#define ATAUSB_T_BBB_CSW1		3
-#define ATAUSB_T_BBB_CSW2		4
-#define ATAUSB_T_BBB_SCLEAR		5
-#define ATAUSB_T_BBB_RESET1		6
-#define ATAUSB_T_BBB_RESET2		7
-#define ATAUSB_T_BBB_RESET3		8
-#define ATAUSB_T_MAX			9
-    usbd_xfer_handle	transfer[ATAUSB_T_MAX];
+	struct usb2_xfer *xfer[ATAUSB_T_MAX];
+	caddr_t	ata_data;
+	device_t dev;
 
-    int			state;
-#define	ATAUSB_S_ATTACH			0
-#define	ATAUSB_S_IDLE			1
-#define	ATAUSB_S_BBB_COMMAND		2
-#define	ATAUSB_S_BBB_DATA		3
-#define	ATAUSB_S_BBB_DCLEAR		4
-#define	ATAUSB_S_BBB_STATUS1		5
-#define	ATAUSB_S_BBB_SCLEAR		6
-#define	ATAUSB_S_BBB_STATUS2		7
-#define	ATAUSB_S_BBB_RESET1		8
-#define	ATAUSB_S_BBB_RESET2		9
-#define	ATAUSB_S_BBB_RESET3		10
-#define	ATAUSB_S_DETACH			11
+	uint32_t timeout;
+	uint32_t ata_donecount;
+	uint32_t ata_bytecount;
 
-    struct mtx		locked_mtx;
-    struct ata_channel	*locked_ch;
-    struct ata_channel	*restart_ch;
+	uint8_t	last_xfer_no;
+	uint8_t	usb2_speed;
+	uint8_t	intr_stalled;
+	uint8_t	maxlun;
+	uint8_t	iface_no;
+	uint8_t	status_try;
 };
 
-static int atausbdebug = 0;
+static const int atausbdebug = 0;
+
+/* prototypes */
+
+static device_probe_t atausb2_probe;
+static device_attach_t atausb2_attach;
+static device_detach_t atausb2_detach;
+
+static usb2_callback_t atausb2_t_bbb_reset1_callback;
+static usb2_callback_t atausb2_t_bbb_reset2_callback;
+static usb2_callback_t atausb2_t_bbb_reset3_callback;
+static usb2_callback_t atausb2_t_bbb_command_callback;
+static usb2_callback_t atausb2_t_bbb_data_read_callback;
+static usb2_callback_t atausb2_t_bbb_data_rd_cs_callback;
+static usb2_callback_t atausb2_t_bbb_data_write_callback;
+static usb2_callback_t atausb2_t_bbb_data_wr_cs_callback;
+static usb2_callback_t atausb2_t_bbb_status_callback;
+static usb2_callback_t atausb2_tr_error;
+
+static void atausb2_cancel_request(struct atausb2_softc *sc);
+static void atausb2_transfer_start(struct atausb2_softc *sc, uint8_t xfer_no);
+static void atausb2_t_bbb_data_clear_stall_callback(struct usb2_xfer *xfer, uint8_t next_xfer, uint8_t stall_xfer);
+static int ata_usbchannel_begin_transaction(struct ata_request *request);
+static int ata_usbchannel_end_transaction(struct ata_request *request);
 
-/* prototypes*/
-static usbd_status atausb_start(struct atausb_softc *sc, usbd_pipe_handle pipe, void *buffer, int buflen, int flags, usbd_xfer_handle xfer);
-static usbd_status atausb_ctl_start(struct atausb_softc *sc, usbd_device_handle udev, usb_device_request_t *req, void *buffer, int buflen, int flags, usbd_xfer_handle xfer);
-static void atausb_clear_stall(struct atausb_softc *sc, u_int8_t endpt, usbd_pipe_handle pipe, int state, usbd_xfer_handle xfer);
-static void atausb_bbb_reset(struct atausb_softc *sc);
-static int atausb_bbb_start(struct ata_request *request);
-static void atausb_bbb_finish(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status err);
-int ata_usbchannel_begin_transaction(struct ata_request *request);
-int ata_usbchannel_end_transaction(struct ata_request *request);
+static device_probe_t ata_usbchannel_probe;
+static device_attach_t ata_usbchannel_attach;
+static device_detach_t ata_usbchannel_detach;
 
+static ata_setmode_t ata_usbchannel_setmode;
+static ata_locking_t ata_usbchannel_locking;
 
 /*
  * USB frontend part
  */
-USB_DECLARE_DRIVER(atausb);
-DRIVER_MODULE(atausb, uhub, atausb_driver, atausb_devclass, 0, 0);
+
+struct usb2_config atausb2_config[ATAUSB_T_BBB_MAX] = {
+
+	[ATAUSB_T_BBB_RESET1] = {
+		.type = UE_CONTROL,
+		.endpoint = 0x00,	/* Control pipe */
+		.direction = UE_DIR_ANY,
+		.mh.bufsize = sizeof(struct usb2_device_request),
+		.mh.flags = {},
+		.mh.callback = &atausb2_t_bbb_reset1_callback,
+		.mh.timeout = 5000,	/* 5 seconds */
+		.mh.interval = 500,	/* 500 milliseconds */
+	},
+
+	[ATAUSB_T_BBB_RESET2] = {
+		.type = UE_CONTROL,
+		.endpoint = 0x00,	/* Control pipe */
+		.direction = UE_DIR_ANY,
+		.mh.bufsize = sizeof(struct usb2_device_request),
+		.mh.flags = {},
+		.mh.callback = &atausb2_t_bbb_reset2_callback,
+		.mh.timeout = 5000,	/* 5 seconds */
+		.mh.interval = 50,	/* 50 milliseconds */
+	},
+
+	[ATAUSB_T_BBB_RESET3] = {
+		.type = UE_CONTROL,
+		.endpoint = 0x00,	/* Control pipe */
+		.direction = UE_DIR_ANY,
+		.mh.bufsize = sizeof(struct usb2_device_request),
+		.mh.flags = {},
+		.mh.callback = &atausb2_t_bbb_reset3_callback,
+		.mh.timeout = 5000,	/* 5 seconds */
+		.mh.interval = 50,	/* 50 milliseconds */
+	},
+
+	[ATAUSB_T_BBB_COMMAND] = {
+		.type = UE_BULK,
+		.endpoint = UE_ADDR_ANY,
+		.direction = UE_DIR_OUT,
+		.mh.bufsize = sizeof(struct bbb_cbw),
+		.mh.flags = {},
+		.mh.callback = &atausb2_t_bbb_command_callback,
+		.mh.timeout = 5000,	/* 5 seconds */
+	},
+
+	[ATAUSB_T_BBB_DATA_READ] = {
+		.type = UE_BULK,
+		.endpoint = UE_ADDR_ANY,
+		.direction = UE_DIR_IN,
+		.mh.bufsize = ATAUSB_BULK_SIZE,
+		.mh.flags = {.proxy_buffer = 1,.short_xfer_ok = 1,},
+		.mh.callback = &atausb2_t_bbb_data_read_callback,
+		.mh.timeout = 0,	/* overwritten later */
+	},
+
+	[ATAUSB_T_BBB_DATA_RD_CS] = {
+		.type = UE_CONTROL,
+		.endpoint = 0x00,	/* Control pipe */
+		.direction = UE_DIR_ANY,
+		.mh.bufsize = sizeof(struct usb2_device_request),
+		.mh.flags = {},
+		.mh.callback = &atausb2_t_bbb_data_rd_cs_callback,
+		.mh.timeout = 5000,	/* 5 seconds */
+	},
+
+	[ATAUSB_T_BBB_DATA_WRITE] = {
+		.type = UE_BULK,
+		.endpoint = UE_ADDR_ANY,
+		.direction = UE_DIR_OUT,
+		.mh.bufsize = ATAUSB_BULK_SIZE,
+		.mh.flags = {.proxy_buffer = 1,.short_xfer_ok = 1,},
+		.mh.callback = &atausb2_t_bbb_data_write_callback,
+		.mh.timeout = 0,	/* overwritten later */
+	},
+
+	[ATAUSB_T_BBB_DATA_WR_CS] = {
+		.type = UE_CONTROL,
+		.endpoint = 0x00,	/* Control pipe */
+		.direction = UE_DIR_ANY,
+		.mh.bufsize = sizeof(struct usb2_device_request),
+		.mh.flags = {},
+		.mh.callback = &atausb2_t_bbb_data_wr_cs_callback,
+		.mh.timeout = 5000,	/* 5 seconds */
+	},
+
+	[ATAUSB_T_BBB_STATUS] = {
+		.type = UE_BULK,
+		.endpoint = UE_ADDR_ANY,
+		.direction = UE_DIR_IN,
+		.mh.bufsize = sizeof(struct bbb_csw),
+		.mh.flags = {.short_xfer_ok = 1,},
+		.mh.callback = &atausb2_t_bbb_status_callback,
+		.mh.timeout = 5000,	/* ms */
+	},
+};
+
+static devclass_t atausb2_devclass;
+
+static device_method_t atausb2_methods[] = {
+	DEVMETHOD(device_probe, atausb2_probe),
+	DEVMETHOD(device_attach, atausb2_attach),
+	DEVMETHOD(device_detach, atausb2_detach),
+	{0, 0}
+};
+
+static driver_t atausb2_driver = {
+	.name = "atausb",
+	.methods = atausb2_methods,
+	.size = sizeof(struct atausb2_softc),
+};
+
+DRIVER_MODULE(atausb, ushub, atausb2_driver, atausb2_devclass, 0, 0);
+MODULE_DEPEND(atausb, usb, 1, 1, 1);
 MODULE_VERSION(atausb, 1);
 
 static int
-atausb_match(device_t dev)
+atausb2_probe(device_t dev)
 {
-    struct usb_attach_arg *uaa = device_get_ivars(dev);
-    usb_interface_descriptor_t *id;
+	struct usb2_attach_arg *uaa = device_get_ivars(dev);
+	struct usb2_interface_descriptor *id;
 
-    if (uaa->iface == NULL)
-	return UMATCH_NONE;
-
-    id = usbd_get_interface_descriptor(uaa->iface);
-    if (!id || id->bInterfaceClass != UICLASS_MASS)
-	return UMATCH_NONE;
-
-    switch (id->bInterfaceSubClass) {
-    case UISUBCLASS_QIC157:
-    case UISUBCLASS_RBC:
-    case UISUBCLASS_SCSI:
-    case UISUBCLASS_SFF8020I:
-    case UISUBCLASS_SFF8070I:
-    case UISUBCLASS_UFI:
-	switch (id->bInterfaceProtocol) {
-	case UIPROTO_MASS_CBI:
-	case UIPROTO_MASS_CBI_I:
-	case UIPROTO_MASS_BBB:
-	case UIPROTO_MASS_BBB_OLD:
-	    return UMATCH_IFACECLASS_IFACESUBCLASS_IFACEPROTO;
+	if (uaa->usb2_mode != USB_MODE_HOST) {
+		return (ENXIO);
+	}
+	if (uaa->use_generic == 0) {
+		/* give other drivers a try first */
+		return (ENXIO);
+	}
+	id = usb2_get_interface_descriptor(uaa->iface);
+	if ((!id) || (id->bInterfaceClass != UICLASS_MASS)) {
+		return (ENXIO);
+	}
+	switch (id->bInterfaceSubClass) {
+	case UISUBCLASS_QIC157:
+	case UISUBCLASS_RBC:
+	case UISUBCLASS_SCSI:
+	case UISUBCLASS_SFF8020I:
+	case UISUBCLASS_SFF8070I:
+	case UISUBCLASS_UFI:
+		switch (id->bInterfaceProtocol) {
+		case UIPROTO_MASS_CBI:
+		case UIPROTO_MASS_CBI_I:
+		case UIPROTO_MASS_BBB:
+		case UIPROTO_MASS_BBB_OLD:
+			return (0);
+		default:
+			return (0);
+		}
+		break;
 	default:
-	    return UMATCH_IFACECLASS_IFACESUBCLASS;
+		return (0);
 	}
-	break;
-    default:
-	return UMATCH_IFACECLASS;
-    }
 }
 
 static int
-atausb_attach(device_t dev)
+atausb2_attach(device_t dev)
 {
-    struct atausb_softc *sc = device_get_softc(dev);
-    struct usb_attach_arg *uaa = device_get_ivars(dev);
-    usb_interface_descriptor_t *id;
-    usb_endpoint_descriptor_t *ed;
-    usbd_device_handle udev;
-    usb_device_request_t request;
-    device_t child;
-    char devinfo[1024], *proto, *subclass;
-    u_int8_t maxlun;
-    int err, i;
+	struct atausb2_softc *sc = device_get_softc(dev);
+	struct usb2_attach_arg *uaa = device_get_ivars(dev);
+	struct usb2_interface_descriptor *id;
+	const char *proto, *subclass;
+	struct usb2_device_request request;
+	uint16_t i;
+	uint8_t maxlun;
+	uint8_t has_intr;
+	int err;
 
-    sc->dev = dev;
-    usbd_devinfo(uaa->device, 0, devinfo);
-    device_set_desc_copy(dev, devinfo);
-    sc->bulkin = sc->bulkout = sc->bulkirq = -1;
-    sc->bulkin_pipe = sc->bulkout_pipe= sc->bulkirq_pipe = NULL;
-    sc->iface = uaa->iface;
-    sc->ifaceno = uaa->ifaceno;
-    sc->maxlun = 0;
-    sc->timeout = 5000;
-    sc->locked_ch = NULL;
-    sc->restart_ch = NULL;
-    mtx_init(&sc->locked_mtx, "ATAUSB lock", NULL, MTX_DEF); 
+	device_set_usb2_desc(dev);
 
-    id = usbd_get_interface_descriptor(sc->iface);
-    switch (id->bInterfaceProtocol) {
-    case UIPROTO_MASS_BBB:
-    case UIPROTO_MASS_BBB_OLD:
-	    proto = "Bulk-Only";
-	    break;
-    case UIPROTO_MASS_CBI:
-	    proto = "CBI";
-	    break;
-    case UIPROTO_MASS_CBI_I:
-	    proto = "CBI with CCI";
-	    break;
-    default:
-	    proto = "Unknown";
-    }
-    switch (id->bInterfaceSubClass) {
-    case UISUBCLASS_RBC:
-	    subclass = "RBC";
-	    break;
-    case UISUBCLASS_QIC157:
-    case UISUBCLASS_SFF8020I:
-    case UISUBCLASS_SFF8070I:
-	    subclass = "ATAPI";
-	    break;
-    case UISUBCLASS_SCSI:
-	    subclass = "SCSI";
-	    break;
-    case UISUBCLASS_UFI:
-	    subclass = "UFI";
-	    break;
-    default:
-	    subclass = "Unknown";
-    }
-    device_printf(dev, "using %s over %s\n", subclass, proto);
-    if (strcmp(proto, "Bulk-Only") ||
-	(strcmp(subclass, "ATAPI") && strcmp(subclass, "SCSI")))
-	return ENXIO;
+	sc->dev = dev;
+	sc->maxlun = 0;
+	sc->locked_ch = NULL;
+	sc->restart_ch = NULL;
+	sc->usb2_speed = usb2_get_speed(uaa->device);
+	mtx_init(&sc->locked_mtx, "ATAUSB lock", NULL, (MTX_DEF | MTX_RECURSE));
 
-    for (i = 0 ; i < id->bNumEndpoints ; i++) {
-	if (!(ed = usbd_interface2endpoint_descriptor(sc->iface, i))) {
-	    device_printf(sc->dev, "could not read endpoint descriptor\n");
-	    return ENXIO;
+	id = usb2_get_interface_descriptor(uaa->iface);
+	switch (id->bInterfaceProtocol) {
+	case UIPROTO_MASS_BBB:
+	case UIPROTO_MASS_BBB_OLD:
+		proto = "Bulk-Only";
+		break;
+	case UIPROTO_MASS_CBI:
+		proto = "CBI";
+		break;
+	case UIPROTO_MASS_CBI_I:
+		proto = "CBI with CCI";
+		break;
+	default:
+		proto = "Unknown";
 	}
-	if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
-	    (ed->bmAttributes & UE_XFERTYPE) == UE_BULK) {
-	    sc->bulkin = ed->bEndpointAddress;
+
+	switch (id->bInterfaceSubClass) {
+	case UISUBCLASS_RBC:
+		subclass = "RBC";
+		break;
+	case UISUBCLASS_QIC157:
+	case UISUBCLASS_SFF8020I:
+	case UISUBCLASS_SFF8070I:
+		subclass = "ATAPI";
+		break;
+	case UISUBCLASS_SCSI:
+		subclass = "SCSI";
+		break;
+	case UISUBCLASS_UFI:
+		subclass = "UFI";
+		break;
+	default:
+		subclass = "Unknown";
 	}
-	if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT &&
-	           (ed->bmAttributes & UE_XFERTYPE) == UE_BULK) {
-	    sc->bulkout = ed->bEndpointAddress;
+
+	has_intr = (id->bInterfaceProtocol == UIPROTO_MASS_CBI_I);
+	sc->iface_no = id->bInterfaceNumber;
+
+	device_printf(dev, "using %s over %s\n", subclass, proto);
+	if (strcmp(proto, "Bulk-Only") ||
+	    (strcmp(subclass, "ATAPI") && strcmp(subclass, "SCSI"))) {
+		goto detach;
 	}
-	if (id->bInterfaceProtocol == UIPROTO_MASS_CBI_I &&
-	           UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
-	           (ed->bmAttributes & UE_XFERTYPE) == UE_INTERRUPT) {
-	    sc->bulkirq = ed->bEndpointAddress;
-	}
-    }
+	err = usb2_transfer_setup(uaa->device, &uaa->info.bIfaceIndex,
+	    sc->xfer, atausb2_config, ATAUSB_T_BBB_MAX, sc,
+	    &sc->locked_mtx);
 
-    /* check whether we found at least the endpoints we need */
-    if (!sc->bulkin || !sc->bulkout) {
-	device_printf(sc->dev, "needed endpoints not found (%d,%d)\n",
-		      sc->bulkin, sc->bulkout);
-	atausb_detach(dev);
-	return ENXIO;
-    }
+	/* skip reset first time */
+	sc->last_xfer_no = ATAUSB_T_BBB_COMMAND;
 
-    /* open the pipes */
-    if (usbd_open_pipe(sc->iface, sc->bulkout,
-		       USBD_EXCLUSIVE_USE, &sc->bulkout_pipe)) {
-	device_printf(sc->dev, "cannot open bulkout pipe (%d)\n", sc->bulkout);
-	atausb_detach(dev);
-	return ENXIO;
-    }
-    if (usbd_open_pipe(sc->iface, sc->bulkin,
-		       USBD_EXCLUSIVE_USE, &sc->bulkin_pipe)) {
-	device_printf(sc->dev, "cannot open bulkin pipe (%d)\n", sc->bulkin);
-	atausb_detach(dev);
-	return ENXIO;
-    }
-    if (id->bInterfaceProtocol == UIPROTO_MASS_CBI_I) {
-	if (usbd_open_pipe(sc->iface, sc->bulkirq,
-			   USBD_EXCLUSIVE_USE, &sc->bulkirq_pipe)) {
-	    device_printf(sc->dev, "cannot open bulkirq pipe (%d)\n",
-	    		  sc->bulkirq);
-	    atausb_detach(dev);
-	    return ENXIO;
+	if (err) {
+		device_printf(sc->dev, "could not setup required "
+		    "transfers, %s\n", usb2_errstr(err));
+		goto detach;
 	}
-    }
-    sc->state = ATAUSB_S_ATTACH;
+	/* get number of devices so we can add matching channels */
+	request.bmRequestType = UT_READ_CLASS_INTERFACE;
+	request.bRequest = 0xfe;	/* GET_MAX_LUN; */
+	USETW(request.wValue, 0);
+	USETW(request.wIndex, sc->iface_no);
+	USETW(request.wLength, sizeof(maxlun));
+	err = usb2_do_request(uaa->device, &Giant, &request, &maxlun);
 
-    /* alloc needed number of transfer handles */
-    for (i = 0; i < ATAUSB_T_MAX; i++) {
-	sc->transfer[i] = usbd_alloc_xfer(uaa->device);
-	if (!sc->transfer[i]) {
-	    device_printf(sc->dev, "out of memory\n");
-	    atausb_detach(dev);
-	    return ENXIO;
+	if (err) {
+		if (bootverbose) {
+			device_printf(sc->dev, "get maxlun not supported %s\n",
+			    usb2_errstr(err));
+		}
+	} else {
+		sc->maxlun = maxlun;
+		if (bootverbose) {
+			device_printf(sc->dev, "maxlun=%d\n", sc->maxlun);
+		}
 	}
-    }
 
-    /* driver is ready to process requests here */
-    sc->state = ATAUSB_S_IDLE;
+	/* ata channels are children to this USB control device */
+	for (i = 0; i <= sc->maxlun; i++) {
+		if (!device_add_child(sc->dev, "ata",
+		    devclass_find_free_unit(ata_devclass, 2))) {
+			device_printf(sc->dev, "failed to attach ata child device\n");
+			goto detach;
+		}
+	}
+	bus_generic_attach(sc->dev);
 
-    /* get number of devices so we can add matching channels */
-    usbd_interface2device_handle(sc->iface, &udev);
-    request.bmRequestType = UT_READ_CLASS_INTERFACE;
-    request.bRequest = 0xfe; //GET_MAX_LUN;
-    USETW(request.wValue, 0);
-    USETW(request.wIndex, sc->ifaceno);
-    USETW(request.wLength, sizeof(maxlun));
-    switch ((err = usbd_do_request(udev, &request, &maxlun))) {
-    case USBD_NORMAL_COMPLETION:
-	if (bootverbose)
-	    device_printf(sc->dev, "maxlun=%d\n", maxlun);
-	sc->maxlun = maxlun;
-	break;
-    default:
-	if (bootverbose)
-	    device_printf(sc->dev, "get maxlun not supported %s\n",
-	usbd_errstr(err));
-    }
+	return (0);
 
-    /* ata channels are children to this USB control device */
-    for (i = 0; i <= sc->maxlun; i++) {
-	if ((child = device_add_child(sc->dev, "ata",
-		devclass_find_free_unit(ata_devclass, 2))) == NULL) {
-	    device_printf(sc->dev, "failed to add ata child device\n");
-	} else
-	    device_set_ivars(child, (void *)(intptr_t)i);
-    }
-    bus_generic_attach(sc->dev);
-    return 0;
+detach:
+	atausb2_detach(dev);
+	return (ENXIO);
 }
 
 static int
-atausb_detach(device_t dev)
+atausb2_detach(device_t dev)
+{
+	struct atausb2_softc *sc = device_get_softc(dev);
+	device_t *children;
+	int nchildren, i;
+
+	/* teardown our statemachine */
+
+	usb2_transfer_unsetup(sc->xfer, ATAUSB_T_MAX);
+
+	/* detach & delete all children, if any */
+
+	if (!device_get_children(dev, &children, &nchildren)) {
+		for (i = 0; i < nchildren; i++) {
+			device_delete_child(dev, children[i]);
+		}
+		free(children, M_TEMP);
+	}
+	mtx_destroy(&sc->locked_mtx);
+	return (0);
+}
+
+static void
+atausb2_transfer_start(struct atausb2_softc *sc, uint8_t xfer_no)
+{
+	if (atausbdebug) {
+		device_printf(sc->dev, "BBB transfer %d\n", xfer_no);
+	}
+	if (sc->xfer[xfer_no]) {
+		sc->last_xfer_no = xfer_no;
+		usb2_transfer_start(sc->xfer[xfer_no]);
+	} else {
+		atausb2_cancel_request(sc);
+	}
+}
+
+static void
+atausb2_t_bbb_reset1_callback(struct usb2_xfer *xfer)
 {
-    struct atausb_softc *sc = device_get_softc(dev);
-    usbd_device_handle udev;
-    device_t *children;
-    int nchildren, i;
+	struct atausb2_softc *sc = xfer->priv_sc;
+	struct usb2_device_request req;
+
+	switch (USB_GET_STATE(xfer)) {
+	case USB_ST_TRANSFERRED:
+		atausb2_transfer_start(sc, ATAUSB_T_BBB_RESET2);
+		return;
 
-    /* signal that device is going away */
-    sc->state = ATAUSB_S_DETACH;
+	case USB_ST_SETUP:
+		req.bmRequestType = UT_WRITE_CLASS_INTERFACE;
+		req.bRequest = 0xff;	/* bulk-only reset */
+		USETW(req.wValue, 0);
+		req.wIndex[0] = sc->iface_no;
+		req.wIndex[1] = 0;
+		USETW(req.wLength, 0);
 
-    /* abort all the pipes in case there are active transfers */
-    usbd_interface2device_handle(sc->iface, &udev);
-    usbd_abort_default_pipe(udev);
-    if (sc->bulkout_pipe)
-        usbd_abort_pipe(sc->bulkout_pipe);
-    if (sc->bulkin_pipe)
-        usbd_abort_pipe(sc->bulkin_pipe);
-    if (sc->bulkirq_pipe)
-        usbd_abort_pipe(sc->bulkirq_pipe);
+		usb2_copy_in(xfer->frbuffers, 0, &req, sizeof(req));
 
-    /* detach & delete all children */
-    if (!device_get_children(dev, &children, &nchildren)) {
-        for (i = 0; i < nchildren; i++)
-            device_delete_child(dev, children[i]);
-        free(children, M_TEMP);
-    }
+		xfer->frlengths[0] = sizeof(req);
+		xfer->nframes = 1;
+		usb2_start_hardware(xfer);
+		return;
 
-    /* free the transfers */
-    for (i = 0; i < ATAUSB_T_MAX; i++)
-	if (sc->transfer[i])
-	    usbd_free_xfer(sc->transfer[i]);
+	default:			/* Error */
+		atausb2_tr_error(xfer);
+		return;
 
-    /* remove all the pipes */
-    if (sc->bulkout_pipe)
-        usbd_close_pipe(sc->bulkout_pipe);
-    if (sc->bulkin_pipe)
-        usbd_close_pipe(sc->bulkin_pipe);
-    if (sc->bulkirq_pipe)
-        usbd_close_pipe(sc->bulkirq_pipe);
+	}
+}
 
-    mtx_destroy(&sc->locked_mtx);
-    return 0;
+static void
+atausb2_t_bbb_reset2_callback(struct usb2_xfer *xfer)
+{
+	atausb2_t_bbb_data_clear_stall_callback(xfer, ATAUSB_T_BBB_RESET3,
+	    ATAUSB_T_BBB_DATA_READ);
 }
 
+static void
+atausb2_t_bbb_reset3_callback(struct usb2_xfer *xfer)
+{
+	atausb2_t_bbb_data_clear_stall_callback(xfer, ATAUSB_T_BBB_COMMAND,
+	    ATAUSB_T_BBB_DATA_WRITE);
+}
 
-/*
- * Generic USB transfer routines 
- */
-static usbd_status
-atausb_start(struct atausb_softc *sc, usbd_pipe_handle pipe,
-	     void *buffer, int buflen, int flags, usbd_xfer_handle xfer)
+static void
+atausb2_t_bbb_data_clear_stall_callback(struct usb2_xfer *xfer,
+    uint8_t next_xfer,
+    uint8_t stall_xfer)
 {
-    usbd_status err;
+	struct atausb2_softc *sc = xfer->priv_sc;
+
+	switch (USB_GET_STATE(xfer)) {
+	case USB_ST_TRANSFERRED:
+tr_transferred:
+		atausb2_transfer_start(sc, next_xfer);
+		return;
+
+	case USB_ST_SETUP:
+		if (usb2_clear_stall_callback(xfer, sc->xfer[stall_xfer])) {
+			goto tr_transferred;
+		}
+		return;
 
-    if (sc->state == ATAUSB_S_DETACH)
-	return USBD_NOT_STARTED;
+	default:			/* Error */
+		atausb2_tr_error(xfer);
+		return;
 
-    usbd_setup_xfer(xfer, pipe, (void *)sc, buffer, buflen, flags,
-		    sc->timeout, atausb_bbb_finish);
-    err = usbd_transfer(xfer);
-    if (err && (err != USBD_IN_PROGRESS)) {
-	if (atausbdebug)
-	    device_printf(sc->dev, "failed to setup transfer, %s\n",
-		          usbd_errstr(err));
-	return err;
-    }
-    return USBD_NORMAL_COMPLETION;
+	}
 }
 
-static usbd_status
-atausb_ctl_start(struct atausb_softc *sc, usbd_device_handle udev,
-	 	 usb_device_request_t *req, void *buffer, int buflen, int flags,
- 		 usbd_xfer_handle xfer)
+static void
+atausb2_t_bbb_command_callback(struct usb2_xfer *xfer)
 {
-    usbd_status err;
+	struct atausb2_softc *sc = xfer->priv_sc;
+	struct ata_request *request = sc->ata_request;
+	struct ata_channel *ch;
+	uint32_t tag;
+
+	switch (USB_GET_STATE(xfer)) {
+	case USB_ST_TRANSFERRED:
+		atausb2_transfer_start
+		    (sc, ((request->flags & ATA_R_READ) ? ATAUSB_T_BBB_DATA_READ :
+		    (request->flags & ATA_R_WRITE) ? ATAUSB_T_BBB_DATA_WRITE :
+		    ATAUSB_T_BBB_STATUS));
+		return;
+
+	case USB_ST_SETUP:
+
+		sc->status_try = 0;
+
+		if (request) {
+			ch = device_get_softc(request->parent);
+
+			sc->timeout = (request->timeout * 1000) + 5000;
+
+			tag = UGETDW(sc->cbw.tag) + 1;
+
+			USETDW(sc->cbw.signature, CBWSIGNATURE);
+			USETDW(sc->cbw.tag, tag);
+			USETDW(sc->cbw.transfer_length, request->bytecount);
+			sc->cbw.flags = (request->flags & ATA_R_READ) ? CBWFLAGS_IN : CBWFLAGS_OUT;
+			sc->cbw.lun = ch->unit;
+			sc->cbw.length = 16;
+			bzero(sc->cbw.cdb, 16);
+			bcopy(request->u.atapi.ccb, sc->cbw.cdb, 12);	/* XXX SOS */
+
+			usb2_copy_in(xfer->frbuffers, 0, &sc->cbw, sizeof(sc->cbw));
+
+			xfer->frlengths[0] = sizeof(sc->cbw);
+			usb2_start_hardware(xfer);
+		}
+		return;
 
-    if (sc->state == ATAUSB_S_DETACH)
-	return USBD_NOT_STARTED;
+	default:			/* Error */
+		atausb2_tr_error(xfer);
+		return;
 
-    usbd_setup_default_xfer(xfer, udev, (void *)sc, sc->timeout, req,
-   			    buffer, buflen, flags, atausb_bbb_finish);
-    err = usbd_transfer(xfer);
-    if (err && (err != USBD_IN_PROGRESS)) {
-	if (atausbdebug)
-	    device_printf(sc->dev, "failed to setup ctl transfer, %s\n",
-	                  usbd_errstr(err));
-	return err;
-    }
-    return USBD_NORMAL_COMPLETION;
+	}
 }
 
 static void
-atausb_clear_stall(struct atausb_softc *sc, u_int8_t endpt,
-		   usbd_pipe_handle pipe, int state, usbd_xfer_handle xfer)
+atausb2_t_bbb_data_read_callback(struct usb2_xfer *xfer)
 {
-    usbd_device_handle udev;
+	struct atausb2_softc *sc = xfer->priv_sc;
+	uint32_t max_bulk = xfer->max_data_length;
+
+	switch (USB_GET_STATE(xfer)) {
+	case USB_ST_TRANSFERRED:
+
+		usb2_copy_out(xfer->frbuffers, 0,
+		    sc->ata_data, xfer->actlen);
+
+		sc->ata_bytecount -= xfer->actlen;
+		sc->ata_data += xfer->actlen;
+		sc->ata_donecount += xfer->actlen;
+
+		if (xfer->actlen < xfer->sumlen) {
+			/* short transfer */
+			sc->ata_bytecount = 0;
+		}
+	case USB_ST_SETUP:
+
+		if (atausbdebug > 1) {
+			device_printf(sc->dev, "%s: max_bulk=%d, ata_bytecount=%d\n",
+			    __FUNCTION__, max_bulk, sc->ata_bytecount);
+		}
+		if (sc->ata_bytecount == 0) {
+			atausb2_transfer_start(sc, ATAUSB_T_BBB_STATUS);
+			return;
+		}
+		if (max_bulk > sc->ata_bytecount) {
+			max_bulk = sc->ata_bytecount;
+		}
+		xfer->timeout = sc->timeout;
+		xfer->frlengths[0] = max_bulk;
+
+		usb2_start_hardware(xfer);
+		return;
+
+	default:			/* Error */
+		if (xfer->error == USB_ERR_CANCELLED) {
+			atausb2_tr_error(xfer);
+		} else {
+			atausb2_transfer_start(sc, ATAUSB_T_BBB_DATA_RD_CS);
+		}
+		return;
 
-    if (atausbdebug)
-	device_printf(sc->dev, "clear endpoint 0x%02x stall\n", endpt);
-    usbd_interface2device_handle(sc->iface, &udev);
-    sc->state = state;
-    usbd_clear_endpoint_toggle(pipe);
-    sc->usb_request.bmRequestType = UT_WRITE_ENDPOINT;
-    sc->usb_request.bRequest = UR_CLEAR_FEATURE;
-    USETW(sc->usb_request.wValue, UF_ENDPOINT_HALT);
-    USETW(sc->usb_request.wIndex, endpt);
-    USETW(sc->usb_request.wLength, 0);
-    atausb_ctl_start(sc, udev, &sc->usb_request, NULL, 0, 0, xfer);
+	}
 }
 
+static void
+atausb2_t_bbb_data_rd_cs_callback(struct usb2_xfer *xfer)
+{
+	atausb2_t_bbb_data_clear_stall_callback(xfer, ATAUSB_T_BBB_STATUS,
+	    ATAUSB_T_BBB_DATA_READ);
+}
 
-/*
- * Bulk-Only transport part

>>> TRUNCATED FOR MAIL (1000 lines) <<<


More information about the p4-projects mailing list