Changeset 5994cc3 in mainline
- Timestamp:
- 2012-12-16T20:08:54Z (12 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 9c7ed9c
- Parents:
- ddab093
- Location:
- uspace
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/bus/usb/ohci/ohci.c
rddab093 r5994cc3 46 46 #include "hc.h" 47 47 48 typedef struct ohci {49 ddf_fun_t *hc_fun;50 ddf_fun_t *rh_fun;51 } ohci_t;52 48 53 static inline ohci_t *dev_to_ohci(ddf_dev_t *dev)54 {55 return ddf_dev_data_get(dev);56 }57 58 static inline hcd_t *dev_to_hcd(ddf_dev_t *dev)59 {60 ohci_t *ohci = dev_to_ohci(dev);61 if (!ohci || !ohci->hc_fun) {62 usb_log_error("Invalid OHCI device.\n");63 return NULL;64 }65 return ddf_fun_data_get(ohci->hc_fun);66 }67 68 static inline hc_t * dev_to_hc(ddf_dev_t *dev)69 {70 hcd_t *hcd = dev_to_hcd(dev);71 if (!hcd) {72 usb_log_error("Invalid OHCI HCD");73 return NULL;74 }75 return hcd->private_data;76 }77 49 78 50 /** IRQ handling callback, identifies device … … 85 57 { 86 58 assert(dev); 87 hc _t *hc = dev_to_hc(dev);88 if (!hc ) {59 hcd_t *hcd = dev_to_hcd(dev); 60 if (!hcd || !hcd->private_data) { 89 61 usb_log_warning("Interrupt on device that is not ready.\n"); 90 62 return; … … 92 64 93 65 const uint16_t status = IPC_GET_ARG1(*call); 94 hc_interrupt(hc , status);66 hc_interrupt(hcd->private_data, status); 95 67 } 96 97 /** Get USB address assigned to root hub.98 *99 * @param[in] fun Root hub function.100 * @param[out] address Store the address here.101 * @return Error code.102 */103 static int rh_get_my_address(ddf_fun_t *fun, usb_address_t *address)104 {105 assert(fun);106 107 if (address != NULL) {108 hc_t *hc = dev_to_hc(ddf_fun_get_dev(fun));109 assert(hc);110 *address = hc->rh.address;111 }112 113 return EOK;114 }115 116 /** Gets handle of the respective hc (this device, hc function).117 *118 * @param[in] root_hub_fun Root hub function seeking hc handle.119 * @param[out] handle Place to write the handle.120 * @return Error code.121 */122 static int rh_get_hc_handle(ddf_fun_t *fun, devman_handle_t *handle)123 {124 assert(fun);125 126 if (handle != NULL) {127 ddf_fun_t *hc_fun = dev_to_ohci(ddf_fun_get_dev(fun))->hc_fun;128 assert(hc_fun);129 *handle = ddf_fun_get_handle(hc_fun);130 }131 return EOK;132 }133 134 /** Root hub USB interface */135 static usb_iface_t usb_iface = {136 .get_hc_handle = rh_get_hc_handle,137 .get_my_address = rh_get_my_address,138 };139 140 /** Standard USB HC options (HC interface) */141 static ddf_dev_ops_t hc_ops = {142 .interfaces[USBHC_DEV_IFACE] = &hcd_iface,143 };144 145 /** Standard USB RH options (RH interface) */146 static ddf_dev_ops_t rh_ops = {147 .interfaces[USB_DEV_IFACE] = &usb_iface,148 };149 68 150 69 /** Initialize hc and rh ddf structures and their respective drivers. … … 159 78 * - registers interrupt handler 160 79 */ 161 static int device_setup_hcd(ddf_dev_t *device)162 {163 if (device == NULL)164 return EBADMEM;165 166 ohci_t *instance = ddf_dev_data_alloc(device, sizeof(ohci_t));167 if (instance == NULL) {168 usb_log_error("Failed to allocate OHCI driver.\n");169 return ENOMEM;170 }171 172 #define CHECK_RET_DEST_FREE_RETURN(ret, message...) \173 if (ret != EOK) { \174 if (instance->hc_fun) { \175 ddf_fun_destroy(instance->hc_fun); \176 } \177 usb_log_error(message); \178 return ret; \179 } else (void)0180 181 instance->hc_fun = ddf_fun_create(device, fun_exposed, "ohci_hc");182 int ret = instance->hc_fun ? EOK : ENOMEM;183 CHECK_RET_DEST_FREE_RETURN(ret,184 "Failed to create OHCI HC function: %s.\n", str_error(ret));185 ddf_fun_set_ops(instance->hc_fun, &hc_ops);186 hcd_t *hcd = ddf_fun_data_alloc(instance->hc_fun, sizeof(hcd_t));187 ret = hcd ? EOK : ENOMEM;188 CHECK_RET_DEST_FREE_RETURN(ret,189 "Failed to allocate HCD structure: %s.\n", str_error(ret));190 191 hcd_init(hcd, USB_SPEED_FULL, BANDWIDTH_AVAILABLE_USB11,192 bandwidth_count_usb11);193 194 ret = ddf_fun_bind(instance->hc_fun);195 CHECK_RET_DEST_FREE_RETURN(ret,196 "Failed to bind OHCI device function: %s.\n", str_error(ret));197 198 #define CHECK_RET_UNBIND_FREE_RETURN(ret, message...) \199 if (ret != EOK) { \200 ddf_fun_unbind(instance->hc_fun); \201 CHECK_RET_DEST_FREE_RETURN(ret, \202 "Failed to add OHCI to HC class: %s.\n", str_error(ret)); \203 } else (void)0204 ret = ddf_fun_add_to_category(instance->hc_fun, USB_HC_CATEGORY);205 CHECK_RET_UNBIND_FREE_RETURN(ret,206 "Failed to add hc to category: %s\n", str_error(ret));207 208 /* HC should be ok at this point (except it can't do anything) */209 210 return EOK;211 }212 213 80 int device_setup_ohci(ddf_dev_t *device) 214 81 { … … 264 131 } 265 132 266 ret = device_setup_hcd(device);133 ret = hcd_setup_device(device); 267 134 if (ret != EOK) { 268 135 unregister_interrupt_handler(device, irq); … … 285 152 CHECK_RET_CLEAN_RETURN(ret, "Failed to init hc: %s.\n", str_error(ret)); 286 153 287 ohci_t *ohci = dev_to_ohci(device);288 289 154 hcd_set_implementation(dev_to_hcd(device), hc_impl, 290 155 hc_schedule, ohci_endpoint_init, ohci_endpoint_fini); 156 ret = hcd_setup_hub(dev_to_hcd(device), &hc_impl->rh.address, device); 157 CHECK_RET_CLEAN_RETURN(ret, 158 "Failed to register OHCI root hub: %s.\n", str_error(ret)); 291 159 292 #define CHECK_RET_FINI_RETURN(ret, message...) \293 if (ret != EOK) { \294 hc_fini(hc_impl); \295 CHECK_RET_CLEAN_RETURN(ret, message); \296 } else (void)0297 ohci->rh_fun = ddf_fun_create(device, fun_inner, "ohci_rh");298 ret = ohci->rh_fun ? EOK : ENOMEM;299 CHECK_RET_FINI_RETURN(ret,300 "Failed to create OHCI RH function: %s.\n", str_error(ret));301 ddf_fun_set_ops(ohci->rh_fun, &rh_ops);302 303 ret = hcd_register_hub(dev_to_hcd(device), &hc_impl->rh.address, ohci->rh_fun);304 CHECK_RET_FINI_RETURN(ret,305 "Failed to register OHCI root hub: %s.\n", str_error(ret));306 160 return ret; 307 161 } -
uspace/lib/usbhost/include/usb/host/hcd.h
rddab093 r5994cc3 67 67 }; 68 68 69 69 70 /** Initialize hcd_t structure. 70 71 * Initializes device and endpoint managers. Sets data and hook pointer to NULL. … … 109 110 } 110 111 111 int hcd_register_hub(hcd_t *instance, usb_address_t *address, ddf_fun_t *hub_fun); 112 int hcd_setup_device(ddf_dev_t *device); 113 int hcd_setup_hub(hcd_t *instance, usb_address_t *address, ddf_dev_t *dev); 112 114 115 hcd_t *dev_to_hcd(ddf_dev_t *dev); 113 116 114 117 /** Data retrieve wrapper. -
uspace/lib/usbhost/src/hcd.c
rddab093 r5994cc3 36 36 #include <errno.h> 37 37 #include <str_error.h> 38 #include <usb_iface.h> 38 39 #include <usb/debug.h> 39 40 40 41 #include <usb/host/hcd.h> 42 43 typedef struct hc_dev { 44 ddf_fun_t *hc_fun; 45 ddf_fun_t *rh_fun; 46 } hc_dev_t; 47 48 static hc_dev_t *dev_to_hc_dev(ddf_dev_t *dev) 49 { 50 return ddf_dev_data_get(dev); 51 } 52 53 hcd_t *dev_to_hcd(ddf_dev_t *dev) 54 { 55 hc_dev_t *hc_dev = dev_to_hc_dev(dev); 56 if (!hc_dev || !hc_dev->hc_fun) { 57 usb_log_error("Invalid OHCI device.\n"); 58 return NULL; 59 } 60 return ddf_fun_data_get(hc_dev->hc_fun); 61 } 62 63 typedef struct usb_dev { 64 usb_address_t address; 65 usb_speed_t speed; 66 devman_handle_t handle; 67 } usb_dev_t; 68 69 /** Get USB address assigned to root hub. 70 * 71 * @param[in] fun Root hub function. 72 * @param[out] address Store the address here. 73 * @return Error code. 74 */ 75 static int rh_get_my_address(ddf_fun_t *fun, usb_address_t *address) 76 { 77 assert(fun); 78 if (address != NULL) { 79 usb_dev_t *usb_dev = ddf_fun_data_get(fun); 80 *address = usb_dev->address; 81 } 82 return EOK; 83 } 84 85 /** Gets handle of the respective hc (this device, hc function). 86 * 87 * @param[in] root_hub_fun Root hub function seeking hc handle. 88 * @param[out] handle Place to write the handle. 89 * @return Error code. 90 */ 91 static int rh_get_hc_handle(ddf_fun_t *fun, devman_handle_t *handle) 92 { 93 assert(fun); 94 95 if (handle != NULL) { 96 usb_dev_t *usb_dev = ddf_fun_data_get(fun); 97 *handle = usb_dev->handle; 98 } 99 return EOK; 100 } 101 102 /** Root hub USB interface */ 103 static usb_iface_t usb_iface = { 104 .get_hc_handle = rh_get_hc_handle, 105 .get_my_address = rh_get_my_address, 106 }; 107 /** Standard USB RH options (RH interface) */ 108 static ddf_dev_ops_t rh_ops = { 109 .interfaces[USB_DEV_IFACE] = &usb_iface, 110 }; 111 112 /** Standard USB HC options (HC interface) */ 113 static ddf_dev_ops_t hc_ops = { 114 .interfaces[USBHC_DEV_IFACE] = &hcd_iface, 115 }; 41 116 42 117 /** Announce root hub to the DDF … … 46 121 * @return Error code 47 122 */ 48 int hcd_ register_hub(hcd_t *instance, usb_address_t *address, ddf_fun_t *hub_fun)123 int hcd_setup_hub(hcd_t *instance, usb_address_t *address, ddf_dev_t *device) 49 124 { 50 125 assert(instance); 51 126 assert(address); 52 assert(hub_fun); 53 54 int ret = usb_device_manager_request_address( 55 &instance->dev_manager, address, false, 56 USB_SPEED_FULL); 127 assert(device); 128 129 hc_dev_t *hc_dev = ddf_dev_data_get(device); 130 hc_dev->rh_fun = ddf_fun_create(device, fun_inner, "rh"); 131 if (!hc_dev->rh_fun) 132 return ENOMEM; 133 usb_dev_t *rh = ddf_fun_data_alloc(hc_dev->rh_fun, sizeof(usb_dev_t)); 134 if (!rh) { 135 ddf_fun_destroy(hc_dev->rh_fun); 136 return ENOMEM; 137 } 138 139 140 int ret = usb_device_manager_request_address(&instance->dev_manager, 141 address, false, USB_SPEED_FULL); 57 142 if (ret != EOK) { 58 143 usb_log_error("Failed to get root hub address: %s\n", 59 144 str_error(ret)); 145 ddf_fun_destroy(hc_dev->rh_fun); 60 146 return ret; 61 147 } 148 149 rh->address = *address; 150 rh->speed = USB_SPEED_FULL; 151 rh->handle = ddf_fun_get_handle(hc_dev->hc_fun); 152 153 ddf_fun_set_ops(hc_dev->rh_fun, &rh_ops); 62 154 63 155 #define CHECK_RET_UNREG_RETURN(ret, message...) \ … … 69 161 usb_device_manager_release_address( \ 70 162 &instance->dev_manager, *address); \ 163 ddf_fun_destroy(hc_dev->rh_fun); \ 71 164 return ret; \ 72 165 } else (void)0 … … 80 173 str_error(ret)); 81 174 82 ret = ddf_fun_add_match_id(h ub_fun, "usb&class=hub", 100);175 ret = ddf_fun_add_match_id(hc_dev->rh_fun, "usb&class=hub", 100); 83 176 CHECK_RET_UNREG_RETURN(ret, 84 177 "Failed to add root hub match-id: %s.\n", str_error(ret)); 85 178 86 ret = ddf_fun_bind(h ub_fun);179 ret = ddf_fun_bind(hc_dev->rh_fun); 87 180 CHECK_RET_UNREG_RETURN(ret, 88 181 "Failed to bind root hub function: %s.\n", str_error(ret)); 89 182 90 183 ret = usb_device_manager_bind_address(&instance->dev_manager, 91 *address, ddf_fun_get_handle(h ub_fun));184 *address, ddf_fun_get_handle(hc_dev->rh_fun)); 92 185 if (ret != EOK) 93 186 usb_log_warning("Failed to bind root hub address: %s.\n", 94 187 str_error(ret)); 95 188 189 96 190 return EOK; 97 191 #undef CHECK_RET_UNREG_RETURN 192 } 193 194 /** Initialize hc structures. 195 * 196 * @param[in] device DDF instance of the device to use. 197 * 198 * This function does all the preparatory work for hc driver implementation. 199 * - gets device hw resources 200 * - disables OHCI legacy support 201 * - asks for interrupt 202 * - registers interrupt handler 203 */ 204 int hcd_setup_device(ddf_dev_t *device) 205 { 206 if (device == NULL) 207 return EBADMEM; 208 209 hc_dev_t *instance = ddf_dev_data_alloc(device, sizeof(hc_dev_t)); 210 if (instance == NULL) { 211 usb_log_error("Failed to allocate OHCI driver.\n"); 212 return ENOMEM; 213 } 214 215 #define CHECK_RET_DEST_FREE_RETURN(ret, message...) \ 216 if (ret != EOK) { \ 217 if (instance->hc_fun) { \ 218 ddf_fun_destroy(instance->hc_fun); \ 219 } \ 220 usb_log_error(message); \ 221 return ret; \ 222 } else (void)0 223 224 instance->hc_fun = ddf_fun_create(device, fun_exposed, "hc"); 225 int ret = instance->hc_fun ? EOK : ENOMEM; 226 CHECK_RET_DEST_FREE_RETURN(ret, 227 "Failed to create OHCI HC function: %s.\n", str_error(ret)); 228 ddf_fun_set_ops(instance->hc_fun, &hc_ops); 229 hcd_t *hcd = ddf_fun_data_alloc(instance->hc_fun, sizeof(hcd_t)); 230 ret = hcd ? EOK : ENOMEM; 231 CHECK_RET_DEST_FREE_RETURN(ret, 232 "Failed to allocate HCD structure: %s.\n", str_error(ret)); 233 234 hcd_init(hcd, USB_SPEED_FULL, BANDWIDTH_AVAILABLE_USB11, 235 bandwidth_count_usb11); 236 237 ret = ddf_fun_bind(instance->hc_fun); 238 CHECK_RET_DEST_FREE_RETURN(ret, 239 "Failed to bind OHCI device function: %s.\n", str_error(ret)); 240 241 #define CHECK_RET_UNBIND_FREE_RETURN(ret, message...) \ 242 if (ret != EOK) { \ 243 ddf_fun_unbind(instance->hc_fun); \ 244 CHECK_RET_DEST_FREE_RETURN(ret, \ 245 "Failed to add OHCI to HC class: %s.\n", str_error(ret)); \ 246 } else (void)0 247 ret = ddf_fun_add_to_category(instance->hc_fun, USB_HC_CATEGORY); 248 CHECK_RET_UNBIND_FREE_RETURN(ret, 249 "Failed to add hc to category: %s\n", str_error(ret)); 250 251 /* HC should be ok at this point (except it can't do anything) */ 252 253 return EOK; 98 254 } 99 255 -
uspace/lib/usbhost/src/iface.c
rddab093 r5994cc3 215 215 assert(hcd); 216 216 usb_log_debug("Address release %d.\n", address); 217 usb_device_manager_release_address(&hcd->dev_manager, address);218 217 usb_endpoint_manager_remove_address(&hcd->ep_manager, address, 219 218 unregister_helper_warn, hcd); 219 usb_device_manager_release_address(&hcd->dev_manager, address); 220 220 return EOK; 221 221 }
Note:
See TracChangeset
for help on using the changeset viewer.