Changeset b4b534ac in mainline for uspace/drv/bus/usb/uhci
- Timestamp:
- 2016-07-22T08:24:47Z (9 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- f76d2c2
- Parents:
- 5b18137 (diff), 8351f9a4 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)links above to see all the changes relative to each parent. - Location:
- uspace/drv/bus/usb/uhci
- Files:
-
- 1 added
- 3 deleted
- 12 edited
- 1 moved
-
Makefile (modified) (3 diffs)
-
hc.c (modified) (10 diffs)
-
hc.h (modified) (4 diffs)
-
hw_struct/link_pointer.h (modified) (1 diff)
-
hw_struct/queue_head.h (modified) (1 diff)
-
hw_struct/transfer_descriptor.c (modified) (1 diff)
-
hw_struct/transfer_descriptor.h (modified) (1 diff)
-
main.c (modified) (4 diffs)
-
res.c (deleted)
-
transfer_list.c (modified) (1 diff)
-
transfer_list.h (modified) (1 diff)
-
uhci.c (deleted)
-
uhci_batch.c (modified) (2 diffs)
-
uhci_batch.h (modified) (1 diff)
-
uhci_rh.c (added)
-
uhci_rh.h (moved) (moved from uspace/drv/bus/usb/uhci/root_hub.h ) (2 diffs)
-
utils/malloc32.h (deleted)
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/bus/usb/uhci/Makefile
r5b18137 rb4b534ac 31 31 LIBS = \ 32 32 $(LIBUSBHOST_PREFIX)/libusbhost.a \ 33 $(LIBUSBVIRT_PREFIX)/libusbvirt.a \ 33 34 $(LIBUSB_PREFIX)/libusb.a \ 34 35 $(LIBDRV_PREFIX)/libdrv.a … … 36 37 EXTRA_CFLAGS += \ 37 38 -I$(LIBUSB_PREFIX)/include \ 39 -I$(LIBUSBDEV_PREFIX)/include \ 38 40 -I$(LIBUSBHOST_PREFIX)/include \ 41 -I$(LIBUSBVIRT_PREFIX)/include \ 39 42 -I$(LIBDRV_PREFIX)/include 40 43 … … 44 47 hc.c \ 45 48 main.c \ 46 res.c \47 root_hub.c \48 49 transfer_list.c \ 49 uhci.c \50 50 uhci_batch.c \ 51 uhci_rh.c \ 51 52 hw_struct/transfer_descriptor.c 52 53 -
uspace/drv/bus/usb/uhci/hc.c
r5b18137 rb4b534ac 32 32 * @brief UHCI Host controller driver routines 33 33 */ 34 35 #include <adt/list.h> 36 #include <assert.h> 37 #include <async.h> 38 #include <ddi.h> 39 #include <device/hw_res_parsed.h> 40 #include <fibril.h> 34 41 #include <errno.h> 42 #include <macros.h> 43 #include <mem.h> 44 #include <stdlib.h> 35 45 #include <str_error.h> 36 #include <adt/list.h> 37 #include <ddi.h> 46 #include <sys/types.h> 38 47 39 48 #include <usb/debug.h> 40 49 #include <usb/usb.h> 41 50 #include <usb/host/utils/malloc32.h> 51 52 #include "uhci_batch.h" 42 53 #include "hc.h" 43 #include "uhci_batch.h"44 54 45 55 #define UHCI_INTR_ALLOW_INTERRUPTS \ … … 85 95 static int hc_init_mem_structures(hc_t *instance); 86 96 static int hc_init_transfer_lists(hc_t *instance); 87 static int hc_schedule(hcd_t *hcd, usb_transfer_batch_t *batch); 88 89 static int hc_interrupt_emulator(void *arg); 97 90 98 static int hc_debug_checker(void *arg); 91 99 92 enum {93 /** Number of PIO ranges used in IRQ code */94 hc_irq_pio_range_count =95 sizeof(uhci_irq_pio_ranges) / sizeof(irq_pio_range_t),96 97 /* Number of commands used in IRQ code */98 hc_irq_cmd_count =99 sizeof(uhci_irq_commands) / sizeof(irq_cmd_t)100 };101 100 102 101 /** Generate IRQ code. 103 * @param[out] ranges PIO ranges buffer. 104 * @param[in] ranges_size Size of the ranges buffer (bytes). 105 * @param[out] cmds Commands buffer. 106 * @param[in] cmds_size Size of the commands buffer (bytes). 107 * @param[in] regs Device's register range. 102 * @param[out] code IRQ code structure. 103 * @param[in] hw_res Device's resources. 108 104 * 109 105 * @return Error code. 110 106 */ 111 int 112 hc_get_irq_code(irq_pio_range_t ranges[], size_t ranges_size, irq_cmd_t cmds[], 113 size_t cmds_size, addr_range_t *regs) 114 { 115 if ((ranges_size < sizeof(uhci_irq_pio_ranges)) || 116 (cmds_size < sizeof(uhci_irq_commands)) || 117 (RNGSZ(*regs) < sizeof(uhci_regs_t))) 107 int uhci_hc_gen_irq_code(irq_code_t *code, const hw_res_list_parsed_t *hw_res) 108 { 109 assert(code); 110 assert(hw_res); 111 112 if (hw_res->irqs.count != 1 || hw_res->io_ranges.count != 1) 113 return EINVAL; 114 const addr_range_t regs = hw_res->io_ranges.ranges[0]; 115 116 if (RNGSZ(regs) < sizeof(uhci_regs_t)) 118 117 return EOVERFLOW; 119 118 120 memcpy(ranges, uhci_irq_pio_ranges, sizeof(uhci_irq_pio_ranges)); 121 ranges[0].base = RNGABS(*regs); 122 123 memcpy(cmds, uhci_irq_commands, sizeof(uhci_irq_commands)); 124 uhci_regs_t *registers = (uhci_regs_t *) RNGABSPTR(*regs); 125 cmds[0].addr = (void *) ®isters->usbsts; 126 cmds[3].addr = (void *) ®isters->usbsts; 127 128 return EOK; 129 } 130 131 /** Register interrupt handler. 132 * 133 * @param[in] device Host controller DDF device 134 * @param[in] regs Register range 135 * @param[in] irq Interrupt number 136 * @paran[in] handler Interrupt handler 137 * 138 * @return EOK on success or negative error code 139 */ 140 int hc_register_irq_handler(ddf_dev_t *device, addr_range_t *regs, int irq, 141 interrupt_handler_t handler) 142 { 143 int rc; 144 irq_pio_range_t irq_ranges[hc_irq_pio_range_count]; 145 irq_cmd_t irq_cmds[hc_irq_cmd_count]; 146 rc = hc_get_irq_code(irq_ranges, sizeof(irq_ranges), irq_cmds, 147 sizeof(irq_cmds), regs); 148 if (rc != EOK) { 149 usb_log_error("Failed to generate IRQ commands: %s.\n", 150 str_error(rc)); 151 return rc; 152 } 153 154 irq_code_t irq_code = { 155 .rangecount = hc_irq_pio_range_count, 156 .ranges = irq_ranges, 157 .cmdcount = hc_irq_cmd_count, 158 .cmds = irq_cmds 159 }; 160 161 /* Register handler to avoid interrupt lockup */ 162 rc = register_interrupt_handler(device, irq, handler, &irq_code); 163 if (rc != EOK) { 164 usb_log_error("Failed to register interrupt handler: %s.\n", 165 str_error(rc)); 166 return rc; 167 } 168 169 return EOK; 119 code->ranges = malloc(sizeof(uhci_irq_pio_ranges)); 120 if (code->ranges == NULL) 121 return ENOMEM; 122 123 code->cmds = malloc(sizeof(uhci_irq_commands)); 124 if (code->cmds == NULL) { 125 free(code->ranges); 126 return ENOMEM; 127 } 128 129 code->rangecount = ARRAY_SIZE(uhci_irq_pio_ranges); 130 code->cmdcount = ARRAY_SIZE(uhci_irq_commands); 131 132 memcpy(code->ranges, uhci_irq_pio_ranges, sizeof(uhci_irq_pio_ranges)); 133 code->ranges[0].base = RNGABS(regs); 134 135 memcpy(code->cmds, uhci_irq_commands, sizeof(uhci_irq_commands)); 136 uhci_regs_t *registers = (uhci_regs_t *) RNGABSPTR(regs); 137 code->cmds[0].addr = (void*)®isters->usbsts; 138 code->cmds[3].addr = (void*)®isters->usbsts; 139 140 usb_log_debug("I/O regs at %p (size %zu), IRQ %d.\n", 141 RNGABSPTR(regs), RNGSZ(regs), hw_res->irqs.irqs[0]); 142 143 return hw_res->irqs.irqs[0]; 170 144 } 171 145 172 146 /** Take action based on the interrupt cause. 173 147 * 174 * @param[in] instance UHCIstructure to use.148 * @param[in] hcd HCD structure to use. 175 149 * @param[in] status Value of the status register at the time of interrupt. 176 150 * … … 180 154 * - resume from suspend state (not implemented) 181 155 */ 182 void hc_interrupt(hc_t *instance, uint16_t status) 183 { 156 void uhci_hc_interrupt(hcd_t *hcd, uint32_t status) 157 { 158 assert(hcd); 159 hc_t *instance = hcd_get_driver_data(hcd); 184 160 assert(instance); 185 161 /* Lower 2 bits are transaction error and transaction complete */ … … 195 171 &instance->transfers_bulk_full, &done); 196 172 197 while (!list_empty(&done)) { 198 link_t *item = list_first(&done); 199 list_remove(item); 173 list_foreach_safe(done, current, next) { 174 list_remove(current); 200 175 uhci_transfer_batch_t *batch = 201 uhci_transfer_batch_from_link( item);176 uhci_transfer_batch_from_link(current); 202 177 uhci_transfer_batch_finish_dispose(batch); 203 178 } … … 230 205 * 231 206 * @param[in] instance Memory place to initialize. 232 * @param[in] HC function node233 207 * @param[in] regs Range of device's I/O control registers. 234 208 * @param[in] interrupts True if hw interrupts should be used. … … 239 213 * interrupt fibrils. 240 214 */ 241 int hc_init(hc_t *instance, ddf_fun_t *fun, addr_range_t *regs, bool interrupts) 242 { 243 assert(regs->size >= sizeof(uhci_regs_t)); 244 int rc; 215 int hc_init(hc_t *instance, const hw_res_list_parsed_t *hw_res, bool interrupts) 216 { 217 assert(instance); 218 assert(hw_res); 219 if (hw_res->io_ranges.count != 1 || 220 hw_res->io_ranges.ranges[0].size < sizeof(uhci_regs_t)) 221 return EINVAL; 245 222 246 223 instance->hw_interrupts = interrupts; … … 248 225 249 226 /* allow access to hc control registers */ 250 uhci_regs_t *io; 251 rc = pio_enable_range(regs, (void **) &io); 252 if (rc != EOK) { 253 usb_log_error("Failed to gain access to registers at %p: %s.\n", 254 io, str_error(rc)); 255 return rc; 256 } 257 258 instance->registers = io; 259 usb_log_debug( 260 "Device registers at %p (%zuB) accessible.\n", io, regs->size); 261 262 rc = hc_init_mem_structures(instance); 263 if (rc != EOK) { 264 usb_log_error("Failed to initialize UHCI memory structures: %s.\n", 265 str_error(rc)); 266 return rc; 267 } 268 269 instance->generic = ddf_fun_data_alloc(fun, sizeof(hcd_t)); 270 if (instance->generic == NULL) { 271 usb_log_error("Out of memory.\n"); 272 return ENOMEM; 273 } 274 275 hcd_init(instance->generic, USB_SPEED_FULL, 276 BANDWIDTH_AVAILABLE_USB11, bandwidth_count_usb11); 277 278 instance->generic->private_data = instance; 279 instance->generic->schedule = hc_schedule; 280 instance->generic->ep_add_hook = NULL; 227 int ret = pio_enable_range(&hw_res->io_ranges.ranges[0], 228 (void **) &instance->registers); 229 if (ret != EOK) { 230 usb_log_error("Failed to gain access to registers: %s.\n", 231 str_error(ret)); 232 return ret; 233 } 234 235 usb_log_debug("Device registers at %" PRIx64 " (%zuB) accessible.\n", 236 hw_res->io_ranges.ranges[0].address.absolute, 237 hw_res->io_ranges.ranges[0].size); 238 239 ret = hc_init_mem_structures(instance); 240 if (ret != EOK) { 241 usb_log_error("Failed to init UHCI memory structures: %s.\n", 242 str_error(ret)); 243 // TODO: we should disable pio here 244 return ret; 245 } 281 246 282 247 hc_init_hw(instance); 283 if (!interrupts) {284 instance->interrupt_emulator =285 fibril_create(hc_interrupt_emulator, instance);286 fibril_add_ready(instance->interrupt_emulator);287 }288 248 (void)hc_debug_checker; 289 249 250 uhci_rh_init(&instance->rh, instance->registers->ports, "uhci"); 251 290 252 return EOK; 253 } 254 255 /** Safely dispose host controller internal structures 256 * 257 * @param[in] instance Host controller structure to use. 258 */ 259 void hc_fini(hc_t *instance) 260 { 261 assert(instance); 262 //TODO Implement 291 263 } 292 264 … … 432 404 instance->transfers[USB_SPEED_FULL][USB_TRANSFER_BULK] = 433 405 &instance->transfers_bulk_full; 434 instance->transfers[USB_SPEED_LOW][USB_TRANSFER_BULK] = 435 &instance->transfers_bulk_full; 436 406 407 return EOK; 408 } 409 410 int uhci_hc_status(hcd_t *hcd, uint32_t *status) 411 { 412 assert(hcd); 413 assert(status); 414 hc_t *instance = hcd_get_driver_data(hcd); 415 assert(instance); 416 417 *status = 0; 418 if (instance->registers) { 419 uint16_t s = pio_read_16(&instance->registers->usbsts); 420 pio_write_16(&instance->registers->usbsts, s); 421 *status = s; 422 } 437 423 return EOK; 438 424 } … … 446 432 * Checks for bandwidth availability and appends the batch to the proper queue. 447 433 */ 448 int hc_schedule(hcd_t *hcd, usb_transfer_batch_t *batch)434 int uhci_hc_schedule(hcd_t *hcd, usb_transfer_batch_t *batch) 449 435 { 450 436 assert(hcd); 451 hc_t *instance = hcd ->private_data;437 hc_t *instance = hcd_get_driver_data(hcd); 452 438 assert(instance); 453 439 assert(batch); 440 441 if (batch->ep->address == uhci_rh_get_address(&instance->rh)) 442 return uhci_rh_schedule(&instance->rh, batch); 443 454 444 uhci_transfer_batch_t *uhci_batch = uhci_transfer_batch_get(batch); 455 445 if (!uhci_batch) { … … 463 453 transfer_list_add_batch(list, uhci_batch); 464 454 465 return EOK;466 }467 468 /** Polling function, emulates interrupts.469 *470 * @param[in] arg UHCI hc structure to use.471 * @return EOK (should never return)472 */473 int hc_interrupt_emulator(void* arg)474 {475 usb_log_debug("Started interrupt emulator.\n");476 hc_t *instance = arg;477 assert(instance);478 479 while (1) {480 /* Read and clear status register */481 uint16_t status = pio_read_16(&instance->registers->usbsts);482 pio_write_16(&instance->registers->usbsts, status);483 if (status != 0)484 usb_log_debug2("UHCI status: %x.\n", status);485 hc_interrupt(instance, status);486 async_usleep(UHCI_INT_EMULATOR_TIMEOUT);487 }488 455 return EOK; 489 456 } -
uspace/drv/bus/usb/uhci/hc.h
r5b18137 rb4b534ac 36 36 #define DRV_UHCI_HC_H 37 37 38 #include <ddf/driver.h>39 #include <ddf/interrupt.h>40 38 #include <device/hw_res_parsed.h> 41 39 #include <fibril.h> 40 #include <macros.h> 41 #include <stdbool.h> 42 #include <sys/types.h> 42 43 #include <usb/host/hcd.h> 44 #include <usb/host/usb_transfer_batch.h> 43 45 46 #include "uhci_rh.h" 44 47 #include "transfer_list.h" 48 #include "hw_struct/link_pointer.h" 45 49 46 50 /** UHCI I/O registers layout */ … … 83 87 /** SOF modification to match external timers */ 84 88 ioport8_t sofmod; 89 90 PADD8[3]; 91 ioport16_t ports[]; 85 92 } uhci_regs_t; 86 93 87 94 #define UHCI_FRAME_LIST_COUNT 1024 88 #define UHCI_INT_EMULATOR_TIMEOUT 1000089 95 #define UHCI_DEBUGER_TIMEOUT 5000000 90 96 #define UHCI_ALLOWED_HW_FAIL 5 91 #define UHCI_NEEDED_IRQ_COMMANDS 592 97 93 98 /** Main UHCI driver structure */ 94 99 typedef struct hc { 95 /** Generic HCD driver structure */ 96 hcd_t *generic; 97 100 uhci_rh_t rh; 98 101 /** Addresses of I/O registers */ 99 102 uhci_regs_t *registers; … … 113 116 /** Pointer table to the above lists, helps during scheduling */ 114 117 transfer_list_t *transfers[2][4]; 115 /** Fibril periodically checking status register*/116 fid_t interrupt_emulator;117 118 /** Indicator of hw interrupts availability */ 118 119 bool hw_interrupts; … … 122 123 } hc_t; 123 124 124 int hc_register_irq_handler(ddf_dev_t *, addr_range_t *, int, 125 interrupt_handler_t); 126 int hc_get_irq_code(irq_pio_range_t [], size_t, irq_cmd_t [], size_t, 127 addr_range_t *); 128 void hc_interrupt(hc_t *instance, uint16_t status); 129 int hc_init(hc_t *, ddf_fun_t *, addr_range_t *, bool); 125 int hc_init(hc_t *instance, const hw_res_list_parsed_t *hw_res, bool interupts); 126 void hc_fini(hc_t *instance); 130 127 131 /** Safely dispose host controller internal structures 132 * 133 * @param[in] instance Host controller structure to use. 134 */ 135 static inline void hc_fini(hc_t *instance) {} /* TODO: implement*/ 128 int uhci_hc_gen_irq_code(irq_code_t *code, const hw_res_list_parsed_t *hw_res); 129 130 void uhci_hc_interrupt(hcd_t *hcd, uint32_t status); 131 int uhci_hc_status(hcd_t *hcd, uint32_t *status); 132 int uhci_hc_schedule(hcd_t *hcd, usb_transfer_batch_t *batch); 133 136 134 #endif 137 135 -
uspace/drv/bus/usb/uhci/hw_struct/link_pointer.h
r5b18137 rb4b534ac 35 35 #define DRV_UHCI_HW_STRUCT_LINK_POINTER_H 36 36 37 #include <sys/types.h> 38 37 39 /** UHCI link pointer, used by many data structures */ 38 40 typedef uint32_t link_pointer_t; -
uspace/drv/bus/usb/uhci/hw_struct/queue_head.h
r5b18137 rb4b534ac 34 34 #ifndef DRV_UHCI_HW_STRUCT_QH_H 35 35 #define DRV_UHCI_HW_STRUCT_QH_H 36 36 37 #include <assert.h> 38 #include <sys/types.h> 39 #include <usb/host/utils/malloc32.h> 37 40 38 41 #include "link_pointer.h" 39 42 #include "transfer_descriptor.h" 40 #include "../utils/malloc32.h"41 43 42 44 /** This structure is defined in UHCI design guide p. 31 */ -
uspace/drv/bus/usb/uhci/hw_struct/transfer_descriptor.c
r5b18137 rb4b534ac 32 32 * @brief UHCI driver 33 33 */ 34 35 #include <assert.h> 34 36 #include <errno.h> 37 35 38 #include <usb/debug.h> 39 #include <usb/usb.h> 40 #include <usb/host/utils/malloc32.h> 36 41 42 #include "link_pointer.h" 37 43 #include "transfer_descriptor.h" 38 #include "../utils/malloc32.h"39 44 40 45 /** Initialize Transfer Descriptor -
uspace/drv/bus/usb/uhci/hw_struct/transfer_descriptor.h
r5b18137 rb4b534ac 35 35 #define DRV_UHCI_HW_STRUCT_TRANSFER_DESCRIPTOR_H 36 36 37 #include < mem.h>37 #include <assert.h> 38 38 #include <usb/usb.h> 39 #include <stdbool.h> 40 #include <sys/types.h> 39 41 40 42 #include "link_pointer.h" -
uspace/drv/bus/usb/uhci/main.c
r5b18137 rb4b534ac 26 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 27 */ 28 /** @addtogroup drvusbuhci hc28 /** @addtogroup drvusbuhci 29 29 * @{ 30 30 */ … … 32 32 * @brief UHCI driver initialization 33 33 */ 34 35 #include <assert.h> 34 36 #include <ddf/driver.h> 37 #include <devman.h> 35 38 #include <errno.h> 39 #include <io/log.h> 40 #include <io/logctl.h> 41 #include <pci_dev_iface.h> 42 #include <stdio.h> 36 43 #include <str_error.h> 44 #include <usb/debug.h> 45 #include <usb/host/ddf_helpers.h> 37 46 38 #include <usb/ddfiface.h> 39 #include <usb/debug.h> 40 41 #include "uhci.h" 47 #include "hc.h" 42 48 43 49 #define NAME "uhci" 44 50 45 static int uhci_dev_add(ddf_dev_t *device); 51 static int uhci_driver_init(hcd_t *, const hw_res_list_parsed_t *, bool); 52 static void uhci_driver_fini(hcd_t *); 53 static int disable_legacy(ddf_dev_t *); 46 54 47 static driver_ops_t uhci_driver_ops = { 48 .dev_add = uhci_dev_add, 55 static const ddf_hc_driver_t uhci_hc_driver = { 56 .claim = disable_legacy, 57 .hc_speed = USB_SPEED_FULL, 58 .irq_code_gen = uhci_hc_gen_irq_code, 59 .init = uhci_driver_init, 60 .fini = uhci_driver_fini, 61 .name = "UHCI", 62 .ops = { 63 .schedule = uhci_hc_schedule, 64 .irq_hook = uhci_hc_interrupt, 65 .status_hook = uhci_hc_status, 66 }, 49 67 }; 50 68 51 static driver_t uhci_driver = { 52 .name = NAME, 53 .driver_ops = &uhci_driver_ops 54 }; 69 static int uhci_driver_init(hcd_t *hcd, const hw_res_list_parsed_t *res, bool irq) 70 { 71 assert(hcd); 72 assert(hcd_get_driver_data(hcd) == NULL); 73 74 hc_t *instance = malloc(sizeof(hc_t)); 75 if (!instance) 76 return ENOMEM; 77 78 const int ret = hc_init(instance, res, irq); 79 if (ret == EOK) { 80 hcd_set_implementation(hcd, instance, &uhci_hc_driver.ops); 81 } else { 82 free(instance); 83 } 84 return ret; 85 } 86 87 static void uhci_driver_fini(hcd_t *hcd) 88 { 89 assert(hcd); 90 hc_t *hc = hcd_get_driver_data(hcd); 91 if (hc) 92 hc_fini(hc); 93 94 hcd_set_implementation(hcd, NULL, NULL); 95 free(hc); 96 } 97 98 /** Call the PCI driver with a request to clear legacy support register 99 * 100 * @param[in] device Device asking to disable interrupts 101 * @return Error code. 102 */ 103 static int disable_legacy(ddf_dev_t *device) 104 { 105 assert(device); 106 107 async_sess_t *parent_sess = devman_parent_device_connect( 108 ddf_dev_get_handle(device), IPC_FLAG_BLOCKING); 109 if (!parent_sess) 110 return ENOMEM; 111 112 /* See UHCI design guide page 45 for these values. 113 * Write all WC bits in USB legacy register */ 114 const int rc = pci_config_space_write_16(parent_sess, 0xc0, 0xaf00); 115 116 async_hangup(parent_sess); 117 return rc; 118 } 55 119 56 120 /** Initialize a new ddf driver instance for uhci hc and hub. … … 59 123 * @return Error code. 60 124 */ 61 int uhci_dev_add(ddf_dev_t *device)125 static int uhci_dev_add(ddf_dev_t *device) 62 126 { 63 127 usb_log_debug2("uhci_dev_add() called\n"); 64 128 assert(device); 129 return hcd_ddf_add_hc(device, &uhci_hc_driver); 130 } 65 131 66 const int ret = device_setup_uhci(device); 67 if (ret != EOK) { 68 usb_log_error("Failed to initialize UHCI driver: %s.\n", 69 str_error(ret)); 70 } else { 71 usb_log_info("Controlling new UHCI device '%s'.\n", 72 ddf_dev_get_name(device)); 73 } 132 static const driver_ops_t uhci_driver_ops = { 133 .dev_add = uhci_dev_add, 134 }; 74 135 75 return ret; 76 } 136 static const driver_t uhci_driver = { 137 .name = NAME, 138 .driver_ops = &uhci_driver_ops 139 }; 140 77 141 78 142 /** Initialize global driver structures (NONE). … … 88 152 printf(NAME ": HelenOS UHCI driver.\n"); 89 153 log_init(NAME); 90 154 logctl_set_log_level(NAME, LVL_NOTE); 91 155 return ddf_driver_main(&uhci_driver); 92 156 } -
uspace/drv/bus/usb/uhci/transfer_list.c
r5b18137 rb4b534ac 34 34 */ 35 35 36 #include <assert.h> 36 37 #include <errno.h> 38 #include <libarch/barrier.h> 39 #include <sys/types.h> 37 40 #include <usb/debug.h> 38 #include <libarch/barrier.h> 39 41 #include <usb/host/usb_transfer_batch.h> 42 #include <usb/host/utils/malloc32.h> 43 44 #include "hw_struct/link_pointer.h" 40 45 #include "transfer_list.h" 41 46 -
uspace/drv/bus/usb/uhci/transfer_list.h
r5b18137 rb4b534ac 35 35 #define DRV_UHCI_TRANSFER_LIST_H 36 36 37 #include <adt/list.h> 37 38 #include <fibril_synch.h> 38 39 -
uspace/drv/bus/usb/uhci/uhci_batch.c
r5b18137 rb4b534ac 32 32 * @brief UHCI driver USB transfer structure 33 33 */ 34 35 #include <assert.h> 34 36 #include <errno.h> 35 #include <str_error.h>36 37 #include <macros.h> 38 #include <mem.h> 39 #include <stdlib.h> 37 40 38 41 #include <usb/usb.h> 39 42 #include <usb/debug.h> 43 #include <usb/host/endpoint.h> 44 #include <usb/host/utils/malloc32.h> 40 45 41 46 #include "uhci_batch.h" 42 #include "transfer_list.h"43 47 #include "hw_struct/transfer_descriptor.h" 44 #include "utils/malloc32.h"45 48 46 49 #define DEFAULT_ERROR_COUNT 3 … … 67 70 assert(uhci_batch); 68 71 assert(uhci_batch->usb_batch); 72 assert(!link_in_use(&uhci_batch->link)); 69 73 usb_transfer_batch_finish(uhci_batch->usb_batch, 70 74 uhci_transfer_batch_data_buffer(uhci_batch)); -
uspace/drv/bus/usb/uhci/uhci_batch.h
r5b18137 rb4b534ac 35 35 #define DRV_UHCI_BATCH_H 36 36 37 #include <adt/list.h> 38 #include <assert.h> 39 #include <errno.h> 40 #include <stdbool.h> 41 #include <sys/types.h> 37 42 #include <usb/host/usb_transfer_batch.h> 38 #include <adt/list.h>39 43 40 44 #include "hw_struct/queue_head.h" -
uspace/drv/bus/usb/uhci/uhci_rh.h
r5b18137 rb4b534ac 1 1 /* 2 * Copyright (c) 201 1Jan Vesely2 * Copyright (c) 2013 Jan Vesely 3 3 * All rights reserved. 4 4 * … … 31 31 */ 32 32 /** @file 33 * @brief UHCI driver33 * @brief UHCI host controller driver structure 34 34 */ 35 #ifndef DRV_UHCI_ RH_H36 #define DRV_UHCI_ RH_H35 #ifndef DRV_UHCI_UHCI_RH_H 36 #define DRV_UHCI_UHCI_RH_H 37 37 38 #include < ddf/driver.h>39 #include < ops/hw_res.h>40 #include < ops/pio_window.h>38 #include <usbvirt/virthub_base.h> 39 #include <usb/host/usb_transfer_batch.h> 40 #include <usb/usb.h> 41 41 42 /** DDF support structure for uhci_rhd driver, provides I/O resources */ 43 typedef struct rh { 44 /** List of resources available to the root hub. */ 45 hw_resource_list_t resource_list; 46 /** The only resource in the RH resource list */ 47 hw_resource_t io_regs; 48 /** PIO window in which the RH will operate. */ 49 pio_window_t pio_window; 50 } rh_t; 42 #include <stdbool.h> 43 #include <sys/types.h> 51 44 52 extern int rh_init(rh_t *, ddf_fun_t *, addr_range_t *, uintptr_t, size_t); 45 /** Endpoint number for status change pipe. */ 46 #define HUB_STATUS_CHANGE_PIPE 1 47 48 /** Virtual to UHCI hub connector */ 49 typedef struct { 50 /** Virtual hub software implementation */ 51 virthub_base_t base; 52 /** UHCI root hub port io registers */ 53 ioport16_t *ports[2]; 54 /** Reset change indicator, it is not reported by regs */ 55 bool reset_changed[2]; 56 } uhci_rh_t; 57 58 int uhci_rh_init(uhci_rh_t *instance, ioport16_t *ports, const char *name); 59 int uhci_rh_schedule(uhci_rh_t *instance, usb_transfer_batch_t *batch); 60 61 /** Get UHCI rh address. 62 * 63 * @param instance UHCI rh instance. 64 * @return USB address assigned to the hub. 65 * Wrapper for virtual hub address 66 */ 67 static inline usb_address_t uhci_rh_get_address(uhci_rh_t *instance) 68 { 69 return virthub_base_get_address(&instance->base); 70 } 53 71 54 72 #endif
Note:
See TracChangeset
for help on using the changeset viewer.
