Changes in / [bb41b85:c32688d] in mainline
- Files:
-
- 4 added
- 7 deleted
- 49 edited
Legend:
- Unmodified
- Added
- Removed
-
dist/Makefile
rbb41b85 rc32688d 43 43 44 44 SUFFIX = $(suffix $(IMGFILE)) 45 46 ifdef PROFILE 47 DISTFILE = Helenos-$(shell echo $(PROFILE) | tr '/' '-')$(SUFFIX) 48 else 49 DISTFILE = HelenOS-$(RELEASE)-$(PLATFORM)-$(MACHINE)-$(PROCESSOR)$(SUFFIX) 50 endif 45 DISTFILE = HelenOS-$(RELEASE)-$(PLATFORM)-$(MACHINE)-$(PROCESSOR)$(SUFFIX) 51 46 52 47 .PHONY: all clean dist distfile … … 58 53 cp $< $@ 59 54 60 $(IMGFILE):61 $(MAKE) -C ..62 63 55 dist: 64 56 for profile in $(PROFILES); do \ -
uspace/app/usbinfo/info.c
rbb41b85 rc32688d 65 65 goto leave; 66 66 } 67 rc = usb_endpoint_pipe_probe_default_control(&ctrl_pipe);68 if (rc != EOK) {69 fprintf(stderr,70 NAME ": probing default control pipe failed: %s.\n",71 str_error(rc));72 goto leave;73 }74 67 rc = usb_endpoint_pipe_start_session(&ctrl_pipe); 75 68 if (rc != EOK) { -
uspace/app/usbinfo/main.c
rbb41b85 rc32688d 82 82 83 83 if (str_cmp(path, "uhci") == 0) { 84 path = "/hw/pci0/00:01.2/uhci -hc";84 path = "/hw/pci0/00:01.2/uhci"; 85 85 } 86 86 -
uspace/doc/doxygroups.h
rbb41b85 rc32688d 253 253 * @defgroup drvusbuhci UHCI driver 254 254 * @ingroup usb 255 * @brief Drivers for USB UHCI host controller and root hub. 256 */ 257 258 /** 259 * @defgroup drvusbuhcirh UHCI root hub driver 260 * @ingroup drvusbuhci 261 * @brief Driver for UHCI complaint root hub. 262 */ 263 264 /** 265 * @defgroup drvusbuhcihc UHCI host controller driver 266 * @ingroup drvusbuhci 267 * @brief Driver for UHCI complaint USB host controller. 268 */ 255 * @brief Driver for USB host controller UHCI. 256 */ 269 257 270 258 /** -
uspace/drv/ehci-hcd/main.c
rbb41b85 rc32688d 27 27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 28 */ 29 /** @addtogroup drvusbehci29 /** @addtogroup usbdrvehci 30 30 * @{ 31 31 */ -
uspace/drv/ehci-hcd/pci.c
rbb41b85 rc32688d 247 247 248 248 249 if ((value & USBLEGSUP_BIOS_CONTROL) == 0) {249 if ((value & USBLEGSUP_BIOS_CONTROL) != 0) { 250 250 usb_log_info("BIOS released control after %d usec.\n", wait); 251 251 } else { 252 252 /* BIOS failed to hand over control, this should not happen. */ 253 usb_log_warning( "BIOS failed to release control after 253 usb_log_warning( "BIOS failed to release control after" 254 254 "%d usecs, force it.\n", wait); 255 255 ret = async_req_3_0(parent_phone, DEV_IFACE_ID(PCI_DEV_IFACE), … … 258 258 CHECK_RET_HANGUP_RETURN(ret, 259 259 "Failed(%d) to force OS EHCI control.\n", ret); 260 /* TODO: This does not seem to work on my machine */ 260 261 } 261 262 … … 279 280 usb_log_debug2("USBLEGSUP: %x.\n", value); 280 281 281 282 * TURN OFF EHCI FOR NOW, DRIVER WILL REINITIALIZE IT 283 282 /* 283 * TURN OFF EHCI FOR NOW, REMOVE IF THE DRIVER IS IMPLEMENTED 284 */ 284 285 285 286 /* Get size of capability registers in memory space. */ -
uspace/drv/pciintel/pci.c
rbb41b85 rc32688d 92 92 pci_fun_t *dev_data = (pci_fun_t *) fnode->driver_data; 93 93 94 95 94 sysarg_t apic; 95 sysarg_t i8259; 96 96 97 97 int irc_phone = -1; 98 int irc_service = -1;99 100 101 98 int irc_service = 0; 99 100 if ((sysinfo_get_value("apic", &apic) == EOK) && (apic)) { 101 irc_service = SERVICE_APIC; 102 102 } else if ((sysinfo_get_value("i8259", &i8259) == EOK) && (i8259)) { 103 104 } 105 106 if (irc_service == -1) { 103 irc_service = SERVICE_I8259; 104 } 105 106 if (irc_service == 0) 107 107 return false; 108 }109 108 110 109 irc_phone = service_connect_blocking(irc_service, 0, 0); 111 if (irc_phone < 0) {110 if (irc_phone < 0) 112 111 return false; 113 }114 112 115 113 size_t i; 116 114 for (i = 0; i < dev_data->hw_resources.count; i++) { 117 115 if (dev_data->hw_resources.resources[i].type == INTERRUPT) { 118 116 int irq = dev_data->hw_resources.resources[i].res.interrupt.irq; -
uspace/drv/uhci-hcd/Makefile
rbb41b85 rc32688d 35 35 iface.c \ 36 36 main.c \ 37 root_hub.c \ 37 38 transfer_list.c \ 38 39 uhci.c \ 39 uhci_hc.c \40 uhci_rh.c \41 40 uhci_struct/transfer_descriptor.c \ 42 41 utils/device_keeper.c \ -
uspace/drv/uhci-hcd/batch.c
rbb41b85 rc32688d 26 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 27 */ 28 /** @addtogroup drvusbuhcihc28 /** @addtogroup usb 29 29 * @{ 30 30 */ 31 31 /** @file 32 * @brief UHCI driver USB transaction structure32 * @brief UHCI driver 33 33 */ 34 34 #include <errno.h> … … 40 40 #include "batch.h" 41 41 #include "transfer_list.h" 42 #include "uhci _hc.h"42 #include "uhci.h" 43 43 #include "utils/malloc32.h" 44 44 45 45 #define DEFAULT_ERROR_COUNT 3 46 47 static int batch_schedule(batch_t *instance); 46 48 47 49 static void batch_control(batch_t *instance, … … 52 54 static void batch_call_in_and_dispose(batch_t *instance); 53 55 static void batch_call_out_and_dispose(batch_t *instance); 54 55 56 /** Allocate memory and initialize internal data structure. 56 static void batch_dispose(batch_t *instance); 57 58 59 /** Allocates memory and initializes internal data structures. 57 60 * 58 61 * @param[in] fun DDF function to pass to callback. … … 69 72 * @param[in] arg additional parameter to func_in or func_out 70 73 * @param[in] manager Pointer to toggle management structure. 71 * @return Valid pointer if all substructures were successfully created, 72 * NULL otherwise. 73 * 74 * Determines the number of needed packets (TDs). Prepares a transport buffer 75 * (that is accessible by the hardware). Initializes parameters needed for the 76 * transaction and callback. 74 * @return False, if there is an active TD, true otherwise. 77 75 */ 78 76 batch_t * batch_get(ddf_fun_t *fun, usb_target_t target, … … 102 100 bzero(instance, sizeof(batch_t)); 103 101 104 instance->qh = malloc32(sizeof(q h_t));102 instance->qh = malloc32(sizeof(queue_head_t)); 105 103 CHECK_NULL_DISPOSE_RETURN(instance->qh, 106 104 "Failed to allocate batch queue head.\n"); 107 q h_init(instance->qh);105 queue_head_init(instance->qh); 108 106 109 107 instance->packets = (size + max_packet_size - 1) / max_packet_size; … … 116 114 instance->tds, "Failed to allocate transfer descriptors.\n"); 117 115 bzero(instance->tds, sizeof(td_t) * instance->packets); 116 117 // const size_t transport_size = max_packet_size * instance->packets; 118 118 119 119 if (size > 0) { … … 143 143 instance->speed = speed; 144 144 instance->manager = manager; 145 instance->callback_out = func_out; 146 instance->callback_in = func_in; 147 148 qh_set_element_td(instance->qh, addr_to_phys(instance->tds)); 145 146 if (func_out) 147 instance->callback_out = func_out; 148 if (func_in) 149 instance->callback_in = func_in; 150 151 queue_head_set_element_td(instance->qh, addr_to_phys(instance->tds)); 149 152 150 153 usb_log_debug("Batch(%p) %d:%d memory structures ready.\n", … … 153 156 } 154 157 /*----------------------------------------------------------------------------*/ 155 /** Check batch TDs for activity.158 /** Checks batch TDs for activity. 156 159 * 157 160 * @param[in] instance Batch structure to use. 158 161 * @return False, if there is an active TD, true otherwise. 159 *160 * Walk all TDs. Stop with false if there is an active one (it is to be161 * processed). Stop with true if an error is found. Return true if the last TS162 * is reached.163 162 */ 164 163 bool batch_is_complete(batch_t *instance) … … 178 177 usb_log_debug("Batch(%p) found error TD(%d):%x.\n", 179 178 instance, i, instance->tds[i].status); 180 td_print_status(&instance->tds[i]);181 179 182 180 device_keeper_set_toggle(instance->manager, … … 199 197 * 200 198 * @param[in] instance Batch structure to use. 201 *202 * Uses genercir control function with pids OUT and IN.203 199 */ 204 200 void batch_control_write(batch_t *instance) 205 201 { 206 202 assert(instance); 207 /* We are data out, we are supposed to provide data */203 /* we are data out, we are supposed to provide data */ 208 204 memcpy(instance->transport_buffer, instance->buffer, 209 205 instance->buffer_size); … … 211 207 instance->next_step = batch_call_out_and_dispose; 212 208 usb_log_debug("Batch(%p) CONTROL WRITE initialized.\n", instance); 209 batch_schedule(instance); 213 210 } 214 211 /*----------------------------------------------------------------------------*/ … … 216 213 * 217 214 * @param[in] instance Batch structure to use. 218 *219 * Uses generic control with pids IN and OUT.220 215 */ 221 216 void batch_control_read(batch_t *instance) … … 225 220 instance->next_step = batch_call_in_and_dispose; 226 221 usb_log_debug("Batch(%p) CONTROL READ initialized.\n", instance); 227 } 228 /*----------------------------------------------------------------------------*/ 229 /** Prepare interrupt in transaction. 230 * 231 * @param[in] instance Batch structure to use. 232 * 233 * Data transaction with PID_IN. 222 batch_schedule(instance); 223 } 224 /*----------------------------------------------------------------------------*/ 225 /** Prepares interrupt in transaction. 226 * 227 * @param[in] instance Batch structure to use. 234 228 */ 235 229 void batch_interrupt_in(batch_t *instance) … … 239 233 instance->next_step = batch_call_in_and_dispose; 240 234 usb_log_debug("Batch(%p) INTERRUPT IN initialized.\n", instance); 241 } 242 /*----------------------------------------------------------------------------*/ 243 /** Prepare interrupt out transaction. 244 * 245 * @param[in] instance Batch structure to use. 246 * 247 * Data transaction with PID_OUT. 235 batch_schedule(instance); 236 } 237 /*----------------------------------------------------------------------------*/ 238 /** Prepares interrupt out transaction. 239 * 240 * @param[in] instance Batch structure to use. 248 241 */ 249 242 void batch_interrupt_out(batch_t *instance) 250 243 { 251 244 assert(instance); 252 /* We are data out, we are supposed to provide data */245 /* we are data out, we are supposed to provide data */ 253 246 memcpy(instance->transport_buffer, instance->buffer, instance->buffer_size); 254 247 batch_data(instance, USB_PID_OUT); 255 248 instance->next_step = batch_call_out_and_dispose; 256 249 usb_log_debug("Batch(%p) INTERRUPT OUT initialized.\n", instance); 257 } 258 /*----------------------------------------------------------------------------*/ 259 /** Prepare bulk in transaction. 260 * 261 * @param[in] instance Batch structure to use. 262 * 263 * Data transaction with PID_IN. 250 batch_schedule(instance); 251 } 252 /*----------------------------------------------------------------------------*/ 253 /** Prepares bulk in transaction. 254 * 255 * @param[in] instance Batch structure to use. 264 256 */ 265 257 void batch_bulk_in(batch_t *instance) … … 269 261 instance->next_step = batch_call_in_and_dispose; 270 262 usb_log_debug("Batch(%p) BULK IN initialized.\n", instance); 271 } 272 /*----------------------------------------------------------------------------*/ 273 /** Prepare bulk out transaction. 274 * 275 * @param[in] instance Batch structure to use. 276 * 277 * Data transaction with PID_OUT. 263 batch_schedule(instance); 264 } 265 /*----------------------------------------------------------------------------*/ 266 /** Prepares bulk out transaction. 267 * 268 * @param[in] instance Batch structure to use. 278 269 */ 279 270 void batch_bulk_out(batch_t *instance) 280 271 { 281 272 assert(instance); 282 /* We are data out, we are supposed to provide data */283 273 memcpy(instance->transport_buffer, instance->buffer, instance->buffer_size); 284 274 batch_data(instance, USB_PID_OUT); 285 275 instance->next_step = batch_call_out_and_dispose; 286 276 usb_log_debug("Batch(%p) BULK OUT initialized.\n", instance); 287 } 288 /*----------------------------------------------------------------------------*/ 289 /** Prepare generic data transaction 277 batch_schedule(instance); 278 } 279 /*----------------------------------------------------------------------------*/ 280 /** Prepares generic data transaction 290 281 * 291 282 * @param[in] instance Batch structure to use. 292 283 * @param[in] pid to use for data packets. 293 *294 * Packets with alternating toggle bit and supplied pid value.295 * The last packet is marked with IOC flag.296 284 */ 297 285 void batch_data(batch_t *instance, usb_packet_id pid) … … 330 318 ++packet; 331 319 } 332 td_set_ioc(&instance->tds[packet - 1]);333 320 device_keeper_set_toggle(instance->manager, instance->target, toggle); 334 321 } 335 322 /*----------------------------------------------------------------------------*/ 336 /** Prepare generic control transaction323 /** Prepares generic control transaction 337 324 * 338 325 * @param[in] instance Batch structure to use. 339 326 * @param[in] data_stage to use for data packets. 340 327 * @param[in] status_stage to use for data packets. 341 *342 * Setup stage with toggle 0 and USB_PID_SETUP.343 * Data stage with alternating toggle and pid supplied by parameter.344 * Status stage with toggle 1 and pid supplied by parameter.345 * The last packet is marked with IOC.346 328 */ 347 329 void batch_control(batch_t *instance, … … 387 369 0, 1, false, low_speed, instance->target, status_stage, NULL, NULL); 388 370 389 td_set_ioc(&instance->tds[packet]); 371 372 instance->tds[packet].status |= TD_STATUS_COMPLETE_INTERRUPT_FLAG; 390 373 usb_log_debug2("Control last TD status: %x.\n", 391 374 instance->tds[packet].status); 392 375 } 393 376 /*----------------------------------------------------------------------------*/ 394 /** Prepare data, get error status and call callback in. 395 * 396 * @param[in] instance Batch structure to use. 397 * Copies data from transport buffer, and calls callback with appropriate 398 * parameters. 377 /** Prepares data, gets error status and calls callback in. 378 * 379 * @param[in] instance Batch structure to use. 399 380 */ 400 381 void batch_call_in(batch_t *instance) … … 403 384 assert(instance->callback_in); 404 385 405 /* We are data in, we need data */386 /* we are data in, we need data */ 406 387 memcpy(instance->buffer, instance->transport_buffer, 407 388 instance->buffer_size); … … 416 397 } 417 398 /*----------------------------------------------------------------------------*/ 418 /** Get error status and callcallback out.399 /** Gets error status and calls callback out. 419 400 * 420 401 * @param[in] instance Batch structure to use. … … 432 413 } 433 414 /*----------------------------------------------------------------------------*/ 434 /** Helper function calls callback and correctly disposes of batch structure.415 /** Prepares data, gets error status, calls callback in and dispose. 435 416 * 436 417 * @param[in] instance Batch structure to use. … … 443 424 } 444 425 /*----------------------------------------------------------------------------*/ 445 /** Helper function calls callback and correctly disposes of batch structure.426 /** Gets error status, calls callback out and dispose. 446 427 * 447 428 * @param[in] instance Batch structure to use. … … 454 435 } 455 436 /*----------------------------------------------------------------------------*/ 456 /** Correctly dispose all used data structures.437 /** Correctly disposes all used data structures. 457 438 * 458 439 * @param[in] instance Batch structure to use. … … 469 450 free(instance); 470 451 } 452 /*----------------------------------------------------------------------------*/ 453 int batch_schedule(batch_t *instance) 454 { 455 assert(instance); 456 uhci_t *hc = fun_to_uhci(instance->fun); 457 assert(hc); 458 return uhci_schedule(hc, instance); 459 } 471 460 /** 472 461 * @} -
uspace/drv/uhci-hcd/batch.h
rbb41b85 rc32688d 26 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 27 */ 28 /** @addtogroup drvusbuhcihc28 /** @addtogroup usb 29 29 * @{ 30 30 */ 31 31 /** @file 32 * @brief UHCI driver USB transaction structure32 * @brief UHCI driver 33 33 */ 34 34 #ifndef DRV_UHCI_BATCH_H … … 50 50 usb_target_t target; 51 51 usb_transfer_type_t transfer_type; 52 usbhc_iface_transfer_in_callback_t callback_in; 53 usbhc_iface_transfer_out_callback_t callback_out; 52 union { 53 usbhc_iface_transfer_in_callback_t callback_in; 54 usbhc_iface_transfer_out_callback_t callback_out; 55 }; 54 56 void *arg; 55 57 char *transport_buffer; … … 63 65 int error; 64 66 ddf_fun_t *fun; 65 q h_t *qh;67 queue_head_t *qh; 66 68 td_t *tds; 67 69 void (*next_step)(struct batch*); … … 77 79 device_keeper_t *manager 78 80 ); 79 80 void batch_dispose(batch_t *instance);81 81 82 82 bool batch_is_complete(batch_t *instance); -
uspace/drv/uhci-hcd/iface.c
rbb41b85 rc32688d 26 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 27 */ 28 /** @addtogroup drvusbuhcihc28 /** @addtogroup usb 29 29 * @{ 30 30 */ 31 31 /** @file 32 * @brief UHCI driver hc interface implementation32 * @brief UHCI driver 33 33 */ 34 34 #include <ddf/driver.h> … … 40 40 41 41 #include "iface.h" 42 #include "uhci _hc.h"42 #include "uhci.h" 43 43 #include "utils/device_keeper.h" 44 44 … … 53 53 { 54 54 assert(fun); 55 uhci_ hc_t *hc = fun_to_uhci_hc(fun);55 uhci_t *hc = fun_to_uhci(fun); 56 56 assert(hc); 57 57 usb_log_debug("Default address request with speed %d.\n", speed); … … 68 68 { 69 69 assert(fun); 70 uhci_ hc_t *hc = fun_to_uhci_hc(fun);70 uhci_t *hc = fun_to_uhci(fun); 71 71 assert(hc); 72 72 usb_log_debug("Default address release.\n"); … … 86 86 { 87 87 assert(fun); 88 uhci_ hc_t *hc = fun_to_uhci_hc(fun);88 uhci_t *hc = fun_to_uhci(fun); 89 89 assert(hc); 90 90 assert(address); … … 109 109 { 110 110 assert(fun); 111 uhci_ hc_t *hc = fun_to_uhci_hc(fun);111 uhci_t *hc = fun_to_uhci(fun); 112 112 assert(hc); 113 113 usb_log_debug("Address bind %d-%d.\n", address, handle); … … 125 125 { 126 126 assert(fun); 127 uhci_ hc_t *hc = fun_to_uhci_hc(fun);127 uhci_t *hc = fun_to_uhci(fun); 128 128 assert(hc); 129 129 usb_log_debug("Address release %d.\n", address); … … 148 148 { 149 149 assert(fun); 150 uhci_ hc_t *hc = fun_to_uhci_hc(fun);150 uhci_t *hc = fun_to_uhci(fun); 151 151 assert(hc); 152 152 usb_speed_t speed = device_keeper_speed(&hc->device_manager, target.address); … … 161 161 return ENOMEM; 162 162 batch_interrupt_out(batch); 163 const int ret = uhci_hc_schedule(hc, batch);164 if (ret != EOK) {165 batch_dispose(batch);166 return ret;167 }168 163 return EOK; 169 164 } … … 185 180 { 186 181 assert(fun); 187 uhci_ hc_t *hc = fun_to_uhci_hc(fun);182 uhci_t *hc = fun_to_uhci(fun); 188 183 assert(hc); 189 184 usb_speed_t speed = device_keeper_speed(&hc->device_manager, target.address); … … 197 192 return ENOMEM; 198 193 batch_interrupt_in(batch); 199 const int ret = uhci_hc_schedule(hc, batch);200 if (ret != EOK) {201 batch_dispose(batch);202 return ret;203 }204 194 return EOK; 205 195 } … … 221 211 { 222 212 assert(fun); 223 uhci_ hc_t *hc = fun_to_uhci_hc(fun);213 uhci_t *hc = fun_to_uhci(fun); 224 214 assert(hc); 225 215 usb_speed_t speed = device_keeper_speed(&hc->device_manager, target.address); … … 234 224 return ENOMEM; 235 225 batch_bulk_out(batch); 236 const int ret = uhci_hc_schedule(hc, batch);237 if (ret != EOK) {238 batch_dispose(batch);239 return ret;240 }241 226 return EOK; 242 227 } … … 258 243 { 259 244 assert(fun); 260 uhci_ hc_t *hc = fun_to_uhci_hc(fun);245 uhci_t *hc = fun_to_uhci(fun); 261 246 assert(hc); 262 247 usb_speed_t speed = device_keeper_speed(&hc->device_manager, target.address); … … 270 255 return ENOMEM; 271 256 batch_bulk_in(batch); 272 const int ret = uhci_hc_schedule(hc, batch);273 if (ret != EOK) {274 batch_dispose(batch);275 return ret;276 }277 257 return EOK; 278 258 } … … 297 277 { 298 278 assert(fun); 299 uhci_ hc_t *hc = fun_to_uhci_hc(fun);300 assert(hc); 301 usb_speed_t speed = device_keeper_speed(&hc->device_manager, target.address); 302 usb_log_debug("Control WRITE (%d)%d:%d %zu(%zu).\n",303 speed,target.address, target.endpoint, size, max_packet_size);279 uhci_t *hc = fun_to_uhci(fun); 280 assert(hc); 281 usb_speed_t speed = device_keeper_speed(&hc->device_manager, target.address); 282 usb_log_debug("Control WRITE %d:%d %zu(%zu).\n", 283 target.address, target.endpoint, size, max_packet_size); 304 284 305 285 if (setup_size != 8) … … 313 293 device_keeper_reset_if_need(&hc->device_manager, target, setup_data); 314 294 batch_control_write(batch); 315 const int ret = uhci_hc_schedule(hc, batch);316 if (ret != EOK) {317 batch_dispose(batch);318 return ret;319 }320 295 return EOK; 321 296 } … … 340 315 { 341 316 assert(fun); 342 uhci_ hc_t *hc = fun_to_uhci_hc(fun);343 assert(hc); 344 usb_speed_t speed = device_keeper_speed(&hc->device_manager, target.address); 345 346 usb_log_debug("Control READ (%d)%d:%d %zu(%zu).\n",347 speed,target.address, target.endpoint, size, max_packet_size);317 uhci_t *hc = fun_to_uhci(fun); 318 assert(hc); 319 usb_speed_t speed = device_keeper_speed(&hc->device_manager, target.address); 320 321 usb_log_debug("Control READ %d:%d %zu(%zu).\n", 322 target.address, target.endpoint, size, max_packet_size); 348 323 batch_t *batch = batch_get(fun, target, USB_TRANSFER_CONTROL, 349 324 max_packet_size, speed, data, size, setup_data, setup_size, callback, … … 352 327 return ENOMEM; 353 328 batch_control_read(batch); 354 const int ret = uhci_hc_schedule(hc, batch); 355 if (ret != EOK) { 356 batch_dispose(batch); 357 return ret; 358 } 359 return EOK; 360 } 361 /*----------------------------------------------------------------------------*/ 362 usbhc_iface_t uhci_hc_iface = { 329 return EOK; 330 } 331 /*----------------------------------------------------------------------------*/ 332 usbhc_iface_t uhci_iface = { 363 333 .reserve_default_address = reserve_default_address, 364 334 .release_default_address = release_default_address, -
uspace/drv/uhci-hcd/iface.h
rbb41b85 rc32688d 27 27 */ 28 28 29 /** @addtogroup drvusbuhcihc29 /** @addtogroup usb 30 30 * @{ 31 31 */ 32 32 /** @file 33 * @brief UHCI driver iface33 * @brief UHCI driver 34 34 */ 35 35 #ifndef DRV_UHCI_IFACE_H … … 38 38 #include <usbhc_iface.h> 39 39 40 extern usbhc_iface_t uhci_ hc_iface;40 extern usbhc_iface_t uhci_iface; 41 41 42 42 #endif -
uspace/drv/uhci-hcd/main.c
rbb41b85 rc32688d 26 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 27 */ 28 /** @addtogroup drvusbuhcihc28 /** @addtogroup usb 29 29 * @{ 30 30 */ 31 31 /** @file 32 * @brief UHCI driver initialization32 * @brief UHCI driver 33 33 */ 34 34 #include <ddf/driver.h> 35 #include <ddf/interrupt.h> 36 #include <device/hw_res.h> 35 37 #include <errno.h> 36 38 #include <str_error.h> 37 39 40 #include <usb_iface.h> 38 41 #include <usb/ddfiface.h> 39 42 #include <usb/debug.h> 40 43 41 44 #include "iface.h" 45 #include "pci.h" 46 #include "root_hub.h" 42 47 #include "uhci.h" 43 48 … … 55 60 }; 56 61 /*----------------------------------------------------------------------------*/ 57 /** Initialize a new ddf driver instance for uhci hc and hub. 62 /** IRQ handling callback, identifies devic 63 * 64 * @param[in] dev DDF instance of the device to use. 65 * @param[in] iid (Unused). 66 * @param[in] call Pointer to the call that represents interrupt. 67 */ 68 static void irq_handler(ddf_dev_t *dev, ipc_callid_t iid, ipc_call_t *call) 69 { 70 assert(dev); 71 uhci_t *hc = dev_to_uhci(dev); 72 uint16_t status = IPC_GET_ARG1(*call); 73 assert(hc); 74 uhci_interrupt(hc, status); 75 } 76 /*----------------------------------------------------------------------------*/ 77 /** Initializes a new ddf driver instance of UHCI hcd. 58 78 * 59 79 * @param[in] device DDF instance of the device to initialize. 60 80 * @return Error code. 81 * 82 * Gets and initialies hardware resources, disables any legacy support, 83 * and reports root hub device. 61 84 */ 62 85 int uhci_add_device(ddf_dev_t *device) 63 86 { 87 assert(device); 88 uhci_t *hcd = NULL; 89 #define CHECK_RET_FREE_HC_RETURN(ret, message...) \ 90 if (ret != EOK) { \ 91 usb_log_error(message); \ 92 if (hcd != NULL) \ 93 free(hcd); \ 94 return ret; \ 95 } 96 64 97 usb_log_info("uhci_add_device() called\n"); 65 assert(device); 66 uhci_t *uhci = malloc(sizeof(uhci_t)); 67 if (uhci == NULL) { 68 usb_log_error("Failed to allocate UHCI driver.\n"); 69 return ENOMEM; 98 99 uintptr_t io_reg_base = 0; 100 size_t io_reg_size = 0; 101 int irq = 0; 102 103 int ret = 104 pci_get_my_registers(device, &io_reg_base, &io_reg_size, &irq); 105 CHECK_RET_FREE_HC_RETURN(ret, 106 "Failed(%d) to get I/O addresses:.\n", ret, device->handle); 107 usb_log_info("I/O regs at 0x%X (size %zu), IRQ %d.\n", 108 io_reg_base, io_reg_size, irq); 109 110 ret = pci_disable_legacy(device); 111 CHECK_RET_FREE_HC_RETURN(ret, 112 "Failed(%d) to disable legacy USB: %s.\n", ret, str_error(ret)); 113 114 #if 0 115 ret = pci_enable_interrupts(device); 116 if (ret != EOK) { 117 usb_log_warning( 118 "Failed(%d) to enable interrupts, fall back to polling.\n", 119 ret); 70 120 } 121 #endif 71 122 72 int ret = uhci_init(uhci, device); 73 if (ret != EOK) { 74 usb_log_error("Failed to initialzie UHCI driver.\n"); 75 return ret; 76 } 77 device->driver_data = uhci; 123 hcd = malloc(sizeof(uhci_t)); 124 ret = (hcd != NULL) ? EOK : ENOMEM; 125 CHECK_RET_FREE_HC_RETURN(ret, 126 "Failed(%d) to allocate memory for uhci hcd.\n", ret); 127 128 ret = uhci_init(hcd, device, (void*)io_reg_base, io_reg_size); 129 CHECK_RET_FREE_HC_RETURN(ret, "Failed(%d) to init uhci-hcd.\n", ret); 130 #undef CHECK_RET_FREE_HC_RETURN 131 132 /* 133 * We might free hcd, but that does not matter since no one 134 * else would access driver_data anyway. 135 */ 136 device->driver_data = hcd; 137 138 ddf_fun_t *rh = NULL; 139 #define CHECK_RET_FINI_FREE_RETURN(ret, message...) \ 140 if (ret != EOK) { \ 141 usb_log_error(message); \ 142 if (hcd != NULL) {\ 143 uhci_fini(hcd); \ 144 free(hcd); \ 145 } \ 146 if (rh != NULL) \ 147 free(rh); \ 148 return ret; \ 149 } 150 151 /* It does no harm if we register this on polling */ 152 ret = register_interrupt_handler(device, irq, irq_handler, 153 &hcd->interrupt_code); 154 CHECK_RET_FINI_FREE_RETURN(ret, 155 "Failed(%d) to register interrupt handler.\n", ret); 156 157 ret = setup_root_hub(&rh, device); 158 CHECK_RET_FINI_FREE_RETURN(ret, 159 "Failed(%d) to setup UHCI root hub.\n", ret); 160 rh->driver_data = hcd->ddf_instance; 161 162 ret = ddf_fun_bind(rh); 163 CHECK_RET_FINI_FREE_RETURN(ret, 164 "Failed(%d) to register UHCI root hub.\n", ret); 165 78 166 return EOK; 167 #undef CHECK_RET_FINI_FREE_RETURN 79 168 } 80 169 /*----------------------------------------------------------------------------*/ 81 /** Initialize global driver structures (NONE).170 /** Initializes global driver structures (NONE). 82 171 * 83 172 * @param[in] argc Nmber of arguments in argv vector (ignored). … … 89 178 int main(int argc, char *argv[]) 90 179 { 91 sleep(3); /* TODO: remove in final version */180 sleep(3); 92 181 usb_log_enable(USB_LOG_LEVEL_DEBUG, NAME); 93 182 -
uspace/drv/uhci-hcd/pci.c
rbb41b85 rc32688d 27 27 */ 28 28 /** 29 * @addtogroup drvusbuhci hc29 * @addtogroup drvusbuhci 30 30 * @{ 31 31 */ … … 117 117 } 118 118 /*----------------------------------------------------------------------------*/ 119 /** Call the PCI driver with a request to enable interrupts119 /** Calls the PCI driver with a request to enable interrupts 120 120 * 121 121 * @param[in] device Device asking for interrupts … … 131 131 } 132 132 /*----------------------------------------------------------------------------*/ 133 /** Call the PCI driver with a request to clear legacy support register133 /** Calls the PCI driver with a request to clear legacy support register 134 134 * 135 135 * @param[in] device Device asking to disable interrupts -
uspace/drv/uhci-hcd/pci.h
rbb41b85 rc32688d 27 27 */ 28 28 29 /** @addtogroup drvusbuhci hc29 /** @addtogroup drvusbuhci 30 30 * @{ 31 31 */ 32 32 /** @file 33 * @brief UHCI driver PCI helper functions33 * @brief UHCI driver 34 34 */ 35 35 #ifndef DRV_UHCI_PCI_H -
uspace/drv/uhci-hcd/transfer_list.c
rbb41b85 rc32688d 26 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 27 */ 28 /** @addtogroup drvusbuhcihc28 /** @addtogroup usb 29 29 * @{ 30 30 */ 31 31 /** @file 32 * @brief UHCI driver transfer list implementation32 * @brief UHCI driver 33 33 */ 34 34 #include <errno.h> 35 35 36 #include <usb/debug.h> 36 37 … … 40 41 transfer_list_t *instance, batch_t *batch); 41 42 /*----------------------------------------------------------------------------*/ 42 /** Initialize transfer list structures.43 /** Initializes transfer list structures. 43 44 * 44 45 * @param[in] instance Memory place to use. 45 * @param[in] name Name of t he new list.46 * @param[in] name Name of te new list. 46 47 * @return Error code 47 48 * 48 * Allocates memory for interna l qh_t structure.49 * Allocates memory for internat queue_head_t structure. 49 50 */ 50 51 int transfer_list_init(transfer_list_t *instance, const char *name) 51 52 { 52 53 assert(instance); 54 instance->next = NULL; 53 55 instance->name = name; 54 instance->queue_head = malloc32(sizeof(q h_t));56 instance->queue_head = malloc32(sizeof(queue_head_t)); 55 57 if (!instance->queue_head) { 56 58 usb_log_error("Failed to allocate queue head.\n"); … … 59 61 instance->queue_head_pa = addr_to_phys(instance->queue_head); 60 62 61 q h_init(instance->queue_head);63 queue_head_init(instance->queue_head); 62 64 list_initialize(&instance->batch_list); 63 65 fibril_mutex_initialize(&instance->guard); … … 65 67 } 66 68 /*----------------------------------------------------------------------------*/ 67 /** Set the next list in transfer listchain.69 /** Set the next list in chain. 68 70 * 69 71 * @param[in] instance List to lead. 70 72 * @param[in] next List to append. 71 73 * @return Error code 72 *73 * Does not check whether this replaces an existing list .74 74 */ 75 75 void transfer_list_set_next(transfer_list_t *instance, transfer_list_t *next) … … 79 79 if (!instance->queue_head) 80 80 return; 81 /* Set both next and element to point to the same QH */ 82 qh_set_next_qh(instance->queue_head, next->queue_head_pa); 83 qh_set_element_qh(instance->queue_head, next->queue_head_pa); 81 queue_head_append_qh(instance->queue_head, next->queue_head_pa); 82 instance->queue_head->element = instance->queue_head->next_queue; 84 83 } 85 84 /*----------------------------------------------------------------------------*/ 86 /** Submit transfer batch to thelist and queue.85 /** Submits a new transfer batch to list and queue. 87 86 * 88 87 * @param[in] instance List to use. 89 88 * @param[in] batch Transfer batch to submit. 90 89 * @return Error code 91 *92 * The batch is added to the end of the list and queue.93 90 */ 94 91 void transfer_list_add_batch(transfer_list_t *instance, batch_t *batch) … … 96 93 assert(instance); 97 94 assert(batch); 98 usb_log_debug2("Queue %s: Adding batch(%p).\n", instance->name, batch); 95 usb_log_debug2( 96 "Adding batch(%p) to queue %s.\n", batch, instance->name); 99 97 100 const uint32_t pa =addr_to_phys(batch->qh);98 uint32_t pa = (uintptr_t)addr_to_phys(batch->qh); 101 99 assert((pa & LINK_POINTER_ADDRESS_MASK) == pa); 100 pa |= LINK_POINTER_QUEUE_HEAD_FLAG; 102 101 103 /* New batch will be added to the end of the current list 104 * so set the link accordingly */ 105 qh_set_next_qh(batch->qh, instance->queue_head->next); 102 batch->qh->next_queue = instance->queue_head->next_queue; 106 103 107 104 fibril_mutex_lock(&instance->guard); 108 105 109 /* Add to the hardware queue. */ 110 if (list_empty(&instance->batch_list)) { 111 /* There is nothing scheduled */ 112 qh_t *qh = instance->queue_head; 113 assert(qh->element == qh->next); 114 qh_set_element_qh(qh, pa); 115 } else { 116 /* There is something scheduled */ 117 batch_t *last = list_get_instance( 118 instance->batch_list.prev, batch_t, link); 119 qh_set_next_qh(last->qh, pa); 106 if (instance->queue_head->element == instance->queue_head->next_queue) { 107 /* there is nothing scheduled */ 108 list_append(&batch->link, &instance->batch_list); 109 instance->queue_head->element = pa; 110 usb_log_debug("Batch(%p) added to queue %s first.\n", 111 batch, instance->name); 112 fibril_mutex_unlock(&instance->guard); 113 return; 120 114 } 121 /* Add to the driver list */ 115 /* now we can be sure that there is someting scheduled */ 116 assert(!list_empty(&instance->batch_list)); 117 batch_t *first = list_get_instance( 118 instance->batch_list.next, batch_t, link); 119 batch_t *last = list_get_instance( 120 instance->batch_list.prev, batch_t, link); 121 queue_head_append_qh(last->qh, pa); 122 122 list_append(&batch->link, &instance->batch_list); 123 123 124 batch_t *first = list_get_instance( 125 instance->batch_list.next, batch_t, link); 126 usb_log_debug("Batch(%p) added to queue %s, first is %p.\n", 124 usb_log_debug("Batch(%p) added to queue %s last, first is %p.\n", 127 125 batch, instance->name, first); 128 126 fibril_mutex_unlock(&instance->guard); 129 127 } 130 128 /*----------------------------------------------------------------------------*/ 131 /** Remove a transfer batch from thelist and queue.129 /** Removes a transfer batch from list and queue. 132 130 * 133 131 * @param[in] instance List to use. 134 132 * @param[in] batch Transfer batch to remove. 135 133 * @return Error code 136 *137 * Does not lock the transfer list, caller is responsible for that.138 134 */ 139 135 void transfer_list_remove_batch(transfer_list_t *instance, batch_t *batch) … … 144 140 assert(batch->qh); 145 141 usb_log_debug2( 146 " Queue %s: removing batch(%p).\n", instance->name, batch);142 "Removing batch(%p) from queue %s.\n", batch, instance->name); 147 143 148 const char * pos = NULL;149 /* Remove from the hardware queue */150 144 if (batch->link.prev == &instance->batch_list) { 151 145 /* I'm the first one here */ 152 qh_set_element_qh(instance->queue_head, batch->qh->next); 153 pos = "FIRST"; 146 usb_log_debug( 147 "Batch(%p) removed (FIRST) from %s, next element %x.\n", 148 batch, instance->name, batch->qh->next_queue); 149 instance->queue_head->element = batch->qh->next_queue; 154 150 } else { 151 usb_log_debug( 152 "Batch(%p) removed (FIRST:NO) from %s, next element %x.\n", 153 batch, instance->name, batch->qh->next_queue); 155 154 batch_t *prev = 156 155 list_get_instance(batch->link.prev, batch_t, link); 157 qh_set_next_qh(prev->qh, batch->qh->next); 158 pos = "NOT FIRST"; 156 prev->qh->next_queue = batch->qh->next_queue; 159 157 } 160 /* Remove from the driver list */161 158 list_remove(&batch->link); 162 usb_log_debug("Batch(%p) removed (%s) from %s, next element %x.\n",163 batch, pos, instance->name, batch->qh->next);164 159 } 165 160 /*----------------------------------------------------------------------------*/ 166 /** Check list for finished batches.161 /** Checks list for finished transfers. 167 162 * 168 163 * @param[in] instance List to use. 169 164 * @return Error code 170 *171 * Creates a local list of finished batches and calls next_step on each and172 * every one. This is safer because next_step may theoretically access173 * this transfer list leading to the deadlock if its done inline.174 165 */ 175 166 void transfer_list_remove_finished(transfer_list_t *instance) … … 186 177 187 178 if (batch_is_complete(batch)) { 188 /* Save for post-processing */189 179 transfer_list_remove_batch(instance, batch); 190 180 list_append(current, &done); -
uspace/drv/uhci-hcd/transfer_list.h
rbb41b85 rc32688d 26 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 27 */ 28 /** @addtogroup drvusbuhcihc28 /** @addtogroup usb 29 29 * @{ 30 30 */ 31 31 /** @file 32 * @brief UHCI driver transfer list structure32 * @brief UHCI driver 33 33 */ 34 34 #ifndef DRV_UHCI_TRANSFER_LIST_H … … 44 44 { 45 45 fibril_mutex_t guard; 46 q h_t *queue_head;46 queue_head_t *queue_head; 47 47 uint32_t queue_head_pa; 48 struct transfer_list *next; 48 49 const char *name; 49 50 link_t batch_list; 50 51 } transfer_list_t; 51 52 52 /** Dispose transfer list structures. 53 * 54 * @param[in] instance Memory place to use. 55 * 56 * Frees memory for internal qh_t structure. 57 */ 53 int transfer_list_init(transfer_list_t *instance, const char *name); 54 55 void transfer_list_set_next(transfer_list_t *instance, transfer_list_t *next); 56 58 57 static inline void transfer_list_fini(transfer_list_t *instance) 59 58 { … … 61 60 free32(instance->queue_head); 62 61 } 63 64 int transfer_list_init(transfer_list_t *instance, const char *name);65 66 void transfer_list_set_next(transfer_list_t *instance, transfer_list_t *next);67 68 62 void transfer_list_remove_finished(transfer_list_t *instance); 69 63 -
uspace/drv/uhci-hcd/uhci.c
rbb41b85 rc32688d 26 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 27 */ 28 29 /** @addtogroup drvusbuhci 28 /** @addtogroup usb 30 29 * @{ 31 30 */ … … 35 34 #include <errno.h> 36 35 #include <str_error.h> 37 #include <ddf/interrupt.h> 36 #include <adt/list.h> 37 #include <libarch/ddi.h> 38 39 #include <usb/debug.h> 40 #include <usb/usb.h> 41 #include <usb/ddfiface.h> 38 42 #include <usb_iface.h> 39 #include <usb/ddfiface.h>40 #include <usb/debug.h>41 43 42 44 #include "uhci.h" 43 45 #include "iface.h" 44 #include "pci.h" 45 46 47 /** IRQ handling callback, identifies device 48 * 49 * @param[in] dev DDF instance of the device to use. 50 * @param[in] iid (Unused). 51 * @param[in] call Pointer to the call that represents interrupt. 52 */ 53 static void irq_handler(ddf_dev_t *dev, ipc_callid_t iid, ipc_call_t *call) 54 { 55 assert(dev);56 uhci_hc_t *hc = &((uhci_t*)dev->driver_data)->hc;57 uint16_t status = IPC_GET_ARG1(*call);58 assert(hc);59 uhci_hc_interrupt(hc, status);60 } 61 /* ----------------------------------------------------------------------------*/62 /** Get address of the device identified by handle. 63 * 64 * @param[in] dev DDF instance of the device to use.65 * @param[ in] iid (Unused).66 * @ param[in] call Pointer to the call that represents interrupt.46 47 static irq_cmd_t uhci_cmds[] = { 48 { 49 .cmd = CMD_PIO_READ_16, 50 .addr = NULL, /* patched for every instance */ 51 .dstarg = 1 52 }, 53 { 54 .cmd = CMD_PIO_WRITE_16, 55 .addr = NULL, /* pathed for every instance */ 56 .value = 0x1f 57 }, 58 { 59 .cmd = CMD_ACCEPT 60 } 61 }; 62 63 /** Gets USB address of the calling device. 64 * 65 * @param[in] fun UHCI hc function. 66 * @param[in] handle Handle of the device seeking address. 67 * @param[out] address Place to store found address. 68 * @return Error code. 67 69 */ 68 70 static int usb_iface_get_address( … … 70 72 { 71 73 assert(fun); 72 device_keeper_t *manager = &((uhci_t*)fun->dev->driver_data)->hc.device_manager; 73 74 usb_address_t addr = device_keeper_find(manager, handle); 74 uhci_t *hc = fun_to_uhci(fun); 75 assert(hc); 76 77 usb_address_t addr = device_keeper_find(&hc->device_manager, 78 handle); 75 79 if (addr < 0) { 76 80 return addr; … … 84 88 } 85 89 /*----------------------------------------------------------------------------*/ 86 /** Gets handle of the respective hc (this or parent device). 87 * 88 * @param[in] root_hub_fun Root hub function seeking hc handle. 89 * @param[out] handle Place to write the handle. 90 * @return Error code. 91 */ 92 static int usb_iface_get_hc_handle( 93 ddf_fun_t *fun, devman_handle_t *handle) 94 { 95 assert(handle); 96 ddf_fun_t *hc_fun = ((uhci_t*)fun->dev->driver_data)->hc_fun; 97 assert(hc_fun != NULL); 98 99 *handle = hc_fun->handle; 100 return EOK; 101 } 102 /*----------------------------------------------------------------------------*/ 103 /** This iface is generic for both RH and HC. */ 104 static usb_iface_t usb_iface = { 105 .get_hc_handle = usb_iface_get_hc_handle, 90 static usb_iface_t hc_usb_iface = { 91 .get_hc_handle = usb_iface_get_hc_handle_hc_impl, 106 92 .get_address = usb_iface_get_address 107 93 }; 108 94 /*----------------------------------------------------------------------------*/ 109 static ddf_dev_ops_t uhci_ hc_ops = {110 .interfaces[USB_DEV_IFACE] = & usb_iface,111 .interfaces[USBHC_DEV_IFACE] = &uhci_ hc_iface, /* see iface.h/c */95 static ddf_dev_ops_t uhci_ops = { 96 .interfaces[USB_DEV_IFACE] = &hc_usb_iface, 97 .interfaces[USBHC_DEV_IFACE] = &uhci_iface, 112 98 }; 113 99 /*----------------------------------------------------------------------------*/ 114 /** Get root hub hw resources (I/O registers). 115 * 116 * @param[in] fun Root hub function. 117 * @return Pointer to the resource list used by the root hub. 118 */ 119 static hw_resource_list_t *get_resource_list(ddf_fun_t *fun) 120 { 121 assert(fun); 122 return &((uhci_rh_t*)fun->driver_data)->resource_list; 123 } 124 /*----------------------------------------------------------------------------*/ 125 static hw_res_ops_t hw_res_iface = { 126 .get_resource_list = get_resource_list, 127 .enable_interrupt = NULL 128 }; 129 /*----------------------------------------------------------------------------*/ 130 static ddf_dev_ops_t uhci_rh_ops = { 131 .interfaces[USB_DEV_IFACE] = &usb_iface, 132 .interfaces[HW_RES_DEV_IFACE] = &hw_res_iface 133 }; 134 /*----------------------------------------------------------------------------*/ 135 /** Initialize hc and rh ddf structures and their respective drivers. 136 * 137 * @param[in] instance UHCI structure to use. 138 * @param[in] device DDF instance of the device to use. 139 * 140 * This function does all the preparatory work for hc and rh drivers: 141 * - gets device hw resources 142 * - disables UHCI legacy support 143 * - asks for interrupt 144 * - registers interrupt handler 145 */ 146 int uhci_init(uhci_t *instance, ddf_dev_t *device) 147 { 148 assert(instance); 149 instance->hc_fun = NULL; 150 instance->rh_fun = NULL; 100 static int uhci_init_transfer_lists(uhci_t *instance); 101 static int uhci_init_mem_structures(uhci_t *instance); 102 static void uhci_init_hw(uhci_t *instance); 103 104 static int uhci_interrupt_emulator(void *arg); 105 static int uhci_debug_checker(void *arg); 106 107 static bool allowed_usb_packet( 108 bool low_speed, usb_transfer_type_t transfer, size_t size); 109 /*----------------------------------------------------------------------------*/ 110 /** Initializes UHCI hcd driver structure 111 * 112 * @param[in] instance Memory place to initialize. 113 * @param[in] dev DDF device. 114 * @param[in] regs Address of I/O control registers. 115 * @param[in] size Size of I/O control registers. 116 * @return Error code. 117 * @note Should be called only once on any structure. 118 */ 119 int uhci_init(uhci_t *instance, ddf_dev_t *dev, void *regs, size_t reg_size) 120 { 121 assert(reg_size >= sizeof(regs_t)); 122 int ret; 123 151 124 #define CHECK_RET_DEST_FUN_RETURN(ret, message...) \ 152 if (ret != EOK) { \ 153 usb_log_error(message); \ 154 if (instance->hc_fun) \ 155 ddf_fun_destroy(instance->hc_fun); \ 156 if (instance->rh_fun) \ 157 ddf_fun_destroy(instance->rh_fun); \ 158 return ret; \ 159 } 160 161 uintptr_t io_reg_base = 0; 162 size_t io_reg_size = 0; 163 int irq = 0; 164 165 int ret = 166 pci_get_my_registers(device, &io_reg_base, &io_reg_size, &irq); 125 if (ret != EOK) { \ 126 usb_log_error(message); \ 127 if (instance->ddf_instance) \ 128 ddf_fun_destroy(instance->ddf_instance); \ 129 return ret; \ 130 } else (void) 0 131 132 /* Create UHCI function. */ 133 instance->ddf_instance = ddf_fun_create(dev, fun_exposed, "uhci"); 134 ret = (instance->ddf_instance == NULL) ? ENOMEM : EOK; 167 135 CHECK_RET_DEST_FUN_RETURN(ret, 168 "Failed(%d) to get I/O addresses:.\n", ret, device->handle); 169 usb_log_info("I/O regs at 0x%X (size %zu), IRQ %d.\n", 170 io_reg_base, io_reg_size, irq); 171 172 ret = pci_disable_legacy(device); 173 CHECK_RET_DEST_FUN_RETURN(ret, 174 "Failed(%d) to disable legacy USB: %s.\n", ret, str_error(ret)); 175 176 bool interrupts = false; 177 ret = pci_enable_interrupts(device); 178 if (ret != EOK) { 179 usb_log_warning( 180 "Failed(%d) to enable interrupts, fall back to polling.\n", 181 ret); 182 } else { 183 usb_log_debug("Hw interrupts enabled.\n"); 184 interrupts = true; 185 } 186 187 instance->hc_fun = ddf_fun_create(device, fun_exposed, "uhci-hc"); 188 ret = (instance->hc_fun == NULL) ? ENOMEM : EOK; 189 CHECK_RET_DEST_FUN_RETURN(ret, 190 "Failed(%d) to create HC function.\n", ret); 191 192 ret = uhci_hc_init(&instance->hc, instance->hc_fun, 193 (void*)io_reg_base, io_reg_size, interrupts); 194 CHECK_RET_DEST_FUN_RETURN(ret, "Failed(%d) to init uhci-hcd.\n", ret); 195 instance->hc_fun->ops = &uhci_hc_ops; 196 instance->hc_fun->driver_data = &instance->hc; 197 ret = ddf_fun_bind(instance->hc_fun); 136 "Failed to create UHCI device function.\n"); 137 138 instance->ddf_instance->ops = &uhci_ops; 139 instance->ddf_instance->driver_data = instance; 140 141 ret = ddf_fun_bind(instance->ddf_instance); 198 142 CHECK_RET_DEST_FUN_RETURN(ret, 199 143 "Failed(%d) to bind UHCI device function: %s.\n", 200 144 ret, str_error(ret)); 201 #undef CHECK_RET_HC_RETURN 202 203 #define CHECK_RET_FINI_RETURN(ret, message...) \ 204 if (ret != EOK) { \ 205 usb_log_error(message); \ 206 if (instance->hc_fun) \ 207 ddf_fun_destroy(instance->hc_fun); \ 208 if (instance->rh_fun) \ 209 ddf_fun_destroy(instance->rh_fun); \ 210 uhci_hc_fini(&instance->hc); \ 211 return ret; \ 212 } 213 214 /* It does no harm if we register this on polling */ 215 ret = register_interrupt_handler(device, irq, irq_handler, 216 &instance->hc.interrupt_code); 217 CHECK_RET_FINI_RETURN(ret, 218 "Failed(%d) to register interrupt handler.\n", ret); 219 220 instance->rh_fun = ddf_fun_create(device, fun_inner, "uhci-rh"); 221 ret = (instance->rh_fun == NULL) ? ENOMEM : EOK; 222 CHECK_RET_FINI_RETURN(ret, 223 "Failed(%d) to create root hub function.\n", ret); 224 225 ret = uhci_rh_init(&instance->rh, instance->rh_fun, 226 (uintptr_t)instance->hc.registers + 0x10, 4); 227 CHECK_RET_FINI_RETURN(ret, 228 "Failed(%d) to setup UHCI root hub.\n", ret); 229 230 instance->rh_fun->ops = &uhci_rh_ops; 231 instance->rh_fun->driver_data = &instance->rh; 232 ret = ddf_fun_bind(instance->rh_fun); 233 CHECK_RET_FINI_RETURN(ret, 234 "Failed(%d) to register UHCI root hub.\n", ret); 235 236 return EOK; 237 #undef CHECK_RET_FINI_RETURN 145 146 /* allow access to hc control registers */ 147 regs_t *io; 148 ret = pio_enable(regs, reg_size, (void**)&io); 149 CHECK_RET_DEST_FUN_RETURN(ret, 150 "Failed(%d) to gain access to registers at %p: %s.\n", 151 ret, str_error(ret), io); 152 instance->registers = io; 153 usb_log_debug("Device registers at %p(%u) accessible.\n", 154 io, reg_size); 155 156 ret = uhci_init_mem_structures(instance); 157 CHECK_RET_DEST_FUN_RETURN(ret, 158 "Failed to initialize UHCI memory structures.\n"); 159 160 uhci_init_hw(instance); 161 instance->cleaner = 162 fibril_create(uhci_interrupt_emulator, instance); 163 fibril_add_ready(instance->cleaner); 164 165 instance->debug_checker = fibril_create(uhci_debug_checker, instance); 166 fibril_add_ready(instance->debug_checker); 167 168 usb_log_info("Started UHCI driver.\n"); 169 return EOK; 170 #undef CHECK_RET_DEST_FUN_RETURN 171 } 172 /*----------------------------------------------------------------------------*/ 173 /** Initializes UHCI hcd hw resources. 174 * 175 * @param[in] instance UHCI structure to use. 176 */ 177 void uhci_init_hw(uhci_t *instance) 178 { 179 assert(instance); 180 regs_t *registers = instance->registers; 181 182 /* Reset everything, who knows what touched it before us */ 183 pio_write_16(®isters->usbcmd, UHCI_CMD_GLOBAL_RESET); 184 async_usleep(10000); /* 10ms according to USB spec */ 185 pio_write_16(®isters->usbcmd, 0); 186 187 /* Reset hc, all states and counters */ 188 pio_write_16(®isters->usbcmd, UHCI_CMD_HCRESET); 189 do { async_usleep(10); } 190 while ((pio_read_16(®isters->usbcmd) & UHCI_CMD_HCRESET) != 0); 191 192 /* Set framelist pointer */ 193 const uint32_t pa = addr_to_phys(instance->frame_list); 194 pio_write_32(®isters->flbaseadd, pa); 195 196 /* Enable all interrupts, but resume interrupt */ 197 // pio_write_16(&instance->registers->usbintr, 198 // UHCI_INTR_CRC | UHCI_INTR_COMPLETE | UHCI_INTR_SHORT_PACKET); 199 200 uint16_t status = pio_read_16(®isters->usbcmd); 201 if (status != 0) 202 usb_log_warning("Previous command value: %x.\n", status); 203 204 /* Start the hc with large(64B) packet FSBR */ 205 pio_write_16(®isters->usbcmd, 206 UHCI_CMD_RUN_STOP | UHCI_CMD_MAX_PACKET | UHCI_CMD_CONFIGURE); 207 } 208 /*----------------------------------------------------------------------------*/ 209 /** Initializes UHCI hcd memory structures. 210 * 211 * @param[in] instance UHCI structure to use. 212 * @return Error code 213 * @note Should be called only once on any structure. 214 */ 215 int uhci_init_mem_structures(uhci_t *instance) 216 { 217 assert(instance); 218 #define CHECK_RET_DEST_CMDS_RETURN(ret, message...) \ 219 if (ret != EOK) { \ 220 usb_log_error(message); \ 221 if (instance->interrupt_code.cmds != NULL) \ 222 free(instance->interrupt_code.cmds); \ 223 return ret; \ 224 } else (void) 0 225 226 /* Init interrupt code */ 227 instance->interrupt_code.cmds = malloc(sizeof(uhci_cmds)); 228 int ret = (instance->interrupt_code.cmds == NULL) ? ENOMEM : EOK; 229 CHECK_RET_DEST_CMDS_RETURN(ret, 230 "Failed to allocate interrupt cmds space.\n"); 231 232 { 233 irq_cmd_t *interrupt_commands = instance->interrupt_code.cmds; 234 memcpy(interrupt_commands, uhci_cmds, sizeof(uhci_cmds)); 235 interrupt_commands[0].addr = 236 (void*)&instance->registers->usbsts; 237 interrupt_commands[1].addr = 238 (void*)&instance->registers->usbsts; 239 instance->interrupt_code.cmdcount = 240 sizeof(uhci_cmds) / sizeof(irq_cmd_t); 241 } 242 243 /* Init transfer lists */ 244 ret = uhci_init_transfer_lists(instance); 245 CHECK_RET_DEST_CMDS_RETURN(ret, "Failed to init transfer lists.\n"); 246 usb_log_debug("Initialized transfer lists.\n"); 247 248 /* Init USB frame list page*/ 249 instance->frame_list = get_page(); 250 ret = instance ? EOK : ENOMEM; 251 CHECK_RET_DEST_CMDS_RETURN(ret, "Failed to get frame list page.\n"); 252 usb_log_debug("Initialized frame list.\n"); 253 254 /* Set all frames to point to the first queue head */ 255 const uint32_t queue = 256 instance->transfers_interrupt.queue_head_pa 257 | LINK_POINTER_QUEUE_HEAD_FLAG; 258 259 unsigned i = 0; 260 for(; i < UHCI_FRAME_LIST_COUNT; ++i) { 261 instance->frame_list[i] = queue; 262 } 263 264 /* Init device keeper*/ 265 device_keeper_init(&instance->device_manager); 266 usb_log_debug("Initialized device manager.\n"); 267 268 return EOK; 269 #undef CHECK_RET_DEST_CMDS_RETURN 270 } 271 /*----------------------------------------------------------------------------*/ 272 /** Initializes UHCI hcd transfer lists. 273 * 274 * @param[in] instance UHCI structure to use. 275 * @return Error code 276 * @note Should be called only once on any structure. 277 */ 278 int uhci_init_transfer_lists(uhci_t *instance) 279 { 280 assert(instance); 281 #define CHECK_RET_CLEAR_RETURN(ret, message...) \ 282 if (ret != EOK) { \ 283 usb_log_error(message); \ 284 transfer_list_fini(&instance->transfers_bulk_full); \ 285 transfer_list_fini(&instance->transfers_control_full); \ 286 transfer_list_fini(&instance->transfers_control_slow); \ 287 transfer_list_fini(&instance->transfers_interrupt); \ 288 return ret; \ 289 } else (void) 0 290 291 /* initialize TODO: check errors */ 292 int ret; 293 ret = transfer_list_init(&instance->transfers_bulk_full, "BULK_FULL"); 294 CHECK_RET_CLEAR_RETURN(ret, "Failed to init BULK list."); 295 296 ret = transfer_list_init( 297 &instance->transfers_control_full, "CONTROL_FULL"); 298 CHECK_RET_CLEAR_RETURN(ret, "Failed to init CONTROL FULL list."); 299 300 ret = transfer_list_init( 301 &instance->transfers_control_slow, "CONTROL_SLOW"); 302 CHECK_RET_CLEAR_RETURN(ret, "Failed to init CONTROL SLOW list."); 303 304 ret = transfer_list_init(&instance->transfers_interrupt, "INTERRUPT"); 305 CHECK_RET_CLEAR_RETURN(ret, "Failed to init INTERRUPT list."); 306 307 transfer_list_set_next(&instance->transfers_control_full, 308 &instance->transfers_bulk_full); 309 transfer_list_set_next(&instance->transfers_control_slow, 310 &instance->transfers_control_full); 311 transfer_list_set_next(&instance->transfers_interrupt, 312 &instance->transfers_control_slow); 313 314 /*FSBR*/ 315 #ifdef FSBR 316 transfer_list_set_next(&instance->transfers_bulk_full, 317 &instance->transfers_control_full); 318 #endif 319 320 /* Assign pointers to be used during scheduling */ 321 instance->transfers[USB_SPEED_FULL][USB_TRANSFER_INTERRUPT] = 322 &instance->transfers_interrupt; 323 instance->transfers[USB_SPEED_LOW][USB_TRANSFER_INTERRUPT] = 324 &instance->transfers_interrupt; 325 instance->transfers[USB_SPEED_FULL][USB_TRANSFER_CONTROL] = 326 &instance->transfers_control_full; 327 instance->transfers[USB_SPEED_LOW][USB_TRANSFER_CONTROL] = 328 &instance->transfers_control_slow; 329 instance->transfers[USB_SPEED_FULL][USB_TRANSFER_BULK] = 330 &instance->transfers_bulk_full; 331 332 return EOK; 333 #undef CHECK_RET_CLEAR_RETURN 334 } 335 /*----------------------------------------------------------------------------*/ 336 /** Schedules batch for execution. 337 * 338 * @param[in] instance UHCI structure to use. 339 * @param[in] batch Transfer batch to schedule. 340 * @return Error code 341 */ 342 int uhci_schedule(uhci_t *instance, batch_t *batch) 343 { 344 assert(instance); 345 assert(batch); 346 const int low_speed = (batch->speed == USB_SPEED_LOW); 347 if (!allowed_usb_packet( 348 low_speed, batch->transfer_type, batch->max_packet_size)) { 349 usb_log_warning( 350 "Invalid USB packet specified %s SPEED %d %zu.\n", 351 low_speed ? "LOW" : "FULL" , batch->transfer_type, 352 batch->max_packet_size); 353 return ENOTSUP; 354 } 355 /* TODO: check available bandwith here */ 356 357 transfer_list_t *list = 358 instance->transfers[low_speed][batch->transfer_type]; 359 assert(list); 360 transfer_list_add_batch(list, batch); 361 362 return EOK; 363 } 364 /*----------------------------------------------------------------------------*/ 365 /** Takes action based on the interrupt cause. 366 * 367 * @param[in] instance UHCI structure to use. 368 * @param[in] status Value of the stsatus regiser at the time of interrupt. 369 */ 370 void uhci_interrupt(uhci_t *instance, uint16_t status) 371 { 372 assert(instance); 373 /* TODO: Check interrupt cause here */ 374 transfer_list_remove_finished(&instance->transfers_interrupt); 375 transfer_list_remove_finished(&instance->transfers_control_slow); 376 transfer_list_remove_finished(&instance->transfers_control_full); 377 transfer_list_remove_finished(&instance->transfers_bulk_full); 378 } 379 /*----------------------------------------------------------------------------*/ 380 /** Polling function, emulates interrupts. 381 * 382 * @param[in] arg UHCI structure to use. 383 * @return EOK 384 */ 385 int uhci_interrupt_emulator(void* arg) 386 { 387 usb_log_debug("Started interrupt emulator.\n"); 388 uhci_t *instance = (uhci_t*)arg; 389 assert(instance); 390 391 while (1) { 392 uint16_t status = pio_read_16(&instance->registers->usbsts); 393 if (status != 0) 394 usb_log_debug2("UHCI status: %x.\n", status); 395 status |= 1; 396 uhci_interrupt(instance, status); 397 pio_write_16(&instance->registers->usbsts, 0x1f); 398 async_usleep(UHCI_CLEANER_TIMEOUT); 399 } 400 return EOK; 401 } 402 /*---------------------------------------------------------------------------*/ 403 /** Debug function, checks consistency of memory structures. 404 * 405 * @param[in] arg UHCI structure to use. 406 * @return EOK 407 */ 408 int uhci_debug_checker(void *arg) 409 { 410 uhci_t *instance = (uhci_t*)arg; 411 assert(instance); 412 413 #define QH(queue) \ 414 instance->transfers_##queue.queue_head 415 416 while (1) { 417 const uint16_t cmd = pio_read_16(&instance->registers->usbcmd); 418 const uint16_t sts = pio_read_16(&instance->registers->usbsts); 419 const uint16_t intr = 420 pio_read_16(&instance->registers->usbintr); 421 422 if (((cmd & UHCI_CMD_RUN_STOP) != 1) || (sts != 0)) { 423 usb_log_debug2("Command: %X Status: %X Intr: %x\n", 424 cmd, sts, intr); 425 } 426 427 uintptr_t frame_list = 428 pio_read_32(&instance->registers->flbaseadd) & ~0xfff; 429 if (frame_list != addr_to_phys(instance->frame_list)) { 430 usb_log_debug("Framelist address: %p vs. %p.\n", 431 frame_list, addr_to_phys(instance->frame_list)); 432 } 433 434 int frnum = pio_read_16(&instance->registers->frnum) & 0x3ff; 435 usb_log_debug2("Framelist item: %d \n", frnum ); 436 437 uintptr_t expected_pa = instance->frame_list[frnum] & (~0xf); 438 uintptr_t real_pa = addr_to_phys(QH(interrupt)); 439 if (expected_pa != real_pa) { 440 usb_log_debug("Interrupt QH: %p vs. %p.\n", 441 expected_pa, real_pa); 442 } 443 444 expected_pa = QH(interrupt)->next_queue & (~0xf); 445 real_pa = addr_to_phys(QH(control_slow)); 446 if (expected_pa != real_pa) { 447 usb_log_debug("Control Slow QH: %p vs. %p.\n", 448 expected_pa, real_pa); 449 } 450 451 expected_pa = QH(control_slow)->next_queue & (~0xf); 452 real_pa = addr_to_phys(QH(control_full)); 453 if (expected_pa != real_pa) { 454 usb_log_debug("Control Full QH: %p vs. %p.\n", 455 expected_pa, real_pa); 456 } 457 458 expected_pa = QH(control_full)->next_queue & (~0xf); 459 real_pa = addr_to_phys(QH(bulk_full)); 460 if (expected_pa != real_pa ) { 461 usb_log_debug("Bulk QH: %p vs. %p.\n", 462 expected_pa, real_pa); 463 } 464 async_usleep(UHCI_DEBUGER_TIMEOUT); 465 } 466 return EOK; 467 #undef QH 468 } 469 /*----------------------------------------------------------------------------*/ 470 /** Checks transfer packets, for USB validity 471 * 472 * @param[in] low_speed Transfer speed. 473 * @param[in] transfer Transer type 474 * @param[in] size Maximum size of used packets 475 * @return EOK 476 */ 477 bool allowed_usb_packet( 478 bool low_speed, usb_transfer_type_t transfer, size_t size) 479 { 480 /* see USB specification chapter 5.5-5.8 for magic numbers used here */ 481 switch(transfer) 482 { 483 case USB_TRANSFER_ISOCHRONOUS: 484 return (!low_speed && size < 1024); 485 case USB_TRANSFER_INTERRUPT: 486 return size <= (low_speed ? 8 : 64); 487 case USB_TRANSFER_CONTROL: /* device specifies its own max size */ 488 return (size <= (low_speed ? 8 : 64)); 489 case USB_TRANSFER_BULK: /* device specifies its own max size */ 490 return (!low_speed && size <= 64); 491 } 492 return false; 238 493 } 239 494 /** -
uspace/drv/uhci-hcd/uhci.h
rbb41b85 rc32688d 1 1 /* 2 * Copyright (c) 201 1Jan Vesely2 * Copyright (c) 2010 Jan Vesely 3 3 * All rights reserved. 4 4 * … … 31 31 */ 32 32 /** @file 33 * @brief UHCI driver main structure for both host controller and root-hub.33 * @brief UHCI driver 34 34 */ 35 35 #ifndef DRV_UHCI_UHCI_H 36 36 #define DRV_UHCI_UHCI_H 37 38 #include <fibril.h> 39 #include <fibril_synch.h> 40 #include <adt/list.h> 37 41 #include <ddi.h> 38 #include <ddf/driver.h>39 42 40 #include "uhci_hc.h" 41 #include "uhci_rh.h" 43 #include <usbhc_iface.h> 44 45 #include "batch.h" 46 #include "transfer_list.h" 47 #include "utils/device_keeper.h" 48 49 typedef struct uhci_regs { 50 uint16_t usbcmd; 51 #define UHCI_CMD_MAX_PACKET (1 << 7) 52 #define UHCI_CMD_CONFIGURE (1 << 6) 53 #define UHCI_CMD_DEBUG (1 << 5) 54 #define UHCI_CMD_FORCE_GLOBAL_RESUME (1 << 4) 55 #define UHCI_CMD_FORCE_GLOBAL_SUSPEND (1 << 3) 56 #define UHCI_CMD_GLOBAL_RESET (1 << 2) 57 #define UHCI_CMD_HCRESET (1 << 1) 58 #define UHCI_CMD_RUN_STOP (1 << 0) 59 60 uint16_t usbsts; 61 #define UHCI_STATUS_HALTED (1 << 5) 62 #define UHCI_STATUS_PROCESS_ERROR (1 << 4) 63 #define UHCI_STATUS_SYSTEM_ERROR (1 << 3) 64 #define UHCI_STATUS_RESUME (1 << 2) 65 #define UHCI_STATUS_ERROR_INTERRUPT (1 << 1) 66 #define UHCI_STATUS_INTERRUPT (1 << 0) 67 68 uint16_t usbintr; 69 #define UHCI_INTR_SHORT_PACKET (1 << 3) 70 #define UHCI_INTR_COMPLETE (1 << 2) 71 #define UHCI_INTR_RESUME (1 << 1) 72 #define UHCI_INTR_CRC (1 << 0) 73 74 uint16_t frnum; 75 uint32_t flbaseadd; 76 uint8_t sofmod; 77 } regs_t; 78 79 #define UHCI_FRAME_LIST_COUNT 1024 80 #define UHCI_CLEANER_TIMEOUT 10000 81 #define UHCI_DEBUGER_TIMEOUT 5000000 42 82 43 83 typedef struct uhci { 44 ddf_fun_t *hc_fun; 45 ddf_fun_t *rh_fun; 84 device_keeper_t device_manager; 46 85 47 uhci_hc_t hc; 48 uhci_rh_t rh; 86 regs_t *registers; 87 88 link_pointer_t *frame_list; 89 90 transfer_list_t transfers_bulk_full; 91 transfer_list_t transfers_control_full; 92 transfer_list_t transfers_control_slow; 93 transfer_list_t transfers_interrupt; 94 95 transfer_list_t *transfers[2][4]; 96 97 irq_code_t interrupt_code; 98 99 fid_t cleaner; 100 fid_t debug_checker; 101 102 ddf_fun_t *ddf_instance; 49 103 } uhci_t; 50 104 51 int uhci_init(uhci_t *instance, ddf_dev_t *device); 105 /* init uhci specifics in device.driver_data */ 106 int uhci_init(uhci_t *instance, ddf_dev_t *dev, void *regs, size_t reg_size); 107 108 static inline void uhci_fini(uhci_t *instance) {}; 109 110 int uhci_schedule(uhci_t *instance, batch_t *batch); 111 112 void uhci_interrupt(uhci_t *instance, uint16_t status); 113 114 static inline uhci_t * dev_to_uhci(ddf_dev_t *dev) 115 { return (uhci_t*)dev->driver_data; } 116 117 static inline uhci_t * fun_to_uhci(ddf_fun_t *fun) 118 { return (uhci_t*)fun->driver_data; } 119 52 120 53 121 #endif -
uspace/drv/uhci-hcd/uhci_struct/link_pointer.h
rbb41b85 rc32688d 26 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 27 */ 28 /** @addtogroup drvusbuhcihc28 /** @addtogroup usb 29 29 * @{ 30 30 */ … … 46 46 #define LINK_POINTER_ADDRESS_MASK 0xfffffff0 /* upper 28 bits */ 47 47 48 #define LINK_POINTER_QH(address) \49 ((address & LINK_POINTER_ADDRESS_MASK) | LINK_POINTER_QUEUE_HEAD_FLAG)50 51 48 #endif 52 49 /** -
uspace/drv/uhci-hcd/uhci_struct/queue_head.h
rbb41b85 rc32688d 1 1 2 /* 2 3 * Copyright (c) 2010 Jan Vesely … … 26 27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 28 */ 28 /** @addtogroup drv usbuhcihc29 /** @addtogroup usb 29 30 * @{ 30 31 */ … … 42 43 43 44 typedef struct queue_head { 44 volatile link_pointer_t next ;45 volatile link_pointer_t next_queue; 45 46 volatile link_pointer_t element; 46 } __attribute__((packed)) qh_t; 47 /*----------------------------------------------------------------------------*/ 48 /** Initialize queue head structure 49 * 50 * @param[in] instance qh_t structure to initialize. 51 * 52 * Sets both pointer to terminal NULL. 53 */ 54 static inline void qh_init(qh_t *instance) 47 } __attribute__((packed)) queue_head_t; 48 49 static inline void queue_head_init(queue_head_t *instance) 55 50 { 56 51 assert(instance); 57 52 58 53 instance->element = 0 | LINK_POINTER_TERMINATE_FLAG; 59 instance->next = 0 | LINK_POINTER_TERMINATE_FLAG;54 instance->next_queue = 0 | LINK_POINTER_TERMINATE_FLAG; 60 55 } 61 /*----------------------------------------------------------------------------*/ 62 /** Set queue head next pointer 63 * 64 * @param[in] instance qh_t structure to use. 65 * @param[in] pa Physical address of the next queue head. 66 * 67 * Adds proper flag. If the pointer is NULL or terminal, sets next to terminal 68 * NULL. 69 */ 70 static inline void qh_set_next_qh(qh_t *instance, uint32_t pa) 56 57 static inline void queue_head_append_qh(queue_head_t *instance, uint32_t pa) 71 58 { 72 /* Address is valid and not terminal */ 73 if (pa && ((pa & LINK_POINTER_TERMINATE_FLAG) == 0)) { 74 instance->next = (pa & LINK_POINTER_ADDRESS_MASK) 59 if (pa) { 60 instance->next_queue = (pa & LINK_POINTER_ADDRESS_MASK) 75 61 | LINK_POINTER_QUEUE_HEAD_FLAG; 76 } else {77 instance->next = 0 | LINK_POINTER_TERMINATE_FLAG;78 62 } 79 63 } 80 /*----------------------------------------------------------------------------*/ 81 /** Set queue head element pointer 82 * 83 * @param[in] instance qh_t structure to initialize. 84 * @param[in] pa Physical address of the next queue head. 85 * 86 * Adds proper flag. If the pointer is NULL or terminal, sets element 87 * to terminal NULL. 88 */ 89 static inline void qh_set_element_qh(qh_t *instance, uint32_t pa) 64 65 static inline void queue_head_element_qh(queue_head_t *instance, uint32_t pa) 90 66 { 91 /* Address is valid and not terminal */ 92 if (pa && ((pa & LINK_POINTER_TERMINATE_FLAG) == 0)) { 93 instance->element = (pa & LINK_POINTER_ADDRESS_MASK) 67 if (pa) { 68 instance->next_queue = (pa & LINK_POINTER_ADDRESS_MASK) 94 69 | LINK_POINTER_QUEUE_HEAD_FLAG; 95 } else {96 instance->element = 0 | LINK_POINTER_TERMINATE_FLAG;97 70 } 98 71 } 99 /*----------------------------------------------------------------------------*/ 100 /** Set queue head element pointer 101 * 102 * @param[in] instance qh_t structure to initialize. 103 * @param[in] pa Physical address of the TD structure. 104 * 105 * Adds proper flag. If the pointer is NULL or terminal, sets element 106 * to terminal NULL. 107 */ 108 static inline void qh_set_element_td(qh_t *instance, uint32_t pa) 72 73 static inline void queue_head_set_element_td(queue_head_t *instance, uint32_t pa) 109 74 { 110 if (pa && ((pa & LINK_POINTER_TERMINATE_FLAG) == 0)) {75 if (pa) { 111 76 instance->element = (pa & LINK_POINTER_ADDRESS_MASK); 112 } else {113 instance->element = 0 | LINK_POINTER_TERMINATE_FLAG;114 77 } 115 78 } -
uspace/drv/uhci-hcd/uhci_struct/transfer_descriptor.c
rbb41b85 rc32688d 26 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 27 */ 28 /** @addtogroup drvusbuhcihc28 /** @addtogroup usb 29 29 * @{ 30 30 */ … … 38 38 #include "utils/malloc32.h" 39 39 40 /** Initialize Transfer Descriptor40 /** Initializes Transfer Descriptor 41 41 * 42 42 * @param[in] instance Memory place to initialize. … … 44 44 * @param[in] size Size of data source. 45 45 * @param[in] toggle Value of toggle bit. 46 * @param[in] iso True if TD representsIsochronous transfer.46 * @param[in] iso True if TD is for Isochronous transfer. 47 47 * @param[in] low_speed Target device's speed. 48 48 * @param[in] target Address and endpoint receiving the transfer. … … 51 51 * @param[in] next Net TD in transaction. 52 52 * @return Error code. 53 *54 * Uses a mix of supplied and default values.55 * Implicit values:56 * - all TDs have vertical flag set (makes transfers to endpoints atomic)57 * - in the error field only active it is set58 * - if the packet uses PID_IN and is not isochronous SPD is set59 *60 * Dumps 8 bytes of buffer if PID_SETUP is used.61 53 */ 62 54 void td_init(td_t *instance, int err_count, size_t size, bool toggle, bool iso, … … 96 88 } 97 89 98 usb_log_debug2("Created TD (%p): %X:%X:%X:%X(%p).\n",99 instance , instance->next, instance->status, instance->device,90 usb_log_debug2("Created TD: %X:%X:%X:%X(%p).\n", 91 instance->next, instance->status, instance->device, 100 92 instance->buffer_ptr, buffer); 101 td_print_status(instance);102 93 if (pid == USB_PID_SETUP) { 103 94 usb_log_debug("SETUP BUFFER: %s\n", 104 95 usb_debug_str_buffer(buffer, 8, 8)); 105 96 } 106 97 } 107 98 /*----------------------------------------------------------------------------*/ 108 /** Convert TD status into standard error code99 /** Converts TD status into standard error code 109 100 * 110 101 * @param[in] instance TD structure to use. … … 135 126 return EOK; 136 127 } 137 /*----------------------------------------------------------------------------*/138 /** Print values in status field (dw1) in a human readable way.139 *140 * @param[in] instance TD structure to use.141 */142 void td_print_status(td_t *instance)143 {144 assert(instance);145 const uint32_t s = instance->status;146 usb_log_debug2("TD(%p) status(%#x):%s %d,%s%s%s%s%s%s%s%s%s%s%s %d.\n",147 instance, instance->status,148 (s & TD_STATUS_SPD_FLAG) ? " SPD," : "",149 (s >> TD_STATUS_ERROR_COUNT_POS) & TD_STATUS_ERROR_COUNT_MASK,150 (s & TD_STATUS_LOW_SPEED_FLAG) ? " LOW SPEED," : "",151 (s & TD_STATUS_ISOCHRONOUS_FLAG) ? " ISOCHRONOUS," : "",152 (s & TD_STATUS_IOC_FLAG) ? " IOC," : "",153 (s & TD_STATUS_ERROR_ACTIVE) ? " ACTIVE," : "",154 (s & TD_STATUS_ERROR_STALLED) ? " STALLED," : "",155 (s & TD_STATUS_ERROR_BUFFER) ? " BUFFER," : "",156 (s & TD_STATUS_ERROR_BABBLE) ? " BABBLE," : "",157 (s & TD_STATUS_ERROR_NAK) ? " NAK," : "",158 (s & TD_STATUS_ERROR_CRC) ? " CRC/TIMEOUT," : "",159 (s & TD_STATUS_ERROR_BIT_STUFF) ? " BIT_STUFF," : "",160 (s & TD_STATUS_ERROR_RESERVED) ? " RESERVED," : "",161 (s >> TD_STATUS_ACTLEN_POS) & TD_STATUS_ACTLEN_MASK162 );163 }164 128 /** 165 129 * @} -
uspace/drv/uhci-hcd/uhci_struct/transfer_descriptor.h
rbb41b85 rc32688d 1 1 /* 2 * Copyright (c) 201 1Jan Vesely2 * Copyright (c) 2010 Jan Vesely 3 3 * All rights reserved. 4 4 * … … 26 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 27 */ 28 /** @addtogroup drvusbuhcihc28 /** @addtogroup usb 29 29 * @{ 30 30 */ … … 45 45 46 46 volatile uint32_t status; 47 47 48 #define TD_STATUS_RESERVED_MASK 0xc000f800 48 49 #define TD_STATUS_SPD_FLAG ( 1 << 29 ) 49 50 #define TD_STATUS_ERROR_COUNT_POS ( 27 ) 50 51 #define TD_STATUS_ERROR_COUNT_MASK ( 0x3 ) 52 #define TD_STATUS_ERROR_COUNT_DEFAULT 3 51 53 #define TD_STATUS_LOW_SPEED_FLAG ( 1 << 26 ) 52 54 #define TD_STATUS_ISOCHRONOUS_FLAG ( 1 << 25 ) 53 #define TD_STATUS_ IOC_FLAG ( 1 << 24 )55 #define TD_STATUS_COMPLETE_INTERRUPT_FLAG ( 1 << 24 ) 54 56 55 57 #define TD_STATUS_ERROR_ACTIVE ( 1 << 23 ) … … 68 70 69 71 volatile uint32_t device; 72 70 73 #define TD_DEVICE_MAXLEN_POS 21 71 74 #define TD_DEVICE_MAXLEN_MASK ( 0x7ff ) … … 82 85 83 86 /* there is 16 bytes of data available here, according to UHCI 84 * Design guide, according to linux kernel the hardware does not care ,85 * it just needs to be aligned,we don't use it anyway87 * Design guide, according to linux kernel the hardware does not care 88 * we don't use it anyway 86 89 */ 87 90 } __attribute__((packed)) td_t; 88 91 89 92 90 void td_init(td_t *instance, int error_count, size_t size, bool toggle, 91 bool iso, bool low_speed, usb_target_t target, usb_packet_id pid,92 void *buffer,td_t *next);93 void td_init(td_t *instance, int error_count, size_t size, bool toggle, bool iso, 94 bool low_speed, usb_target_t target, usb_packet_id pid, void *buffer, 95 td_t *next); 93 96 94 97 int td_status(td_t *instance); 95 98 96 void td_print_status(td_t *instance);97 /*----------------------------------------------------------------------------*/98 /** Helper function for parsing actual size out of TD.99 *100 * @param[in] instance TD structure to use.101 * @return Parsed actual size.102 */103 99 static inline size_t td_act_size(td_t *instance) 104 100 { 105 101 assert(instance); 106 const uint32_t s = instance->status; 107 return ((s >> TD_STATUS_ACTLEN_POS) + 1) & TD_STATUS_ACTLEN_MASK; 102 return 103 ((instance->status >> TD_STATUS_ACTLEN_POS) + 1) 104 & TD_STATUS_ACTLEN_MASK; 108 105 } 109 /*----------------------------------------------------------------------------*/ 110 /** Check whether less than max data were recieved and packet is marked as SPD. 111 * 112 * @param[in] instance TD structure to use. 113 * @return True if packet is short (less than max bytes and SPD set), false 114 * otherwise. 115 */ 106 116 107 static inline bool td_is_short(td_t *instance) 117 108 { … … 123 114 (instance->status | TD_STATUS_SPD_FLAG) && act_size < max_size; 124 115 } 125 /*----------------------------------------------------------------------------*/ 126 /** Helper function for parsing value of toggle bit. 127 * 128 * @param[in] instance TD structure to use. 129 * @return Toggle bit value. 130 */ 116 131 117 static inline int td_toggle(td_t *instance) 132 118 { 133 119 assert(instance); 134 return (instance->device & TD_DEVICE_DATA_TOGGLE_ONE_FLAG) ? 1 : 0; 120 return ((instance->device & TD_DEVICE_DATA_TOGGLE_ONE_FLAG) != 0) 121 ? 1 : 0; 135 122 } 136 /*----------------------------------------------------------------------------*/ 137 /** Helper function for parsing value of active bit 138 * 139 * @param[in] instance TD structure to use. 140 * @return Active bit value. 141 */ 123 142 124 static inline bool td_is_active(td_t *instance) 143 125 { … … 145 127 return (instance->status & TD_STATUS_ERROR_ACTIVE) != 0; 146 128 } 147 /*----------------------------------------------------------------------------*/148 /** Helper function for setting IOC bit.149 *150 * @param[in] instance TD structure to use.151 */152 static inline void td_set_ioc(td_t *instance)153 {154 assert(instance);155 instance->status |= TD_STATUS_IOC_FLAG;156 }157 /*----------------------------------------------------------------------------*/158 129 #endif 159 130 /** -
uspace/drv/uhci-hcd/utils/device_keeper.c
rbb41b85 rc32688d 27 27 */ 28 28 29 /** @addtogroup drvusbuhci hc29 /** @addtogroup drvusbuhci 30 30 * @{ 31 31 */ … … 40 40 41 41 /*----------------------------------------------------------------------------*/ 42 /** Initialize device keeper structure.42 /** Initializes device keeper structure. 43 43 * 44 44 * @param[in] instance Memory place to initialize. 45 *46 * Set all values to false/0.47 45 */ 48 46 void device_keeper_init(device_keeper_t *instance) … … 60 58 } 61 59 /*----------------------------------------------------------------------------*/ 62 /** Attempt to obtain address 0, blocks.60 /** Attempts to obtain address 0, blocks. 63 61 * 64 62 * @param[in] instance Device keeper structure to use. … … 78 76 } 79 77 /*----------------------------------------------------------------------------*/ 80 /** Attempt to obtain address 0, blocks.78 /** Attempts to obtain address 0, blocks. 81 79 * 82 80 * @param[in] instance Device keeper structure to use. … … 92 90 } 93 91 /*----------------------------------------------------------------------------*/ 94 /** Check setup packetdata for signs of toggle reset.92 /** Checks setup data for signs of toggle reset. 95 93 * 96 94 * @param[in] instance Device keeper structure to use. 97 95 * @param[in] target Device to receive setup packet. 98 96 * @param[in] data Setup packet data. 99 *100 * Really ugly one.101 97 */ 102 98 void device_keeper_reset_if_need( … … 109 105 || !instance->devices[target.address].occupied) { 110 106 fibril_mutex_unlock(&instance->guard); 111 usb_log_error("Invalid data when checking for toggle reset.\n");112 107 return; 113 108 } … … 135 130 } 136 131 /*----------------------------------------------------------------------------*/ 137 /** Get current value of endpoint toggle.132 /** Gets current value of endpoint toggle. 138 133 * 139 134 * @param[in] instance Device keeper structure to use. … … 149 144 || target.address >= USB_ADDRESS_COUNT || target.address < 0 150 145 || !instance->devices[target.address].occupied) { 151 usb_log_error("Invalid data when asking for toggle value.\n");152 146 ret = EINVAL; 153 147 } else { 154 ret = (instance->devices[target.address].toggle_status 148 ret = 149 (instance->devices[target.address].toggle_status 155 150 >> target.endpoint) & 1; 156 151 } … … 159 154 } 160 155 /*----------------------------------------------------------------------------*/ 161 /** Set current value of endpoint toggle.156 /** Sets current value of endpoint toggle. 162 157 * 163 158 * @param[in] instance Device keeper structure to use. 164 159 * @param[in] target Device and endpoint used. 165 * @param[in] toggle Toggle value.160 * @param[in] toggle Current toggle value. 166 161 * @return Error code. 167 162 */ … … 175 170 || target.address >= USB_ADDRESS_COUNT || target.address < 0 176 171 || !instance->devices[target.address].occupied) { 177 usb_log_error("Invalid data when setting toggle value.\n");178 172 ret = EINVAL; 179 173 } else { … … 189 183 } 190 184 /*----------------------------------------------------------------------------*/ 191 /** Get a free USB address185 /** Gets a free USB address 192 186 * 193 187 * @param[in] instance Device keeper structure to use. … … 222 216 } 223 217 /*----------------------------------------------------------------------------*/ 224 /** Bind USB address to devman handle.218 /** Binds USB address to devman handle. 225 219 * 226 220 * @param[in] instance Device keeper structure to use. … … 240 234 } 241 235 /*----------------------------------------------------------------------------*/ 242 /** Release used USB address.236 /** Releases used USB address. 243 237 * 244 238 * @param[in] instance Device keeper structure to use. … … 257 251 } 258 252 /*----------------------------------------------------------------------------*/ 259 /** Find USB address associated with the device253 /** Finds USB address associated with the device 260 254 * 261 255 * @param[in] instance Device keeper structure to use. … … 280 274 } 281 275 /*----------------------------------------------------------------------------*/ 282 /** Get speed associated with the address276 /** Gets speed associated with the address 283 277 * 284 278 * @param[in] instance Device keeper structure to use. -
uspace/drv/uhci-hcd/utils/device_keeper.h
rbb41b85 rc32688d 27 27 */ 28 28 29 /** @addtogroup drvusbuhci hc29 /** @addtogroup drvusbuhci 30 30 * @{ 31 31 */ -
uspace/drv/uhci-hcd/utils/malloc32.h
rbb41b85 rc32688d 43 43 #define UHCI_REQUIRED_PAGE_SIZE 4096 44 44 45 /** Get physical address translation46 *47 * @param[in] addr Virtual address to translate48 * @return Physical address if exists, NULL otherwise.49 */50 45 static inline uintptr_t addr_to_phys(void *addr) 51 46 { … … 53 48 int ret = as_get_physical_mapping(addr, &result); 54 49 55 if (ret != EOK) 56 return 0; 50 assert(ret == 0); 57 51 return (result | ((uintptr_t)addr & 0xfff)); 58 52 } 59 /*----------------------------------------------------------------------------*/ 60 /** Physical mallocator simulator 61 * 62 * @param[in] size Size of the required memory space 63 * @return Address of the alligned and big enough memory place, NULL on failure. 64 */ 53 65 54 static inline void * malloc32(size_t size) 66 55 { return memalign(UHCI_STRCUTURES_ALIGNMENT, size); } 67 /*----------------------------------------------------------------------------*/ 68 /** Physical mallocator simulator 69 * 70 * @param[in] addr Address of the place allocated by malloc32 71 */ 72 static inline void free32(void *addr) 73 { if (addr) free(addr); } 74 /*----------------------------------------------------------------------------*/ 75 /** Create 4KB page mapping 76 * 77 * @return Address of the mapped page, NULL on failure. 78 */ 79 static inline void * get_page(void) 56 57 static inline void * get_page() 80 58 { 81 59 void * free_address = as_get_mappable_page(UHCI_REQUIRED_PAGE_SIZE); 82 60 assert(free_address); 83 61 if (free_address == 0) 84 return NULL;62 return 0; 85 63 void* ret = 86 64 as_area_create(free_address, UHCI_REQUIRED_PAGE_SIZE, 87 65 AS_AREA_READ | AS_AREA_WRITE); 88 66 if (ret != free_address) 89 return NULL;67 return 0; 90 68 return ret; 91 69 } 70 71 static inline void free32(void *addr) 72 { if (addr) free(addr); } 92 73 93 74 #endif -
uspace/drv/uhci-rhd/Makefile
rbb41b85 rc32688d 35 35 main.c \ 36 36 port.c \ 37 port_status.c \ 37 38 root_hub.c 38 39 -
uspace/drv/uhci-rhd/main.c
rbb41b85 rc32688d 26 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 27 */ 28 /** @addtogroup drvusbuhcirh28 /** @addtogroup usb 29 29 * @{ 30 30 */ 31 31 /** @file 32 * @brief UHCI root hub initialization routines32 * @brief UHCI driver 33 33 */ 34 34 #include <ddf/driver.h> … … 40 40 #include <usb/debug.h> 41 41 42 43 42 44 #include "root_hub.h" 43 45 … … 45 47 static int hc_get_my_registers(ddf_dev_t *dev, 46 48 uintptr_t *io_reg_address, size_t *io_reg_size); 47 #if 048 49 /*----------------------------------------------------------------------------*/ 49 50 static int usb_iface_get_hc_handle(ddf_fun_t *fun, devman_handle_t *handle) … … 66 67 .interfaces[USB_DEV_IFACE] = &uhci_rh_usb_iface, 67 68 }; 68 #endif69 69 /*----------------------------------------------------------------------------*/ 70 /** Initialize a new ddf driver instance of UHCI root hub.70 /** Initializes a new ddf driver instance of UHCI root hub. 71 71 * 72 72 * @param[in] device DDF instance of the device to initialize. … … 81 81 82 82 //device->ops = &uhci_rh_ops; 83 (void) uhci_rh_ops; 84 85 uhci_root_hub_t *rh = malloc(sizeof(uhci_root_hub_t)); 86 if (!rh) { 87 usb_log_error("Failed to allocate memory for driver instance.\n"); 88 return ENOMEM; 89 } 90 83 91 uintptr_t io_regs = 0; 84 92 size_t io_size = 0; 85 93 86 94 int ret = hc_get_my_registers(device, &io_regs, &io_size); 87 if (ret != EOK) { 88 usb_log_error("Failed(%d) to get registers from parent hc.", 89 ret); 90 } 91 usb_log_info("I/O regs at %#X (size %zu).\n", io_regs, io_size); 95 assert(ret == EOK); 92 96 93 uhci_root_hub_t *rh = malloc(sizeof(uhci_root_hub_t)); 94 if (!rh) { 95 usb_log_error("Failed to allocate driver instance.\n"); 96 return ENOMEM; 97 } 98 97 /* TODO: verify values from hc */ 98 usb_log_info("I/O regs at 0x%X (size %zu).\n", io_regs, io_size); 99 99 ret = uhci_root_hub_init(rh, (void*)io_regs, io_size, device); 100 100 if (ret != EOK) { … … 119 119 }; 120 120 /*----------------------------------------------------------------------------*/ 121 /** Initialize global driver structures (NONE).121 /** Initializes global driver structures (NONE). 122 122 * 123 123 * @param[in] argc Nmber of arguments in argv vector (ignored). -
uspace/drv/uhci-rhd/port.c
rbb41b85 rc32688d 26 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 27 */ 28 /** @addtogroup drvusbuhcirh28 /** @addtogroup usb 29 29 * @{ 30 30 */ 31 31 /** @file 32 * @brief UHCI root hub port routines 33 */ 34 #include <libarch/ddi.h> /* pio_read and pio_write */ 32 * @brief UHCI driver 33 */ 35 34 #include <errno.h> 36 35 #include <str_error.h> … … 38 37 39 38 #include <usb/usb.h> /* usb_address_t */ 39 #include <usb/usbdevice.h> 40 40 #include <usb/hub.h> 41 #include <usb/request.h> 41 42 #include <usb/debug.h> 43 #include <usb/recognise.h> 42 44 43 45 #include "port.h" 46 #include "port_status.h" 44 47 45 48 static int uhci_port_new_device(uhci_port_t *port, usb_speed_t speed); … … 48 51 static int uhci_port_check(void *port); 49 52 static int uhci_port_reset_enable(int portno, void *arg); 50 static void uhci_port_print_status( 51 uhci_port_t *port, const port_status_t value); 52 53 /** Register reading helper function. 54 * 55 * @param[in] port Structure to use. 56 * @return Error code. (Always EOK) 57 */ 58 static inline port_status_t uhci_port_read_status(uhci_port_t *port) 59 { 60 assert(port); 61 return pio_read_16(port->address); 62 } 63 /*----------------------------------------------------------------------------*/ 64 /** Register writing helper function. 65 * 66 * @param[in] port Structure to use. 67 * @param[in] value New register value. 68 * @return Error code. (Always EOK) 69 */ 70 static inline void uhci_port_write_status( 71 uhci_port_t *port, port_status_t value) 72 { 73 assert(port); 74 pio_write_16(port->address, value); 75 } 76 77 /*----------------------------------------------------------------------------*/ 78 /** Initialize UHCI root hub port instance. 53 /*----------------------------------------------------------------------------*/ 54 /** Initializes UHCI root hub port instance. 79 55 * 80 56 * @param[in] port Memory structure to use. … … 85 61 * @return Error code. 86 62 * 87 * Creates and starts the polling fibril.63 * Starts the polling fibril. 88 64 */ 89 65 int uhci_port_init(uhci_port_t *port, … … 91 67 { 92 68 assert(port); 93 asprintf(&port->id_string, "Port (%p - %d)", port, number);94 if (port->id_string == NULL) {95 return ENOMEM;96 }97 69 98 70 port->address = address; … … 111 83 port->checker = fibril_create(uhci_port_check, port); 112 84 if (port->checker == 0) { 113 usb_log_error(" %s: failed to create pollingfibril.",114 port-> id_string);85 usb_log_error("Port(%p - %d): failed to launch root hub fibril.", 86 port->address, port->number); 115 87 return ENOMEM; 116 88 } 117 89 118 90 fibril_add_ready(port->checker); 119 usb_log_debug(" %s: Started polling fibril(%x).\n",120 port-> id_string, port->checker);121 return EOK; 122 } 123 /*----------------------------------------------------------------------------*/ 124 /** CleanupUHCI root hub port instance.91 usb_log_debug("Port(%p - %d): Added fibril. %x\n", 92 port->address, port->number, port->checker); 93 return EOK; 94 } 95 /*----------------------------------------------------------------------------*/ 96 /** Finishes UHCI root hub port instance. 125 97 * 126 98 * @param[in] port Memory structure to use. … … 130 102 void uhci_port_fini(uhci_port_t *port) 131 103 { 132 assert(port);133 free(port->id_string);134 104 /* TODO: Kill fibril here */ 135 105 return; … … 138 108 /** Periodically checks port status and reports new devices. 139 109 * 140 * @param[in] port Portstructure to use.110 * @param[in] port Memory structure to use. 141 111 * @return Error code. 142 112 */ … … 146 116 assert(instance); 147 117 118 /* Iteration count, for debug purposes only */ 119 unsigned count = 0; 120 148 121 while (1) { 149 122 async_usleep(instance->wait_period_usec); 150 123 151 /* Read register value */ 152 port_status_t port_status = uhci_port_read_status(instance); 153 154 /* Print the value if it's interesting */ 155 if (port_status & ~STATUS_ALWAYS_ONE) 156 uhci_port_print_status(instance, port_status); 124 /* read register value */ 125 port_status_t port_status = port_status_read(instance->address); 126 127 /* debug print mutex */ 128 static fibril_mutex_t dbg_mtx = 129 FIBRIL_MUTEX_INITIALIZER(dbg_mtx); 130 fibril_mutex_lock(&dbg_mtx); 131 usb_log_debug2("Port(%p - %d): Status: %#04x. === %u\n", 132 instance->address, instance->number, port_status, count++); 133 // print_port_status(port_status); 134 fibril_mutex_unlock(&dbg_mtx); 157 135 158 136 if ((port_status & STATUS_CONNECTED_CHANGED) == 0) 159 137 continue; 160 138 161 usb_log_debug(" %s: Connected change detected: %x.\n",162 instance-> id_string, port_status);139 usb_log_debug("Port(%p - %d): Connected change detected: %x.\n", 140 instance->address, instance->number, port_status); 163 141 164 142 int rc = 165 143 usb_hc_connection_open(&instance->hc_connection); 166 144 if (rc != EOK) { 167 usb_log_error(" %s: Failed to connect to HC.",168 instance-> id_string);145 usb_log_error("Port(%p - %d): Failed to connect to HC.", 146 instance->address, instance->number); 169 147 continue; 170 148 } … … 172 150 /* Remove any old device */ 173 151 if (instance->attached_device) { 174 usb_log_debug2(" %s: Removing device.\n",175 instance-> id_string);152 usb_log_debug2("Port(%p - %d): Removing device.\n", 153 instance->address, instance->number); 176 154 uhci_port_remove_device(instance); 177 155 } … … 185 163 } else { 186 164 /* Write one to WC bits, to ack changes */ 187 uhci_port_write_status(instance, port_status);188 usb_log_debug(" %s: status changeACK.\n",189 instance-> id_string);165 port_status_write(instance->address, port_status); 166 usb_log_debug("Port(%p - %d): Change status ACK.\n", 167 instance->address, instance->number); 190 168 } 191 169 192 170 rc = usb_hc_connection_close(&instance->hc_connection); 193 171 if (rc != EOK) { 194 usb_log_error(" %s: Failed to disconnect.",195 instance-> id_string);172 usb_log_error("Port(%p - %d): Failed to disconnect.", 173 instance->address, instance->number); 196 174 } 197 175 } … … 204 182 * @param arg Pointer to uhci_port_t of port with the new device. 205 183 * @return Error code. 206 *207 * Resets and enables the ub port.208 184 */ 209 185 int uhci_port_reset_enable(int portno, void *arg) … … 211 187 uhci_port_t *port = (uhci_port_t *) arg; 212 188 213 usb_log_debug2("%s: new_device_enable_port.\n", port->id_string); 189 usb_log_debug2("Port(%p - %d): new_device_enable_port.\n", 190 port->address, port->number); 214 191 215 192 /* … … 219 196 async_usleep(100000); 220 197 221 /* 222 * Resets from root ports should be nominally 50ms 198 199 /* The hub maintains the reset signal to that port for 10 ms 200 * (See Section 11.5.1.5) 223 201 */ 224 202 { 225 usb_log_debug("%s: Reset Signal start.\n", port->id_string); 226 port_status_t port_status = uhci_port_read_status(port); 203 usb_log_debug("Port(%p - %d): Reset Signal start.\n", 204 port->address, port->number); 205 port_status_t port_status = 206 port_status_read(port->address); 227 207 port_status |= STATUS_IN_RESET; 228 uhci_port_write_status(port, port_status);229 async_usleep( 50000);230 port_status = uhci_port_read_status(port);208 port_status_write(port->address, port_status); 209 async_usleep(10000); 210 port_status = port_status_read(port->address); 231 211 port_status &= ~STATUS_IN_RESET; 232 uhci_port_write_status(port, port_status); 233 usb_log_debug("%s: Reset Signal stop.\n", port->id_string); 234 } 235 236 /* the reset recovery time 10ms */ 237 async_usleep(10000); 212 port_status_write(port->address, port_status); 213 usb_log_debug("Port(%p - %d): Reset Signal stop.\n", 214 port->address, port->number); 215 } 238 216 239 217 /* Enable the port. */ 240 218 uhci_port_set_enabled(port, true); 241 242 return EOK; 243 } 244 /*----------------------------------------------------------------------------*/ 245 /** Initialize and report connected device. 246 * 247 * @param[in] port Port structure to use. 219 return EOK; 220 } 221 /*----------------------------------------------------------------------------*/ 222 /** Initializes and reports connected device. 223 * 224 * @param[in] port Memory structure to use. 248 225 * @param[in] speed Detected speed. 249 226 * @return Error code. … … 256 233 assert(usb_hc_connection_is_opened(&port->hc_connection)); 257 234 258 usb_log_info("%s: Detected new device.\n", port->id_string); 235 usb_log_info("Port(%p-%d): Detected new device.\n", 236 port->address, port->number); 259 237 260 238 usb_address_t dev_addr; … … 264 242 265 243 if (rc != EOK) { 266 usb_log_error(" %s: Failed(%d) to add device: %s.\n",267 port-> id_string, rc, str_error(rc));244 usb_log_error("Port(%p-%d): Failed(%d) to add device: %s.\n", 245 port->address, port->number, rc, str_error(rc)); 268 246 uhci_port_set_enabled(port, false); 269 247 return rc; 270 248 } 271 249 272 usb_log_info("%s: New device has address %d (handle %zu).\n", 273 port->id_string, dev_addr, port->attached_device); 274 275 return EOK; 276 } 277 /*----------------------------------------------------------------------------*/ 278 /** Remove device. 279 * 280 * @param[in] port Memory structure to use. 281 * @return Error code. 282 * 283 * Does not work, DDF does not support device removal. 284 * Does not even free used USB address (it would be dangerous if tis driver 285 * is still running). 250 usb_log_info("Port(%p-%d): New device has address %d (handle %zu).\n", 251 port->address, port->number, dev_addr, port->attached_device); 252 253 return EOK; 254 } 255 /*----------------------------------------------------------------------------*/ 256 /** Removes device. 257 * 258 * @param[in] port Memory structure to use. 259 * @return Error code. 260 * 261 * Does not work DDF does not support device removal. 286 262 */ 287 263 int uhci_port_remove_device(uhci_port_t *port) 288 264 { 289 usb_log_error("%s: Don't know how to remove device %d.\n", 290 port->id_string, (unsigned int)port->attached_device); 291 return EOK; 292 } 293 /*----------------------------------------------------------------------------*/ 294 /** Enable or disable root hub port. 295 * 296 * @param[in] port Port structure to use. 297 * @param[in] enabled Port status to set. 265 usb_log_error("Port(%p-%d): Don't know how to remove device %#x.\n", 266 port->address, port->number, (unsigned int)port->attached_device); 267 return EOK; 268 } 269 /*----------------------------------------------------------------------------*/ 270 /** Enables and disables port. 271 * 272 * @param[in] port Memory structure to use. 298 273 * @return Error code. (Always EOK) 299 274 */ … … 303 278 304 279 /* Read register value */ 305 port_status_t port_status = uhci_port_read_status(port);280 port_status_t port_status = port_status_read(port->address); 306 281 307 282 /* Set enabled bit */ … … 313 288 314 289 /* Write new value. */ 315 uhci_port_write_status(port, port_status); 316 317 usb_log_info("%s: %sabled port.\n", 318 port->id_string, enabled ? "En" : "Dis"); 319 return EOK; 320 } 321 /*----------------------------------------------------------------------------*/ 322 /** Print the port status value in a human friendly way 323 * 324 * @param[in] port Port structure to use. 325 * @param[in] value Port register value to print. 326 * @return Error code. (Always EOK) 327 */ 328 void uhci_port_print_status(uhci_port_t *port, const port_status_t value) 329 { 330 assert(port); 331 usb_log_debug2("%s Port status(%#x):%s%s%s%s%s%s%s%s%s%s%s.\n", 332 port->id_string, value, 333 (value & STATUS_SUSPEND) ? " SUSPENDED," : "", 334 (value & STATUS_RESUME) ? " IN RESUME," : "", 335 (value & STATUS_IN_RESET) ? " IN RESET," : "", 336 (value & STATUS_LINE_D_MINUS) ? " VD-," : "", 337 (value & STATUS_LINE_D_PLUS) ? " VD+," : "", 338 (value & STATUS_LOW_SPEED) ? " LOWSPEED," : "", 339 (value & STATUS_ENABLED_CHANGED) ? " ENABLED-CHANGE," : "", 340 (value & STATUS_ENABLED) ? " ENABLED," : "", 341 (value & STATUS_CONNECTED_CHANGED) ? " CONNECTED-CHANGE," : "", 342 (value & STATUS_CONNECTED) ? " CONNECTED," : "", 343 (value & STATUS_ALWAYS_ONE) ? " ALWAYS ONE" : " ERROR: NO ALWAYS ONE" 344 ); 345 } 290 port_status_write(port->address, port_status); 291 292 usb_log_info("Port(%p-%d): %sabled port.\n", 293 port->address, port->number, enabled ? "En" : "Dis"); 294 return EOK; 295 } 296 /*----------------------------------------------------------------------------*/ 346 297 /** 347 298 * @} -
uspace/drv/uhci-rhd/port.h
rbb41b85 rc32688d 1 1 /* 2 * Copyright (c) 201 1Jan Vesely2 * Copyright (c) 2010 Jan Vesely 3 3 * All rights reserved. 4 4 * … … 26 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 27 */ 28 /** @addtogroup drvusbuhcirh28 /** @addtogroup usb 29 29 * @{ 30 30 */ 31 31 /** @file 32 * @brief UHCI root hub port routines32 * @brief UHCI port driver 33 33 */ 34 34 #ifndef DRV_UHCI_PORT_H 35 35 #define DRV_UHCI_PORT_H 36 36 37 #include <assert.h> 38 #include <ddf/driver.h> 37 39 #include <stdint.h> 38 #include <fibril.h> 39 #include <ddf/driver.h> 40 #include <usb/usbdevice.h> /* usb_hc_connection_t */ 40 #include <usb/usbdevice.h> 41 41 42 typedef uint16_t port_status_t; 43 #define STATUS_CONNECTED (1 << 0) 44 #define STATUS_CONNECTED_CHANGED (1 << 1) 45 #define STATUS_ENABLED (1 << 2) 46 #define STATUS_ENABLED_CHANGED (1 << 3) 47 #define STATUS_LINE_D_PLUS (1 << 4) 48 #define STATUS_LINE_D_MINUS (1 << 5) 49 #define STATUS_RESUME (1 << 6) 50 #define STATUS_ALWAYS_ONE (1 << 7) 51 52 #define STATUS_LOW_SPEED (1 << 8) 53 #define STATUS_IN_RESET (1 << 9) 54 #define STATUS_SUSPEND (1 << 12) 42 #include "port_status.h" 55 43 56 44 typedef struct uhci_port 57 45 { 58 char *id_string;59 46 port_status_t *address; 60 47 unsigned number; … … 71 58 72 59 void uhci_port_fini(uhci_port_t *port); 73 74 60 #endif 75 61 /** -
uspace/drv/uhci-rhd/root_hub.c
rbb41b85 rc32688d 26 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 27 */ 28 /** @addtogroup drvusbuhcirh28 /** @addtogroup usb 29 29 * @{ 30 30 */ 31 31 /** @file 32 * @brief UHCI root hubdriver32 * @brief UHCI driver 33 33 */ 34 34 #include <errno.h> 35 #include <stdint.h> 35 36 #include <ddi.h> 37 #include <devman.h> 36 38 #include <usb/debug.h> 37 39 38 40 #include "root_hub.h" 39 41 40 /** Initialize UHCI root hub instance.42 /** Initializes UHCI root hub instance. 41 43 * 42 44 * @param[in] instance Driver memory structure to use. 43 45 * @param[in] addr Address of I/O registers. 44 46 * @param[in] size Size of available I/O space. 45 * @param[in] rh Pointer to ddf instance ofthe root hub driver.47 * @param[in] rh Pointer to ddf instance fo the root hub driver. 46 48 * @return Error code. 47 49 */ … … 59 61 if (ret < 0) { 60 62 usb_log_error( 61 "Failed(%d) to gain access to port registers at %p\n", 62 ret, regs); 63 "Failed to gain access to port registers at %p\n", regs); 63 64 return ret; 64 65 } 65 66 66 /* Initialize root hub ports */67 /* add fibrils for periodic port checks */ 67 68 unsigned i = 0; 68 69 for (; i < UHCI_ROOT_HUB_PORT_COUNT; ++i) { … … 81 82 } 82 83 /*----------------------------------------------------------------------------*/ 83 /** CleanupUHCI root hub instance.84 /** Finishes UHCI root hub instance. 84 85 * 85 * @param[in] instance Root hubstructure to use.86 * @param[in] instance Driver memory structure to use. 86 87 * @return Error code. 87 88 */ -
uspace/drv/uhci-rhd/root_hub.h
rbb41b85 rc32688d 1 1 /* 2 * Copyright (c) 201 1Jan Vesely2 * Copyright (c) 2010 Jan Vesely 3 3 * All rights reserved. 4 4 * … … 26 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 27 */ 28 /** @addtogroup drvusbuhcirh28 /** @addtogroup usb 29 29 * @{ 30 30 */ … … 35 35 #define DRV_UHCI_ROOT_HUB_H 36 36 37 #include <fibril.h> 37 38 #include <ddf/driver.h> 38 39 -
uspace/drv/usbhid/hiddev.c
rbb41b85 rc32688d 411 411 return rc; 412 412 } 413 rc = usb_endpoint_pipe_probe_default_control(&hid_dev->ctrl_pipe); 414 if (rc != EOK) { 415 usb_log_error("Probing default control pipe failed: %s.\n", 416 str_error(rc)); 417 return rc; 418 } 419 413 420 414 /* 421 415 * Initialize the report parser. -
uspace/drv/usbhub/usbhub.c
rbb41b85 rc32688d 72 72 int usb_hub_control_loop(void * hub_info_param){ 73 73 usb_hub_info_t * hub_info = (usb_hub_info_t*)hub_info_param; 74 int errorCode = EOK; 75 76 while(errorCode == EOK){ 77 errorCode = usb_hub_check_hub_changes(hub_info); 74 while(true){ 75 usb_hub_check_hub_changes(hub_info); 78 76 async_usleep(1000 * 1000 );/// \TODO proper number once 79 77 } 80 dprintf(USB_LOG_LEVEL_ERROR,81 "something in ctrl loop went wrong, errno %d",errorCode);82 78 return 0; 83 79 } … … 122 118 dprintf(USB_LOG_LEVEL_ERROR, 123 119 "could not initialize connection to device endpoint, errno %d",opResult); 124 return opResult; 125 } 126 127 opResult = usb_endpoint_pipe_probe_default_control(&hub->endpoints.control); 128 if (opResult != EOK) { 129 dprintf(USB_LOG_LEVEL_ERROR, "failed probing endpoint 0, %d", opResult); 130 return opResult; 131 } 132 133 return EOK; 120 } 121 return opResult; 134 122 } 135 123 … … 384 372 * @param target 385 373 */ 386 static void usb_hub_init_add_device(usb_hub_info_t * hub, uint16_t port, 387 bool isLowSpeed) { 374 static void usb_hub_init_add_device(usb_hub_info_t * hub, uint16_t port) { 388 375 usb_device_request_setup_packet_t request; 389 376 int opResult; … … 391 378 assert(hub->endpoints.control.hc_phone); 392 379 //get default address 393 usb_speed_t speed = isLowSpeed?USB_SPEED_LOW:USB_SPEED_FULL;394 opResult = usb_hc_reserve_default_address(&hub->connection, speed);380 //opResult = usb_drv_reserve_default_address(hc); 381 opResult = usb_hc_reserve_default_address(&hub->connection, USB_SPEED_LOW); 395 382 396 383 if (opResult != EOK) { … … 443 430 &new_device_pipe, 444 431 &new_device_connection); 445 usb_endpoint_pipe_probe_default_control(&new_device_pipe);446 432 /// \TODO get highspeed info 447 433 usb_speed_t speed = isLowSpeed?USB_SPEED_LOW:USB_SPEED_FULL; … … 451 437 usb_address_t new_device_address = usb_hc_request_address( 452 438 &hub->connection, 453 speed 439 speed/// \TODO fullspeed?? 454 440 ); 455 441 if (new_device_address < 0) { … … 515 501 static void usb_hub_removed_device( 516 502 usb_hub_info_t * hub,uint16_t port) { 517 503 //usb_device_request_setup_packet_t request; 504 int opResult; 505 518 506 /** \TODO remove device from device manager - not yet implemented in 519 507 * devide manager … … 522 510 //close address 523 511 if(hub->attached_devs[port].address!=0){ 524 / *uncomment this code to use it when DDF allows device removal512 //opResult = usb_drv_release_address(hc,hub->attached_devs[port].address); 525 513 opResult = usb_hc_unregister_device( 526 514 &hub->connection, hub->attached_devs[port].address); … … 531 519 hub->attached_devs[port].address = 0; 532 520 hub->attached_devs[port].handle = 0; 533 */534 521 }else{ 535 522 dprintf(USB_LOG_LEVEL_WARNING, "this is strange, disconnected device had no address"); … … 601 588 if (usb_port_dev_connected(&status)) { 602 589 dprintf(USB_LOG_LEVEL_INFO, "some connection changed"); 603 usb_hub_init_add_device(hub, port , usb_port_low_speed(&status));590 usb_hub_init_add_device(hub, port); 604 591 } else { 605 592 usb_hub_removed_device(hub, port); … … 639 626 /** 640 627 * Check changes on particular hub 641 * @param hub_info_param pointer to usb_hub_info_t structure 642 * @return error code if there is problem when initializing communication with 643 * hub, EOK otherwise 644 */ 645 int usb_hub_check_hub_changes(usb_hub_info_t * hub_info){ 628 * @param hub_info_param 629 */ 630 void usb_hub_check_hub_changes(usb_hub_info_t * hub_info){ 646 631 int opResult; 647 632 opResult = usb_endpoint_pipe_start_session(&hub_info->endpoints.status_change); … … 649 634 dprintf(USB_LOG_LEVEL_ERROR, 650 635 "could not initialize communication for hub; %d", opResult); 651 return opResult;636 return; 652 637 } 653 638 … … 671 656 dprintf(USB_LOG_LEVEL_WARNING, "something went wrong while getting status of hub"); 672 657 usb_endpoint_pipe_end_session(&hub_info->endpoints.status_change); 673 return opResult;658 return; 674 659 } 675 660 unsigned int port; … … 679 664 opResult); 680 665 usb_endpoint_pipe_end_session(&hub_info->endpoints.status_change); 681 return opResult;666 return; 682 667 } 683 668 opResult = usb_hc_connection_open(&hub_info->connection); … … 687 672 usb_endpoint_pipe_end_session(&hub_info->endpoints.control); 688 673 usb_endpoint_pipe_end_session(&hub_info->endpoints.status_change); 689 return opResult;674 return; 690 675 } 691 676 … … 703 688 usb_endpoint_pipe_end_session(&hub_info->endpoints.status_change); 704 689 free(change_bitmap); 705 return EOK;706 690 } 707 691 -
uspace/drv/usbhub/usbhub.h
rbb41b85 rc32688d 87 87 88 88 /** 89 * Check changes on specified hub89 * check changes on specified hub 90 90 * @param hub_info_param pointer to usb_hub_info_t structure 91 * @return error code if there is problem when initializing communication with92 * hub, EOK otherwise93 91 */ 94 intusb_hub_check_hub_changes(usb_hub_info_t * hub_info_param);92 void usb_hub_check_hub_changes(usb_hub_info_t * hub_info_param); 95 93 96 94 -
uspace/drv/usbmid/usbmid.c
rbb41b85 rc32688d 116 116 return NULL; 117 117 } 118 rc = usb_endpoint_pipe_probe_default_control(&mid->ctrl_pipe);119 if (rc != EOK) {120 usb_log_error("Probing default control pipe failed: %s.\n",121 str_error(rc));122 free(mid);123 return NULL;124 }125 118 126 119 mid->dev = dev; -
uspace/drv/usbmouse/init.c
rbb41b85 rc32688d 42 42 43 43 /** Mouse polling endpoint description for boot protocol subclass. */ 44 usb_endpoint_description_t poll_endpoint_description = {44 static usb_endpoint_description_t poll_endpoint_description = { 45 45 .transfer_type = USB_TRANSFER_INTERRUPT, 46 46 .direction = USB_DIRECTION_IN, … … 51 51 }; 52 52 53 /** Initialize poll pipe. 54 * 55 * Expects that session is already started on control pipe zero. 56 * 57 * @param mouse Mouse device. 58 * @param my_interface Interface number. 59 * @return Error code. 60 */ 61 static int intialize_poll_pipe(usb_mouse_t *mouse, int my_interface) 62 { 63 assert(usb_endpoint_pipe_is_session_started(&mouse->ctrl_pipe)); 64 65 int rc; 66 67 void *config_descriptor; 68 size_t config_descriptor_size; 69 70 rc = usb_request_get_full_configuration_descriptor_alloc( 71 &mouse->ctrl_pipe, 0, &config_descriptor, &config_descriptor_size); 72 if (rc != EOK) { 73 return rc; 74 } 75 76 usb_endpoint_mapping_t endpoint_mapping[1] = { 77 { 78 .pipe = &mouse->poll_pipe, 79 .description = &poll_endpoint_description, 80 .interface_no = my_interface 81 } 82 }; 83 84 rc = usb_endpoint_pipe_initialize_from_configuration(endpoint_mapping, 85 1, config_descriptor, config_descriptor_size, &mouse->wire); 86 if (rc != EOK) { 87 return rc; 88 } 89 90 if (!endpoint_mapping[0].present) { 91 return ENOENT; 92 } 93 94 mouse->poll_interval_us = 1000 * endpoint_mapping[0].descriptor->poll_interval; 95 96 usb_log_debug("prepared polling endpoint %d (interval %zu).\n", 97 mouse->poll_pipe.endpoint_no, mouse->poll_interval_us); 98 99 return EOK; 100 } 101 53 102 static void default_connection_handler(ddf_fun_t *, ipc_callid_t, ipc_call_t *); 54 103 /** Device ops for USB mouse. */ … … 94 143 * @return Error code. 95 144 */ 96 int usb_mouse_create( usb_device_t *dev)145 int usb_mouse_create(ddf_dev_t *dev) 97 146 { 98 147 usb_mouse_t *mouse = malloc(sizeof(usb_mouse_t)); … … 100 149 return ENOMEM; 101 150 } 102 mouse->dev = dev;151 mouse->device = dev; 103 152 mouse->console_phone = -1; 104 153 105 154 int rc; 106 155 156 /* Initialize the backing connection. */ 157 rc = usb_device_connection_initialize_from_device(&mouse->wire, dev); 158 if (rc != EOK) { 159 goto leave; 160 } 161 162 /* Initialize the default control pipe. */ 163 rc = usb_endpoint_pipe_initialize_default_control(&mouse->ctrl_pipe, 164 &mouse->wire); 165 if (rc != EOK) { 166 goto leave; 167 } 168 169 rc = usb_endpoint_pipe_start_session(&mouse->ctrl_pipe); 170 if (rc != EOK) { 171 goto leave; 172 } 173 174 rc = intialize_poll_pipe(mouse, usb_device_get_assigned_interface(dev)); 175 176 /* We can ignore error here. */ 177 usb_endpoint_pipe_end_session(&mouse->ctrl_pipe); 178 179 if (rc != EOK) { 180 goto leave; 181 } 182 107 183 /* Create DDF function. */ 108 mouse->mouse_fun = ddf_fun_create(dev ->ddf_dev, fun_exposed, "mouse");184 mouse->mouse_fun = ddf_fun_create(dev, fun_exposed, "mouse"); 109 185 if (mouse->mouse_fun == NULL) { 110 186 rc = ENOMEM; -
uspace/drv/usbmouse/main.c
rbb41b85 rc32688d 44 44 * @return Error code. 45 45 */ 46 static int usbmouse_add_device( usb_device_t *dev)46 static int usbmouse_add_device(ddf_dev_t *dev) 47 47 { 48 48 int rc = usb_mouse_create(dev); … … 53 53 } 54 54 55 usb_log_debug("Polling pipe at endpoint %d.\n", dev->pipes[0].pipe->endpoint_no); 56 57 rc = usb_device_auto_poll(dev, 0, 58 usb_mouse_polling_callback, dev->pipes[0].pipe->max_packet_size, 59 usb_mouse_polling_ended_callback, dev->driver_data); 60 61 if (rc != EOK) { 62 usb_log_error("Failed to start polling fibril: %s.\n", 63 str_error(rc)); 64 return rc; 55 fid_t poll_fibril = fibril_create(usb_mouse_polling_fibril, dev); 56 if (poll_fibril == 0) { 57 usb_log_error("Failed to initialize polling fibril.\n"); 58 /* FIXME: free allocated resources. */ 59 return ENOMEM; 65 60 } 66 61 62 fibril_add_ready(poll_fibril); 63 67 64 usb_log_info("controlling new mouse (handle %llu).\n", 68 dev-> ddf_dev->handle);65 dev->handle); 69 66 70 67 return EOK; … … 72 69 73 70 /** USB mouse driver ops. */ 74 static usb_driver_ops_t mouse_driver_ops = {71 static driver_ops_t mouse_driver_ops = { 75 72 .add_device = usbmouse_add_device, 76 73 }; 77 74 78 static usb_endpoint_description_t *endpoints[] = {79 &poll_endpoint_description,80 NULL81 };82 83 75 /** USB mouse driver. */ 84 static usb_driver_t mouse_driver = {76 static driver_t mouse_driver = { 85 77 .name = NAME, 86 .ops = &mouse_driver_ops, 87 .endpoints = endpoints 78 .driver_ops = &mouse_driver_ops 88 79 }; 89 80 … … 92 83 usb_log_enable(USB_LOG_LEVEL_DEBUG, NAME); 93 84 94 return usb_driver_main(&mouse_driver);85 return ddf_driver_main(&mouse_driver); 95 86 } 96 87 -
uspace/drv/usbmouse/mouse.c
rbb41b85 rc32688d 40 40 #include <ipc/mouse.h> 41 41 42 /** Mouse polling callback.42 /** Fibril function for polling the mouse device. 43 43 * 44 * @param dev Device that is being polled.45 * @param buffer Data buffer.46 * @param buffer_size Buffer size in bytes.47 * @param arg Custom argument - points to usb_mouse_t.48 * @return Always true.44 * This function shall not terminate unless the device breaks and fails 45 * to send data (e.g. stalls on data request). 46 * 47 * @param arg ddf_dev_t type representing the mouse device. 48 * @return EOK Always. 49 49 */ 50 bool usb_mouse_polling_callback(usb_device_t *dev, 51 uint8_t *buffer, size_t buffer_size, void *arg) 50 int usb_mouse_polling_fibril(void *arg) 52 51 { 53 usb_mouse_t *mouse = (usb_mouse_t *) arg; 52 assert(arg != NULL); 53 ddf_dev_t *dev = (ddf_dev_t *) arg; 54 usb_mouse_t *mouse = (usb_mouse_t *) dev->driver_data; 54 55 55 usb_log_debug2("got buffer: %s.\n", 56 usb_debug_str_buffer(buffer, buffer_size, 0)); 56 assert(mouse); 57 57 58 uint8_t butt = buffer[0]; 59 char str_buttons[4] = { 60 butt & 1 ? '#' : '.', 61 butt & 2 ? '#' : '.', 62 butt & 4 ? '#' : '.', 63 0 64 }; 58 size_t buffer_size = mouse->poll_pipe.max_packet_size; 65 59 66 int shift_x = ((int) buffer[1]) - 127; 67 int shift_y = ((int) buffer[2]) - 127; 68 int wheel = ((int) buffer[3]) - 127; 69 70 if (buffer[1] == 0) { 71 shift_x = 0; 72 } 73 if (buffer[2] == 0) { 74 shift_y = 0; 75 } 76 if (buffer[3] == 0) { 77 wheel = 0; 60 if (buffer_size < 4) { 61 usb_log_error("Weird mouse, results will be skewed.\n"); 62 buffer_size = 4; 78 63 } 79 64 80 if (mouse->console_phone >= 0) { 81 if ((shift_x != 0) || (shift_y != 0)) { 82 /* FIXME: guessed for QEMU */ 83 async_req_2_0(mouse->console_phone, 84 MEVENT_MOVE, 85 - shift_x / 10, - shift_y / 10); 86 } 87 if (butt) { 88 /* FIXME: proper button clicking. */ 89 async_req_2_0(mouse->console_phone, 90 MEVENT_BUTTON, 1, 1); 91 async_req_2_0(mouse->console_phone, 92 MEVENT_BUTTON, 1, 0); 93 } 65 uint8_t *buffer = malloc(buffer_size); 66 if (buffer == NULL) { 67 usb_log_error("Out of memory, poll fibril aborted.\n"); 68 return ENOMEM; 94 69 } 95 70 96 usb_log_debug("buttons=%s dX=%+3d dY=%+3d wheel=%+3d\n",97 str_buttons, shift_x, shift_y, wheel);71 while (true) { 72 async_usleep(mouse->poll_interval_us); 98 73 99 /* Guess. */100 async_usleep(1000);74 size_t actual_size; 75 int rc; 101 76 102 return true; 77 /* 78 * Error checking note: 79 * - failure when starting a session is considered 80 * temporary (e.g. out of phones, next try might succeed) 81 * - failure of transfer considered fatal (probably the 82 * device was unplugged) 83 * - session closing not checked (shall not fail anyway) 84 */ 85 86 rc = usb_endpoint_pipe_start_session(&mouse->poll_pipe); 87 if (rc != EOK) { 88 usb_log_warning("Failed to start session, will try again: %s.\n", 89 str_error(rc)); 90 continue; 91 } 92 93 rc = usb_endpoint_pipe_read(&mouse->poll_pipe, 94 buffer, buffer_size, &actual_size); 95 96 usb_endpoint_pipe_end_session(&mouse->poll_pipe); 97 98 if (rc != EOK) { 99 usb_log_error("Failed reading mouse input: %s.\n", 100 str_error(rc)); 101 break; 102 } 103 104 usb_log_debug2("got buffer: %s.\n", 105 usb_debug_str_buffer(buffer, buffer_size, 0)); 106 107 uint8_t butt = buffer[0]; 108 char str_buttons[4] = { 109 butt & 1 ? '#' : '.', 110 butt & 2 ? '#' : '.', 111 butt & 4 ? '#' : '.', 112 0 113 }; 114 115 int shift_x = ((int) buffer[1]) - 127; 116 int shift_y = ((int) buffer[2]) - 127; 117 int wheel = ((int) buffer[3]) - 127; 118 119 if (buffer[1] == 0) { 120 shift_x = 0; 121 } 122 if (buffer[2] == 0) { 123 shift_y = 0; 124 } 125 if (buffer[3] == 0) { 126 wheel = 0; 127 } 128 129 if (mouse->console_phone >= 0) { 130 if ((shift_x != 0) || (shift_y != 0)) { 131 /* FIXME: guessed for QEMU */ 132 async_req_2_0(mouse->console_phone, 133 MEVENT_MOVE, 134 - shift_x / 10, - shift_y / 10); 135 } 136 if (butt) { 137 /* FIXME: proper button clicking. */ 138 async_req_2_0(mouse->console_phone, 139 MEVENT_BUTTON, 1, 1); 140 async_req_2_0(mouse->console_phone, 141 MEVENT_BUTTON, 1, 0); 142 } 143 } 144 145 usb_log_debug("buttons=%s dX=%+3d dY=%+3d wheel=%+3d\n", 146 str_buttons, shift_x, shift_y, wheel); 147 } 148 149 /* 150 * Device was probably unplugged. 151 * Hang-up the phone to the console. 152 * FIXME: release allocated memory. 153 */ 154 async_hangup(mouse->console_phone); 155 mouse->console_phone = -1; 156 157 usb_log_error("Mouse polling fibril terminated.\n"); 158 159 return EOK; 103 160 } 104 161 105 /** Callback when polling is terminated.106 *107 * @param dev Device where the polling terminated.108 * @param recurring_errors Whether the polling was terminated due to109 * recurring errors.110 * @param arg Custom argument - points to usb_mouse_t.111 */112 void usb_mouse_polling_ended_callback(usb_device_t *dev,113 bool recurring_errors, void *arg)114 {115 usb_mouse_t *mouse = (usb_mouse_t *) arg;116 117 async_hangup(mouse->console_phone);118 mouse->console_phone = -1;119 }120 162 121 163 /** -
uspace/drv/usbmouse/mouse.h
rbb41b85 rc32688d 37 37 #define USBMOUSE_MOUSE_H_ 38 38 39 #include < usb/devdrv.h>39 #include <ddf/driver.h> 40 40 #include <usb/pipes.h> 41 41 #include <time.h> … … 46 46 typedef struct { 47 47 /** Generic device container. */ 48 usb_device_t *dev;48 ddf_dev_t *device; 49 49 /** Function representing the device. */ 50 50 ddf_fun_t *mouse_fun; 51 /** Representation of connection to the device. */ 52 usb_device_connection_t wire; 53 /** Default (zero) control pipe. */ 54 usb_endpoint_pipe_t ctrl_pipe; 55 /** Polling (in) pipe. */ 56 usb_endpoint_pipe_t poll_pipe; 51 57 /** Polling interval in microseconds. */ 52 58 suseconds_t poll_interval_us; … … 55 61 } usb_mouse_t; 56 62 57 #define POLL_PIPE(dev) ((dev)->pipes[0].pipe) 63 int usb_mouse_create(ddf_dev_t *); 58 64 59 extern usb_endpoint_description_t poll_endpoint_description; 60 61 int usb_mouse_create(usb_device_t *); 62 63 bool usb_mouse_polling_callback(usb_device_t *, uint8_t *, size_t, void *); 64 void usb_mouse_polling_ended_callback(usb_device_t *, bool, void *); 65 int usb_mouse_polling_fibril(void *); 65 66 66 67 #endif -
uspace/lib/block/libblock.c
rbb41b85 rc32688d 411 411 l = hash_table_find(&cache->block_hash, &key); 412 412 if (l) { 413 found:414 413 /* 415 414 * We found the block in the cache. … … 494 493 fibril_mutex_unlock(&b->lock); 495 494 goto retry; 496 }497 l = hash_table_find(&cache->block_hash, &key);498 if (l) {499 /*500 * Someone else must have already501 * instantiated the block while we were502 * not holding the cache lock.503 * Leave the recycled block on the504 * freelist and continue as if we505 * found the block of interest during506 * the first try.507 */508 fibril_mutex_unlock(&b->lock);509 goto found;510 495 } 511 496 -
uspace/lib/drv/generic/remote_usbhc.c
rbb41b85 rc32688d 55 55 static void remote_usbhc_bind_address(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *); 56 56 static void remote_usbhc_release_address(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *); 57 static void remote_usbhc_register_endpoint(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);58 static void remote_usbhc_unregister_endpoint(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);59 57 //static void remote_usbhc(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *); 60 58 … … 75 73 76 74 remote_usbhc_control_write, 77 remote_usbhc_control_read, 78 79 remote_usbhc_register_endpoint, 80 remote_usbhc_unregister_endpoint 75 remote_usbhc_control_read 81 76 }; 82 77 … … 527 522 528 523 529 void remote_usbhc_register_endpoint(ddf_fun_t *fun, void *iface,530 ipc_callid_t callid, ipc_call_t *call)531 {532 usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface;533 534 if (!usb_iface->register_endpoint) {535 async_answer_0(callid, ENOTSUP);536 return;537 }538 539 #define INIT_FROM_HIGH_DATA(type, var, arg_no) \540 type var = (type) DEV_IPC_GET_ARG##arg_no(*call) / 256541 #define INIT_FROM_LOW_DATA(type, var, arg_no) \542 type var = (type) DEV_IPC_GET_ARG##arg_no(*call) % 256543 544 INIT_FROM_HIGH_DATA(usb_address_t, address, 1);545 INIT_FROM_LOW_DATA(usb_endpoint_t, endpoint, 1);546 INIT_FROM_HIGH_DATA(usb_transfer_type_t, transfer_type, 2);547 INIT_FROM_LOW_DATA(usb_direction_t, direction, 2);548 549 #undef INIT_FROM_HIGH_DATA550 #undef INIT_FROM_LOW_DATA551 552 size_t max_packet_size = (size_t) DEV_IPC_GET_ARG3(*call);553 unsigned int interval = (unsigned int) DEV_IPC_GET_ARG4(*call);554 555 int rc = usb_iface->register_endpoint(fun, address, endpoint,556 transfer_type, direction, max_packet_size, interval);557 558 async_answer_0(callid, rc);559 }560 561 562 void remote_usbhc_unregister_endpoint(ddf_fun_t *fun, void *iface,563 ipc_callid_t callid, ipc_call_t *call)564 {565 usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface;566 567 if (!usb_iface->unregister_endpoint) {568 async_answer_0(callid, ENOTSUP);569 return;570 }571 572 usb_address_t address = (usb_address_t) DEV_IPC_GET_ARG1(*call);573 usb_endpoint_t endpoint = (usb_endpoint_t) DEV_IPC_GET_ARG2(*call);574 usb_direction_t direction = (usb_direction_t) DEV_IPC_GET_ARG3(*call);575 576 int rc = usb_iface->unregister_endpoint(fun,577 address, endpoint, direction);578 579 async_answer_0(callid, rc);580 }581 582 524 583 525 /** -
uspace/lib/drv/include/usbhc_iface.h
rbb41b85 rc32688d 167 167 IPC_M_USBHC_CONTROL_READ, 168 168 169 /** Register endpoint attributes at host controller. 170 * This is used to reserve portion of USB bandwidth. 171 * Parameters: 172 * - USB address + endpoint number (ADDR * 256 + EP) 173 * - transfer type + direction (TYPE * 256 + DIR) 174 * - maximum packet size 175 * - interval (in milliseconds) 176 * Answer: 177 * - EOK - reservation successful 178 * - ELIMIT - not enough bandwidth to satisfy the request 179 */ 180 IPC_M_USBHC_REGISTER_ENDPOINT, 181 182 /** Revert endpoint registration. 183 * Parameters: 184 * - USB address 185 * - endpoint number 186 * - data direction 187 * Answer: 188 * - EOK - endpoint unregistered 189 * - ENOENT - unknown endpoint 190 */ 191 IPC_M_USBHC_UNREGISTER_ENDPOINT 169 /* IPC_M_USB_ */ 192 170 } usbhc_iface_funcs_t; 193 171 … … 222 200 int (*release_address)(ddf_fun_t *, usb_address_t); 223 201 224 int (*register_endpoint)(ddf_fun_t *, usb_address_t, usb_endpoint_t,225 usb_transfer_type_t, usb_direction_t, size_t, unsigned int);226 int (*unregister_endpoint)(ddf_fun_t *, usb_address_t, usb_endpoint_t,227 usb_direction_t);228 229 202 usbhc_iface_transfer_out_t interrupt_out; 230 203 usbhc_iface_transfer_in_t interrupt_in; -
uspace/lib/usb/Makefile
rbb41b85 rc32688d 37 37 src/ddfiface.c \ 38 38 src/debug.c \ 39 src/devdrv.c \40 src/devpoll.c \41 39 src/dp.c \ 42 40 src/dump.c \ -
uspace/lib/usb/include/usb/pipes.h
rbb41b85 rc32688d 106 106 const usb_endpoint_description_t *description; 107 107 /** Interface number the endpoint must belong to (-1 for any). */ 108 int interface_no;108 const int interface_no; 109 109 /** Found descriptor fitting the description. */ 110 110 usb_standard_endpoint_descriptor_t *descriptor; … … 129 129 int usb_endpoint_pipe_initialize_default_control(usb_endpoint_pipe_t *, 130 130 usb_device_connection_t *); 131 int usb_endpoint_pipe_probe_default_control(usb_endpoint_pipe_t *);132 131 int usb_endpoint_pipe_initialize_from_configuration(usb_endpoint_mapping_t *, 133 132 size_t, uint8_t *, size_t, usb_device_connection_t *); 134 int usb_endpoint_pipe_register(usb_endpoint_pipe_t *, unsigned int, 135 usb_hc_connection_t *); 136 int usb_endpoint_pipe_unregister(usb_endpoint_pipe_t *, usb_hc_connection_t *); 133 137 134 138 135 int usb_endpoint_pipe_start_session(usb_endpoint_pipe_t *); -
uspace/lib/usb/src/hub.c
rbb41b85 rc32688d 235 235 goto leave_release_default_address; 236 236 } 237 rc = usb_endpoint_pipe_probe_default_control(&ctrl_pipe);238 if (rc != EOK) {239 rc = ENOTCONN;240 goto leave_release_default_address;241 }242 237 243 238 rc = usb_endpoint_pipe_start_session(&ctrl_pipe); -
uspace/lib/usb/src/pipesinit.c
rbb41b85 rc32688d 37 37 #include <usb/pipes.h> 38 38 #include <usb/dp.h> 39 #include <usb/request.h>40 #include <usbhc_iface.h>41 39 #include <errno.h> 42 40 #include <assert.h> 43 44 #define CTRL_PIPE_MIN_PACKET_SIZE 845 #define DEV_DESCR_MAX_PACKET_SIZE_OFFSET 746 41 47 42 … … 374 369 375 370 int rc = usb_endpoint_pipe_initialize(pipe, connection, 376 0, USB_TRANSFER_CONTROL, CTRL_PIPE_MIN_PACKET_SIZE, 377 USB_DIRECTION_BOTH); 371 0, USB_TRANSFER_CONTROL, 8, USB_DIRECTION_BOTH); 378 372 379 373 return rc; 380 }381 382 /** Probe default control pipe for max packet size.383 *384 * The function tries to get the correct value of max packet size several385 * time before giving up.386 *387 * The session on the pipe shall not be started.388 *389 * @param pipe Default control pipe.390 * @return Error code.391 */392 int usb_endpoint_pipe_probe_default_control(usb_endpoint_pipe_t *pipe)393 {394 assert(pipe);395 assert(DEV_DESCR_MAX_PACKET_SIZE_OFFSET < CTRL_PIPE_MIN_PACKET_SIZE);396 397 if ((pipe->direction != USB_DIRECTION_BOTH) ||398 (pipe->transfer_type != USB_TRANSFER_CONTROL) ||399 (pipe->endpoint_no != 0)) {400 return EINVAL;401 }402 403 #define TRY_LOOP(attempt_var) \404 for (attempt_var = 0; attempt_var < 3; attempt_var++)405 406 size_t failed_attempts;407 int rc;408 409 TRY_LOOP(failed_attempts) {410 rc = usb_endpoint_pipe_start_session(pipe);411 if (rc == EOK) {412 break;413 }414 }415 if (rc != EOK) {416 return rc;417 }418 419 420 uint8_t dev_descr_start[CTRL_PIPE_MIN_PACKET_SIZE];421 size_t transferred_size;422 TRY_LOOP(failed_attempts) {423 rc = usb_request_get_descriptor(pipe, USB_REQUEST_TYPE_STANDARD,424 USB_REQUEST_RECIPIENT_DEVICE, USB_DESCTYPE_DEVICE,425 0, 0, dev_descr_start, CTRL_PIPE_MIN_PACKET_SIZE,426 &transferred_size);427 if (rc == EOK) {428 if (transferred_size != CTRL_PIPE_MIN_PACKET_SIZE) {429 rc = ELIMIT;430 continue;431 }432 break;433 }434 }435 usb_endpoint_pipe_end_session(pipe);436 if (rc != EOK) {437 return rc;438 }439 440 pipe->max_packet_size441 = dev_descr_start[DEV_DESCR_MAX_PACKET_SIZE_OFFSET];442 443 return EOK;444 }445 446 /** Register endpoint with the host controller.447 *448 * @param pipe Pipe to be registered.449 * @param interval Polling interval.450 * @param hc_connection Connection to the host controller (must be opened).451 * @return Error code.452 */453 int usb_endpoint_pipe_register(usb_endpoint_pipe_t *pipe,454 unsigned int interval,455 usb_hc_connection_t *hc_connection)456 {457 assert(pipe);458 assert(hc_connection);459 460 if (!usb_hc_connection_is_opened(hc_connection)) {461 return EBADF;462 }463 464 #define _PACK(high, low) ((high) * 256 + (low))465 466 return async_req_5_0(hc_connection->hc_phone,467 DEV_IFACE_ID(USBHC_DEV_IFACE), IPC_M_USBHC_REGISTER_ENDPOINT,468 _PACK(pipe->wire->address, pipe->endpoint_no),469 _PACK(pipe->transfer_type, pipe->direction),470 pipe->max_packet_size, interval);471 472 #undef _PACK473 }474 475 /** Revert endpoint registration with the host controller.476 *477 * @param pipe Pipe to be unregistered.478 * @param hc_connection Connection to the host controller (must be opened).479 * @return Error code.480 */481 int usb_endpoint_pipe_unregister(usb_endpoint_pipe_t *pipe,482 usb_hc_connection_t *hc_connection)483 {484 assert(pipe);485 assert(hc_connection);486 487 if (!usb_hc_connection_is_opened(hc_connection)) {488 return EBADF;489 }490 491 return async_req_4_0(hc_connection->hc_phone,492 DEV_IFACE_ID(USBHC_DEV_IFACE), IPC_M_USBHC_UNREGISTER_ENDPOINT,493 pipe->wire->address, pipe->endpoint_no, pipe->direction);494 374 } 495 375 -
uspace/lib/usb/src/recognise.c
rbb41b85 rc32688d 369 369 goto failure; 370 370 } 371 rc = usb_endpoint_pipe_probe_default_control(&ctrl_pipe);372 if (rc != EOK) {373 goto failure;374 }375 371 376 372 /* … … 378 374 * naming etc., something more descriptive could be created. 379 375 */ 380 rc = asprintf(&child_name, "usb%02zu_a%d", 381 this_device_name_index, address); 376 rc = asprintf(&child_name, "usbdev%02zu", this_device_name_index); 382 377 if (rc < 0) { 383 378 goto failure; -
uspace/srv/hw/irc/apic/apic.c
rbb41b85 rc32688d 54 54 #define NAME "apic" 55 55 56 static bool apic_found = false;57 58 56 static int apic_enable_irq(sysarg_t irq) 59 57 { … … 81 79 callid = async_get_call(&call); 82 80 83 sysarg_t method = IPC_GET_IMETHOD(call); 84 if (method == IPC_M_PHONE_HUNGUP) { 85 return; 86 } 87 88 if (!apic_found) { 89 async_answer_0(callid, ENOTSUP); 90 break; 91 } 92 93 switch (method) { 81 switch (IPC_GET_IMETHOD(call)) { 94 82 case IRC_ENABLE_INTERRUPT: 95 83 async_answer_0(callid, apic_enable_irq(IPC_GET_ARG1(call))); … … 109 97 * 110 98 */ 111 static voidapic_init(void)99 static bool apic_init(void) 112 100 { 113 101 sysarg_t apic; 114 102 115 apic_found = sysinfo_get_value("apic", &apic) && apic;116 if (!apic_found) {117 printf(NAME ": Warning: no APIC found\n");103 if ((sysinfo_get_value("apic", &apic) != EOK) || (!apic)) { 104 printf(NAME ": No APIC found\n"); 105 return false; 118 106 } 119 107 120 108 async_set_client_connection(apic_connection); 121 109 service_register(SERVICE_APIC); 110 111 return true; 122 112 } 123 113 … … 126 116 printf(NAME ": HelenOS APIC driver\n"); 127 117 128 apic_init(); 129 118 if (!apic_init()) 119 return -1; 120 130 121 printf(NAME ": Accepting connections\n"); 131 122 async_manager();
Note:
See TracChangeset
for help on using the changeset viewer.