usbai_util.c (35f36846) | usbai_util.c (d73ae94e) |
---|---|
1/* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the | 1/* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the |
5 * Common Development and Distribution License, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. | 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. |
8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22/* | 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21/* |
23 * Copyright 2005 Sun Microsystems, Inc. All rights reserved. | 22 * Copyright 2006 Sun Microsystems, Inc. All rights reserved. |
24 * Use is subject to license terms. 25 */ 26 27#pragma ident "%Z%%M% %I% %E% SMI" 28 29/* 30 * USBA: Solaris USB Architecture support 31 * 32 * Utility functions 33 */ 34#define USBA_FRAMEWORK 35#include <sys/usb/usba/usba_impl.h> 36#include <sys/usb/usba/hcdi_impl.h> 37 | 23 * Use is subject to license terms. 24 */ 25 26#pragma ident "%Z%%M% %I% %E% SMI" 27 28/* 29 * USBA: Solaris USB Architecture support 30 * 31 * Utility functions 32 */ 33#define USBA_FRAMEWORK 34#include <sys/usb/usba/usba_impl.h> 35#include <sys/usb/usba/hcdi_impl.h> 36 |
37extern void usba_free_evdata(usba_evdata_t *); 38 |
|
38static mblk_t *usba_get_cfg_cloud(dev_info_t *, usb_pipe_handle_t, int); 39 40/* local functions */ 41static int usba_sync_set_cfg(dev_info_t *, usba_ph_impl_t *, 42 usba_pipe_async_req_t *, usb_flags_t); 43static int usba_sync_set_alt_if(dev_info_t *, usba_ph_impl_t *, 44 usba_pipe_async_req_t *, usb_flags_t); 45static int usba_sync_clear_feature(dev_info_t *, usba_ph_impl_t *, --- 764 unchanged lines hidden (view full) --- 810usb_owns_device(dev_info_t *dip) 811{ 812 int interface_num = usb_get_if_number(dip); 813 814 return (interface_num < 0 ? B_TRUE : B_FALSE); 815} 816 817 | 39static mblk_t *usba_get_cfg_cloud(dev_info_t *, usb_pipe_handle_t, int); 40 41/* local functions */ 42static int usba_sync_set_cfg(dev_info_t *, usba_ph_impl_t *, 43 usba_pipe_async_req_t *, usb_flags_t); 44static int usba_sync_set_alt_if(dev_info_t *, usba_ph_impl_t *, 45 usba_pipe_async_req_t *, usb_flags_t); 46static int usba_sync_clear_feature(dev_info_t *, usba_ph_impl_t *, --- 764 unchanged lines hidden (view full) --- 811usb_owns_device(dev_info_t *dip) 812{ 813 int interface_num = usb_get_if_number(dip); 814 815 return (interface_num < 0 ? B_TRUE : B_FALSE); 816} 817 818 |
819/* check whether the interface is in this interface association */ 820boolean_t 821usba_check_if_in_ia(dev_info_t *dip, int n_if) 822{ 823 int first_if, if_count; 824 825 first_if = usb_get_if_number(dip); 826 if_count = ddi_prop_get_int(DDI_DEV_T_ANY, dip, 827 DDI_PROP_DONTPASS, "interface-count", -1); 828 if_count += first_if; 829 830 return ((n_if >= first_if && n_if < if_count) ? B_TRUE : B_FALSE); 831} 832 833 |
|
818uint8_t 819usba_get_ifno(dev_info_t *dip) 820{ 821 int interface_num = usb_get_if_number(dip); 822 823 return (interface_num < 0 ? 0 : interface_num); 824} 825 --- 86 unchanged lines hidden (view full) --- 912 usba_pipe_handle_data_t *ph_data = usba_get_ph_data( 913 (usb_pipe_handle_t)ph_impl); 914 915 USB_DPRINTF_L4(DPRINT_MASK_USBA, usbai_log_handle, 916 "usb_set_alt_if: %s, interface#=0x%x, alt#=0x%x, " 917 "uf=0x%x", ddi_node_name(dip), interface, 918 alt_number, flags); 919 | 834uint8_t 835usba_get_ifno(dev_info_t *dip) 836{ 837 int interface_num = usb_get_if_number(dip); 838 839 return (interface_num < 0 ? 0 : interface_num); 840} 841 --- 86 unchanged lines hidden (view full) --- 928 usba_pipe_handle_data_t *ph_data = usba_get_ph_data( 929 (usb_pipe_handle_t)ph_impl); 930 931 USB_DPRINTF_L4(DPRINT_MASK_USBA, usbai_log_handle, 932 "usb_set_alt_if: %s, interface#=0x%x, alt#=0x%x, " 933 "uf=0x%x", ddi_node_name(dip), interface, 934 alt_number, flags); 935 |
920 /* if we don't own the device, we must own the interface */ 921 if (!usb_owns_device(dip) && | 936 /* if we don't own the device, we must own the interface or ia */ 937 if (!usb_owns_device(dip) && !usba_check_if_in_ia(dip, interface) && |
922 (interface != usb_get_if_number(dip))) { 923 usba_release_ph_data(ph_data->p_ph_impl); 924 925 return (USB_INVALID_PERM); 926 } 927 928 /* set the alternate setting */ 929 rval = usb_pipe_sync_ctrl_xfer(dip, usba_get_dflt_pipe_handle(dip), --- 1242 unchanged lines hidden (view full) --- 2172 2173 return (NULL); 2174 } else { 2175 2176 return (allocb(size, pri)); 2177 } 2178} 2179#endif | 938 (interface != usb_get_if_number(dip))) { 939 usba_release_ph_data(ph_data->p_ph_impl); 940 941 return (USB_INVALID_PERM); 942 } 943 944 /* set the alternate setting */ 945 rval = usb_pipe_sync_ctrl_xfer(dip, usba_get_dflt_pipe_handle(dip), --- 1242 unchanged lines hidden (view full) --- 2188 2189 return (NULL); 2190 } else { 2191 2192 return (allocb(size, pri)); 2193 } 2194} 2195#endif |
2196 2197 2198/* 2199 * usb common power management for usb_mid, usb_ia and maybe other simple 2200 * drivers. 2201 */ 2202 2203/* 2204 * functions to handle power transition for OS levels 0 -> 3 2205 */ 2206static int 2207usb_common_pwrlvl0(dev_info_t *dip, usb_common_power_t *pm, int *dev_state) 2208{ 2209 int rval; 2210 2211 switch (*dev_state) { 2212 case USB_DEV_ONLINE: 2213 /* Issue USB D3 command to the device here */ 2214 rval = usb_set_device_pwrlvl3(dip); 2215 ASSERT(rval == USB_SUCCESS); 2216 2217 *dev_state = USB_DEV_PWRED_DOWN; 2218 pm->uc_current_power = USB_DEV_OS_PWR_OFF; 2219 /* FALLTHRU */ 2220 case USB_DEV_DISCONNECTED: 2221 case USB_DEV_SUSPENDED: 2222 /* allow a disconnected/cpr'ed device to go to low pwr */ 2223 2224 return (USB_SUCCESS); 2225 case USB_DEV_PWRED_DOWN: 2226 default: 2227 return (USB_FAILURE); 2228 } 2229} 2230 2231 2232/* ARGSUSED */ 2233static int 2234usb_common_pwrlvl1(dev_info_t *dip, usb_common_power_t *pm, int *dev_state) 2235{ 2236 int rval; 2237 2238 /* Issue USB D2 command to the device here */ 2239 rval = usb_set_device_pwrlvl2(dip); 2240 ASSERT(rval == USB_SUCCESS); 2241 2242 return (USB_FAILURE); 2243} 2244 2245 2246/* ARGSUSED */ 2247static int 2248usb_common_pwrlvl2(dev_info_t *dip, usb_common_power_t *pm, int *dev_state) 2249{ 2250 int rval; 2251 2252 /* Issue USB D1 command to the device here */ 2253 rval = usb_set_device_pwrlvl1(dip); 2254 ASSERT(rval == USB_SUCCESS); 2255 2256 return (USB_FAILURE); 2257} 2258 2259 2260static int 2261usb_common_pwrlvl3(dev_info_t *dip, usb_common_power_t *pm, int *dev_state) 2262{ 2263 int rval; 2264 2265 switch (*dev_state) { 2266 case USB_DEV_PWRED_DOWN: 2267 /* Issue USB D0 command to the device here */ 2268 rval = usb_set_device_pwrlvl0(dip); 2269 ASSERT(rval == USB_SUCCESS); 2270 2271 *dev_state = USB_DEV_ONLINE; 2272 pm->uc_current_power = USB_DEV_OS_FULL_PWR; 2273 2274 /* FALLTHRU */ 2275 case USB_DEV_ONLINE: 2276 /* we are already in full power */ 2277 2278 /* FALLTHRU */ 2279 case USB_DEV_DISCONNECTED: 2280 case USB_DEV_SUSPENDED: 2281 /* allow a disconnected/cpr'ed device to go to low power */ 2282 2283 return (USB_SUCCESS); 2284 default: 2285 USB_DPRINTF_L2(DPRINT_MASK_USBA, usbai_log_handle, 2286 "usb_common_pwrlvl3: Illegal state (%s)", 2287 usb_str_dev_state(*dev_state)); 2288 2289 return (USB_FAILURE); 2290 } 2291} 2292 2293/* power management */ 2294int 2295usba_common_power(dev_info_t *dip, usb_common_power_t *pm, int *dev_state, 2296 int level) 2297{ 2298 int rval = DDI_FAILURE; 2299 2300 switch (level) { 2301 case USB_DEV_OS_PWR_OFF: 2302 rval = usb_common_pwrlvl0(dip, pm, dev_state); 2303 break; 2304 case USB_DEV_OS_PWR_1: 2305 rval = usb_common_pwrlvl1(dip, pm, dev_state); 2306 break; 2307 case USB_DEV_OS_PWR_2: 2308 rval = usb_common_pwrlvl2(dip, pm, dev_state); 2309 break; 2310 case USB_DEV_OS_FULL_PWR: 2311 rval = usb_common_pwrlvl3(dip, pm, dev_state); 2312 break; 2313 } 2314 2315 return ((rval == USB_SUCCESS) ? DDI_SUCCESS : DDI_FAILURE); 2316} 2317 2318/* 2319 * register and unregister for events from our parent for usb_mid and usb_ia 2320 * and maybe other nexus driver. 2321 * 2322 * Note: The cookie fields in usba_device structure is not used. They are 2323 * used/shared by children. 2324 */ 2325void 2326usba_common_register_events(dev_info_t *dip, uint_t if_num, 2327 void (*event_cb)(dev_info_t *, ddi_eventcookie_t, void *, void *)) 2328{ 2329 int rval; 2330 usba_evdata_t *evdata; 2331 ddi_eventcookie_t cookie; 2332 2333 USB_DPRINTF_L4(DPRINT_MASK_USBA, usbai_log_handle, 2334 "usb_common_register_events:"); 2335 2336 evdata = usba_get_evdata(dip); 2337 2338 /* get event cookie, discard level and icookie for now */ 2339 rval = ddi_get_eventcookie(dip, DDI_DEVI_REMOVE_EVENT, 2340 &cookie); 2341 2342 if (rval == DDI_SUCCESS) { 2343 rval = ddi_add_event_handler(dip, 2344 cookie, event_cb, NULL, &evdata->ev_rm_cb_id); 2345 2346 if (rval != DDI_SUCCESS) { 2347 2348 goto fail; 2349 } 2350 } 2351 rval = ddi_get_eventcookie(dip, DDI_DEVI_INSERT_EVENT, 2352 &cookie); 2353 if (rval == DDI_SUCCESS) { 2354 rval = ddi_add_event_handler(dip, cookie, event_cb, 2355 NULL, &evdata->ev_ins_cb_id); 2356 2357 if (rval != DDI_SUCCESS) { 2358 2359 goto fail; 2360 } 2361 } 2362 rval = ddi_get_eventcookie(dip, USBA_PRE_SUSPEND_EVENT, &cookie); 2363 if (rval == DDI_SUCCESS) { 2364 rval = ddi_add_event_handler(dip, 2365 cookie, event_cb, NULL, &evdata->ev_suspend_cb_id); 2366 2367 if (rval != DDI_SUCCESS) { 2368 2369 goto fail; 2370 } 2371 } 2372 rval = ddi_get_eventcookie(dip, USBA_POST_RESUME_EVENT, &cookie); 2373 if (rval == DDI_SUCCESS) { 2374 rval = ddi_add_event_handler(dip, cookie, event_cb, NULL, 2375 &evdata->ev_resume_cb_id); 2376 2377 if (rval != DDI_SUCCESS) { 2378 2379 goto fail; 2380 } 2381 } 2382 2383 return; 2384 2385 2386fail: 2387 usba_common_unregister_events(dip, if_num); 2388 2389} 2390 2391void 2392usba_common_unregister_events(dev_info_t *dip, uint_t if_num) 2393{ 2394 usba_evdata_t *evdata; 2395 usba_device_t *usba_device = usba_get_usba_device(dip); 2396 int i; 2397 2398 evdata = usba_get_evdata(dip); 2399 2400 if (evdata->ev_rm_cb_id != NULL) { 2401 (void) ddi_remove_event_handler(evdata->ev_rm_cb_id); 2402 evdata->ev_rm_cb_id = NULL; 2403 } 2404 2405 if (evdata->ev_ins_cb_id != NULL) { 2406 (void) ddi_remove_event_handler(evdata->ev_ins_cb_id); 2407 evdata->ev_ins_cb_id = NULL; 2408 } 2409 2410 if (evdata->ev_suspend_cb_id != NULL) { 2411 (void) ddi_remove_event_handler(evdata->ev_suspend_cb_id); 2412 evdata->ev_suspend_cb_id = NULL; 2413 } 2414 2415 if (evdata->ev_resume_cb_id != NULL) { 2416 (void) ddi_remove_event_handler(evdata->ev_resume_cb_id); 2417 evdata->ev_resume_cb_id = NULL; 2418 } 2419 2420 /* clear event data for children, required for cfgmadm unconfigure */ 2421 if (usb_owns_device(dip)) { 2422 usba_free_evdata(usba_device->usb_evdata); 2423 usba_device->usb_evdata = NULL; 2424 usba_device->rm_cookie = NULL; 2425 usba_device->ins_cookie = NULL; 2426 usba_device->suspend_cookie = NULL; 2427 usba_device->resume_cookie = NULL; 2428 } else { 2429 for (i = 0; i < if_num; i++) { 2430 usba_device->usb_client_flags[usba_get_ifno(dip) + i] 2431 &= ~USBA_CLIENT_FLAG_EV_CBS; 2432 } 2433 } 2434} |
|