PERFORCE change 149821 for review
Hans Petter Selasky
hselasky at FreeBSD.org
Mon Sep 15 20:23:54 UTC 2008
http://perforce.freebsd.org/chv.cgi?CH=149821
Change 149821 by hselasky at hselasky_laptop001 on 2008/09/15 20:23:52
This patch works around a problem in the CAM layer where a
dissappearing SIM is not supported. USB is not the right place
to solve it, but for sake of user-friendlyness I am doing this
workaround in the UMASS driver. Tested and works.
Affected files ...
.. //depot/projects/usb/src/sys/dev/usb2/storage/umass2.c#11 edit
Differences ...
==== //depot/projects/usb/src/sys/dev/usb2/storage/umass2.c#11 (text+ko) ====
@@ -167,6 +167,8 @@
#define DPRINTF(...) do { } while (0)
#endif
+#define UMASS_MAXUNIT 64 /* XXX temporary */
+
#define UMASS_BULK_SIZE (1 << 17)
#define UMASS_CBI_DIAGNOSTIC_CMDLEN 12 /* bytes */
#define UMASS_MAX_CMDLEN MAX(12, CAM_MAX_CDBLEN) /* bytes */
@@ -1013,11 +1015,11 @@
static void umass_cam_quirk_cb(struct umass_softc *sc, union ccb *ccb, uint32_t residue, uint8_t status);
static uint8_t umass_scsi_transform(struct umass_softc *sc, uint8_t *cmd_ptr, uint8_t cmd_len);
static uint8_t umass_rbc_transform(struct umass_softc *sc, uint8_t *cmd_ptr, uint8_t cmd_len);
-
static uint8_t umass_ufi_transform(struct umass_softc *sc, uint8_t *cmd_ptr, uint8_t cmd_len);
static uint8_t umass_atapi_transform(struct umass_softc *sc, uint8_t *cmd_ptr, uint8_t cmd_len);
static uint8_t umass_no_transform(struct umass_softc *sc, uint8_t *cmd, uint8_t cmdlen);
static uint8_t umass_std_transform(struct umass_softc *sc, union ccb *ccb, uint8_t *cmd, uint8_t cmdlen);
+static int umass_driver_loaded(struct module *mod, int what, void *arg);
#if USB_DEBUG
static void umass_bbb_dump_cbw(struct umass_softc *sc, umass_bbb_cbw_t *cbw);
@@ -1240,6 +1242,9 @@
#define UFI_COMMAND_LENGTH 12 /* UFI commands are always 12 bytes */
#define ATAPI_COMMAND_LENGTH 12 /* ATAPI commands are always 12 bytes */
+static struct cam_sim *umass_sim[UMASS_MAXUNIT];
+static struct mtx umass_mtx;
+
static devclass_t umass_devclass;
static device_method_t umass_methods[] = {
@@ -1256,8 +1261,7 @@
.size = sizeof(struct umass_softc),
};
-DRIVER_MODULE(umass, ushub, umass_driver, umass_devclass, NULL, 0);
-
+DRIVER_MODULE(umass, ushub, umass_driver, umass_devclass, umass_driver_loaded, 0);
MODULE_DEPEND(umass, usb2_core, 1, 1, 1);
MODULE_DEPEND(umass, cam, 1, 1, 1);
@@ -1417,6 +1421,11 @@
if (sc == NULL) {
return (ENOMEM);
}
+ if (device_get_unit(dev) >= UMASS_MAXUNIT) {
+ device_printf(dev, "Maxunit(%u) limit reached!\n",
+ UMASS_MAXUNIT);
+ return (ENOMEM);
+ }
/*
* NOTE: the softc struct is bzero-ed in device_set_driver.
* We can safely call umass_detach without specifically
@@ -1434,8 +1443,6 @@
device_set_usb2_desc(dev);
- mtx_init(&sc->sc_mtx, "UMASS lock", NULL, (MTX_DEF | MTX_RECURSE));
-
/* get interface index */
id = usb2_get_interface_descriptor(uaa->iface);
@@ -1504,7 +1511,7 @@
err = usb2_transfer_setup(uaa->device,
&uaa->info.bIfaceIndex, sc->sc_xfer, umass_bbb_config,
- UMASS_T_BBB_MAX, sc, &sc->sc_mtx);
+ UMASS_T_BBB_MAX, sc, &umass_mtx);
/* skip reset first time */
sc->sc_last_xfer_index = UMASS_T_BBB_COMMAND;
@@ -1515,7 +1522,7 @@
&uaa->info.bIfaceIndex, sc->sc_xfer, umass_cbi_config,
(sc->sc_proto & UMASS_PROTO_CBI_I) ?
UMASS_T_CBI_MAX : (UMASS_T_CBI_MAX - 2), sc,
- &sc->sc_mtx);
+ &umass_mtx);
/* skip reset first time */
sc->sc_last_xfer_index = UMASS_T_CBI_COMMAND;
@@ -1588,16 +1595,14 @@
usb2_transfer_unsetup(sc->sc_xfer, UMASS_T_MAX);
#if (__FreeBSD_version >= 700037)
- mtx_lock(&sc->sc_mtx);
+ mtx_lock(&umass_mtx);
#endif
umass_cam_detach_sim(sc);
#if (__FreeBSD_version >= 700037)
- mtx_unlock(&sc->sc_mtx);
+ mtx_unlock(&umass_mtx);
#endif
- mtx_destroy(&sc->sc_mtx);
-
return (0); /* success */
}
@@ -1662,7 +1667,7 @@
{
union ccb *ccb;
- mtx_assert(&sc->sc_mtx, MA_OWNED);
+ mtx_assert(&umass_mtx, MA_OWNED);
ccb = sc->sc_transfer.ccb;
sc->sc_transfer.ccb = NULL;
@@ -2585,6 +2590,10 @@
{
struct cam_devq *devq; /* Per device Queue */
+ if (umass_sim[sc->sc_unit] != NULL) {
+ sc->sc_sim = umass_sim[sc->sc_unit];
+ goto register_only;
+ }
/*
* A HBA is attached to the CAM layer.
*
@@ -2602,7 +2611,7 @@
sc /* priv */ ,
sc->sc_unit /* unit number */ ,
#if (__FreeBSD_version >= 700037)
- &sc->sc_mtx /* mutex */ ,
+ &umass_mtx /* mutex */ ,
#endif
1 /* maximum device openings */ ,
0 /* maximum tagged device openings */ ,
@@ -2612,26 +2621,33 @@
cam_simq_free(devq);
return (ENOMEM);
}
+ umass_sim[sc->sc_unit] = sc->sc_sim;
+
+register_only:
+
+ /* update the softc pointer */
+ sc->sc_sim->softc = sc;
+
#if (__FreeBSD_version >= 700037)
- mtx_lock(&sc->sc_mtx);
+ mtx_lock(&umass_mtx);
#endif
#if (__FreeBSD_version >= 700048)
if (xpt_bus_register(sc->sc_sim, sc->sc_dev, sc->sc_unit) != CAM_SUCCESS) {
- mtx_unlock(&sc->sc_mtx);
+ mtx_unlock(&umass_mtx);
return (ENOMEM);
}
#else
if (xpt_bus_register(sc->sc_sim, sc->sc_unit) != CAM_SUCCESS) {
#if (__FreeBSD_version >= 700037)
- mtx_unlock(&sc->sc_mtx);
+ mtx_unlock(&umass_mtx);
#endif
return (ENOMEM);
}
#endif
#if (__FreeBSD_version >= 700037)
- mtx_unlock(&sc->sc_mtx);
+ mtx_unlock(&umass_mtx);
#endif
return (0);
}
@@ -2674,14 +2690,14 @@
return;
}
#if (__FreeBSD_version >= 700037)
- mtx_lock(&sc->sc_mtx);
+ mtx_lock(&umass_mtx);
#endif
if (xpt_create_path(&path, xpt_periph, cam_sim_path(sc->sc_sim),
CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD)
!= CAM_REQ_CMP) {
#if (__FreeBSD_version >= 700037)
- mtx_unlock(&sc->sc_mtx);
+ mtx_unlock(&umass_mtx);
#endif
free(ccb, M_USBDEV);
return;
@@ -2693,7 +2709,7 @@
xpt_action(ccb);
#if (__FreeBSD_version >= 700037)
- mtx_unlock(&sc->sc_mtx);
+ mtx_unlock(&umass_mtx);
#endif
/* The scan is in progress now. */
@@ -2736,7 +2752,9 @@
{
if (sc->sc_sim) {
if (xpt_bus_deregister(cam_sim_path(sc->sc_sim))) {
+#if 0 /* NOTYET */
cam_sim_free(sc->sc_sim, /* free_devq */ TRUE);
+#endif
} else {
panic("%s: CAM layer is busy!\n",
sc->sc_name);
@@ -2757,7 +2775,7 @@
if (sc) {
#if (__FreeBSD_version < 700037)
- mtx_lock(&sc->sc_mtx);
+ mtx_lock(&umass_mtx);
#endif
}
/*
@@ -3041,7 +3059,7 @@
done:
#if (__FreeBSD_version < 700037)
if (sc) {
- mtx_unlock(&sc->sc_mtx);
+ mtx_unlock(&umass_mtx);
}
#endif
return;
@@ -3612,3 +3630,28 @@
}
#endif
+
+static int
+umass_driver_loaded(struct module *mod, int what, void *arg)
+{
+ uint16_t x;
+
+ switch (what) {
+ case MOD_LOAD:
+ mtx_init(&umass_mtx, "UMASS lock", NULL, (MTX_DEF | MTX_RECURSE));
+ break;
+
+ case MOD_UNLOAD:
+ for (x = 0; x != UMASS_MAXUNIT; x++) {
+ /* cleanup */
+ if (umass_sim[x])
+ cam_sim_free(umass_sim[x], /* free_devq */ TRUE);
+ }
+ mtx_destroy(&umass_mtx);
+ break;
+ default:
+ return (EOPNOTSUPP);
+ }
+
+ return (0);
+}
More information about the p4-projects
mailing list