From owner-p4-projects@FreeBSD.ORG Mon Sep 15 20:23:54 2008 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id CD7EE106567B; Mon, 15 Sep 2008 20:23:53 +0000 (UTC) Delivered-To: perforce@FreeBSD.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 90EB61065677 for ; Mon, 15 Sep 2008 20:23:53 +0000 (UTC) (envelope-from hselasky@FreeBSD.org) Received: from repoman.freebsd.org (repoman.freebsd.org [IPv6:2001:4f8:fff6::29]) by mx1.freebsd.org (Postfix) with ESMTP id 7B7C08FC08 for ; Mon, 15 Sep 2008 20:23:53 +0000 (UTC) (envelope-from hselasky@FreeBSD.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.14.3/8.14.3) with ESMTP id m8FKNr6x000571 for ; Mon, 15 Sep 2008 20:23:53 GMT (envelope-from hselasky@FreeBSD.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.14.3/8.14.3/Submit) id m8FKNrBR000569 for perforce@freebsd.org; Mon, 15 Sep 2008 20:23:53 GMT (envelope-from hselasky@FreeBSD.org) Date: Mon, 15 Sep 2008 20:23:53 GMT Message-Id: <200809152023.m8FKNrBR000569@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to hselasky@FreeBSD.org using -f From: Hans Petter Selasky To: Perforce Change Reviews Cc: Subject: PERFORCE change 149821 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 15 Sep 2008 20:23:54 -0000 http://perforce.freebsd.org/chv.cgi?CH=149821 Change 149821 by hselasky@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); +}