diff options
author | n_hibma <n_hibma@FreeBSD.org> | 2010-11-10 18:41:38 +0000 |
---|---|---|
committer | n_hibma <n_hibma@FreeBSD.org> | 2010-11-10 18:41:38 +0000 |
commit | c905973491138e09498591249e79537ca474f694 (patch) | |
tree | 27917b5824dcee576de20f2d4480605f711f735e /sys/dev | |
parent | 540593911ba28e330a197daaea7ed02aae240c33 (diff) | |
download | FreeBSD-src-c905973491138e09498591249e79537ca474f694.zip FreeBSD-src-c905973491138e09498591249e79537ca474f694.tar.gz |
Allow specification of eject method through quirks, so people can test
drive eject methods before supplying patches.
Diffstat (limited to 'sys/dev')
-rw-r--r-- | sys/dev/usb/quirk/usb_quirk.c | 10 | ||||
-rw-r--r-- | sys/dev/usb/quirk/usb_quirk.h | 58 | ||||
-rw-r--r-- | sys/dev/usb/serial/u3g.c | 38 |
3 files changed, 77 insertions, 29 deletions
diff --git a/sys/dev/usb/quirk/usb_quirk.c b/sys/dev/usb/quirk/usb_quirk.c index c619a24..6691538 100644 --- a/sys/dev/usb/quirk/usb_quirk.c +++ b/sys/dev/usb/quirk/usb_quirk.c @@ -512,6 +512,16 @@ static const char *usb_quirk_str[USB_QUIRK_MAX] = { [UQ_MSC_FORCE_PROTO_ATAPI] = "UQ_MSC_FORCE_PROTO_ATAPI", [UQ_MSC_FORCE_PROTO_UFI] = "UQ_MSC_FORCE_PROTO_UFI", [UQ_MSC_FORCE_PROTO_RBC] = "UQ_MSC_FORCE_PROTO_RBC", + [UQ_MSC_EJECT_HUAWEI] = "UQ_MSC_EJECT_HUAWEI", + [UQ_MSC_EJECT_SIERRA] = "UQ_MSC_EJECT_SIERRA", + [UQ_MSC_EJECT_SCSIEJECT] = "UQ_MSC_EJECT_SCSIEJECT", + [UQ_MSC_EJECT_REZERO] = "UQ_MSC_EJECT_REZERO", + [UQ_MSC_EJECT_ZTESTOR] = "UQ_MSC_EJECT_ZTESTOR", + [UQ_MSC_EJECT_CMOTECH] = "UQ_MSC_EJECT_CMOTECH", + [UQ_MSC_EJECT_WAIT] = "UQ_MSC_EJECT_WAIT", + [UQ_MSC_EJECT_SAEL_M460] = "UQ_MSC_EJECT_SAEL_M460", + [UQ_MSC_EJECT_HUAWEISCSI] = "UQ_MSC_EJECT_HUAWEISCSI", + [UQ_MSC_EJECT_TCT] = "UQ_MSC_EJECT_TCT", }; /*------------------------------------------------------------------------* diff --git a/sys/dev/usb/quirk/usb_quirk.h b/sys/dev/usb/quirk/usb_quirk.h index d681402..856ab89 100644 --- a/sys/dev/usb/quirk/usb_quirk.h +++ b/sys/dev/usb/quirk/usb_quirk.h @@ -59,31 +59,43 @@ enum { /* keep in sync with usb_quirk_str table */ UQ_CFG_INDEX_3, /* select configuration index 3 by default */ UQ_CFG_INDEX_4, /* select configuration index 4 by default */ UQ_CFG_INDEX_0, /* select configuration index 0 by default */ - UQ_ASSUME_CM_OVER_DATA, /* modem device breaks on cm over data */ + UQ_ASSUME_CM_OVER_DATA, /* assume cm over data feature */ /* USB Mass Storage Quirks. See "storage/umass.c" for a detailed description. */ - UQ_MSC_NO_TEST_UNIT_READY, - UQ_MSC_NO_RS_CLEAR_UA, - UQ_MSC_NO_START_STOP, - UQ_MSC_NO_GETMAXLUN, - UQ_MSC_NO_INQUIRY, - UQ_MSC_NO_INQUIRY_EVPD, - UQ_MSC_NO_SYNC_CACHE, - UQ_MSC_SHUTTLE_INIT, - UQ_MSC_ALT_IFACE_1, - UQ_MSC_FLOPPY_SPEED, - UQ_MSC_IGNORE_RESIDUE, - UQ_MSC_WRONG_CSWSIG, - UQ_MSC_RBC_PAD_TO_12, - UQ_MSC_READ_CAP_OFFBY1, - UQ_MSC_FORCE_SHORT_INQ, - UQ_MSC_FORCE_WIRE_BBB, - UQ_MSC_FORCE_WIRE_CBI, - UQ_MSC_FORCE_WIRE_CBI_I, - UQ_MSC_FORCE_PROTO_SCSI, - UQ_MSC_FORCE_PROTO_ATAPI, - UQ_MSC_FORCE_PROTO_UFI, - UQ_MSC_FORCE_PROTO_RBC, + UQ_MSC_NO_TEST_UNIT_READY, /* send start/stop instead of TUR */ + UQ_MSC_NO_RS_CLEAR_UA, /* does not reset Unit Att. */ + UQ_MSC_NO_START_STOP, /* does not support start/stop */ + UQ_MSC_NO_GETMAXLUN, /* does not support get max LUN */ + UQ_MSC_NO_INQUIRY, /* fake generic inq response */ + UQ_MSC_NO_INQUIRY_EVPD, /* does not support inq EVPD */ + UQ_MSC_NO_SYNC_CACHE, /* does not support sync cache */ + UQ_MSC_SHUTTLE_INIT, /* requires Shuttle init sequence */ + UQ_MSC_ALT_IFACE_1, /* switch to alternate interface 1 */ + UQ_MSC_FLOPPY_SPEED, /* does floppy speeds (20kb/s) */ + UQ_MSC_IGNORE_RESIDUE, /* gets residue wrong */ + UQ_MSC_WRONG_CSWSIG, /* uses wrong CSW signature */ + UQ_MSC_RBC_PAD_TO_12, /* pad RBC requests to 12 bytes */ + UQ_MSC_READ_CAP_OFFBY1, /* reports sector count, not max sec. */ + UQ_MSC_FORCE_SHORT_INQ, /* does not support full inq. */ + UQ_MSC_FORCE_WIRE_BBB, /* force BBB wire protocol */ + UQ_MSC_FORCE_WIRE_CBI, /* force CBI wire protocol */ + UQ_MSC_FORCE_WIRE_CBI_I, /* force CBI with int. wire protocol */ + UQ_MSC_FORCE_PROTO_SCSI, /* force SCSI command protocol */ + UQ_MSC_FORCE_PROTO_ATAPI, /* force ATAPI command protocol */ + UQ_MSC_FORCE_PROTO_UFI, /* force UFI command protocol */ + UQ_MSC_FORCE_PROTO_RBC, /* force RBC command protocol */ + + /* Ejection of mass storage (driver disk) */ + UQ_MSC_EJECT_HUAWEI, /* ejects after Huawei USB command */ + UQ_MSC_EJECT_SIERRA, /* ejects after Sierra USB command */ + UQ_MSC_EJECT_SCSIEJECT, /* ejects after SCSI eject command */ + UQ_MSC_EJECT_REZERO, /* ejects after SCSI rezero command */ + UQ_MSC_EJECT_ZTESTOR, /* ejects after ZTE SCSI command */ + UQ_MSC_EJECT_CMOTECH, /* ejects after C-motech SCSI cmd */ + UQ_MSC_EJECT_WAIT, /* wait for the device to eject */ + UQ_MSC_EJECT_SAEL_M460, /* ejects after Sael USB commands */ + UQ_MSC_EJECT_HUAWEISCSI, /* ejects after Huawei SCSI command */ + UQ_MSC_EJECT_TCT, /* ejects after TCT SCSI command */ USB_QUIRK_MAX }; diff --git a/sys/dev/usb/serial/u3g.c b/sys/dev/usb/serial/u3g.c index 9376e9e..12bd3f4 100644 --- a/sys/dev/usb/serial/u3g.c +++ b/sys/dev/usb/serial/u3g.c @@ -62,6 +62,7 @@ #include <dev/usb/usb_msctest.h> #include <dev/usb/serial/usb_serial.h> +#include <dev/usb/quirk/usb_quirk.h> #ifdef USB_DEBUG static int u3g_debug = 0; @@ -84,6 +85,7 @@ SYSCTL_INT(_hw_usb_u3g, OID_AUTO, debug, CTLFLAG_RW, #define U3GSP_HSPA 6 #define U3GSP_MAX 7 +/* Eject methods; See also usb_quirks.h:UQ_MSC_EJECT_* */ #define U3GINIT_HUAWEI 1 /* Requires Huawei init command */ #define U3GINIT_SIERRA 2 /* Requires Sierra init command */ #define U3GINIT_SCSIEJECT 3 /* Requires SCSI eject command */ @@ -641,6 +643,7 @@ u3g_test_autoinst(void *arg, struct usb_device *udev, struct usb_interface *iface; struct usb_interface_descriptor *id; int error; + unsigned long method; if (uaa->dev_state != UAA_DEV_READY) return; @@ -651,16 +654,37 @@ u3g_test_autoinst(void *arg, struct usb_device *udev, id = iface->idesc; if (id == NULL || id->bInterfaceClass != UICLASS_MASS) return; - if (usbd_lookup_id_by_uaa(u3g_devs, sizeof(u3g_devs), uaa)) + + if (usb_test_quirk(uaa, UQ_MSC_EJECT_HUAWEI)) + method = U3GINIT_HUAWEI; + else if (usb_test_quirk(uaa, UQ_MSC_EJECT_SIERRA)) + method = U3GINIT_SIERRA; + else if (usb_test_quirk(uaa, UQ_MSC_EJECT_SCSIEJECT)) + method = U3GINIT_SCSIEJECT; + else if (usb_test_quirk(uaa, UQ_MSC_EJECT_REZERO)) + method = U3GINIT_REZERO; + else if (usb_test_quirk(uaa, UQ_MSC_EJECT_ZTESTOR)) + method = U3GINIT_ZTESTOR; + else if (usb_test_quirk(uaa, UQ_MSC_EJECT_CMOTECH)) + method = U3GINIT_CMOTECH; + else if (usb_test_quirk(uaa, UQ_MSC_EJECT_WAIT)) + method = U3GINIT_WAIT; + else if (usb_test_quirk(uaa, UQ_MSC_EJECT_HUAWEISCSI)) + method = U3GINIT_HUAWEISCSI; + else if (usb_test_quirk(uaa, UQ_MSC_EJECT_TCT)) + method = U3GINIT_TCT; + else if (usbd_lookup_id_by_uaa(u3g_devs, sizeof(u3g_devs), uaa) == 0) + method = USB_GET_DRIVER_INFO(uaa); + else return; /* no device match */ if (bootverbose) { - printf("Ejecting 0x%04x:0x%04x using method %ld\n", - uaa->info.idVendor, uaa->info.idProduct, - USB_GET_DRIVER_INFO(uaa)); + printf("Ejecting %s %s using method %ld\n", + usb_get_manufacturer(udev), + usb_get_product(udev), method); } - switch (USB_GET_DRIVER_INFO(uaa)) { + switch (method) { case U3GINIT_HUAWEI: error = u3g_huawei_init(udev); break; @@ -752,8 +776,10 @@ u3g_attach(device_t dev) DPRINTF("sc=%p\n", sc); type = USB_GET_DRIVER_INFO(uaa); - if (type == U3GINIT_SAEL_M460) + if (type == U3GINIT_SAEL_M460 + || usb_test_quirk(uaa, UQ_MSC_EJECT_SAEL_M460)) { u3g_sael_m460_init(uaa->device); + } /* copy in USB config */ for (n = 0; n != U3G_N_TRANSFER; n++) |