Changeset 15d3b54 in mainline for uspace/drv/uhci-hcd
- Timestamp:
- 2011-03-14T21:24:02Z (15 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/fix-logger-deadlock, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- fcf07e6
- Parents:
- c69209d (diff), 9370884 (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/uhci-hcd
- Files:
-
- 21 edited
-
batch.c (modified) (19 diffs)
-
batch.h (modified) (2 diffs)
-
iface.c (modified) (7 diffs)
-
iface.h (modified) (1 diff)
-
main.c (modified) (4 diffs)
-
pci.c (modified) (3 diffs)
-
pci.h (modified) (1 diff)
-
transfer_list.c (modified) (12 diffs)
-
transfer_list.h (modified) (3 diffs)
-
uhci.c (modified) (6 diffs)
-
uhci.h (modified) (1 diff)
-
uhci_hc.c (modified) (16 diffs)
-
uhci_hc.h (modified) (3 diffs)
-
uhci_rh.c (modified) (3 diffs)
-
uhci_struct/link_pointer.h (modified) (1 diff)
-
uhci_struct/queue_head.h (modified) (6 diffs)
-
uhci_struct/transfer_descriptor.c (modified) (3 diffs)
-
uhci_struct/transfer_descriptor.h (modified) (3 diffs)
-
utils/device_keeper.c (modified) (15 diffs)
-
utils/device_keeper.h (modified) (1 diff)
-
utils/malloc32.h (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/uhci-hcd/batch.c
rc69209d r15d3b54 26 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 27 */ 28 /** @addtogroup usb28 /** @addtogroup drvusbuhcihc 29 29 * @{ 30 30 */ 31 31 /** @file 32 * @brief UHCI driver 32 * @brief UHCI driver USB transaction structure 33 33 */ 34 34 #include <errno.h> … … 44 44 45 45 #define DEFAULT_ERROR_COUNT 3 46 47 static int batch_schedule(batch_t *instance);48 46 49 47 static void batch_control(batch_t *instance, … … 54 52 static void batch_call_in_and_dispose(batch_t *instance); 55 53 static void batch_call_out_and_dispose(batch_t *instance); 56 static void batch_dispose(batch_t *instance); 57 58 59 /** Allocates memory and initializes internal data structures. 54 55 56 /** Allocate memory and initialize internal data structure. 60 57 * 61 58 * @param[in] fun DDF function to pass to callback. … … 72 69 * @param[in] arg additional parameter to func_in or func_out 73 70 * @param[in] manager Pointer to toggle management structure. 74 * @return False, if there is an active TD, true otherwise. 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. 75 77 */ 76 78 batch_t * batch_get(ddf_fun_t *fun, usb_target_t target, … … 151 153 } 152 154 /*----------------------------------------------------------------------------*/ 153 /** Check sbatch TDs for activity.155 /** Check batch TDs for activity. 154 156 * 155 157 * @param[in] instance Batch structure to use. 156 158 * @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 be 161 * processed). Stop with true if an error is found. Return true if the last TS 162 * is reached. 157 163 */ 158 164 bool batch_is_complete(batch_t *instance) … … 193 199 * 194 200 * @param[in] instance Batch structure to use. 201 * 202 * Uses genercir control function with pids OUT and IN. 195 203 */ 196 204 void batch_control_write(batch_t *instance) 197 205 { 198 206 assert(instance); 199 /* we are data out, we are supposed to provide data */207 /* We are data out, we are supposed to provide data */ 200 208 memcpy(instance->transport_buffer, instance->buffer, 201 209 instance->buffer_size); … … 203 211 instance->next_step = batch_call_out_and_dispose; 204 212 usb_log_debug("Batch(%p) CONTROL WRITE initialized.\n", instance); 205 batch_schedule(instance);206 213 } 207 214 /*----------------------------------------------------------------------------*/ … … 209 216 * 210 217 * @param[in] instance Batch structure to use. 218 * 219 * Uses generic control with pids IN and OUT. 211 220 */ 212 221 void batch_control_read(batch_t *instance) … … 216 225 instance->next_step = batch_call_in_and_dispose; 217 226 usb_log_debug("Batch(%p) CONTROL READ initialized.\n", instance); 218 batch_schedule(instance); 219 } 220 /*----------------------------------------------------------------------------*/ 221 /** Prepares interrupt in transaction. 222 * 223 * @param[in] instance Batch structure to use. 227 } 228 /*----------------------------------------------------------------------------*/ 229 /** Prepare interrupt in transaction. 230 * 231 * @param[in] instance Batch structure to use. 232 * 233 * Data transaction with PID_IN. 224 234 */ 225 235 void batch_interrupt_in(batch_t *instance) … … 229 239 instance->next_step = batch_call_in_and_dispose; 230 240 usb_log_debug("Batch(%p) INTERRUPT IN initialized.\n", instance); 231 batch_schedule(instance); 232 } 233 /*----------------------------------------------------------------------------*/ 234 /** Prepares interrupt out transaction. 235 * 236 * @param[in] instance Batch structure to use. 241 } 242 /*----------------------------------------------------------------------------*/ 243 /** Prepare interrupt out transaction. 244 * 245 * @param[in] instance Batch structure to use. 246 * 247 * Data transaction with PID_OUT. 237 248 */ 238 249 void batch_interrupt_out(batch_t *instance) 239 250 { 240 251 assert(instance); 241 /* we are data out, we are supposed to provide data */252 /* We are data out, we are supposed to provide data */ 242 253 memcpy(instance->transport_buffer, instance->buffer, instance->buffer_size); 243 254 batch_data(instance, USB_PID_OUT); 244 255 instance->next_step = batch_call_out_and_dispose; 245 256 usb_log_debug("Batch(%p) INTERRUPT OUT initialized.\n", instance); 246 batch_schedule(instance); 247 } 248 /*----------------------------------------------------------------------------*/ 249 /** Prepares bulk in transaction. 250 * 251 * @param[in] instance Batch structure to use. 257 } 258 /*----------------------------------------------------------------------------*/ 259 /** Prepare bulk in transaction. 260 * 261 * @param[in] instance Batch structure to use. 262 * 263 * Data transaction with PID_IN. 252 264 */ 253 265 void batch_bulk_in(batch_t *instance) … … 257 269 instance->next_step = batch_call_in_and_dispose; 258 270 usb_log_debug("Batch(%p) BULK IN initialized.\n", instance); 259 batch_schedule(instance); 260 } 261 /*----------------------------------------------------------------------------*/ 262 /** Prepares bulk out transaction. 263 * 264 * @param[in] instance Batch structure to use. 271 } 272 /*----------------------------------------------------------------------------*/ 273 /** Prepare bulk out transaction. 274 * 275 * @param[in] instance Batch structure to use. 276 * 277 * Data transaction with PID_OUT. 265 278 */ 266 279 void batch_bulk_out(batch_t *instance) 267 280 { 268 281 assert(instance); 282 /* We are data out, we are supposed to provide data */ 269 283 memcpy(instance->transport_buffer, instance->buffer, instance->buffer_size); 270 284 batch_data(instance, USB_PID_OUT); 271 285 instance->next_step = batch_call_out_and_dispose; 272 286 usb_log_debug("Batch(%p) BULK OUT initialized.\n", instance); 273 batch_schedule(instance); 274 } 275 /*----------------------------------------------------------------------------*/ 276 /** Prepares generic data transaction 287 } 288 /*----------------------------------------------------------------------------*/ 289 /** Prepare generic data transaction 277 290 * 278 291 * @param[in] instance Batch structure to use. 279 292 * @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. 280 296 */ 281 297 void batch_data(batch_t *instance, usb_packet_id pid) … … 318 334 } 319 335 /*----------------------------------------------------------------------------*/ 320 /** Prepare sgeneric control transaction336 /** Prepare generic control transaction 321 337 * 322 338 * @param[in] instance Batch structure to use. 323 339 * @param[in] data_stage to use for data packets. 324 340 * @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. 325 346 */ 326 347 void batch_control(batch_t *instance, … … 371 392 } 372 393 /*----------------------------------------------------------------------------*/ 373 /** Prepares data, gets error status and calls callback in. 374 * 375 * @param[in] instance Batch structure to use. 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. 376 399 */ 377 400 void batch_call_in(batch_t *instance) … … 380 403 assert(instance->callback_in); 381 404 382 /* we are data in, we need data */405 /* We are data in, we need data */ 383 406 memcpy(instance->buffer, instance->transport_buffer, 384 407 instance->buffer_size); … … 393 416 } 394 417 /*----------------------------------------------------------------------------*/ 395 /** Get s error status and callscallback out.418 /** Get error status and call callback out. 396 419 * 397 420 * @param[in] instance Batch structure to use. … … 409 432 } 410 433 /*----------------------------------------------------------------------------*/ 411 /** Prepares data, gets error status, calls callback in and dispose.434 /** Helper function calls callback and correctly disposes of batch structure. 412 435 * 413 436 * @param[in] instance Batch structure to use. … … 420 443 } 421 444 /*----------------------------------------------------------------------------*/ 422 /** Gets error status, calls callback out and dispose.445 /** Helper function calls callback and correctly disposes of batch structure. 423 446 * 424 447 * @param[in] instance Batch structure to use. … … 431 454 } 432 455 /*----------------------------------------------------------------------------*/ 433 /** Correctly dispose sall used data structures.456 /** Correctly dispose all used data structures. 434 457 * 435 458 * @param[in] instance Batch structure to use. … … 446 469 free(instance); 447 470 } 448 /*----------------------------------------------------------------------------*/449 int batch_schedule(batch_t *instance)450 {451 assert(instance);452 uhci_hc_t *hc = fun_to_uhci_hc(instance->fun);453 assert(hc);454 return uhci_hc_schedule(hc, instance);455 }456 471 /** 457 472 * @} -
uspace/drv/uhci-hcd/batch.h
rc69209d r15d3b54 26 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 27 */ 28 /** @addtogroup usb28 /** @addtogroup drvusbuhcihc 29 29 * @{ 30 30 */ 31 31 /** @file 32 * @brief UHCI driver 32 * @brief UHCI driver USB transaction structure 33 33 */ 34 34 #ifndef DRV_UHCI_BATCH_H … … 78 78 ); 79 79 80 void batch_dispose(batch_t *instance); 81 80 82 bool batch_is_complete(batch_t *instance); 81 83 -
uspace/drv/uhci-hcd/iface.c
rc69209d r15d3b54 26 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 27 */ 28 /** @addtogroup usb28 /** @addtogroup drvusbuhcihc 29 29 * @{ 30 30 */ 31 31 /** @file 32 * @brief UHCI driver 32 * @brief UHCI driver hc interface implementation 33 33 */ 34 34 #include <ddf/driver.h> … … 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 } 163 168 return EOK; 164 169 } … … 192 197 return ENOMEM; 193 198 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 } 194 204 return EOK; 195 205 } … … 224 234 return ENOMEM; 225 235 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 } 226 241 return EOK; 227 242 } … … 255 270 return ENOMEM; 256 271 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 } 257 277 return EOK; 258 278 } … … 293 313 device_keeper_reset_if_need(&hc->device_manager, target, setup_data); 294 314 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 } 295 320 return EOK; 296 321 } … … 327 352 return ENOMEM; 328 353 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 } 329 359 return EOK; 330 360 } -
uspace/drv/uhci-hcd/iface.h
rc69209d r15d3b54 27 27 */ 28 28 29 /** @addtogroup usb29 /** @addtogroup drvusbuhcihc 30 30 * @{ 31 31 */ 32 32 /** @file 33 * @brief UHCI driver 33 * @brief UHCI driver iface 34 34 */ 35 35 #ifndef DRV_UHCI_IFACE_H -
uspace/drv/uhci-hcd/main.c
rc69209d r15d3b54 26 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 27 */ 28 /** @addtogroup usb28 /** @addtogroup drvusbuhcihc 29 29 * @{ 30 30 */ 31 31 /** @file 32 * @brief UHCI driver 32 * @brief UHCI driver initialization 33 33 */ 34 34 #include <ddf/driver.h> … … 55 55 }; 56 56 /*----------------------------------------------------------------------------*/ 57 /** Initialize sa new ddf driver instance for uhci hc and hub.57 /** Initialize a new ddf driver instance for uhci hc and hub. 58 58 * 59 59 * @param[in] device DDF instance of the device to initialize. 60 60 * @return Error code. 61 *62 * Gets and initialies hardware resources, disables any legacy support,63 * and reports root hub device.64 61 */ 65 62 int uhci_add_device(ddf_dev_t *device) … … 82 79 } 83 80 /*----------------------------------------------------------------------------*/ 84 /** Initialize sglobal driver structures (NONE).81 /** Initialize global driver structures (NONE). 85 82 * 86 83 * @param[in] argc Nmber of arguments in argv vector (ignored). … … 92 89 int main(int argc, char *argv[]) 93 90 { 94 sleep(3); 91 sleep(3); /* TODO: remove in final version */ 95 92 usb_log_enable(USB_LOG_LEVEL_DEBUG, NAME); 96 93 -
uspace/drv/uhci-hcd/pci.c
rc69209d r15d3b54 27 27 */ 28 28 /** 29 * @addtogroup drvusbuhci 29 * @addtogroup drvusbuhcihc 30 30 * @{ 31 31 */ … … 117 117 } 118 118 /*----------------------------------------------------------------------------*/ 119 /** Call sthe PCI driver with a request to enable interrupts119 /** Call 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 sthe PCI driver with a request to clear legacy support register133 /** Call 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
rc69209d r15d3b54 27 27 */ 28 28 29 /** @addtogroup drvusbuhci 29 /** @addtogroup drvusbuhcihc 30 30 * @{ 31 31 */ 32 32 /** @file 33 * @brief UHCI driver 33 * @brief UHCI driver PCI helper functions 34 34 */ 35 35 #ifndef DRV_UHCI_PCI_H -
uspace/drv/uhci-hcd/transfer_list.c
rc69209d r15d3b54 26 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 27 */ 28 /** @addtogroup usb28 /** @addtogroup drvusbuhcihc 29 29 * @{ 30 30 */ 31 31 /** @file 32 * @brief UHCI driver 32 * @brief UHCI driver transfer list implementation 33 33 */ 34 34 #include <errno.h> 35 36 35 #include <usb/debug.h> 37 36 … … 41 40 transfer_list_t *instance, batch_t *batch); 42 41 /*----------------------------------------------------------------------------*/ 43 /** Initialize stransfer list structures.42 /** Initialize transfer list structures. 44 43 * 45 44 * @param[in] instance Memory place to use. 46 * @param[in] name Name of t e new list.45 * @param[in] name Name of the new list. 47 46 * @return Error code 48 47 * … … 66 65 } 67 66 /*----------------------------------------------------------------------------*/ 68 /** Set the next list in chain.67 /** Set the next list in transfer list chain. 69 68 * 70 69 * @param[in] instance List to lead. … … 72 71 * @return Error code 73 72 * 74 * Does not check whether th ere was a next list already.73 * Does not check whether this replaces an existing list . 75 74 */ 76 75 void transfer_list_set_next(transfer_list_t *instance, transfer_list_t *next) … … 80 79 if (!instance->queue_head) 81 80 return; 82 /* set both next and element to point to the same QH */81 /* Set both next and element to point to the same QH */ 83 82 qh_set_next_qh(instance->queue_head, next->queue_head_pa); 84 83 qh_set_element_qh(instance->queue_head, next->queue_head_pa); 85 84 } 86 85 /*----------------------------------------------------------------------------*/ 87 /** Submit s a new transfer batch tolist and queue.86 /** Submit transfer batch to the list and queue. 88 87 * 89 88 * @param[in] instance List to use. 90 89 * @param[in] batch Transfer batch to submit. 91 90 * @return Error code 91 * 92 * The batch is added to the end of the list and queue. 92 93 */ 93 94 void transfer_list_add_batch(transfer_list_t *instance, batch_t *batch) … … 106 107 fibril_mutex_lock(&instance->guard); 107 108 109 /* Add to the hardware queue. */ 108 110 if (list_empty(&instance->batch_list)) { 109 111 /* There is nothing scheduled */ … … 117 119 qh_set_next_qh(last->qh, pa); 118 120 } 121 /* Add to the driver list */ 119 122 list_append(&batch->link, &instance->batch_list); 120 123 … … 126 129 } 127 130 /*----------------------------------------------------------------------------*/ 128 /** Remove sa transfer batch from the list and queue.131 /** Remove a transfer batch from the list and queue. 129 132 * 130 133 * @param[in] instance List to use. … … 144 147 145 148 const char * pos = NULL; 149 /* Remove from the hardware queue */ 146 150 if (batch->link.prev == &instance->batch_list) { 147 151 /* I'm the first one here */ … … 154 158 pos = "NOT FIRST"; 155 159 } 160 /* Remove from the driver list */ 156 161 list_remove(&batch->link); 157 162 usb_log_debug("Batch(%p) removed (%s) from %s, next element %x.\n", … … 159 164 } 160 165 /*----------------------------------------------------------------------------*/ 161 /** Check slist for finished batches.166 /** Check list for finished batches. 162 167 * 163 168 * @param[in] instance List to use. 164 169 * @return Error code 170 * 171 * Creates a local list of finished batches and calls next_step on each and 172 * every one. This is safer because next_step may theoretically access 173 * this transfer list leading to the deadlock if its done inline. 165 174 */ 166 175 void transfer_list_remove_finished(transfer_list_t *instance) … … 177 186 178 187 if (batch_is_complete(batch)) { 188 /* Save for post-processing */ 179 189 transfer_list_remove_batch(instance, batch); 180 190 list_append(current, &done); -
uspace/drv/uhci-hcd/transfer_list.h
rc69209d r15d3b54 26 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 27 */ 28 /** @addtogroup usb28 /** @addtogroup drvusbuhcihc 29 29 * @{ 30 30 */ 31 31 /** @file 32 * @brief UHCI driver 32 * @brief UHCI driver transfer list structure 33 33 */ 34 34 #ifndef DRV_UHCI_TRANSFER_LIST_H … … 50 50 } transfer_list_t; 51 51 52 int transfer_list_init(transfer_list_t *instance, const char *name); 53 54 void transfer_list_set_next(transfer_list_t *instance, transfer_list_t *next); 55 52 /** Dispose transfer list structures. 53 * 54 * @param[in] instance Memory place to use. 55 * 56 * Frees memory for internal qh_t structure. 57 */ 56 58 static inline void transfer_list_fini(transfer_list_t *instance) 57 59 { … … 59 61 free32(instance->queue_head); 60 62 } 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 61 68 void transfer_list_remove_finished(transfer_list_t *instance); 62 69 -
uspace/drv/uhci-hcd/uhci.c
rc69209d r15d3b54 60 60 } 61 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. 67 */ 62 68 static int usb_iface_get_address( 63 69 ddf_fun_t *fun, devman_handle_t handle, usb_address_t *address) … … 106 112 }; 107 113 /*----------------------------------------------------------------------------*/ 108 /** Get s root hub hw resources.114 /** Get root hub hw resources (I/O registers). 109 115 * 110 116 * @param[in] fun Root hub function. … … 127 133 }; 128 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 */ 129 146 int uhci_init(uhci_t *instance, ddf_dev_t *device) 130 147 { … … 157 174 "Failed(%d) to disable legacy USB: %s.\n", ret, str_error(ret)); 158 175 159 #if 0 176 bool interrupts = false; 160 177 ret = pci_enable_interrupts(device); 161 178 if (ret != EOK) { … … 163 180 "Failed(%d) to enable interrupts, fall back to polling.\n", 164 181 ret); 182 } else { 183 usb_log_debug("Hw interrupts enabled.\n"); 184 interrupts = true; 165 185 } 166 #endif167 186 168 187 instance->hc_fun = ddf_fun_create(device, fun_exposed, "uhci-hc"); 169 188 ret = (instance->hc_fun == NULL) ? ENOMEM : EOK; 170 CHECK_RET_DEST_FUN_RETURN(ret, "Failed(%d) to create HC function.\n", ret); 171 172 ret = uhci_hc_init( 173 &instance->hc, instance->hc_fun, (void*)io_reg_base, io_reg_size); 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); 174 194 CHECK_RET_DEST_FUN_RETURN(ret, "Failed(%d) to init uhci-hcd.\n", ret); 175 195 instance->hc_fun->ops = &uhci_hc_ops; … … 217 237 #undef CHECK_RET_FINI_RETURN 218 238 } 219 220 239 /** 221 240 * @} -
uspace/drv/uhci-hcd/uhci.h
rc69209d r15d3b54 31 31 */ 32 32 /** @file 33 * @brief UHCI driver 33 * @brief UHCI driver main structure for both host controller and root-hub. 34 34 */ 35 35 #ifndef DRV_UHCI_UHCI_H -
uspace/drv/uhci-hcd/uhci_hc.c
rc69209d r15d3b54 26 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 27 */ 28 /** @addtogroup usb28 /** @addtogroup drvusbuhcihc 29 29 * @{ 30 30 */ 31 31 /** @file 32 * @brief UHCI driver32 * @brief UHCI Host controller driver routines 33 33 */ 34 34 #include <errno.h> … … 59 59 } 60 60 }; 61 62 /** Gets USB address of the calling device.63 *64 * @param[in] fun UHCI hc function.65 * @param[in] handle Handle of the device seeking address.66 * @param[out] address Place to store found address.67 * @return Error code.68 */69 61 /*----------------------------------------------------------------------------*/ 70 62 static int uhci_hc_init_transfer_lists(uhci_hc_t *instance); … … 78 70 bool low_speed, usb_transfer_type_t transfer, size_t size); 79 71 /*----------------------------------------------------------------------------*/ 80 /** Initialize sUHCI hcd driver structure72 /** Initialize UHCI hcd driver structure 81 73 * 82 74 * @param[in] instance Memory place to initialize. … … 86 78 * @return Error code. 87 79 * @note Should be called only once on any structure. 88 */ 89 int uhci_hc_init(uhci_hc_t *instance, ddf_fun_t *fun, void *regs, size_t reg_size) 80 * 81 * Initializes memory structures, starts up hw, and launches debugger and 82 * interrupt fibrils. 83 */ 84 int uhci_hc_init(uhci_hc_t *instance, ddf_fun_t *fun, 85 void *regs, size_t reg_size, bool interrupts) 90 86 { 91 87 assert(reg_size >= sizeof(regs_t)); … … 100 96 } else (void) 0 101 97 98 instance->hw_interrupts = interrupts; 102 99 /* Setup UHCI function. */ 103 100 instance->ddf_instance = fun; … … 118 115 119 116 uhci_hc_init_hw(instance); 120 instance->cleaner = 121 fibril_create(uhci_hc_interrupt_emulator, instance); 122 fibril_add_ready(instance->cleaner); 117 if (!interrupts) { 118 instance->cleaner = 119 fibril_create(uhci_hc_interrupt_emulator, instance); 120 fibril_add_ready(instance->cleaner); 121 } 123 122 124 123 instance->debug_checker = fibril_create(uhci_hc_debug_checker, instance); … … 130 129 } 131 130 /*----------------------------------------------------------------------------*/ 132 /** Initialize s UHCI hcdhw resources.131 /** Initialize UHCI hc hw resources. 133 132 * 134 133 * @param[in] instance UHCI structure to use. 134 * For magic values see UHCI Design Guide 135 135 */ 136 136 void uhci_hc_init_hw(uhci_hc_t *instance) … … 153 153 pio_write_32(®isters->flbaseadd, pa); 154 154 155 /* Enable all interrupts, but resume interrupt */ 156 // pio_write_16(&instance->registers->usbintr, 157 // UHCI_INTR_CRC | UHCI_INTR_COMPLETE | UHCI_INTR_SHORT_PACKET); 155 if (instance->hw_interrupts) { 156 /* Enable all interrupts, but resume interrupt */ 157 pio_write_16(&instance->registers->usbintr, 158 UHCI_INTR_CRC | UHCI_INTR_COMPLETE | UHCI_INTR_SHORT_PACKET); 159 } 158 160 159 161 uint16_t status = pio_read_16(®isters->usbcmd); … … 166 168 } 167 169 /*----------------------------------------------------------------------------*/ 168 /** Initialize s UHCI hcdmemory structures.170 /** Initialize UHCI hc memory structures. 169 171 * 170 172 * @param[in] instance UHCI structure to use. 171 173 * @return Error code 172 174 * @note Should be called only once on any structure. 175 * 176 * Structures: 177 * - interrupt code (I/O addressses are customized per instance) 178 * - transfer lists (queue heads need to be accessible by the hw) 179 * - frame list page (needs to be one UHCI hw accessible 4K page) 173 180 */ 174 181 int uhci_hc_init_mem_structures(uhci_hc_t *instance) … … 229 236 } 230 237 /*----------------------------------------------------------------------------*/ 231 /** Initialize s UHCI hcdtransfer lists.238 /** Initialize UHCI hc transfer lists. 232 239 * 233 240 * @param[in] instance UHCI structure to use. 234 241 * @return Error code 235 242 * @note Should be called only once on any structure. 243 * 244 * Initializes transfer lists and sets them in one chain to support proper 245 * USB scheduling. Sets pointer table for quick access. 236 246 */ 237 247 int uhci_hc_init_transfer_lists(uhci_hc_t *instance) … … 293 303 } 294 304 /*----------------------------------------------------------------------------*/ 295 /** Schedule sbatch for execution.305 /** Schedule batch for execution. 296 306 * 297 307 * @param[in] instance UHCI structure to use. 298 308 * @param[in] batch Transfer batch to schedule. 299 309 * @return Error code 310 * 311 * Checks for bandwidth availability and appends the batch to the proper queue. 300 312 */ 301 313 int uhci_hc_schedule(uhci_hc_t *instance, batch_t *batch) … … 312 324 return ENOTSUP; 313 325 } 314 /* TODO: check available bandwi th here */326 /* TODO: check available bandwidth here */ 315 327 316 328 transfer_list_t *list = … … 322 334 } 323 335 /*----------------------------------------------------------------------------*/ 324 /** Take saction based on the interrupt cause.336 /** Take action based on the interrupt cause. 325 337 * 326 338 * @param[in] instance UHCI structure to use. 327 * @param[in] status Value of the stsatus regiser at the time of interrupt. 339 * @param[in] status Value of the status register at the time of interrupt. 340 * 341 * Interrupt might indicate: 342 * - transaction completed, either by triggering IOC, SPD, or an error 343 * - some kind of device error 344 * - resume from suspend state (not implemented) 328 345 */ 329 346 void uhci_hc_interrupt(uhci_hc_t *instance, uint16_t status) … … 342 359 /** Polling function, emulates interrupts. 343 360 * 344 * @param[in] arg UHCI structure to use.345 * @return EOK 361 * @param[in] arg UHCI hc structure to use. 362 * @return EOK (should never return) 346 363 */ 347 364 int uhci_hc_interrupt_emulator(void* arg) … … 366 383 * 367 384 * @param[in] arg UHCI structure to use. 368 * @return EOK 385 * @return EOK (should never return) 369 386 */ 370 387 int uhci_hc_debug_checker(void *arg) … … 430 447 } 431 448 /*----------------------------------------------------------------------------*/ 432 /** Check stransfer packets, for USB validity449 /** Check transfer packets, for USB validity 433 450 * 434 451 * @param[in] low_speed Transfer speed. 435 452 * @param[in] transfer Transer type 436 453 * @param[in] size Maximum size of used packets 437 * @return EOK454 * @return True if transaction is allowed by USB specs, false otherwise 438 455 */ 439 456 bool allowed_usb_packet( -
uspace/drv/uhci-hcd/uhci_hc.h
rc69209d r15d3b54 27 27 */ 28 28 29 /** @addtogroup drvusbuhci 29 /** @addtogroup drvusbuhcihc 30 30 * @{ 31 31 */ 32 32 /** @file 33 * @brief UHCI driver33 * @brief UHCI host controller driver structure 34 34 */ 35 35 #ifndef DRV_UHCI_UHCI_HC_H … … 99 99 fid_t cleaner; 100 100 fid_t debug_checker; 101 bool hw_interrupts; 101 102 102 103 ddf_fun_t *ddf_instance; 103 104 } uhci_hc_t; 104 105 105 /* init uhci specifics in device.driver_data */ 106 int uhci_hc_init(uhci_hc_t *instance, ddf_fun_t *fun, void *regs, size_t reg_size); 107 108 static inline void uhci_hc_fini(uhci_hc_t *instance) { /* TODO: implement*/ }; 106 int uhci_hc_init(uhci_hc_t *instance, ddf_fun_t *fun, 107 void *regs, size_t reg_size, bool interupts); 109 108 110 109 int uhci_hc_schedule(uhci_hc_t *instance, batch_t *batch); … … 112 111 void uhci_hc_interrupt(uhci_hc_t *instance, uint16_t status); 113 112 113 /** Safely dispose host controller internal structures 114 * 115 * @param[in] instance Host controller structure to use. 116 */ 117 static inline void uhci_hc_fini(uhci_hc_t *instance) { /* TODO: implement*/ }; 118 119 /** Get and cast pointer to the driver data 120 * 121 * @param[in] fun DDF function pointer 122 * @return cast pointer to driver_data 123 */ 114 124 static inline uhci_hc_t * fun_to_uhci_hc(ddf_fun_t *fun) 115 125 { return (uhci_hc_t*)fun->driver_data; } -
uspace/drv/uhci-hcd/uhci_rh.c
rc69209d r15d3b54 26 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 27 */ 28 /** @addtogroup usb28 /** @addtogroup drvusbuhci 29 29 * @{ 30 30 */ … … 42 42 #include "uhci_hc.h" 43 43 44 /*----------------------------------------------------------------------------*/ 44 /** Root hub initialization 45 * @param[in] instance RH structure to initialize 46 * @param[in] fun DDF function representing UHCI root hub 47 * @param[in] reg_addr Address of root hub status and control registers. 48 * @param[in] reg_size Size of accessible address space. 49 * @return Error code. 50 */ 45 51 int uhci_rh_init( 46 52 uhci_rh_t *instance, ddf_fun_t *fun, uintptr_t reg_addr, size_t reg_size) … … 68 74 instance->io_regs.type = IO_RANGE; 69 75 instance->io_regs.res.io_range.address = reg_addr; 70 // ((uintptr_t)hc->registers) + 0x10; // see UHCI design guide71 76 instance->io_regs.res.io_range.size = reg_size; 72 77 instance->io_regs.res.io_range.endianness = LITTLE_ENDIAN; -
uspace/drv/uhci-hcd/uhci_struct/link_pointer.h
rc69209d r15d3b54 26 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 27 */ 28 /** @addtogroup usb28 /** @addtogroup drvusbuhcihc 29 29 * @{ 30 30 */ -
uspace/drv/uhci-hcd/uhci_struct/queue_head.h
rc69209d r15d3b54 1 2 1 /* 3 2 * Copyright (c) 2010 Jan Vesely … … 27 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 27 */ 29 /** @addtogroup usb28 /** @addtogroup drv usbuhcihc 30 29 * @{ 31 30 */ … … 47 46 } __attribute__((packed)) qh_t; 48 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 */ 49 54 static inline void qh_init(qh_t *instance) 50 55 { … … 55 60 } 56 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 */ 57 70 static inline void qh_set_next_qh(qh_t *instance, uint32_t pa) 58 71 { 59 /* address is valid and not terminal */72 /* Address is valid and not terminal */ 60 73 if (pa && ((pa & LINK_POINTER_TERMINATE_FLAG) == 0)) { 61 74 instance->next = (pa & LINK_POINTER_ADDRESS_MASK) … … 66 79 } 67 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 */ 68 89 static inline void qh_set_element_qh(qh_t *instance, uint32_t pa) 69 90 { 70 /* address is valid and not terminal */91 /* Address is valid and not terminal */ 71 92 if (pa && ((pa & LINK_POINTER_TERMINATE_FLAG) == 0)) { 72 93 instance->element = (pa & LINK_POINTER_ADDRESS_MASK) … … 77 98 } 78 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 */ 79 108 static inline void qh_set_element_td(qh_t *instance, uint32_t pa) 80 109 { -
uspace/drv/uhci-hcd/uhci_struct/transfer_descriptor.c
rc69209d r15d3b54 26 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 27 */ 28 /** @addtogroup usb28 /** @addtogroup drvusbuhcihc 29 29 * @{ 30 30 */ … … 38 38 #include "utils/malloc32.h" 39 39 40 /** Initialize sTransfer Descriptor40 /** Initialize Transfer Descriptor 41 41 * 42 42 * @param[in] instance Memory place to initialize. … … 106 106 } 107 107 /*----------------------------------------------------------------------------*/ 108 /** Convert sTD status into standard error code108 /** Convert TD status into standard error code 109 109 * 110 110 * @param[in] instance TD structure to use. -
uspace/drv/uhci-hcd/uhci_struct/transfer_descriptor.h
rc69209d r15d3b54 1 1 /* 2 * Copyright (c) 201 0Jan Vesely2 * Copyright (c) 2011 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 usb28 /** @addtogroup drvusbuhcihc 29 29 * @{ 30 30 */ … … 108 108 } 109 109 /*----------------------------------------------------------------------------*/ 110 /** Check swhether less than max data were recieved and packet is marked as SPD.110 /** Check whether less than max data were recieved and packet is marked as SPD. 111 111 * 112 112 * @param[in] instance TD structure to use. -
uspace/drv/uhci-hcd/utils/device_keeper.c
rc69209d r15d3b54 27 27 */ 28 28 29 /** @addtogroup drvusbuhci 29 /** @addtogroup drvusbuhcihc 30 30 * @{ 31 31 */ … … 40 40 41 41 /*----------------------------------------------------------------------------*/ 42 /** Initialize sdevice keeper structure.42 /** Initialize device keeper structure. 43 43 * 44 44 * @param[in] instance Memory place to initialize. 45 * 46 * Set all values to false/0. 45 47 */ 46 48 void device_keeper_init(device_keeper_t *instance) … … 58 60 } 59 61 /*----------------------------------------------------------------------------*/ 60 /** Attempt sto obtain address 0, blocks.62 /** Attempt to obtain address 0, blocks. 61 63 * 62 64 * @param[in] instance Device keeper structure to use. … … 76 78 } 77 79 /*----------------------------------------------------------------------------*/ 78 /** Attempt sto obtain address 0, blocks.80 /** Attempt to obtain address 0, blocks. 79 81 * 80 82 * @param[in] instance Device keeper structure to use. … … 90 92 } 91 93 /*----------------------------------------------------------------------------*/ 92 /** Check s setupdata for signs of toggle reset.94 /** Check setup packet data for signs of toggle reset. 93 95 * 94 96 * @param[in] instance Device keeper structure to use. 95 97 * @param[in] target Device to receive setup packet. 96 98 * @param[in] data Setup packet data. 99 * 100 * Really ugly one. 97 101 */ 98 102 void device_keeper_reset_if_need( … … 105 109 || !instance->devices[target.address].occupied) { 106 110 fibril_mutex_unlock(&instance->guard); 111 usb_log_error("Invalid data when checking for toggle reset.\n"); 107 112 return; 108 113 } … … 130 135 } 131 136 /*----------------------------------------------------------------------------*/ 132 /** Get scurrent value of endpoint toggle.137 /** Get current value of endpoint toggle. 133 138 * 134 139 * @param[in] instance Device keeper structure to use. … … 144 149 || target.address >= USB_ADDRESS_COUNT || target.address < 0 145 150 || !instance->devices[target.address].occupied) { 151 usb_log_error("Invalid data when asking for toggle value.\n"); 146 152 ret = EINVAL; 147 153 } else { 148 ret = 149 (instance->devices[target.address].toggle_status 154 ret = (instance->devices[target.address].toggle_status 150 155 >> target.endpoint) & 1; 151 156 } … … 154 159 } 155 160 /*----------------------------------------------------------------------------*/ 156 /** Set scurrent value of endpoint toggle.161 /** Set current value of endpoint toggle. 157 162 * 158 163 * @param[in] instance Device keeper structure to use. 159 164 * @param[in] target Device and endpoint used. 160 * @param[in] toggle Current toggle value.165 * @param[in] toggle Toggle value. 161 166 * @return Error code. 162 167 */ … … 170 175 || target.address >= USB_ADDRESS_COUNT || target.address < 0 171 176 || !instance->devices[target.address].occupied) { 177 usb_log_error("Invalid data when setting toggle value.\n"); 172 178 ret = EINVAL; 173 179 } else { … … 183 189 } 184 190 /*----------------------------------------------------------------------------*/ 185 /** Get sa free USB address191 /** Get a free USB address 186 192 * 187 193 * @param[in] instance Device keeper structure to use. … … 216 222 } 217 223 /*----------------------------------------------------------------------------*/ 218 /** Bind sUSB address to devman handle.224 /** Bind USB address to devman handle. 219 225 * 220 226 * @param[in] instance Device keeper structure to use. … … 234 240 } 235 241 /*----------------------------------------------------------------------------*/ 236 /** Release sused USB address.242 /** Release used USB address. 237 243 * 238 244 * @param[in] instance Device keeper structure to use. … … 251 257 } 252 258 /*----------------------------------------------------------------------------*/ 253 /** Find sUSB address associated with the device259 /** Find USB address associated with the device 254 260 * 255 261 * @param[in] instance Device keeper structure to use. … … 274 280 } 275 281 /*----------------------------------------------------------------------------*/ 276 /** Get sspeed associated with the address282 /** Get speed associated with the address 277 283 * 278 284 * @param[in] instance Device keeper structure to use. -
uspace/drv/uhci-hcd/utils/device_keeper.h
rc69209d r15d3b54 27 27 */ 28 28 29 /** @addtogroup drvusbuhci 29 /** @addtogroup drvusbuhcihc 30 30 * @{ 31 31 */ -
uspace/drv/uhci-hcd/utils/malloc32.h
rc69209d r15d3b54 43 43 #define UHCI_REQUIRED_PAGE_SIZE 4096 44 44 45 /** Get physical address translation 46 * 47 * @param[in] addr Virtual address to translate 48 * @return Physical address if exists, NULL otherwise. 49 */ 45 50 static inline uintptr_t addr_to_phys(void *addr) 46 51 { … … 48 53 int ret = as_get_physical_mapping(addr, &result); 49 54 50 assert(ret == 0); 55 if (ret != EOK) 56 return 0; 51 57 return (result | ((uintptr_t)addr & 0xfff)); 52 58 } 53 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 */ 54 65 static inline void * malloc32(size_t size) 55 66 { return memalign(UHCI_STRCUTURES_ALIGNMENT, size); } 56 57 static inline void * get_page() 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) 58 80 { 59 81 void * free_address = as_get_mappable_page(UHCI_REQUIRED_PAGE_SIZE); 60 82 assert(free_address); 61 83 if (free_address == 0) 62 return 0;84 return NULL; 63 85 void* ret = 64 86 as_area_create(free_address, UHCI_REQUIRED_PAGE_SIZE, 65 87 AS_AREA_READ | AS_AREA_WRITE); 66 88 if (ret != free_address) 67 return 0;89 return NULL; 68 90 return ret; 69 91 } 70 71 static inline void free32(void *addr)72 { if (addr) free(addr); }73 92 74 93 #endif
Note:
See TracChangeset
for help on using the changeset viewer.
