Changes in / [c6394aa:b6c9e1e] in mainline
- Location:
- uspace
- Files:
-
- 6 deleted
- 25 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/app/usbinfo/dev.c
rc6394aa rb6c9e1e 50 50 51 51 int rc; 52 bool transfer_started = false;53 52 54 53 rc = usb_device_connection_initialize(&dev->wire, hc_handle, dev_addr); … … 77 76 } 78 77 79 rc = usb_pipe_start_ long_transfer(&dev->ctrl_pipe);78 rc = usb_pipe_start_session(&dev->ctrl_pipe); 80 79 if (rc != EOK) { 81 80 fprintf(stderr, 82 NAME ": failed to start transferon control pipe: %s.\n",81 NAME ": failed to start session on control pipe: %s.\n", 83 82 str_error(rc)); 84 83 goto leave; 85 84 } 86 transfer_started = true;87 85 88 86 rc = usb_request_get_device_descriptor(&dev->ctrl_pipe, … … 109 107 110 108 leave: 111 if ( transfer_started) {112 usb_pipe_end_ long_transfer(&dev->ctrl_pipe);109 if (usb_pipe_is_session_started(&dev->ctrl_pipe)) { 110 usb_pipe_end_session(&dev->ctrl_pipe); 113 111 } 114 112 … … 120 118 void destroy_device(usbinfo_device_t *dev) 121 119 { 122 usb_pipe_end_ long_transfer(&dev->ctrl_pipe);120 usb_pipe_end_session(&dev->ctrl_pipe); 123 121 free(dev); 124 122 } -
uspace/drv/ohci/Makefile
rc6394aa rb6c9e1e 33 33 34 34 SOURCES = \ 35 iface.c \ 35 36 batch.c \ 37 main.c \ 36 38 hc.c \ 37 iface.c \38 main.c \39 39 ohci.c \ 40 pci.c \41 40 root_hub.c \ 42 transfer_list.c \ 43 hw_struct/endpoint_descriptor.c \ 44 hw_struct/transfer_descriptor.c 45 41 pci.c 46 42 47 43 include $(USPACE_PREFIX)/Makefile.common -
uspace/drv/ohci/batch.c
rc6394aa rb6c9e1e 40 40 #include "batch.h" 41 41 #include "utils/malloc32.h" 42 #include "hw_struct/endpoint_descriptor.h"43 #include "hw_struct/transfer_descriptor.h"44 42 45 typedef struct ohci_batch {46 ed_t *ed;47 td_t *tds;48 size_t td_count;49 } ohci_batch_t;50 51 static void batch_control(usb_transfer_batch_t *instance,52 usb_direction_t data_dir, usb_direction_t status_dir);53 43 static void batch_call_in_and_dispose(usb_transfer_batch_t *instance); 54 44 static void batch_call_out_and_dispose(usb_transfer_batch_t *instance); 55 45 56 46 #define DEFAULT_ERROR_COUNT 3 57 usb_transfer_batch_t * batch_get(ddf_fun_t *fun, endpoint_t *ep, 58 char *buffer, size_t buffer_size, char* setup_buffer, size_t setup_size, 47 usb_transfer_batch_t * batch_get( 48 ddf_fun_t *fun, 49 usb_target_t target, 50 usb_transfer_type_t transfer_type, 51 size_t max_packet_size, 52 usb_speed_t speed, 53 char *buffer, 54 size_t buffer_size, 55 char *setup_buffer, 56 size_t setup_size, 59 57 usbhc_iface_transfer_in_callback_t func_in, 60 usbhc_iface_transfer_out_callback_t func_out, void *arg) 58 usbhc_iface_transfer_out_callback_t func_out, 59 void *arg, 60 usb_device_keeper_t *manager 61 ) 61 62 { 62 63 #define CHECK_NULL_DISPOSE_RETURN(ptr, message...) \ … … 72 73 CHECK_NULL_DISPOSE_RETURN(instance, 73 74 "Failed to allocate batch instance.\n"); 74 usb_target_t target = 75 { .address = ep->address, .endpoint = ep->endpoint }; 76 usb_transfer_batch_init(instance, target, ep->transfer_type, ep->speed, 77 ep->max_packet_size, buffer, NULL, buffer_size, NULL, setup_size, 78 func_in, func_out, arg, fun, ep, NULL); 79 80 ohci_batch_t *data = malloc(sizeof(ohci_batch_t)); 81 CHECK_NULL_DISPOSE_RETURN(data, "Failed to allocate batch data.\n"); 82 bzero(data, sizeof(ohci_batch_t)); 83 instance->private_data = data; 84 85 /* we needs + 1 transfer descriptor as the last one won't be executed */ 86 data->td_count = 1 + 87 ((buffer_size + OHCI_TD_MAX_TRANSFER - 1) / OHCI_TD_MAX_TRANSFER); 88 if (ep->transfer_type == USB_TRANSFER_CONTROL) { 89 data->td_count += 2; 90 } 91 92 data->tds = malloc32(sizeof(td_t) * data->td_count); 93 CHECK_NULL_DISPOSE_RETURN(data->tds, 94 "Failed to allocate transfer descriptors.\n"); 95 bzero(data->tds, sizeof(td_t) * data->td_count); 96 97 data->ed = malloc32(sizeof(ed_t)); 98 CHECK_NULL_DISPOSE_RETURN(data->ed, 99 "Failed to allocate endpoint descriptor.\n"); 75 usb_transfer_batch_init(instance, target, transfer_type, speed, 76 max_packet_size, buffer, NULL, buffer_size, NULL, setup_size, 77 func_in, func_out, arg, fun, NULL, NULL); 100 78 101 79 if (buffer_size > 0) { … … 112 90 } 113 91 92 114 93 return instance; 115 94 } … … 118 97 { 119 98 assert(instance); 120 ohci_batch_t *data = instance->private_data; 121 assert(data); 122 free32(data->ed); 123 free32(data->tds); 99 free32(instance->transport_buffer); 124 100 free32(instance->setup_buffer); 125 free32(instance->transport_buffer);126 free(data);127 101 free(instance); 128 }129 /*----------------------------------------------------------------------------*/130 bool batch_is_complete(usb_transfer_batch_t *instance)131 {132 assert(instance);133 ohci_batch_t *data = instance->private_data;134 assert(data);135 size_t tds = data->td_count - 1;136 usb_log_debug2("Batch(%p) checking %d td(s) for completion.\n",137 instance, tds);138 size_t i = 0;139 for (; i < tds; ++i) {140 if (!td_is_finished(&data->tds[i]))141 return false;142 instance->error = td_error(&data->tds[i]);143 /* FIXME: calculate real transfered size */144 instance->transfered_size = instance->buffer_size;145 if (instance->error != EOK) {146 usb_log_debug("Batch(%p) found error TD(%d):%x.\n",147 instance, i, data->tds[i].status);148 return true;149 // endpoint_toggle_set(instance->ep,150 }151 }152 return true;153 102 } 154 103 /*----------------------------------------------------------------------------*/ … … 160 109 instance->buffer_size); 161 110 instance->next_step = batch_call_out_and_dispose; 162 batch_control(instance, USB_DIRECTION_OUT, USB_DIRECTION_IN);111 /* TODO: implement */ 163 112 usb_log_debug("Batch(%p) CONTROL WRITE initialized.\n", instance); 164 113 } … … 168 117 assert(instance); 169 118 instance->next_step = batch_call_in_and_dispose; 170 batch_control(instance, USB_DIRECTION_IN, USB_DIRECTION_OUT);119 /* TODO: implement */ 171 120 usb_log_debug("Batch(%p) CONTROL READ initialized.\n", instance); 172 121 } … … 175 124 { 176 125 assert(instance); 177 assert(instance->direction == USB_DIRECTION_IN);126 instance->direction = USB_DIRECTION_IN; 178 127 instance->next_step = batch_call_in_and_dispose; 179 128 /* TODO: implement */ … … 184 133 { 185 134 assert(instance); 186 assert(instance->direction == USB_DIRECTION_OUT);135 instance->direction = USB_DIRECTION_OUT; 187 136 /* We are data out, we are supposed to provide data */ 188 137 memcpy(instance->transport_buffer, instance->buffer, … … 211 160 } 212 161 /*----------------------------------------------------------------------------*/ 213 ed_t * batch_ed(usb_transfer_batch_t *instance)214 {215 assert(instance);216 ohci_batch_t *data = instance->private_data;217 assert(data);218 return data->ed;219 }220 /*----------------------------------------------------------------------------*/221 void batch_control(usb_transfer_batch_t *instance,222 usb_direction_t data_dir, usb_direction_t status_dir)223 {224 assert(instance);225 ohci_batch_t *data = instance->private_data;226 assert(data);227 ed_init(data->ed, instance->ep);228 ed_add_tds(data->ed, &data->tds[0], &data->tds[data->td_count - 1]);229 usb_log_debug("Created ED: %x:%x:%x:%x.\n", data->ed->status,230 data->ed->td_tail, data->ed->td_head, data->ed->next);231 int toggle = 0;232 /* setup stage */233 td_init(&data->tds[0], USB_DIRECTION_BOTH, instance->setup_buffer,234 instance->setup_size, toggle);235 td_set_next(&data->tds[0], &data->tds[1]);236 usb_log_debug("Created SETUP TD: %x:%x:%x:%x.\n", data->tds[0].status,237 data->tds[0].cbp, data->tds[0].next, data->tds[0].be);238 239 /* data stage */240 size_t td_current = 1;241 size_t remain_size = instance->buffer_size;242 char *transfer_buffer = instance->transport_buffer;243 while (remain_size > 0) {244 size_t transfer_size = remain_size > OHCI_TD_MAX_TRANSFER ?245 OHCI_TD_MAX_TRANSFER : remain_size;246 toggle = 1 - toggle;247 248 td_init(&data->tds[td_current], data_dir, transfer_buffer,249 transfer_size, toggle);250 td_set_next(&data->tds[td_current], &data->tds[td_current + 1]);251 usb_log_debug("Created DATA TD: %x:%x:%x:%x.\n",252 data->tds[td_current].status, data->tds[td_current].cbp,253 data->tds[td_current].next, data->tds[td_current].be);254 255 transfer_buffer += transfer_size;256 remain_size -= transfer_size;257 assert(td_current < data->td_count - 2);258 ++td_current;259 }260 261 /* status stage */262 assert(td_current == data->td_count - 2);263 td_init(&data->tds[td_current], status_dir, NULL, 0, 1);264 usb_log_debug("Created STATUS TD: %x:%x:%x:%x.\n",265 data->tds[td_current].status, data->tds[td_current].cbp,266 data->tds[td_current].next, data->tds[td_current].be);267 }268 /*----------------------------------------------------------------------------*/269 162 /** Helper function calls callback and correctly disposes of batch structure. 270 163 * -
uspace/drv/ohci/batch.h
rc6394aa rb6c9e1e 26 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 27 */ 28 /** @addtogroup drvusb uhcihc28 /** @addtogroup drvusbohci 29 29 * @{ 30 30 */ 31 31 /** @file 32 * @brief UHCI driver USB transaction structure32 * @brief OHCI driver USB transaction structure 33 33 */ 34 #ifndef DRV_UHCI_BATCH_H 35 #define DRV_UHCI_BATCH_H 34 #ifndef DRV_OHCI_BATCH_H 35 #define DRV_OHCI_BATCH_H 36 36 37 37 38 #include <usbhc_iface.h> 38 39 #include <usb/usb.h> 39 40 #include <usb/host/device_keeper.h> 40 #include <usb/host/endpoint.h>41 41 #include <usb/host/batch.h> 42 42 43 #include "hw_struct/endpoint_descriptor.h"44 45 43 usb_transfer_batch_t * batch_get( 46 ddf_fun_t *fun, endpoint_t *ep, char *buffer, size_t size, 47 char *setup_buffer, size_t setup_size, 44 ddf_fun_t *fun, 45 usb_target_t target, 46 usb_transfer_type_t transfer_type, 47 size_t max_packet_size, 48 usb_speed_t speed, 49 char *buffer, 50 size_t size, 51 char *setup_buffer, 52 size_t setup_size, 48 53 usbhc_iface_transfer_in_callback_t func_in, 49 54 usbhc_iface_transfer_out_callback_t func_out, 50 void *arg); 55 void *arg, 56 usb_device_keeper_t *manager 57 ); 51 58 52 59 void batch_dispose(usb_transfer_batch_t *instance); 53 54 bool batch_is_complete(usb_transfer_batch_t *instance);55 60 56 61 void batch_control_write(usb_transfer_batch_t *instance); … … 65 70 66 71 void batch_bulk_out(usb_transfer_batch_t *instance); 67 68 ed_t * batch_ed(usb_transfer_batch_t *instance);69 72 #endif 70 73 /** -
uspace/drv/ohci/hc.c
rc6394aa rb6c9e1e 47 47 static void hc_gain_control(hc_t *instance); 48 48 static void hc_init_hw(hc_t *instance); 49 static int hc_init_transfer_lists(hc_t *instance);50 static int hc_init_memory(hc_t *instance);51 49 /*----------------------------------------------------------------------------*/ 52 50 int hc_register_hub(hc_t *instance, ddf_fun_t *hub_fun) … … 61 59 &instance->manager, hub_address, hub_fun->handle); 62 60 63 endpoint_t *ep = malloc(sizeof(endpoint_t));64 assert(ep);65 int ret = endpoint_init(ep, hub_address, 0, USB_DIRECTION_BOTH,66 USB_TRANSFER_CONTROL, USB_SPEED_FULL, 64);67 assert(ret == EOK);68 ret = usb_endpoint_manager_register_ep(&instance->ep_manager, ep, 0);69 assert(ret == EOK);70 71 61 char *match_str = NULL; 72 ret = asprintf(&match_str, "usb&class=hub");73 //ret = (match_str == NULL) ? ret : EOK;62 int ret = asprintf(&match_str, "usb&class=hub"); 63 ret = (match_str == NULL) ? ret : EOK; 74 64 if (ret < 0) { 75 usb_log_error( 76 "Failed(%d) to create root hub match-id string.\n", ret); 65 usb_log_error("Failed to create root hub match-id string.\n"); 77 66 return ret; 78 67 } … … 118 107 rh_init(&instance->rh, dev, instance->registers); 119 108 120 hc_init_memory(instance);121 109 hc_init_hw(instance); 122 110 … … 129 117 assert(instance); 130 118 assert(batch); 131 132 /* check for root hub communication */133 119 if (batch->target.address == instance->rh.address) { 134 120 return rh_request(&instance->rh, batch); 135 121 } 136 137 transfer_list_add_batch( 138 instance->transfers[batch->transfer_type], batch); 139 140 switch (batch->transfer_type) { 141 case USB_TRANSFER_CONTROL: 142 instance->registers->command_status |= CS_CLF; 143 break; 144 case USB_TRANSFER_BULK: 145 instance->registers->command_status |= CS_BLF; 146 break; 147 default: 148 break; 149 } 150 return EOK; 122 /* TODO: implement */ 123 return ENOTSUP; 151 124 } 152 125 /*----------------------------------------------------------------------------*/ … … 161 134 usb_log_info("OHCI interrupt: %x.\n", status); 162 135 163 LIST_INITIALIZE(done); 164 transfer_list_remove_finished(&instance->transfers_interrupt, &done); 165 transfer_list_remove_finished(&instance->transfers_isochronous, &done); 166 transfer_list_remove_finished(&instance->transfers_control, &done); 167 transfer_list_remove_finished(&instance->transfers_bulk, &done); 168 169 while (!list_empty(&done)) { 170 link_t *item = done.next; 171 list_remove(item); 172 usb_transfer_batch_t *batch = 173 list_get_instance(item, usb_transfer_batch_t, link); 174 usb_transfer_batch_finish(batch); 175 } 136 /* TODO: Check for further interrupt causes */ 137 /* TODO: implement */ 176 138 } 177 139 /*----------------------------------------------------------------------------*/ … … 235 197 assert(instance); 236 198 const uint32_t fm_interval = instance->registers->fm_interval; 237 238 /* reset hc */239 199 instance->registers->command_status = CS_HCR; 240 200 async_usleep(10); 241 242 /* restore fm_interval */243 201 instance->registers->fm_interval = fm_interval; 244 202 assert((instance->registers->command_status & CS_HCR) == 0); 245 246 203 /* hc is now in suspend state */ 247 248 /* enablequeues */249 instance->registers->control |= (C_PLE | C_IE | C_CLE | C_BLE);204 /* TODO: init HCCA block */ 205 /* TODO: init queues */ 206 /* TODO: enable queues */ 250 207 /* TODO: enable interrupts */ 251 /* set periodic start to 90% */ 252 instance->registers->periodic_start = (fm_interval / 10) * 9; 208 /* TODO: set periodic start to 90% */ 253 209 254 210 instance->registers->control &= (C_HCFS_OPERATIONAL << C_HCFS_SHIFT); 255 211 usb_log_info("OHCI HC up and running.\n"); 256 212 } 257 /*----------------------------------------------------------------------------*/258 int hc_init_transfer_lists(hc_t *instance)259 {260 assert(instance);261 262 #define SETUP_TRANSFER_LIST(type, name) \263 do { \264 int ret = transfer_list_init(&instance->type, name); \265 if (ret != EOK) { \266 usb_log_error("Failed(%d) to setup %s transfer list.\n", \267 ret, name); \268 transfer_list_fini(&instance->transfers_isochronous); \269 transfer_list_fini(&instance->transfers_interrupt); \270 transfer_list_fini(&instance->transfers_control); \271 transfer_list_fini(&instance->transfers_bulk); \272 } \273 } while (0)274 275 SETUP_TRANSFER_LIST(transfers_isochronous, "ISOCHRONOUS");276 SETUP_TRANSFER_LIST(transfers_interrupt, "INTERRUPT");277 SETUP_TRANSFER_LIST(transfers_control, "CONTROL");278 SETUP_TRANSFER_LIST(transfers_bulk, "BULK");279 280 transfer_list_set_next(&instance->transfers_interrupt,281 &instance->transfers_isochronous);282 283 /* Assign pointers to be used during scheduling */284 instance->transfers[USB_TRANSFER_INTERRUPT] =285 &instance->transfers_interrupt;286 instance->transfers[USB_TRANSFER_ISOCHRONOUS] =287 &instance->transfers_interrupt;288 instance->transfers[USB_TRANSFER_CONTROL] =289 &instance->transfers_control;290 instance->transfers[USB_TRANSFER_BULK] =291 &instance->transfers_bulk;292 293 return EOK;294 #undef CHECK_RET_CLEAR_RETURN295 }296 /*----------------------------------------------------------------------------*/297 int hc_init_memory(hc_t *instance)298 {299 assert(instance);300 /* init queues */301 hc_init_transfer_lists(instance);302 303 /* init HCCA */304 instance->hcca = malloc32(sizeof(hcca_t));305 if (instance->hcca == NULL)306 return ENOMEM;307 bzero(instance->hcca, sizeof(hcca_t));308 instance->registers->hcca = addr_to_phys(instance->hcca);309 310 /* use queues */311 instance->registers->bulk_head = instance->transfers_bulk.list_head_pa;312 instance->registers->control_head =313 instance->transfers_control.list_head_pa;314 315 unsigned i = 0;316 for (; i < 32; ++i) {317 instance->hcca->int_ep[i] =318 instance->transfers_interrupt.list_head_pa;319 }320 321 return EOK;322 }323 213 /** 324 214 * @} -
uspace/drv/ohci/hc.h
rc6394aa rb6c9e1e 48 48 #include "ohci_regs.h" 49 49 #include "root_hub.h" 50 #include "transfer_list.h"51 50 #include "hw_struct/hcca.h" 52 51 … … 55 54 usb_address_t rh_address; 56 55 rh_t rh; 57 58 hcca_t *hcca;59 60 transfer_list_t transfers_isochronous;61 transfer_list_t transfers_interrupt;62 transfer_list_t transfers_control;63 transfer_list_t transfers_bulk;64 65 transfer_list_t *transfers[4];66 67 56 ddf_fun_t *ddf_instance; 68 57 usb_device_keeper_t manager; -
uspace/drv/ohci/hw_struct/completion_codes.h
rc6394aa rb6c9e1e 35 35 #define DRV_OHCI_HW_STRUCT_COMPLETION_CODES_H 36 36 37 #include <errno.h>38 39 37 #define CC_NOERROR (0x0) 40 38 #define CC_CRC (0x1) … … 52 50 #define CC_NOACCESS2 (0xf) 53 51 54 inline static int cc_to_rc(int cc)55 {56 switch (cc) {57 case CC_NOERROR:58 return EOK;59 60 case CC_CRC:61 return EBADCHECKSUM;62 63 case CC_PIDUNEXPECTED:64 case CC_PIDFAIL:65 case CC_BITSTUFF:66 return EIO;67 68 case CC_TOGGLE:69 case CC_STALL:70 return ESTALL;71 72 case CC_NORESPONSE:73 return ETIMEOUT;74 75 case CC_DATAOVERRRUN:76 case CC_DATAUNDERRRUN:77 case CC_BUFFEROVERRRUN:78 case CC_BUFFERUNDERRUN:79 return EOVERFLOW;80 81 case CC_NOACCESS1:82 case CC_NOACCESS2:83 default:84 return ENOTSUP;85 }86 }87 88 52 #endif 89 53 /** -
uspace/drv/ohci/hw_struct/endpoint_descriptor.h
rc6394aa rb6c9e1e 35 35 #define DRV_OHCI_HW_STRUCT_ENDPOINT_DESCRIPTOR_H 36 36 37 #include <assert.h>38 37 #include <stdint.h> 39 40 #include <usb/host/endpoint.h>41 42 #include "utils/malloc32.h"43 #include "transfer_descriptor.h"44 38 45 39 #include "completion_codes.h" … … 50 44 #define ED_STATUS_FA_SHIFT (0) 51 45 #define ED_STATUS_EN_MASK (0xf) /* USB endpoint address */ 52 #define ED_STATUS_EN_SHIFT ( 7)46 #define ED_STATUS_EN_SHIFT (6) 53 47 #define ED_STATUS_D_MASK (0x3) /* direction */ 54 #define ED_STATUS_D_SHIFT (1 1)48 #define ED_STATUS_D_SHIFT (10) 55 49 #define ED_STATUS_D_IN (0x1) 56 50 #define ED_STATUS_D_OUT (0x2) 57 #define ED_STATUS_D_TRANSFER (0x3)58 51 59 #define ED_STATUS_S_FLAG (1 << 13) /* speed flag : 1 = low*/52 #define ED_STATUS_S_FLAG (1 << 13) /* speed flag */ 60 53 #define ED_STATUS_K_FLAG (1 << 14) /* skip flag (no not execute this ED) */ 61 54 #define ED_STATUS_F_FLAG (1 << 15) /* format: 1 = isochronous*/ … … 78 71 #define ED_NEXT_PTR_SHIFT (0) 79 72 } __attribute__((packed)) ed_t; 80 81 void ed_init(ed_t *instance, endpoint_t *ep);82 83 static inline void ed_add_tds(ed_t *instance, td_t *head, td_t *tail)84 {85 assert(instance);86 instance->td_head = addr_to_phys(head) & ED_TDHEAD_PTR_MASK;87 instance->td_tail = addr_to_phys(tail) & ED_TDTAIL_PTR_MASK;88 }89 90 static inline void ed_append_ed(ed_t *instance, ed_t *next)91 {92 assert(instance);93 assert(next);94 uint32_t pa = addr_to_phys(next);95 assert((pa & ED_NEXT_PTR_MASK) << ED_NEXT_PTR_SHIFT == pa);96 instance->next = pa;97 }98 99 73 #endif 100 74 /** -
uspace/drv/ohci/hw_struct/transfer_descriptor.h
rc6394aa rb6c9e1e 35 35 #define DRV_OHCI_HW_STRUCT_TRANSFER_DESCRIPTOR_H 36 36 37 #include <bool.h>38 37 #include <stdint.h> 39 #include "utils/malloc32.h"40 38 41 39 #include "completion_codes.h" 42 43 /* OHCI TDs can handle up to 8KB buffers */44 #define OHCI_TD_MAX_TRANSFER (8 * 1024)45 40 46 41 typedef struct td { … … 57 52 #define TD_STATUS_T_MASK (0x3) /* data toggle 1x = use ED toggle carry */ 58 53 #define TD_STATUS_T_SHIFT (24) 59 #define TD_STATUS_T_0 (0x2)60 #define TD_STATUS_T_1 (0x3)61 54 #define TD_STATUS_EC_MASK (0x3) /* error count */ 62 55 #define TD_STATUS_EC_SHIFT (26) … … 71 64 volatile uint32_t be; /* buffer end, address of the last byte */ 72 65 } __attribute__((packed)) td_t; 73 74 void td_init(75 td_t *instance, usb_direction_t dir, void *buffer, size_t size, int toggle);76 77 inline static void td_set_next(td_t *instance, td_t *next)78 {79 assert(instance);80 instance->next = addr_to_phys(next) & TD_NEXT_PTR_MASK;81 }82 83 inline static bool td_is_finished(td_t *instance)84 {85 assert(instance);86 int cc = (instance->status >> TD_STATUS_CC_SHIFT) & TD_STATUS_CC_MASK;87 /* something went wrong, error code is set */88 if (cc != CC_NOACCESS1 && cc != CC_NOACCESS2 && cc != CC_NOERROR) {89 return true;90 }91 /* everything done */92 if (cc == CC_NOERROR && instance->cbp == 0) {93 return true;94 }95 return false;96 }97 98 static inline int td_error(td_t *instance)99 {100 assert(instance);101 int cc = (instance->status >> TD_STATUS_CC_SHIFT) & TD_STATUS_CC_MASK;102 return cc_to_rc(cc);103 }104 66 #endif 105 67 /** -
uspace/drv/ohci/iface.c
rc6394aa rb6c9e1e 1 1 /* 2 * Copyright (c) 2011 Vojtech Horky , Jan Vesely2 * Copyright (c) 2011 Vojtech Horky 3 3 * All rights reserved. 4 4 * … … 30 30 */ 31 31 /** @file 32 * @brief OHCI driver hc interface implementation32 * USB-HC interface implementation. 33 33 */ 34 34 #include <ddf/driver.h> … … 36 36 37 37 #include <usb/debug.h> 38 #include <usb/host/endpoint.h>39 38 40 39 #include "iface.h" 41 40 #include "hc.h" 42 41 43 static inline int setup_batch( 44 ddf_fun_t *fun, usb_target_t target, usb_direction_t direction, 45 void *data, size_t size, void * setup_data, size_t setup_size, 46 usbhc_iface_transfer_in_callback_t in, 47 usbhc_iface_transfer_out_callback_t out, void *arg, const char* name, 48 hc_t **hc, usb_transfer_batch_t **batch) 49 { 50 assert(hc); 51 assert(batch); 52 assert(fun); 53 *hc = fun_to_hc(fun); 54 assert(*hc); 55 56 size_t res_bw; 57 endpoint_t *ep = usb_endpoint_manager_get_ep(&(*hc)->ep_manager, 58 target.address, target.endpoint, direction, &res_bw); 59 if (ep == NULL) { 60 usb_log_error("Endpoint(%d:%d) not registered for %s.\n", 61 target.address, target.endpoint, name); 62 return ENOENT; 63 } 64 65 const size_t bw = bandwidth_count_usb11( 66 ep->speed, ep->transfer_type, size, ep->max_packet_size); 67 if (res_bw < bw) { 68 usb_log_error("Endpoint(%d:%d) %s needs %zu bw " 69 "but only %zu is reserved.\n", 70 name, target.address, target.endpoint, bw, res_bw); 71 return ENOSPC; 72 } 73 usb_log_debug("%s %d:%d %zu(%zu).\n", 74 name, target.address, target.endpoint, size, ep->max_packet_size); 75 76 assert(ep->speed == 77 usb_device_keeper_get_speed(&(*hc)->manager, target.address)); 78 // assert(ep->max_packet_size == max_packet_size); 79 // assert(ep->transfer_type == USB_TRANSFER_CONTROL); 80 81 *batch = 82 batch_get(fun, ep, data, size, setup_data, setup_size, 83 in, out, arg); 84 if (!batch) 85 return ENOMEM; 86 return EOK; 87 } 88 89 90 /** Reserve default address interface function 91 * 92 * @param[in] fun DDF function that was called. 93 * @param[in] speed Speed to associate with the new default address. 42 #define UNSUPPORTED(methodname) \ 43 usb_log_warning("Unsupported interface method `%s()' in %s:%d.\n", \ 44 methodname, __FILE__, __LINE__) 45 46 /** Reserve default address. 47 * 48 * This function may block the caller. 49 * 50 * @param[in] fun Device function the action was invoked on. 51 * @param[in] speed Speed of the device for which the default address is 52 * reserved. 94 53 * @return Error code. 95 54 */ … … 102 61 usb_device_keeper_reserve_default_address(&hc->manager, speed); 103 62 return EOK; 104 #if 0 105 endpoint_t *ep = malloc(sizeof(endpoint_t)); 106 if (ep == NULL) 107 return ENOMEM; 108 const size_t max_packet_size = speed == USB_SPEED_LOW ? 8 : 64; 109 endpoint_init(ep, USB_TRANSFER_CONTROL, speed, max_packet_size); 110 int ret; 111 try_retgister: 112 ret = usb_endpoint_manager_register_ep(&hc->ep_manager, 113 USB_ADDRESS_DEFAULT, 0, USB_DIRECTION_BOTH, ep, endpoint_destroy, 0); 114 if (ret == EEXISTS) { 115 async_usleep(1000); 116 goto try_retgister; 117 } 118 if (ret != EOK) { 119 endpoint_destroy(ep); 120 } 121 return ret; 122 #endif 123 } 124 /*----------------------------------------------------------------------------*/ 125 /** Release default address interface function 126 * 127 * @param[in] fun DDF function that was called. 63 } 64 /*----------------------------------------------------------------------------*/ 65 /** Release default address. 66 * 67 * @param[in] fun Device function the action was invoked on. 128 68 * @return Error code. 129 69 */ … … 134 74 assert(hc); 135 75 usb_log_debug("Default address release.\n"); 136 // return usb_endpoint_manager_unregister_ep(&hc->ep_manager,137 // USB_ADDRESS_DEFAULT, 0, USB_DIRECTION_BOTH);138 76 usb_device_keeper_release_default_address(&hc->manager); 139 77 return EOK; 140 78 } 141 79 /*----------------------------------------------------------------------------*/ 142 /** Request address interface function143 * 144 * @param[in] fun D DF function that was called.145 * @param[in] speed Speed to associate with the new defaultaddress.146 * @param[out] address Place to write a newaddress.80 /** Found free USB address. 81 * 82 * @param[in] fun Device function the action was invoked on. 83 * @param[in] speed Speed of the device that will get this address. 84 * @param[out] address Non-null pointer where to store the free address. 147 85 * @return Error code. 148 86 */ … … 163 101 } 164 102 /*----------------------------------------------------------------------------*/ 165 /** Bind address interface function166 * 167 * @param[in] fun D DF function that was called.168 * @param[in] address Address of the device169 * @param[in] handle Devman handle of the device driver.103 /** Bind USB address with device devman handle. 104 * 105 * @param[in] fun Device function the action was invoked on. 106 * @param[in] address USB address of the device. 107 * @param[in] handle Devman handle of the device. 170 108 * @return Error code. 171 109 */ 172 110 static int bind_address( 173 ddf_fun_t *fun, usb_address_t address, devman_handle_t handle)111 ddf_fun_t *fun, usb_address_t address, devman_handle_t handle) 174 112 { 175 113 assert(fun); … … 181 119 } 182 120 /*----------------------------------------------------------------------------*/ 183 /** Release address interface function184 * 185 * @param[in] fun D DF function that was called.121 /** Release previously requested address. 122 * 123 * @param[in] fun Device function the action was invoked on. 186 124 * @param[in] address USB address to be released. 187 125 * @return Error code. … … 214 152 size_t max_packet_size, unsigned int interval) 215 153 { 154 assert(fun); 216 155 hc_t *hc = fun_to_hc(fun); 217 156 assert(hc); … … 222 161 speed = ep_speed; 223 162 } 224 const size_t size = 225 (transfer_type == USB_TRANSFER_INTERRUPT 226 || transfer_type == USB_TRANSFER_ISOCHRONOUS) ? 227 max_packet_size : 0; 228 int ret; 229 230 endpoint_t *ep = malloc(sizeof(endpoint_t)); 231 if (ep == NULL) 232 return ENOMEM; 233 ret = endpoint_init(ep, address, endpoint, direction, 234 transfer_type, speed, max_packet_size); 235 if (ret != EOK) { 236 free(ep); 237 return ret; 238 } 239 163 const size_t size = max_packet_size; 240 164 usb_log_debug("Register endpoint %d:%d %s %s(%d) %zu(%zu) %u.\n", 241 165 address, endpoint, usb_str_transfer_type(transfer_type), 242 166 usb_str_speed(speed), direction, size, max_packet_size, interval); 243 244 ret = usb_endpoint_manager_register_ep(&hc->ep_manager, ep, size); 245 if (ret != EOK) { 246 endpoint_destroy(ep); 247 } else { 248 usb_device_keeper_add_ep(&hc->manager, address, ep); 249 } 250 return ret; 251 } 252 /*----------------------------------------------------------------------------*/ 167 // TODO use real endpoint here! 168 return usb_endpoint_manager_register_ep(&hc->ep_manager,NULL, 0); 169 } 170 /*----------------------------------------------------------------------------*/ 171 /** Unregister endpoint (free some bandwidth reservation). 172 * 173 * @param[in] fun Device function the action was invoked on. 174 * @param[in] address USB address of the device. 175 * @param[in] endpoint Endpoint number. 176 * @param[in] direction Endpoint data direction. 177 * @return Error code. 178 */ 253 179 static int unregister_endpoint( 254 180 ddf_fun_t *fun, usb_address_t address, 255 181 usb_endpoint_t endpoint, usb_direction_t direction) 256 182 { 183 assert(fun); 257 184 hc_t *hc = fun_to_hc(fun); 258 185 assert(hc); … … 288 215 size_t size, usbhc_iface_transfer_out_callback_t callback, void *arg) 289 216 { 290 usb_transfer_batch_t *batch = NULL; 291 hc_t *hc = NULL; 292 int ret = setup_batch(fun, target, USB_DIRECTION_OUT, data, size, 293 NULL, 0, NULL, callback, arg, "Interrupt OUT", &hc, &batch); 294 if (ret != EOK) 295 return ret; 217 assert(fun); 218 219 // FIXME: get from endpoint manager 220 size_t max_packet_size = 8; 221 222 hc_t *hc = fun_to_hc(fun); 223 assert(hc); 224 usb_speed_t speed = 225 usb_device_keeper_get_speed(&hc->manager, target.address); 226 227 usb_log_debug("Interrupt OUT %d:%d %zu(%zu).\n", 228 target.address, target.endpoint, size, max_packet_size); 229 230 usb_transfer_batch_t *batch = 231 batch_get(fun, target, USB_TRANSFER_INTERRUPT, max_packet_size, 232 speed, data, size, NULL, 0, NULL, callback, arg, &hc->manager); 233 if (!batch) 234 return ENOMEM; 296 235 batch_interrupt_out(batch); 297 ret = hc_schedule(hc, batch);236 const int ret = hc_schedule(hc, batch); 298 237 if (ret != EOK) { 299 238 batch_dispose(batch); … … 322 261 size_t size, usbhc_iface_transfer_in_callback_t callback, void *arg) 323 262 { 324 usb_transfer_batch_t *batch = NULL; 325 hc_t *hc = NULL; 326 int ret = setup_batch(fun, target, USB_DIRECTION_IN, data, size, 327 NULL, 0, callback, NULL, arg, "Interrupt IN", &hc, &batch); 328 if (ret != EOK) 329 return ret; 263 assert(fun); 264 265 // FIXME: get from endpoint manager 266 size_t max_packet_size = 8; 267 268 hc_t *hc = fun_to_hc(fun); 269 assert(hc); 270 usb_speed_t speed = 271 usb_device_keeper_get_speed(&hc->manager, target.address); 272 usb_log_debug("Interrupt IN %d:%d %zu(%zu).\n", 273 target.address, target.endpoint, size, max_packet_size); 274 275 usb_transfer_batch_t *batch = 276 batch_get(fun, target, USB_TRANSFER_INTERRUPT, max_packet_size, 277 speed, data, size, NULL, 0, callback, NULL, arg, &hc->manager); 278 if (!batch) 279 return ENOMEM; 330 280 batch_interrupt_in(batch); 331 ret = hc_schedule(hc, batch);281 const int ret = hc_schedule(hc, batch); 332 282 if (ret != EOK) { 333 283 batch_dispose(batch); … … 356 306 size_t size, usbhc_iface_transfer_out_callback_t callback, void *arg) 357 307 { 358 usb_transfer_batch_t *batch = NULL; 359 hc_t *hc = NULL; 360 int ret = setup_batch(fun, target, USB_DIRECTION_OUT, data, size, 361 NULL, 0, NULL, callback, arg, "Bulk OUT", &hc, &batch); 362 if (ret != EOK) 363 return ret; 308 assert(fun); 309 310 // FIXME: get from endpoint manager 311 size_t max_packet_size = 8; 312 313 hc_t *hc = fun_to_hc(fun); 314 assert(hc); 315 usb_speed_t speed = 316 usb_device_keeper_get_speed(&hc->manager, target.address); 317 318 usb_log_debug("Bulk OUT %d:%d %zu(%zu).\n", 319 target.address, target.endpoint, size, max_packet_size); 320 321 usb_transfer_batch_t *batch = 322 batch_get(fun, target, USB_TRANSFER_BULK, max_packet_size, speed, 323 data, size, NULL, 0, NULL, callback, arg, &hc->manager); 324 if (!batch) 325 return ENOMEM; 364 326 batch_bulk_out(batch); 365 ret = hc_schedule(hc, batch);327 const int ret = hc_schedule(hc, batch); 366 328 if (ret != EOK) { 367 329 batch_dispose(batch); … … 390 352 size_t size, usbhc_iface_transfer_in_callback_t callback, void *arg) 391 353 { 392 usb_transfer_batch_t *batch = NULL; 393 hc_t *hc = NULL; 394 int ret = setup_batch(fun, target, USB_DIRECTION_IN, data, size, 395 NULL, 0, callback, NULL, arg, "Bulk IN", &hc, &batch); 396 if (ret != EOK) 397 return ret; 354 assert(fun); 355 356 // FIXME: get from endpoint manager 357 size_t max_packet_size = 8; 358 359 hc_t *hc = fun_to_hc(fun); 360 assert(hc); 361 usb_speed_t speed = 362 usb_device_keeper_get_speed(&hc->manager, target.address); 363 usb_log_debug("Bulk IN %d:%d %zu(%zu).\n", 364 target.address, target.endpoint, size, max_packet_size); 365 366 usb_transfer_batch_t *batch = 367 batch_get(fun, target, USB_TRANSFER_BULK, max_packet_size, speed, 368 data, size, NULL, 0, callback, NULL, arg, &hc->manager); 369 if (!batch) 370 return ENOMEM; 398 371 batch_bulk_in(batch); 399 ret = hc_schedule(hc, batch);372 const int ret = hc_schedule(hc, batch); 400 373 if (ret != EOK) { 401 374 batch_dispose(batch); … … 428 401 usbhc_iface_transfer_out_callback_t callback, void *arg) 429 402 { 430 usb_transfer_batch_t *batch = NULL; 431 hc_t *hc = NULL; 432 int ret = setup_batch(fun, target, USB_DIRECTION_BOTH, data, size, 433 setup_data, setup_size, NULL, callback, arg, "Control WRITE", 434 &hc, &batch); 435 if (ret != EOK) 436 return ret; 403 assert(fun); 404 405 // FIXME: get from endpoint manager 406 size_t max_packet_size = 8; 407 408 hc_t *hc = fun_to_hc(fun); 409 assert(hc); 410 usb_speed_t speed = 411 usb_device_keeper_get_speed(&hc->manager, target.address); 412 usb_log_debug("Control WRITE (%d) %d:%d %zu(%zu).\n", 413 speed, target.address, target.endpoint, size, max_packet_size); 414 415 if (setup_size != 8) 416 return EINVAL; 417 418 usb_transfer_batch_t *batch = 419 batch_get(fun, target, USB_TRANSFER_CONTROL, max_packet_size, 420 speed, data, size, setup_data, setup_size, NULL, callback, arg, 421 &hc->manager); 422 if (!batch) 423 return ENOMEM; 437 424 usb_device_keeper_reset_if_need(&hc->manager, target, setup_data); 438 425 batch_control_write(batch); 439 ret = hc_schedule(hc, batch);426 const int ret = hc_schedule(hc, batch); 440 427 if (ret != EOK) { 441 428 batch_dispose(batch); … … 468 455 usbhc_iface_transfer_in_callback_t callback, void *arg) 469 456 { 470 usb_transfer_batch_t *batch = NULL; 471 hc_t *hc = NULL; 472 int ret = setup_batch(fun, target, USB_DIRECTION_BOTH, data, size, 473 setup_data, setup_size, callback, NULL, arg, "Control READ", 474 &hc, &batch); 475 if (ret != EOK) 476 return ret; 457 assert(fun); 458 459 // FIXME: get from endpoint manager 460 size_t max_packet_size = 8; 461 462 hc_t *hc = fun_to_hc(fun); 463 assert(hc); 464 usb_speed_t speed = 465 usb_device_keeper_get_speed(&hc->manager, target.address); 466 467 usb_log_debug("Control READ(%d) %d:%d %zu(%zu).\n", 468 speed, target.address, target.endpoint, size, max_packet_size); 469 usb_transfer_batch_t *batch = 470 batch_get(fun, target, USB_TRANSFER_CONTROL, max_packet_size, 471 speed, data, size, setup_data, setup_size, callback, NULL, arg, 472 &hc->manager); 473 if (!batch) 474 return ENOMEM; 477 475 batch_control_read(batch); 478 ret = hc_schedule(hc, batch);476 const int ret = hc_schedule(hc, batch); 479 477 if (ret != EOK) { 480 478 batch_dispose(batch); … … 483 481 } 484 482 /*----------------------------------------------------------------------------*/ 483 /** Host controller interface implementation for OHCI. */ 485 484 usbhc_iface_t hc_iface = { 486 485 .reserve_default_address = reserve_default_address, … … 502 501 .control_read = control_read, 503 502 }; 503 504 504 /** 505 505 * @} -
uspace/drv/ohci/ohci_regs.h
rc6394aa rb6c9e1e 41 41 const volatile uint32_t revision; 42 42 volatile uint32_t control; 43 #define C_CSBR_MASK (0x3) /* Control-bulk service ratio */ 44 #define C_CSBR_1_1 (0x0) 45 #define C_CSBR_1_2 (0x1) 46 #define C_CSBR_1_3 (0x2) 47 #define C_CSBR_1_4 (0x3) 43 #define C_CSBR_MASK (0x3) 48 44 #define C_CSBR_SHIFT (0) 45 #define C_PLE (1 << 2) 46 #define C_IE (1 << 3) 47 #define C_CLE (1 << 4) 48 #define C_BLE (1 << 5) 49 49 50 #define C_PLE (1 << 2) /* Periodic list enable */ 51 #define C_IE (1 << 3) /* Isochronous enable */ 52 #define C_CLE (1 << 4) /* Control list enable */ 53 #define C_BLE (1 << 5) /* Bulk list enable */ 50 #define C_HCFS_MASK (0x3) 51 #define C_HCFS_SHIFT (6) 52 #define C_HCFS_RESET (0x0) 53 #define C_HCFS_OPERATIONAL (0x1) 54 #define C_HCFS_RESUME (0x2) 55 #define C_HCFS_SUSPEND (0x3) 54 56 55 #define C_HCFS_MASK (0x3) /* Host controller functional state */ 56 #define C_HCFS_RESET (0x0) 57 #define C_HCFS_OPERATIONAL (0x1) 58 #define C_HCFS_RESUME (0x2) 59 #define C_HCFS_SUSPEND (0x3) 60 #define C_HCFS_SHIFT (6) 61 62 #define C_IR (1 << 8) /* Interrupt routing, make sure it's 0 */ 63 #define C_RWC (1 << 9) /* Remote wakeup connected, host specific */ 64 #define C_RWE (1 << 10) /* Remote wakeup enable */ 57 #define C_IR (1 << 8) 58 #define C_RWC (1 << 9) 59 #define C_RWE (1 << 10) 65 60 66 61 volatile uint32_t command_status; 67 #define CS_HCR (1 << 0) /* Host controller reset */68 #define CS_CLF (1 << 1) /* Control list filled */69 #define CS_BLF (1 << 2) /* Bulk list filled */70 #define CS_OCR (1 << 3) /* Ownership change request */71 #define CS_SOC_MASK (0x3) /* Scheduling overrun count */62 #define CS_HCR (1 << 0) 63 #define CS_CLF (1 << 1) 64 #define CS_BLF (1 << 2) 65 #define CS_OCR (1 << 3) 66 #define CS_SOC_MASK (0x3) 72 67 #define CS_SOC_SHIFT (16) 73 68 74 69 volatile uint32_t interrupt_status; 75 #define IS_SO (1 << 0) /* Scheduling overrun */76 #define IS_WDH (1 << 1) /* Write-back done head */77 #define IS_SF (1 << 2) /* Start of frame */78 #define IS_RD (1 << 3) /* Resume detected */79 #define IS_UE (1 << 4) /* Unrecoverable error */80 #define IS_FNO (1 << 5) /* Frame number overflow */81 #define IS_RHSC (1 << 6) /* Root hub status change */82 #define IS_OC (1 << 30) /* Ownership change */70 #define IS_SO (1 << 0) 71 #define IS_WDH (1 << 1) 72 #define IS_SF (1 << 2) 73 #define IS_RD (1 << 3) 74 #define IS_UE (1 << 4) 75 #define IS_FNO (1 << 5) 76 #define IS_RHSC (1 << 6) 77 #define IS_OC (1 << 30) 83 78 84 /** Interupt enable/disable, reads give the same value, writing causes85 * enable/disable */86 79 volatile uint32_t interupt_enable; 80 #define IE_SO (1 << 0) 81 #define IE_WDH (1 << 1) 82 #define IE_SF (1 << 2) 83 #define IE_RD (1 << 3) 84 #define IE_UE (1 << 4) 85 #define IE_FNO (1 << 5) 86 #define IE_RHSC (1 << 6) 87 #define IE_OC (1 << 30) 88 #define IE_MIE (1 << 31) 89 87 90 volatile uint32_t interrupt_disable; 88 #define I_SO (1 << 0) /* Scheduling overrun */89 #define I_WDH (1 << 1) /* Done head write-back */90 #define I_SF (1 << 2) /* Start of frame */91 #define I_RD (1 << 3) /* Resume detect */92 #define I_UE (1 << 4) /* Unrecoverable error */93 #define I_FNO (1 << 5) /* Frame number overflow */94 #define I_RHSC (1 << 6) /* Root hub status change */95 #define I_OC (1 << 30) /* Ownership change */96 #define I_MI (1 << 31) /* Master interrupt (all/any interrupts) */97 98 /** HCCA pointer (see hw_struct hcca.h) */99 91 volatile uint32_t hcca; 100 #define HCCA_PTR_MASK 0xffffff00 /* HCCA is 256B aligned */ 101 102 /** Currently executed period endpoint */ 103 const volatile uint32_t period_current; 104 105 /** The first control endpoint */ 92 volatile uint32_t period_corrent; 106 93 volatile uint32_t control_head; 107 108 /** Currently executed control endpoint */109 94 volatile uint32_t control_current; 110 111 /** The first bulk endpoint */112 95 volatile uint32_t bulk_head; 113 114 /** Currently executed bulk endpoint */115 96 volatile uint32_t bulk_current; 116 117 /** Done TD list, this value is periodically written to HCCA */ 118 const volatile uint32_t done_head; 119 120 /** Frame time and max packet size for all transfers */ 97 volatile uint32_t done_head; 121 98 volatile uint32_t fm_interval; 122 #define FMI_FI_MASK (0x1fff) /* Frame interval in bit times (should be 11999)*/ 123 #define FMI_FI_SHIFT (0) 124 #define FMI_FSMPS_MASK (0x7fff) /* Full speed max packet size */ 125 #define FMI_FSMPS_SHIFT (16) 126 #define FMI_TOGGLE_FLAG (1 << 31) 127 128 /** Bit times remaining in current frame */ 129 const volatile uint32_t fm_remaining; 130 #define FMR_FR_MASK FMI_FI_MASK 131 #define FMR_FR_SHIFT FMI_FI_SHIFT 132 #define FMR_TOGGLE_FLAG FMI_TOGGLE_FLAG 133 134 /** Frame number */ 135 const volatile uint32_t fm_number; 136 #define FMN_NUMBER_MASK (0xffff) 137 138 /** Remaining bit time in frame to start periodic transfers */ 99 volatile uint32_t fm_remaining; 100 volatile uint32_t fm_number; 139 101 volatile uint32_t periodic_start; 140 #define PS_PS_MASK (0x1fff) /* bit time when periodic get priority (0x3e67) */141 142 /** Threshold for starting LS transaction */143 102 volatile uint32_t ls_threshold; 144 #define LST_LST_MASK (0x7fff)145 146 /** The first root hub control register */147 103 volatile uint32_t rh_desc_a; 148 #define RHDA_NDS_MASK (0xff) /* Number of downstream ports, max 15 */149 #define RHDA_NDS_SHIFT (0)150 #define RHDA_PSM_FLAG (1 << 8) /* Power switching mode: 0-global, 1-per port*/151 #define RHDA_NPS_FLAG (1 << 9) /* No power switch: 1-power on, 0-use PSM*/152 #define RHDA_DT_FLAG (1 << 10) /* 1-Compound device, must be 0 */153 #define RHDA_OCPM_FLAG (1 << 11) /* Over-current mode: 0-global, 1-per port */154 #define RHDA_NOCP (1 << 12) /* OC control: 0-use OCPM, 1-OC off */155 #define RHDA_POTPGT_MASK (0xff) /* Power on to power good time */156 #define RHDA_POTPGT_SHIFT (24)157 158 /** The other root hub control register */159 104 volatile uint32_t rh_desc_b; 160 #define RHDB_DR_MASK (0xffff) /* Device removable mask */161 #define RHDB_DR_SHIFT (0)162 #define RHDB_PCC_MASK (0xffff) /* Power control mask */163 #define RHDB_PCC_SHIFT (16)164 165 /* Port device removable status */166 #define RHDB_DR_FLAG(port) (((1 << port) & RHDB_DR_MASK) << RHDB_DR_SHIFT)167 /* Port power control status: 1-per port power control, 0-global power switch */168 #define RHDB_PPC_FLAG(port) (((1 << port) & RHDB_DR_MASK) << RHDB_DR_SHIFT)169 170 /** Root hub status register */171 105 volatile uint32_t rh_status; 172 #define RHS_LPS_FLAG (1 << 0)/* read: 0,173 * write: 0-no effect,174 * 1-turn off port power for ports175 * specified in PPCM(RHDB), or all ports,176 * if power is set globally */177 #define RHS_CLEAR_PORT_POWER RHS_LPS_FLAG /* synonym for the above */178 #define RHS_OCI_FLAG (1 << 1)/* Over-current indicator, if per-port: 0 */179 #define RHS_DRWE_FLAG (1 << 15)/* read: 0-connect status change does not wake HC180 * 1-connect status change wakes HC181 * write: 1-set DRWE, 0-no effect */182 #define RHS_SET_DRWE RHS_DRWE_FLAG183 #define RHS_LPSC_FLAG (1 << 16)/* read: 0,184 * write: 0-no effect185 * 1-turn on port power for ports186 * specified in PPCM(RHDB), or all ports,187 * if power is set globally */188 #define RHS_SET_PORT_POWER RHS_LPSC_FLAG /* synonym for the above */189 #define RHS_OCIC_FLAG (1 << 17)/* Over-current indicator change */190 #define RHS_CLEAR_DRWE (1 << 31)191 192 /** Root hub per port status */193 106 volatile uint32_t rh_port_status[]; 194 #define RHPS_CCS_FLAG (1 << 0) /* r: current connect status,195 * w: 1-clear port enable, 0-nothing */196 #define RHPS_CLEAR_PORT_ENABLE RHPS_CCS_FLAG197 #define RHPS_PES_FLAG (1 << 1) /* r: port enable status198 * w: 1-set port enable, 0-nothing */199 #define RHPS_SET_PORT_ENABLE RHPS_PES_FLAG200 #define RHPS_PSS_FLAG (1 << 2) /* r: port suspend status201 * w: 1-set port suspend, 0-nothing */202 #define RHPS_SET_PORT_SUSPEND RHPS_PSS_FLAG203 #define RHPS_POCI_FLAG (1 << 3) /* r: port over-current (if reports are per-port204 * w: 1-clear port suspend (start resume205 * if suspened)206 * 0-nothing */207 #define RHPS_CLEAR_PORT_SUSPEND RHPS_POCI_FLAG208 #define RHPS_PRS_FLAG (1 << 4) /* r: port reset status209 * w: 1-set port reset, 0-nothing */210 #define RHPS_SET_PORT_RESET RHPS_PRS_FLAG211 #define RHPS_PPS_FLAG (1 << 8) /* r: port power status212 * w: 1-set port power, 0-nothing */213 #define RHPS_SET_PORT_POWER RHPS_PPS_FLAG214 #define RHPS_LSDA_FLAG (1 << 9) /* r: low speed device attached215 * w: 1-clear port power, 0-nothing */216 #define RHPS_CLEAR_PORT_POWER RHPS_LSDA_FLAG217 #define RHPS_CSC_FLAG (1 << 16) /* connect status change Write-Clean */218 #define RHPS_PESC_FLAG (1 << 17) /* port enable status change WC */219 #define RHPS_PSSC_FLAG (1 << 18) /* port suspend status change WC */220 #define RHPS_OCIC_FLAG (1 << 19) /* port over-current change WC */221 #define RHPS_PRSC_FLAG (1 << 20) /* port reset status change WC */222 #define RHPS_CHANGE_WC_MASK 0x1f0000223 107 } __attribute__((packed)) ohci_regs_t; 224 108 #endif -
uspace/drv/ohci/utils/malloc32.h
rc6394aa rb6c9e1e 37 37 #include <assert.h> 38 38 #include <malloc.h> 39 #include <errno.h>40 39 #include <mem.h> 41 40 #include <as.h> -
uspace/drv/uhci-hcd/batch.c
rc6394aa rb6c9e1e 103 103 usb_target_t target = 104 104 { .address = ep->address, .endpoint = ep->endpoint }; 105 usb_transfer_batch_init(instance, target, ep->transfer_type, ep->speed, 106 ep->max_packet_size, buffer, NULL, buffer_size, NULL, setup_size, 107 func_in, func_out, arg, fun, ep, NULL); 105 usb_transfer_batch_init(instance, target, 106 ep->transfer_type, ep->speed, ep->max_packet_size, 107 buffer, NULL, buffer_size, NULL, setup_size, func_in, 108 func_out, arg, fun, ep, NULL); 108 109 109 110 110 111 uhci_batch_t *data = malloc(sizeof(uhci_batch_t)); 111 CHECK_NULL_DISPOSE_RETURN(data, "Failed to allocate batch data.\n"); 112 CHECK_NULL_DISPOSE_RETURN(instance, 113 "Failed to allocate batch instance.\n"); 112 114 bzero(data, sizeof(uhci_batch_t)); 113 115 instance->private_data = data; -
uspace/drv/uhci-hcd/hc.c
rc6394aa rb6c9e1e 240 240 usb_log_debug("Initialized device manager.\n"); 241 241 242 ret = usb_endpoint_manager_init(&instance->ep_manager, 243 BANDWIDTH_AVAILABLE_USB11); 242 ret = 243 usb_endpoint_manager_init(&instance->ep_manager, 244 BANDWIDTH_AVAILABLE_USB11); 244 245 assert(ret == EOK); 245 246 -
uspace/drv/usbmid/main.c
rc6394aa rb6c9e1e 55 55 int rc; 56 56 57 rc = usb_pipe_start_ long_transfer(&dev->ctrl_pipe);57 rc = usb_pipe_start_session(&dev->ctrl_pipe); 58 58 if (rc != EOK) { 59 usb_log_error("Failed to start transferon control pipe: %s.\n",59 usb_log_error("Failed to start session on control pipe: %s.\n", 60 60 str_error(rc)); 61 61 return rc; … … 64 64 bool accept = usbmid_explore_device(dev); 65 65 66 usb_pipe_end_long_transfer(&dev->ctrl_pipe); 66 rc = usb_pipe_end_session(&dev->ctrl_pipe); 67 if (rc != EOK) { 68 usb_log_warning("Failed to end session on control pipe: %s.\n", 69 str_error(rc)); 70 } 67 71 68 72 if (!accept) { -
uspace/lib/usb/Makefile
rc6394aa rb6c9e1e 43 43 src/hidparser.c \ 44 44 src/hub.c \ 45 src/pipepriv.c \46 45 src/pipes.c \ 47 46 src/pipesinit.c \ -
uspace/lib/usb/include/usb/pipes.h
rc6394aa rb6c9e1e 42 42 #include <ipc/devman.h> 43 43 #include <ddf/driver.h> 44 #include <fibril_synch.h>45 44 46 45 /** Abstraction of a physical connection to the device. … … 60 59 * This endpoint must be bound with existing usb_device_connection_t 61 60 * (i.e. the wire to send data over). 62 *63 * Locking order: if you want to lock both mutexes64 * (@c guard and @c hc_phone_mutex), lock @c guard first.65 * It is not necessary to lock @c guard if you want to lock @c hc_phone_mutex66 * only.67 61 */ 68 62 typedef struct { 69 /** Guard of the whole pipe. */70 fibril_mutex_t guard;71 72 63 /** The connection used for sending the data. */ 73 64 usb_device_connection_t *wire; … … 87 78 /** Phone to the host controller. 88 79 * Negative when no session is active. 89 * It is an error to access this member without @c hc_phone_mutex90 * being locked.91 * If call over the phone is to be made, it must be preceeded by92 * call to pipe_add_ref() [internal libusb function].93 80 */ 94 81 int hc_phone; 95 96 /** Guard for serialization of requests over the phone. */97 fibril_mutex_t hc_phone_mutex;98 99 /** Number of active transfers over the pipe. */100 int refcount;101 82 } usb_pipe_t; 102 83 … … 162 143 bool usb_pipe_is_session_started(usb_pipe_t *); 163 144 164 int usb_pipe_start_long_transfer(usb_pipe_t *);165 void usb_pipe_end_long_transfer(usb_pipe_t *);166 167 145 int usb_pipe_read(usb_pipe_t *, void *, size_t, size_t *); 168 146 int usb_pipe_write(usb_pipe_t *, void *, size_t); -
uspace/lib/usb/src/devdrv.c
rc6394aa rb6c9e1e 161 161 162 162 /* 163 * We will do some querying of the device, it is worth to prepare 164 * the long transfer. 163 * For further actions, we need open session on default control pipe. 165 164 */ 166 rc = usb_pipe_start_ long_transfer(&dev->ctrl_pipe);167 if (rc != EOK) { 168 usb_log_error("Failed to start transfer: %s.\n",165 rc = usb_pipe_start_session(&dev->ctrl_pipe); 166 if (rc != EOK) { 167 usb_log_error("Failed to start an IPC session: %s.\n", 169 168 str_error(rc)); 170 169 return rc; … … 186 185 } 187 186 188 usb_pipe_end_long_transfer(&dev->ctrl_pipe); 187 /* No checking here. */ 188 usb_pipe_end_session(&dev->ctrl_pipe); 189 189 190 190 /* Rollback actions. */ -
uspace/lib/usb/src/devpoll.c
rc6394aa rb6c9e1e 77 77 int rc; 78 78 79 rc = usb_pipe_start_session(pipe); 80 if (rc != EOK) { 81 failed_attempts++; 82 continue; 83 } 84 79 85 size_t actual_size; 80 86 rc = usb_pipe_read(pipe, polling_data->buffer, 81 87 polling_data->request_size, &actual_size); 82 88 89 /* Quit the session regardless of errors. */ 90 usb_pipe_end_session(pipe); 83 91 84 92 // if (rc == ESTALL) { -
uspace/lib/usb/src/host/batch.c
rc6394aa rb6c9e1e 63 63 instance->transfer_type = transfer_type; 64 64 instance->speed = speed; 65 instance->direction = ep->direction;65 instance->direction = USB_DIRECTION_BOTH; 66 66 instance->callback_in = func_in; 67 67 instance->callback_out = func_out; -
uspace/lib/usb/src/hub.c
rc6394aa rb6c9e1e 288 288 } 289 289 290 291 rc = usb_pipe_start_session(&ctrl_pipe); 292 if (rc != EOK) { 293 rc = ENOTCONN; 294 goto leave_release_default_address; 295 } 296 290 297 rc = usb_request_set_address(&ctrl_pipe, dev_addr); 291 298 if (rc != EOK) { 292 299 rc = ESTALL; 293 goto leave_release_default_address; 294 } 300 goto leave_stop_session; 301 } 302 303 usb_pipe_end_session(&ctrl_pipe); 295 304 296 305 /* … … 352 361 * Completely ignoring errors here. 353 362 */ 363 364 leave_stop_session: 365 usb_pipe_end_session(&ctrl_pipe); 366 354 367 leave_release_default_address: 355 368 usb_pipe_unregister(&ctrl_pipe, &hc_conn); -
uspace/lib/usb/src/pipes.c
rc6394aa rb6c9e1e 41 41 #include <errno.h> 42 42 #include <assert.h> 43 #include "pipepriv.h"44 43 45 44 #define IPC_AGAIN_DELAY (1000 * 2) /* 2ms */ … … 242 241 * necessary. 243 242 * 244 * @deprecated245 * Obsoleted with introduction of usb_pipe_start_long_transfer246 *247 243 * @param pipe Endpoint pipe to start the session on. 248 244 * @return Error code. … … 250 246 int usb_pipe_start_session(usb_pipe_t *pipe) 251 247 { 252 usb_log_warning("usb_pipe_start_session() was deprecated.\n"); 248 assert(pipe); 249 250 if (usb_pipe_is_session_started(pipe)) { 251 return EBUSY; 252 } 253 254 int phone = devman_device_connect(pipe->wire->hc_handle, 0); 255 if (phone < 0) { 256 return phone; 257 } 258 259 pipe->hc_phone = phone; 260 253 261 return EOK; 254 262 } … … 257 265 /** Ends a session on the endpoint pipe. 258 266 * 259 * @deprecated260 * Obsoleted with introduction of usb_pipe_end_long_transfer261 *262 267 * @see usb_pipe_start_session 263 268 * … … 267 272 int usb_pipe_end_session(usb_pipe_t *pipe) 268 273 { 269 usb_log_warning("usb_pipe_end_session() was deprecated.\n"); 274 assert(pipe); 275 276 if (!usb_pipe_is_session_started(pipe)) { 277 return ENOENT; 278 } 279 280 int rc = async_hangup(pipe->hc_phone); 281 if (rc != EOK) { 282 return rc; 283 } 284 285 pipe->hc_phone = -1; 286 270 287 return EOK; 271 288 } … … 281 298 bool usb_pipe_is_session_started(usb_pipe_t *pipe) 282 299 { 283 pipe_acquire(pipe); 284 bool started = pipe->refcount > 0; 285 pipe_release(pipe); 286 return started; 287 } 288 289 /** Prepare pipe for a long transfer. 290 * 291 * By a long transfer is mean transfer consisting of several 292 * requests to the HC. 293 * Calling such function is optional and it has positive effect of 294 * improved performance because IPC session is initiated only once. 295 * 296 * @param pipe Pipe over which the transfer will happen. 297 * @return Error code. 298 */ 299 int usb_pipe_start_long_transfer(usb_pipe_t *pipe) 300 { 301 return pipe_add_ref(pipe); 302 } 303 304 /** Terminate a long transfer on a pipe. 305 * 306 * @see usb_pipe_start_long_transfer 307 * 308 * @param pipe Pipe where to end the long transfer. 309 */ 310 void usb_pipe_end_long_transfer(usb_pipe_t *pipe) 311 { 312 pipe_drop_ref(pipe); 300 return (pipe->hc_phone >= 0); 313 301 } 314 302 -
uspace/lib/usb/src/pipesinit.c
rc6394aa rb6c9e1e 356 356 assert(connection); 357 357 358 fibril_mutex_initialize(&pipe->guard);359 358 pipe->wire = connection; 360 359 pipe->hc_phone = -1; 361 fibril_mutex_initialize(&pipe->hc_phone_mutex);362 360 pipe->endpoint_no = endpoint_no; 363 361 pipe->transfer_type = transfer_type; 364 362 pipe->max_packet_size = max_packet_size; 365 363 pipe->direction = direction; 366 pipe->refcount = 0;367 364 368 365 return EOK; … … 416 413 int rc; 417 414 418 rc = usb_pipe_start_long_transfer(pipe); 415 TRY_LOOP(failed_attempts) { 416 rc = usb_pipe_start_session(pipe); 417 if (rc == EOK) { 418 break; 419 } 420 } 419 421 if (rc != EOK) { 420 422 return rc; … … 437 439 } 438 440 } 439 usb_pipe_end_ long_transfer(pipe);441 usb_pipe_end_session(pipe); 440 442 if (rc != EOK) { 441 443 return rc; -
uspace/lib/usb/src/pipesio.c
rc6394aa rb6c9e1e 49 49 #include <assert.h> 50 50 #include <usbhc_iface.h> 51 #include "pipepriv.h"52 51 53 52 /** Request an in transfer, no checking of input parameters. … … 79 78 } 80 79 81 /* Ensure serialization over the phone. */82 pipe_start_transaction(pipe);83 84 80 /* 85 81 * Make call identifying target USB device and type of transfer. … … 91 87 NULL); 92 88 if (opening_request == 0) { 93 pipe_end_transaction(pipe);94 89 return ENOMEM; 95 90 } … … 101 96 aid_t data_request = async_data_read(pipe->hc_phone, buffer, size, 102 97 &data_request_call); 103 104 /*105 * Since now on, someone else might access the backing phone106 * without breaking the transfer IPC protocol.107 */108 pipe_end_transaction(pipe);109 98 110 99 if (data_request == 0) { … … 157 146 158 147 if (buffer == NULL) { 159 return EINVAL;148 return EINVAL; 160 149 } 161 150 … … 164 153 } 165 154 155 if (!usb_pipe_is_session_started(pipe)) { 156 return EBADF; 157 } 158 166 159 if (pipe->direction != USB_DIRECTION_IN) { 167 160 return EBADF; … … 172 165 } 173 166 167 size_t act_size = 0; 174 168 int rc; 175 rc = pipe_add_ref(pipe);176 if (rc != EOK) {177 return rc;178 }179 180 181 size_t act_size = 0;182 169 183 170 rc = usb_pipe_read_no_checks(pipe, buffer, size, &act_size); 184 185 pipe_drop_ref(pipe);186 187 171 if (rc != EOK) { 188 172 return rc; … … 226 210 } 227 211 228 /* Ensure serialization over the phone. */229 pipe_start_transaction(pipe);230 231 212 /* 232 213 * Make call identifying target USB device and type of transfer. … … 238 219 NULL); 239 220 if (opening_request == 0) { 240 pipe_end_transaction(pipe);241 221 return ENOMEM; 242 222 } … … 246 226 */ 247 227 int rc = async_data_write_start(pipe->hc_phone, buffer, size); 248 249 /*250 * Since now on, someone else might access the backing phone251 * without breaking the transfer IPC protocol.252 */253 pipe_end_transaction(pipe);254 255 228 if (rc != EOK) { 256 229 async_wait_for(opening_request, NULL); … … 287 260 } 288 261 262 if (!usb_pipe_is_session_started(pipe)) { 263 return EBADF; 264 } 265 289 266 if (pipe->direction != USB_DIRECTION_OUT) { 290 267 return EBADF; … … 295 272 } 296 273 297 int rc; 298 299 rc = pipe_add_ref(pipe); 300 if (rc != EOK) { 301 return rc; 302 } 303 304 rc = usb_pipe_write_no_check(pipe, buffer, size); 305 306 pipe_drop_ref(pipe); 274 int rc = usb_pipe_write_no_check(pipe, buffer, size); 307 275 308 276 return rc; … … 325 293 void *data_buffer, size_t data_buffer_size, size_t *data_transfered_size) 326 294 { 327 /* Ensure serialization over the phone. */328 pipe_start_transaction(pipe);329 330 295 /* 331 296 * Make call identifying target USB device and control transfer type. … … 346 311 setup_buffer, setup_buffer_size); 347 312 if (rc != EOK) { 348 pipe_end_transaction(pipe);349 313 async_wait_for(opening_request, NULL); 350 314 return rc; … … 358 322 data_buffer, data_buffer_size, 359 323 &data_request_call); 360 361 /*362 * Since now on, someone else might access the backing phone363 * without breaking the transfer IPC protocol.364 */365 pipe_end_transaction(pipe);366 367 368 324 if (data_request == 0) { 369 325 async_wait_for(opening_request, NULL); … … 423 379 } 424 380 381 if (!usb_pipe_is_session_started(pipe)) { 382 return EBADF; 383 } 384 425 385 if ((pipe->direction != USB_DIRECTION_BOTH) 426 386 || (pipe->transfer_type != USB_TRANSFER_CONTROL)) { … … 428 388 } 429 389 430 int rc;431 432 rc = pipe_add_ref(pipe);433 if (rc != EOK) {434 return rc;435 }436 437 390 size_t act_size = 0; 438 rc = usb_pipe_control_read_no_check(pipe,391 int rc = usb_pipe_control_read_no_check(pipe, 439 392 setup_buffer, setup_buffer_size, 440 393 data_buffer, data_buffer_size, &act_size); 441 442 pipe_drop_ref(pipe);443 394 444 395 if (rc != EOK) { … … 467 418 void *data_buffer, size_t data_buffer_size) 468 419 { 469 /* Ensure serialization over the phone. */470 pipe_start_transaction(pipe);471 472 420 /* 473 421 * Make call identifying target USB device and control transfer type. … … 480 428 NULL); 481 429 if (opening_request == 0) { 482 pipe_end_transaction(pipe);483 430 return ENOMEM; 484 431 } … … 490 437 setup_buffer, setup_buffer_size); 491 438 if (rc != EOK) { 492 pipe_end_transaction(pipe);493 439 async_wait_for(opening_request, NULL); 494 440 return rc; … … 501 447 rc = async_data_write_start(pipe->hc_phone, 502 448 data_buffer, data_buffer_size); 503 504 /* All data sent, pipe can be released. */505 pipe_end_transaction(pipe);506 507 449 if (rc != EOK) { 508 450 async_wait_for(opening_request, NULL); 509 451 return rc; 510 452 } 511 } else {512 /* No data to send, we can release the pipe for others. */513 pipe_end_transaction(pipe);514 453 } 515 454 … … 552 491 } 553 492 493 if (!usb_pipe_is_session_started(pipe)) { 494 return EBADF; 495 } 496 554 497 if ((pipe->direction != USB_DIRECTION_BOTH) 555 498 || (pipe->transfer_type != USB_TRANSFER_CONTROL)) { … … 557 500 } 558 501 559 int rc; 560 561 rc = pipe_add_ref(pipe); 562 if (rc != EOK) { 563 return rc; 564 } 565 566 rc = usb_pipe_control_write_no_check(pipe, 502 int rc = usb_pipe_control_write_no_check(pipe, 567 503 setup_buffer, setup_buffer_size, data_buffer, data_buffer_size); 568 569 pipe_drop_ref(pipe);570 504 571 505 return rc; -
uspace/lib/usb/src/recognise.c
rc6394aa rb6c9e1e 404 404 child->driver_data = dev_data; 405 405 406 rc = usb_pipe_start_session(&ctrl_pipe); 407 if (rc != EOK) { 408 goto failure; 409 } 410 406 411 rc = usb_device_create_match_ids(&ctrl_pipe, &child->match_ids); 412 if (rc != EOK) { 413 goto failure; 414 } 415 416 rc = usb_pipe_end_session(&ctrl_pipe); 407 417 if (rc != EOK) { 408 418 goto failure;
Note:
See TracChangeset
for help on using the changeset viewer.