source: mainline/uspace/drv/uhci/uhci.c@ 89a0485a

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 89a0485a was 89a0485a, checked in by Jan Vesely <jano.vesely@…>, 14 years ago

Move function implementations to .c files

Unify error reporting in uhci_in()

  • Property mode set to 100644
File size: 5.3 KB
RevLine 
[3515533]1#include <errno.h>
2#include <usb/debug.h>
[18e35a7]3#include <usb/usb.h>
[3515533]4
[9600516]5#include "translating_malloc.h"
6
[bf5a3be]7#include "debug.h"
[3515533]8#include "name.h"
9#include "uhci.h"
10
[9600516]11static int init_tranfer_lists(transfer_list_t list[]);
12
[7977fa1]13//static int init_transfer();
14
[3515533]15int uhci_init(device_t *device, void *regs)
16{
17 assert( device );
[bf5a3be]18 uhci_print_info( "Initializing device at address %p\n", device);
[3515533]19
20 /* create instance */
21 uhci_t *instance = malloc( sizeof(uhci_t) );
22 if (!instance)
23 { return ENOMEM; }
[89a0485a]24 bzero( instance, sizeof(uhci_t) );
[3515533]25
[18e35a7]26 /* init address keeper(libusb) */
27 usb_address_keeping_init( &instance->address_manager, USB11_ADDRESS_MAX );
28
[3515533]29 /* allow access to hc control registers */
30 regs_t *io;
31 int ret = pio_enable( regs, sizeof(regs_t), (void**)&io);
32 if (ret < 0) {
33 free( instance );
[9600516]34 uhci_print_error("Failed to gain access to registers at %p\n", io);
[3515533]35 return ret;
36 }
37 instance->registers = io;
38
39 /* init root hub */
[9600516]40 ret = uhci_root_hub_init(&instance->root_hub, device,
41 (char*)regs + UHCI_ROOT_HUB_PORT_REGISTERS_OFFSET);
[3515533]42 if (ret < 0) {
[9600516]43 free(instance);
44 uhci_print_error("Failed to initialize root hub driver.\n");
45 return ret;
46 }
47
48 instance->frame_list = trans_malloc(sizeof(frame_list_t));
49 if (instance->frame_list == NULL) {
50 uhci_print_error("Failed to allocate frame list pointer.\n");
51 uhci_root_hub_fini(&instance->root_hub);
52 free(instance);
53 return ENOMEM;
54 }
55
56 const uintptr_t pa = (uintptr_t)addr_to_phys(instance->frame_list);
57
58 pio_write_32(&instance->registers->flbaseadd, (uint32_t)pa);
59
60 ret = init_tranfer_lists(instance->transfers);
61 if (ret != EOK) {
62 uhci_print_error("Transfer list initialization failed.\n");
63 uhci_root_hub_fini(&instance->root_hub);
64 free(instance);
[3515533]65 return ret;
66 }
67
68 device->driver_data = instance;
69 return EOK;
70}
71/*----------------------------------------------------------------------------*/
72int uhci_in(
73 device_t *dev,
74 usb_target_t target,
75 usb_transfer_type_t transfer_type,
76 void *buffer, size_t size,
77 usbhc_iface_transfer_in_callback_t callback, void *arg
78 )
79{
[bf5a3be]80 uhci_print_info( "transfer IN [%d.%d (%s); %zu]\n",
[3515533]81 target.address, target.endpoint,
82 usb_str_transfer_type(transfer_type),
83 size);
[7977fa1]84
[643b983]85 if (size >= 1024)
86 return ENOTSUP;
87
[89a0485a]88 transfer_descriptor_t *td = NULL;
89 callback_t *job = NULL;
90 int ret = EOK;
[643b983]91
[89a0485a]92#define CHECK_RET_TRANS_FREE_JOB_TD(message) \
93 if (ret != EOK) { \
[643b983]94 uhci_print_error(message); \
[89a0485a]95 if (job) { \
96 callback_fini(job); \
97 trans_free(job); \
98 } \
99 if (td) { trans_free(td); } \
100 return ret; \
[643b983]101 } else (void) 0
[3515533]102
[643b983]103
[89a0485a]104 job = malloc(sizeof(callback_t));
105 ret= job ? EOK : ENOMEM;
106 CHECK_RET_TRANS_FREE_JOB_TD("Failed to allocate callback structure.\n");
107
108 ret = callback_in_init(job, dev, buffer, size, callback, arg);
109 CHECK_RET_TRANS_FREE_JOB_TD("Failed to initialize callback structure.\n");
110
111 td = trans_malloc(sizeof(transfer_descriptor_t));
112 ret = td ? ENOMEM : EOK;
113 CHECK_RET_TRANS_FREE_JOB_TD("Failed to allocate tranfer descriptor.\n");
[643b983]114
[7977fa1]115 ret = transfer_descriptor_init(td, 3, size, false, target, USB_PID_IN);
[89a0485a]116 CHECK_RET_TRANS_FREE_JOB_TD("Failed to initialize transfer descriptor.\n");
117
[7977fa1]118 td->callback = job;
[643b983]119
[89a0485a]120 assert(dev);
121 uhci_t *instance = (uhci_t*)dev->driver_data;
122 assert(instance);
[643b983]123
[89a0485a]124 ret = transfer_list_append(&instance->transfers[transfer_type], td);
125 CHECK_RET_TRANS_FREE_JOB_TD("Failed to append transfer descriptor.\n");
[f9dd44d]126
127 return EOK;
[3515533]128}
129/*----------------------------------------------------------------------------*/
130int uhci_out(
131 device_t *dev,
132 usb_target_t target,
133 usb_transfer_type_t transfer_type,
134 void *buffer, size_t size,
135 usbhc_iface_transfer_out_callback_t callback, void *arg
136 )
137{
[bf5a3be]138 uhci_print_info( "transfer OUT [%d.%d (%s); %zu]\n",
[3515533]139 target.address, target.endpoint,
140 usb_str_transfer_type(transfer_type),
141 size);
142
[f9dd44d]143 callback( dev, USB_OUTCOME_OK, arg );
144 return EOK;
[3515533]145}
146/*----------------------------------------------------------------------------*/
147int uhci_setup(
148 device_t *dev,
149 usb_target_t target,
150 usb_transfer_type_t transfer_type,
151 void *buffer, size_t size,
152 usbhc_iface_transfer_out_callback_t callback, void *arg
153 )
154{
[bf5a3be]155 uhci_print_info( "transfer SETUP [%d.%d (%s); %zu]\n",
[3515533]156 target.address, target.endpoint,
157 usb_str_transfer_type(transfer_type),
158 size);
[76c40eb]159 uhci_print_info("Setup packet content: %x %x.\n", ((uint8_t*)buffer)[0],
160 ((uint8_t*)buffer)[1]);
[3515533]161
[f9dd44d]162 callback( dev, USB_OUTCOME_OK, arg );
163 return EOK;
[3515533]164}
165/*----------------------------------------------------------------------------*/
[643b983]166int init_tranfer_lists(transfer_list_t transfers[])
167{
168 //TODO:refactor
169 transfers[USB_TRANSFER_ISOCHRONOUS].first = NULL;
170 transfers[USB_TRANSFER_ISOCHRONOUS].last = NULL;
171 int ret;
172 ret = transfer_list_init(&transfers[USB_TRANSFER_BULK], NULL);
173 if (ret != EOK) {
174 uhci_print_error("Failed to inititalize bulk queue.\n");
175 return ret;
176 }
177
178 ret = transfer_list_init(
179 &transfers[USB_TRANSFER_CONTROL], &transfers[USB_TRANSFER_BULK]);
180 if (ret != EOK) {
181 uhci_print_error("Failed to inititalize control queue.\n");
182 transfer_list_fini(&transfers[USB_TRANSFER_BULK]);
183 return ret;
184 }
185
186 ret = transfer_list_init(
187 &transfers[USB_TRANSFER_INTERRUPT], &transfers[USB_TRANSFER_CONTROL]);
188 if (ret != EOK) {
189 uhci_print_error("Failed to interrupt control queue.\n");
190 transfer_list_fini(&transfers[USB_TRANSFER_CONTROL]);
191 transfer_list_fini(&transfers[USB_TRANSFER_BULK]);
192 return ret;
193 }
194
195 return EOK;
196}
Note: See TracBrowser for help on using the repository browser.