Changeset 69334af in mainline
- Timestamp:
- 2011-03-13T17:18:55Z (14 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 4bf94df
- Parents:
- 489c3e7
- Location:
- uspace/lib/usb
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/usb/include/usb/devdrv.h
r489c3e7 r69334af 38 38 #include <usb/pipes.h> 39 39 40 /** USB device structure. */ 40 41 typedef struct { 42 /** The default control pipe. */ 41 43 usb_endpoint_pipe_t ctrl_pipe; 44 /** Other endpoint pipes. 45 * This is an array of other endpoint pipes in the same order as 46 * in usb_driver_t. 47 */ 42 48 usb_endpoint_mapping_t *pipes; 49 /** Generic DDF device backing this one. */ 43 50 ddf_dev_t *ddf_dev; 51 /** Custom driver data. 52 * Do not use the entry in generic device, that is already used 53 * by the framework. 54 */ 44 55 void *driver_data; 56 57 /** Connection backing the pipes. 58 * Typically, you will not need to use this attribute at all. 59 */ 45 60 usb_device_connection_t wire; 46 61 } usb_device_t; 47 62 63 /** USB driver ops. */ 48 64 typedef struct { 65 /** Callback when new device is about to be controlled by the driver. */ 49 66 int (*add_device)(usb_device_t *); 50 67 } usb_driver_ops_t; 51 68 69 /** USB driver structure. */ 52 70 typedef struct { 71 /** Driver name. 72 * This name is copied to the generic driver name and must be exactly 73 * the same as the directory name where the driver executable resides. 74 */ 53 75 const char *name; 76 /** Expected endpoints description. */ 54 77 usb_endpoint_description_t **endpoints; 78 /** Driver ops. */ 55 79 usb_driver_ops_t *ops; 56 80 } usb_driver_t; -
uspace/lib/usb/src/devdrv.c
r489c3e7 r69334af 37 37 #include <usb/debug.h> 38 38 #include <errno.h> 39 #include <str_error.h> 39 40 #include <assert.h> 40 41 … … 50 51 static usb_driver_t *driver = NULL; 51 52 53 54 /** Main routine of USB device driver. 55 * 56 * Under normal conditions, this function never returns. 57 * 58 * @param drv USB device driver structure. 59 * @return Task exit status. 60 */ 52 61 int usb_driver_main(usb_driver_t *drv) 53 62 { 63 assert(drv != NULL); 64 54 65 /* Prepare the generic driver. */ 55 66 generic_driver.name = drv->name; … … 60 71 } 61 72 73 /** Log out of memory error on given device. 74 * 75 * @param dev Device causing the trouble. 76 */ 77 static void usb_log_oom(ddf_dev_t *dev) 78 { 79 usb_log_error("Out of memory when adding device `%s'.\n", 80 dev->name); 81 } 82 83 /** Count number of pipes the driver expects. 84 * 85 * @param drv USB driver. 86 * @return Number of pipes (excluding default control pipe). 87 */ 62 88 static size_t count_other_pipes(usb_driver_t *drv) 63 89 { … … 74 100 } 75 101 102 /** Initialize endpoint pipes, excluding default control one. 103 * 104 * @param drv The device driver. 105 * @param dev Device to be initialized. 106 * @return Error code. 107 */ 76 108 static int initialize_other_pipes(usb_driver_t *drv, usb_device_t *dev) 77 109 { 110 int rc; 78 111 int my_interface = usb_device_get_assigned_interface(dev->ddf_dev); 79 112 80 113 size_t pipe_count = count_other_pipes(drv); 81 114 dev->pipes = malloc(sizeof(usb_endpoint_mapping_t) * pipe_count); 82 assert(dev->pipes != NULL); 115 if (dev->pipes == NULL) { 116 usb_log_oom(dev->ddf_dev); 117 return ENOMEM; 118 } 83 119 84 120 size_t i; 121 122 /* Initialize to NULL first for rollback purposes. */ 123 for (i = 0; i < pipe_count; i++) { 124 dev->pipes[i].pipe = NULL; 125 } 126 85 127 for (i = 0; i < pipe_count; i++) { 86 128 dev->pipes[i].pipe = malloc(sizeof(usb_endpoint_pipe_t)); 87 assert(dev->pipes[i].pipe != NULL); 129 if (dev->pipes[i].pipe == NULL) { 130 usb_log_oom(dev->ddf_dev); 131 rc = ENOMEM; 132 goto rollback; 133 } 134 88 135 dev->pipes[i].description = drv->endpoints[i]; 89 136 dev->pipes[i].interface_no = my_interface; … … 92 139 void *config_descriptor; 93 140 size_t config_descriptor_size; 94 int rc = usb_request_get_full_configuration_descriptor_alloc( 95 &dev->ctrl_pipe, 0, &config_descriptor, &config_descriptor_size); 96 assert(rc == EOK); 141 rc = usb_request_get_full_configuration_descriptor_alloc( 142 &dev->ctrl_pipe, 0, &config_descriptor, &config_descriptor_size); 143 if (rc != EOK) { 144 usb_log_error("Failed retrieving configuration of `%s': %s.\n", 145 dev->ddf_dev->name, str_error(rc)); 146 goto rollback; 147 } 97 148 98 149 rc = usb_endpoint_pipe_initialize_from_configuration(dev->pipes, 99 150 pipe_count, config_descriptor, config_descriptor_size, &dev->wire); 100 assert(rc == EOK); 101 151 if (rc != EOK) { 152 usb_log_error("Failed initializing USB endpoints: %s.\n", 153 str_error(rc)); 154 goto rollback; 155 } 102 156 103 157 return EOK; 104 } 105 158 159 rollback: 160 for (i = 0; i < pipe_count; i++) { 161 if (dev->pipes[i].pipe != NULL) { 162 free(dev->pipes[i].pipe); 163 } 164 } 165 free(dev->pipes); 166 167 return rc; 168 } 169 170 /** Initialize all endpoint pipes. 171 * 172 * @param drv The driver. 173 * @param dev The device to be initialized. 174 * @return Error code. 175 */ 176 static int initialize_pipes(usb_driver_t *drv, usb_device_t *dev) 177 { 178 int rc; 179 180 rc = usb_device_connection_initialize_from_device(&dev->wire, 181 dev->ddf_dev); 182 if (rc != EOK) { 183 usb_log_error( 184 "Failed initializing connection on device `%s'. %s.\n", 185 dev->ddf_dev->name, str_error(rc)); 186 return rc; 187 } 188 189 rc = usb_endpoint_pipe_initialize_default_control(&dev->ctrl_pipe, 190 &dev->wire); 191 if (rc != EOK) { 192 usb_log_error("Failed to initialize default control pipe " \ 193 "on device `%s': %s.\n", 194 dev->ddf_dev->name, str_error(rc)); 195 return rc; 196 } 197 198 /* 199 * Initialization of other pipes requires open session on 200 * default control pipe. 201 */ 202 rc = usb_endpoint_pipe_start_session(&dev->ctrl_pipe); 203 if (rc != EOK) { 204 usb_log_error("Failed to start an IPC session: %s.\n", 205 str_error(rc)); 206 return rc; 207 } 208 209 if (driver->endpoints != NULL) { 210 rc = initialize_other_pipes(driver, dev); 211 } 212 213 /* No checking here. */ 214 usb_endpoint_pipe_end_session(&dev->ctrl_pipe); 215 216 return rc; 217 } 218 219 /** Callback when new device is supposed to be controlled by this driver. 220 * 221 * This callback is a wrapper for USB specific version of @c add_device. 222 * 223 * @param gen_dev Device structure as prepared by DDF. 224 * @return Error code. 225 */ 106 226 int generic_add_device(ddf_dev_t *gen_dev) 107 227 { … … 113 233 114 234 usb_device_t *dev = malloc(sizeof(usb_device_t)); 115 assert(dev); 235 if (dev == NULL) { 236 usb_log_error("Out of memory when adding device `%s'.\n", 237 gen_dev->name); 238 return ENOMEM; 239 } 240 116 241 117 242 dev->ddf_dev = gen_dev; 243 dev->ddf_dev->driver_data = dev; 118 244 dev->driver_data = NULL; 119 245 120 /* Initialize the backing wire abstraction. */ 121 rc = usb_device_connection_initialize_from_device(&dev->wire, gen_dev); 122 assert(rc == EOK); 123 124 /* Initialize the default control pipe. */ 125 rc = usb_endpoint_pipe_initialize_default_control(&dev->ctrl_pipe, 126 &dev->wire); 127 assert(rc == EOK); 128 129 rc = usb_endpoint_pipe_start_session(&dev->ctrl_pipe); 130 assert(rc == EOK); 131 132 /* Initialize remaining pipes. */ 133 if (driver->endpoints != NULL) { 134 initialize_other_pipes(driver, dev); 135 } 136 137 rc = usb_endpoint_pipe_end_session(&dev->ctrl_pipe); 138 assert(rc == EOK); 246 rc = initialize_pipes(driver, dev); 247 if (rc != EOK) { 248 free(dev); 249 return rc; 250 } 139 251 140 252 return driver->ops->add_device(dev);
Note:
See TracChangeset
for help on using the changeset viewer.