PERFORCE change 165544 for review

Andre Oppermann andre at FreeBSD.org
Thu Jul 2 14:56:55 UTC 2009


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

Change 165544 by andre at andre_flirtbox on 2009/07/02 14:56:13

	Integrate some more stuff was missing before.
	
	There seems to be a problem with integrations after the cvs->svn
	switchover.  Especially when files are moved or overwritten.  It
	seems to be an artefact of the svn->svc->p4 exporter chain (?).

Affected files ...

.. //depot/projects/tcp_new/modules/Makefile#4 edit
.. //depot/projects/tcp_reass/dev/ata/ata-usb.c#3 integrate
.. //depot/projects/tcp_reass/dev/sbni/if_sbni.c#2 integrate
.. //depot/projects/tcp_reass/dev/sbni/if_sbni_isa.c#2 integrate
.. //depot/projects/tcp_reass/dev/sbni/if_sbni_pci.c#2 integrate
.. //depot/projects/tcp_reass/dev/sbni/if_sbnireg.h#2 integrate
.. //depot/projects/tcp_reass/dev/sbni/if_sbnivar.h#2 integrate
.. //depot/projects/tcp_reass/dev/sound/usb/uaudio.c#2 integrate
.. //depot/projects/tcp_reass/dev/sound/usb/uaudio.h#2 integrate
.. //depot/projects/tcp_reass/dev/sound/usb/uaudio_pcm.c#2 integrate
.. //depot/projects/tcp_reass/dev/sound/usb/uaudioreg.h#2 integrate
.. //depot/projects/tcp_reass/dev/usb/usb.h#2 integrate
.. //depot/projects/tcp_reass/dev/usb/usb_if.m#2 integrate
.. //depot/projects/tcp_reass/dev/usb/usbdevs#4 integrate
.. //depot/projects/tcp_reass/dev/usb/usbhid.h#2 integrate
.. //depot/projects/tcp_reass/kern/vfs_subr.c#7 integrate
.. //depot/projects/tcp_reass/modules/sbni/Makefile#2 integrate
.. //depot/projects/tcp_reass/modules/usb/Makefile#2 integrate
.. //depot/projects/tcp_reass/netgraph/bluetooth/drivers/ubt/ng_ubt.c#3 integrate
.. //depot/projects/tcp_reass/netgraph/bluetooth/drivers/ubt/ng_ubt_var.h#3 integrate
.. //depot/projects/tcp_reass/netgraph/bluetooth/drivers/ubtbcmfw/ubtbcmfw.c#3 integrate
.. //depot/projects/tcp_reass/netinet/tcp_reass.c#27 edit

Differences ...

==== //depot/projects/tcp_new/modules/Makefile#4 (text+ko) ====

@@ -218,7 +218,6 @@
 	rc \
 	rc4 \
 	re \
-	reiserfs \
 	rl \
 	rp \
 	rue \

==== //depot/projects/tcp_reass/dev/ata/ata-usb.c#3 (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,950 +28,1099 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/dev/ata/ata-usb.c,v 1.8 2008/04/10 13:05:05 sos Exp $");
+__FBSDID("$FreeBSD: src/sys/dev/ata/ata-usb.c,v 1.20 2009/06/23 02:19:59 thompsa Exp $");
 
-#include "opt_ata.h"
+#include <sys/stdint.h>
+#include <sys/stddef.h>
 #include <sys/param.h>
-#include <sys/conf.h>
+#include <sys/queue.h>
+#include <sys/types.h>
 #include <sys/systm.h>
 #include <sys/kernel.h>
+#include <sys/bus.h>
+#include <sys/linker_set.h>
+#include <sys/module.h>
+#include <sys/lock.h>
 #include <sys/mutex.h>
+#include <sys/condvar.h>
+#include <sys/sysctl.h>
+#include <sys/sx.h>
+#include <sys/unistd.h>
+#include <sys/callout.h>
+#include <sys/malloc.h>
+#include <sys/priv.h>
+#include <machine/bus.h>
+
+#include "usbdevs.h"
+#include <dev/usb/usb.h>
+#include <dev/usb/usbdi.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 usb_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 usb_callback_t atausb2_t_bbb_reset1_callback;
+static usb_callback_t atausb2_t_bbb_reset2_callback;
+static usb_callback_t atausb2_t_bbb_reset3_callback;
+static usb_callback_t atausb2_t_bbb_command_callback;
+static usb_callback_t atausb2_t_bbb_data_read_callback;
+static usb_callback_t atausb2_t_bbb_data_rd_cs_callback;
+static usb_callback_t atausb2_t_bbb_data_write_callback;
+static usb_callback_t atausb2_t_bbb_data_wr_cs_callback;
+static usb_callback_t atausb2_t_bbb_status_callback;
+static usb_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 usb_xfer *xfer,
+	    uint8_t next_xfer, uint8_t stall_xfer, usb_error_t error);
+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 usb_config atausb2_config[ATAUSB_T_BBB_MAX] = {
+
+	[ATAUSB_T_BBB_RESET1] = {
+		.type = UE_CONTROL,
+		.endpoint = 0x00,	/* Control pipe */
+		.direction = UE_DIR_ANY,
+		.bufsize = sizeof(struct usb_device_request),
+		.flags = {},
+		.callback = &atausb2_t_bbb_reset1_callback,
+		.timeout = 5000,	/* 5 seconds */
+		.interval = 500,	/* 500 milliseconds */
+	},
+
+	[ATAUSB_T_BBB_RESET2] = {
+		.type = UE_CONTROL,
+		.endpoint = 0x00,	/* Control pipe */
+		.direction = UE_DIR_ANY,
+		.bufsize = sizeof(struct usb_device_request),
+		.flags = {},
+		.callback = &atausb2_t_bbb_reset2_callback,
+		.timeout = 5000,	/* 5 seconds */
+		.interval = 50,	/* 50 milliseconds */
+	},
+
+	[ATAUSB_T_BBB_RESET3] = {
+		.type = UE_CONTROL,
+		.endpoint = 0x00,	/* Control pipe */
+		.direction = UE_DIR_ANY,
+		.bufsize = sizeof(struct usb_device_request),
+		.flags = {},
+		.callback = &atausb2_t_bbb_reset3_callback,
+		.timeout = 5000,	/* 5 seconds */
+		.interval = 50,	/* 50 milliseconds */
+	},
+
+	[ATAUSB_T_BBB_COMMAND] = {
+		.type = UE_BULK,
+		.endpoint = UE_ADDR_ANY,
+		.direction = UE_DIR_OUT,
+		.bufsize = sizeof(struct bbb_cbw),
+		.flags = {},
+		.callback = &atausb2_t_bbb_command_callback,
+		.timeout = 5000,	/* 5 seconds */
+	},
+
+	[ATAUSB_T_BBB_DATA_READ] = {
+		.type = UE_BULK,
+		.endpoint = UE_ADDR_ANY,
+		.direction = UE_DIR_IN,
+		.bufsize = ATAUSB_BULK_SIZE,
+		.flags = {.proxy_buffer = 1,.short_xfer_ok = 1,},
+		.callback = &atausb2_t_bbb_data_read_callback,
+		.timeout = 0,	/* overwritten later */
+	},
+
+	[ATAUSB_T_BBB_DATA_RD_CS] = {
+		.type = UE_CONTROL,
+		.endpoint = 0x00,	/* Control pipe */
+		.direction = UE_DIR_ANY,
+		.bufsize = sizeof(struct usb_device_request),
+		.flags = {},
+		.callback = &atausb2_t_bbb_data_rd_cs_callback,
+		.timeout = 5000,	/* 5 seconds */
+	},
+
+	[ATAUSB_T_BBB_DATA_WRITE] = {
+		.type = UE_BULK,
+		.endpoint = UE_ADDR_ANY,
+		.direction = UE_DIR_OUT,
+		.bufsize = ATAUSB_BULK_SIZE,
+		.flags = {.proxy_buffer = 1,.short_xfer_ok = 1,},
+		.callback = &atausb2_t_bbb_data_write_callback,
+		.timeout = 0,	/* overwritten later */
+	},
+
+	[ATAUSB_T_BBB_DATA_WR_CS] = {
+		.type = UE_CONTROL,
+		.endpoint = 0x00,	/* Control pipe */
+		.direction = UE_DIR_ANY,
+		.bufsize = sizeof(struct usb_device_request),
+		.flags = {},
+		.callback = &atausb2_t_bbb_data_wr_cs_callback,
+		.timeout = 5000,	/* 5 seconds */
+	},
+
+	[ATAUSB_T_BBB_STATUS] = {
+		.type = UE_BULK,
+		.endpoint = UE_ADDR_ANY,
+		.direction = UE_DIR_IN,
+		.bufsize = sizeof(struct bbb_csw),
+		.flags = {.short_xfer_ok = 1,},
+		.callback = &atausb2_t_bbb_status_callback,
+		.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, uhub, 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);
+	struct usb_interface_descriptor *id;
+
+	if (uaa->usb_mode != USB_MODE_HOST) {
+		return (ENXIO);
+	}
+	if (uaa->use_generic == 0) {
+		/* give other drivers a try first */
+		return (ENXIO);
+	}
+	id = usbd_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 (0);
+	}
+}
+
+static int
+atausb2_attach(device_t dev)
 {
-    struct usb_attach_arg *uaa = device_get_ivars(dev);
-    usb_interface_descriptor_t *id;
+	struct atausb2_softc *sc = device_get_softc(dev);
+	struct usb_attach_arg *uaa = device_get_ivars(dev);
+	struct usb_interface_descriptor *id;
+	const char *proto, *subclass;
+	struct usb_device_request request;
+	device_t child;
+	uint16_t i;
+	uint8_t maxlun;
+	uint8_t has_intr;
+	int err;
 
-    if (uaa->iface == NULL)
-	return UMATCH_NONE;
+	device_set_usb_desc(dev);
 
-    id = usbd_get_interface_descriptor(uaa->iface);
-    if (!id || id->bInterfaceClass != UICLASS_MASS)
-	return UMATCH_NONE;
+	sc->dev = dev;
+	sc->maxlun = 0;
+	sc->locked_ch = NULL;
+	sc->restart_ch = NULL;
+	sc->usb2_speed = usbd_get_speed(uaa->device);
+	mtx_init(&sc->locked_mtx, "ATAUSB lock", NULL, (MTX_DEF | MTX_RECURSE));
 
-    switch (id->bInterfaceSubClass) {
-    case UISUBCLASS_QIC157:
-    case UISUBCLASS_RBC:
-    case UISUBCLASS_SCSI:
-    case UISUBCLASS_SFF8020I:
-    case UISUBCLASS_SFF8070I:
-    case UISUBCLASS_UFI:
+	id = usbd_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:
-	case UIPROTO_MASS_BBB:
-	case UIPROTO_MASS_BBB_OLD:
-	    return UMATCH_IFACECLASS_IFACESUBCLASS_IFACEPROTO;
+		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:
-	    return UMATCH_IFACECLASS_IFACESUBCLASS;
+		subclass = "Unknown";
+	}
+
+	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;
+	}
+	err = usbd_transfer_setup(uaa->device, &uaa->info.bIfaceIndex,
+	    sc->xfer, atausb2_config, ATAUSB_T_BBB_MAX, sc,
+	    &sc->locked_mtx);
+
+	/* skip reset first time */
+	sc->last_xfer_no = ATAUSB_T_BBB_COMMAND;
+
+	if (err) {
+		device_printf(sc->dev, "could not setup required "
+		    "transfers, %s\n", usbd_errstr(err));
+		goto detach;
+	}
+	/* 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 = usbd_do_request(uaa->device, &Giant, &request, &maxlun);
+
+	if (err) {
+		if (bootverbose) {
+			device_printf(sc->dev, "get maxlun not supported %s\n",
+			    usbd_errstr(err));
+		}
+	} else {
+		sc->maxlun = maxlun;
+		if (bootverbose) {
+			device_printf(sc->dev, "maxlun=%d\n", sc->maxlun);
+		}
+	}
+
+	/* 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);
 	}
-	break;
-    default:
-	return UMATCH_IFACECLASS;
-    }
+	bus_generic_attach(sc->dev);
+
+	return (0);
+
+detach:
+	atausb2_detach(dev);
+	return (ENXIO);
 }
 
 static int
-atausb_attach(device_t dev)
+atausb2_detach(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;
-    char devinfo[1024], *proto, *subclass;
-    u_int8_t maxlun;
-    int err, i;
+	struct atausb2_softc *sc = device_get_softc(dev);
+	device_t *children;
+	int nchildren, i;
+
+	/* teardown our statemachine */
 
-    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); 
+	usbd_transfer_unsetup(sc->xfer, ATAUSB_T_MAX);
 
-    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;
+	/* detach & delete all children, if any */
 
-    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;
+	if (!device_get_children(dev, &children, &nchildren)) {
+		for (i = 0; i < nchildren; i++) {
+			device_delete_child(dev, children[i]);
+		}
+		free(children, M_TEMP);
 	}
-	if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
-	    (ed->bmAttributes & UE_XFERTYPE) == UE_BULK) {
-	    sc->bulkin = ed->bEndpointAddress;
+	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 (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT &&
-	           (ed->bmAttributes & UE_XFERTYPE) == UE_BULK) {
-	    sc->bulkout = ed->bEndpointAddress;
+	if (sc->xfer[xfer_no]) {
+		sc->last_xfer_no = xfer_no;
+		usbd_transfer_start(sc->xfer[xfer_no]);
+	} else {
+		atausb2_cancel_request(sc);
 	}
-	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;
+}
+
+static void
+atausb2_t_bbb_reset1_callback(struct usb_xfer *xfer, usb_error_t error)
+{
+	struct atausb2_softc *sc = usbd_xfer_softc(xfer);
+	struct usb_device_request req;
+	struct usb_page_cache *pc;
+
+	switch (USB_GET_STATE(xfer)) {
+	case USB_ST_TRANSFERRED:
+		atausb2_transfer_start(sc, ATAUSB_T_BBB_RESET2);
+		return;
+
+	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);
+
+		pc = usbd_xfer_get_frame(xfer, 0);
+		usbd_copy_in(pc, 0, &req, sizeof(req));
+
+		usbd_xfer_set_frame_len(xfer, 0, sizeof(req));
+		usbd_xfer_set_frames(xfer, 1);
+		usbd_transfer_submit(xfer);
+		return;
+
+	default:			/* Error */
+		atausb2_tr_error(xfer, error);
+		return;
+
 	}
-    }
+}
+
+static void
+atausb2_t_bbb_reset2_callback(struct usb_xfer *xfer, usb_error_t error)
+{
+	atausb2_t_bbb_data_clear_stall_callback(xfer, ATAUSB_T_BBB_RESET3,
+	    ATAUSB_T_BBB_DATA_READ, error);
+}
 
-    /* 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;
-    }
+static void
+atausb2_t_bbb_reset3_callback(struct usb_xfer *xfer, usb_error_t error)
+{
+	atausb2_t_bbb_data_clear_stall_callback(xfer, ATAUSB_T_BBB_COMMAND,
+	    ATAUSB_T_BBB_DATA_WRITE, error);
+}
 
-    /* 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;
-	}
-    }
-    sc->state = ATAUSB_S_ATTACH;
+static void
+atausb2_t_bbb_data_clear_stall_callback(struct usb_xfer *xfer,
+    uint8_t next_xfer, uint8_t stall_xfer, usb_error_t error)
+{
+	struct atausb2_softc *sc = usbd_xfer_softc(xfer);
 
-    /* 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;
-	}
-    }
+	switch (USB_GET_STATE(xfer)) {
+	case USB_ST_TRANSFERRED:
+tr_transferred:
+		atausb2_transfer_start(sc, next_xfer);
+		return;
 
-    /* driver is ready to process requests here */
-    sc->state = ATAUSB_S_IDLE;
+	case USB_ST_SETUP:
+		if (usbd_clear_stall_callback(xfer, sc->xfer[stall_xfer])) {
+			goto tr_transferred;
+		}
+		return;
 
-    /* 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));
-    }
+	default:			/* Error */
+		atausb2_tr_error(xfer, error);
+		return;
 
-    /* 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");
-	    atausb_detach(dev);
-	    return ENXIO;
 	}
-    }
-    bus_generic_attach(sc->dev);
-    return 0;
 }
 
-static int
-atausb_detach(device_t dev)
+static void
+atausb2_t_bbb_command_callback(struct usb_xfer *xfer, usb_error_t error)
 {
-    struct atausb_softc *sc = device_get_softc(dev);
-    usbd_device_handle udev;
-    device_t *children;
-    int nchildren, i;
+	struct atausb2_softc *sc = usbd_xfer_softc(xfer);
+	struct ata_request *request = sc->ata_request;
+	struct ata_channel *ch;
+	struct usb_page_cache *pc;
+	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;
 
-    /* signal that device is going away */
-    sc->state = ATAUSB_S_DETACH;
+	case USB_ST_SETUP:
 
-    /* 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);
+		sc->status_try = 0;
 
-    /* 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);
-    }
+		if (request) {
+			ch = device_get_softc(request->parent);
 
-    /* free the transfers */
-    for (i = 0; i < ATAUSB_T_MAX; i++)
-	if (sc->transfer[i])
-	    usbd_free_xfer(sc->transfer[i]);
+			sc->timeout = (request->timeout * 1000) + 5000;
 
-    /* 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);
+			tag = UGETDW(sc->cbw.tag) + 1;
 
-    mtx_destroy(&sc->locked_mtx);
-    return 0;
-}
+			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 */
 
+			pc = usbd_xfer_get_frame(xfer, 0);
+			usbd_copy_in(pc, 0, &sc->cbw, sizeof(sc->cbw));
 
-/*
- * 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)
-{
-    usbd_status err;
+			usbd_xfer_set_frame_len(xfer, 0, sizeof(sc->cbw));
+			usbd_transfer_submit(xfer);
+		}
+		return;
 
-    if (sc->state == ATAUSB_S_DETACH)
-	return USBD_NOT_STARTED;
+	default:			/* Error */
+		atausb2_tr_error(xfer, error);
+		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_data_read_callback(struct usb_xfer *xfer, usb_error_t error)
 {
-    usbd_status err;
+	struct atausb2_softc *sc = usbd_xfer_softc(xfer);
+	uint32_t max_bulk = usbd_xfer_max_len(xfer);
+	struct usb_page_cache *pc;
+	int actlen, sumlen;
+
+	usbd_xfer_status(xfer, &actlen, &sumlen, NULL, NULL);
+
+	switch (USB_GET_STATE(xfer)) {
+	case USB_ST_TRANSFERRED:
+
+		pc = usbd_xfer_get_frame(xfer, 0);
+		usbd_copy_out(pc, 0, sc->ata_data, actlen);
+
+		sc->ata_bytecount -= actlen;
+		sc->ata_data += actlen;
+		sc->ata_donecount += actlen;
+
+		if (actlen < 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;
+		}
+		usbd_xfer_set_timeout(xfer, sc->timeout);
+		usbd_xfer_set_frame_len(xfer, 0, max_bulk);
+
+		usbd_transfer_submit(xfer);
+		return;

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


More information about the p4-projects mailing list