Changeset f20bc82 in mainline
- Timestamp:
- 2011-07-11T17:10:31Z (14 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 14426a0
- Parents:
- b21dfba
- Location:
- uspace/drv/bus/usb/ohci
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/bus/usb/ohci/root_hub.c
rb21dfba rf20bc82 134 134 static void create_serialized_hub_descriptor(rh_t *instance); 135 135 static void rh_init_descriptors(rh_t *instance); 136 static voidcreate_interrupt_mask_in_instance(rh_t *instance);136 static uint16_t create_interrupt_mask_in_instance(rh_t *instance); 137 137 static int get_status_request(rh_t *instance, usb_transfer_batch_t *request); 138 138 static int get_descriptor_request( … … 145 145 static int request_without_data(rh_t *instance, usb_transfer_batch_t *request); 146 146 static int ctrl_request(rh_t *instance, usb_transfer_batch_t *request); 147 static void interrupt_mask_in_instance(148 rh_t *instance, usb_transfer_batch_t *request);149 static bool is_zeros(const void *buffer, size_t size);150 151 147 152 148 #define TRANSFER_OK(bytes) \ … … 175 171 /* Don't forget the hub status bit and round up */ 176 172 instance->interrupt_mask_size = (instance->port_count + 1 + 8) / 8; 177 instance->interrupt_buffer[0] = 0;178 instance->interrupt_buffer[1] = 0;179 173 instance->unfinished_interrupt_transfer = NULL; 180 174 … … 210 204 case USB_TRANSFER_INTERRUPT: 211 205 usb_log_debug("Root hub got INTERRUPT packet\n"); 212 c reate_interrupt_mask_in_instance(instance);213 if (is_zeros(instance->interrupt_buffer,214 instance->interrupt_mask_size)) {206 const uint16_t mask = 207 create_interrupt_mask_in_instance(instance); 208 if (mask == 0) { 215 209 usb_log_debug("No changes..\n"); 216 210 instance->unfinished_interrupt_transfer = request; … … 218 212 } else { 219 213 usb_log_debug("Processing changes..\n"); 220 interrupt_mask_in_instance(instance, request); 214 memcpy(request->data_buffer, &mask, 215 instance->interrupt_mask_size); 216 request->transfered_size = instance->interrupt_mask_size; 217 instance->unfinished_interrupt_transfer = NULL; 218 usb_transfer_batch_finish_error(request, EOK); 221 219 } 222 220 break; … … 240 238 241 239 usb_log_debug("Finalizing interrupt transfer\n"); 242 create_interrupt_mask_in_instance(instance); 243 interrupt_mask_in_instance(instance, 244 instance->unfinished_interrupt_transfer); 240 const uint16_t mask = create_interrupt_mask_in_instance(instance); 241 memcpy(instance->unfinished_interrupt_transfer->data_buffer, 242 &mask, instance->interrupt_mask_size); 243 instance->unfinished_interrupt_transfer->transfered_size = 244 instance->interrupt_mask_size; 245 usb_transfer_batch_finish(instance->unfinished_interrupt_transfer); 246 247 instance->unfinished_interrupt_transfer = NULL; 245 248 } 246 249 /*----------------------------------------------------------------------------*/ … … 383 386 * @param instance root hub instance 384 387 */ 385 void create_interrupt_mask_in_instance(rh_t *instance) 386 { 387 assert(instance); 388 389 uint8_t * bitmap = instance->interrupt_buffer; 390 bzero(bitmap, instance->interrupt_mask_size); 388 uint16_t create_interrupt_mask_in_instance(rh_t *instance) 389 { 390 assert(instance); 391 uint16_t mask = 0; 392 391 393 /* Only local power source change and over-current change can happen */ 392 394 if (instance->registers->rh_status & (RHS_LPSC_FLAG | RHS_OCIC_FLAG)) { 393 bitmap[0]= 1;395 mask |= 1; 394 396 } 395 397 size_t port = 1; … … 399 401 & instance->registers->rh_port_status[port - 1]) { 400 402 401 bitmap[(port) / 8] |= 1 << (port % 8);403 mask |= (1 << port); 402 404 } 403 405 } 406 return host2uint32_t_le(mask); 404 407 } 405 408 /*----------------------------------------------------------------------------*/ … … 700 703 } 701 704 } 702 /*----------------------------------------------------------------------------*/703 /**704 * Process waiting interrupt request705 *706 * If an interrupt transfer has been received and there was no change,707 * the driver stores the transfer information and waits for change to occur.708 * This routine is called when that happens and it finalizes the interrupt709 * transfer.710 *711 * @param instance hub instance712 * @param request batch request to be processed713 *714 * @return715 */716 void interrupt_mask_in_instance(rh_t *instance, usb_transfer_batch_t *request)717 {718 assert(instance);719 assert(request);720 721 memcpy(request->data_buffer, instance->interrupt_buffer,722 instance->interrupt_mask_size);723 request->transfered_size = instance->interrupt_mask_size;724 instance->unfinished_interrupt_transfer = NULL;725 usb_transfer_batch_finish_error(request, EOK);726 }727 /*----------------------------------------------------------------------------*/728 /**729 * return whether the buffer is full of zeros730 *731 * Convenience function.732 * @param buffer733 * @param size734 * @return735 */736 bool is_zeros(const void *buffer, size_t size)737 {738 if (!buffer) return true;739 const char * const end = buffer + size;740 const char *data = buffer;741 for (; data < end; ++data) {742 if (*data)743 return false;744 }745 return true;746 }747 705 748 706 /** -
uspace/drv/bus/usb/ohci/root_hub.h
rb21dfba rf20bc82 42 42 43 43 #define HUB_DESCRIPTOR_MAX_SIZE (7 + 2 + 2) 44 #define INTERRUPT_BUFFER_MAX_SIZE 245 44 46 45 /** … … 56 55 /** interrupt transfer waiting for an actual interrupt to occur */ 57 56 usb_transfer_batch_t *unfinished_interrupt_transfer; 58 /** Interrupt mask of changes59 *60 * OHCI support max 15 ports (specs page 124) + one global bit, it61 * gives max 2 bytes.62 */63 uint8_t interrupt_buffer[INTERRUPT_BUFFER_MAX_SIZE];64 57 /** size of interrupt buffer */ 65 58 size_t interrupt_mask_size;
Note:
See TracChangeset
for help on using the changeset viewer.