Changes in uspace/drv/ohci/batch.c [81dce9f:41b96b4] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/ohci/batch.c
r81dce9f r41b96b4 26 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 27 */ 28 /** @addtogroup drvusbohci 28 /** @addtogroup drvusbohcihc 29 29 * @{ 30 30 */ … … 40 40 #include "batch.h" 41 41 42 #define DEFAULT_ERROR_COUNT 3 43 42 static void batch_call_in(batch_t *instance); 43 static void batch_call_out(batch_t *instance); 44 static void batch_call_in_and_dispose(batch_t *instance); 45 static void batch_call_out_and_dispose(batch_t *instance); 46 47 /** Allocate memory and initialize internal data structure. 48 * 49 * @param[in] fun DDF function to pass to callback. 50 * @param[in] target Device and endpoint target of the transaction. 51 * @param[in] transfer_type Interrupt, Control or Bulk. 52 * @param[in] max_packet_size maximum allowed size of data packets. 53 * @param[in] speed Speed of the transaction. 54 * @param[in] buffer Data source/destination. 55 * @param[in] size Size of the buffer. 56 * @param[in] setup_buffer Setup data source (if not NULL) 57 * @param[in] setup_size Size of setup_buffer (should be always 8) 58 * @param[in] func_in function to call on inbound transaction completion 59 * @param[in] func_out function to call on outbound transaction completion 60 * @param[in] arg additional parameter to func_in or func_out 61 * @param[in] manager Pointer to toggle management structure. 62 * @return Valid pointer if all substructures were successfully created, 63 * NULL otherwise. 64 * 65 * Determines the number of needed packets (TDs). Prepares a transport buffer 66 * (that is accessible by the hardware). Initializes parameters needed for the 67 * transaction and callback. 68 */ 69 batch_t * batch_get(ddf_fun_t *fun, usb_target_t target, 70 usb_transfer_type_t transfer_type, size_t max_packet_size, 71 usb_speed_t speed, char *buffer, size_t size, 72 char* setup_buffer, size_t setup_size, 73 usbhc_iface_transfer_in_callback_t func_in, 74 usbhc_iface_transfer_out_callback_t func_out, void *arg 75 ) 76 { 77 assert(func_in == NULL || func_out == NULL); 78 assert(func_in != NULL || func_out != NULL); 79 80 #define CHECK_NULL_DISPOSE_RETURN(ptr, message...) \ 81 if (ptr == NULL) { \ 82 usb_log_error(message); \ 83 if (instance) { \ 84 batch_dispose(instance); \ 85 } \ 86 return NULL; \ 87 } else (void)0 88 89 batch_t *instance = malloc(sizeof(batch_t)); 90 CHECK_NULL_DISPOSE_RETURN(instance, 91 "Failed to allocate batch instance.\n"); 92 bzero(instance, sizeof(batch_t)); 93 94 if (size > 0) { 95 /* TODO: use device accessible malloc here */ 96 instance->transport_buffer = malloc(size); 97 CHECK_NULL_DISPOSE_RETURN(instance->transport_buffer, 98 "Failed to allocate device accessible buffer.\n"); 99 } 100 101 if (setup_size > 0) { 102 /* TODO: use device accessible malloc here */ 103 instance->setup_buffer = malloc(setup_size); 104 CHECK_NULL_DISPOSE_RETURN(instance->setup_buffer, 105 "Failed to allocate device accessible setup buffer.\n"); 106 memcpy(instance->setup_buffer, setup_buffer, setup_size); 107 } 108 109 link_initialize(&instance->link); 110 111 instance->max_packet_size = max_packet_size; 112 instance->target = target; 113 instance->transfer_type = transfer_type; 114 instance->buffer = buffer; 115 instance->buffer_size = size; 116 instance->setup_size = setup_size; 117 instance->fun = fun; 118 instance->arg = arg; 119 instance->speed = speed; 120 instance->callback_out = func_out; 121 instance->callback_in = func_in; 122 123 usb_log_debug("Batch(%p) %d:%d memory structures ready.\n", 124 instance, target.address, target.endpoint); 125 return instance; 126 } 127 /*----------------------------------------------------------------------------*/ 128 /** Mark batch as finished and continue with next step. 129 * 130 * @param[in] instance Batch structure to use. 131 * 132 */ 133 void batch_finish(batch_t *instance, int error) 134 { 135 assert(instance); 136 instance->error = error; 137 instance->next_step(instance); 138 } 139 /*----------------------------------------------------------------------------*/ 140 /** Check batch TDs for activity. 141 * 142 * @param[in] instance Batch structure to use. 143 * @return False, if there is an active TD, true otherwise. 144 * 145 * Walk all TDs. Stop with false if there is an active one (it is to be 146 * processed). Stop with true if an error is found. Return true if the last TS 147 * is reached. 148 */ 149 bool batch_is_complete(batch_t *instance) 150 { 151 assert(instance); 152 /* TODO: implement */ 153 return true; 154 } 155 /*----------------------------------------------------------------------------*/ 156 /** Prepares control write transaction. 157 * 158 * @param[in] instance Batch structure to use. 159 * 160 * Uses genercir control function with pids OUT and IN. 161 */ 162 void batch_control_write(batch_t *instance) 163 { 164 assert(instance); 165 /* We are data out, we are supposed to provide data */ 166 memcpy(instance->transport_buffer, instance->buffer, 167 instance->buffer_size); 168 instance->next_step = batch_call_out_and_dispose; 169 /* TODO: implement */ 170 usb_log_debug("Batch(%p) CONTROL WRITE initialized.\n", instance); 171 } 172 /*----------------------------------------------------------------------------*/ 173 /** Prepares control read transaction. 174 * 175 * @param[in] instance Batch structure to use. 176 * 177 * Uses generic control with pids IN and OUT. 178 */ 179 void batch_control_read(batch_t *instance) 180 { 181 assert(instance); 182 instance->next_step = batch_call_in_and_dispose; 183 /* TODO: implement */ 184 usb_log_debug("Batch(%p) CONTROL READ initialized.\n", instance); 185 } 186 /*----------------------------------------------------------------------------*/ 187 /** Prepare interrupt in transaction. 188 * 189 * @param[in] instance Batch structure to use. 190 * 191 * Data transaction with PID_IN. 192 */ 193 void batch_interrupt_in(batch_t *instance) 194 { 195 assert(instance); 196 /* TODO: implement */ 197 instance->next_step = batch_call_in_and_dispose; 198 usb_log_debug("Batch(%p) INTERRUPT IN initialized.\n", instance); 199 } 200 /*----------------------------------------------------------------------------*/ 201 /** Prepare interrupt out transaction. 202 * 203 * @param[in] instance Batch structure to use. 204 * 205 * Data transaction with PID_OUT. 206 */ 207 void batch_interrupt_out(batch_t *instance) 208 { 209 assert(instance); 210 /* We are data out, we are supposed to provide data */ 211 memcpy(instance->transport_buffer, instance->buffer, 212 instance->buffer_size); 213 instance->next_step = batch_call_out_and_dispose; 214 /* TODO: implement */ 215 usb_log_debug("Batch(%p) INTERRUPT OUT initialized.\n", instance); 216 } 217 /*----------------------------------------------------------------------------*/ 218 /** Prepare bulk in transaction. 219 * 220 * @param[in] instance Batch structure to use. 221 * 222 * Data transaction with PID_IN. 223 */ 224 void batch_bulk_in(batch_t *instance) 225 { 226 assert(instance); 227 instance->next_step = batch_call_in_and_dispose; 228 /* TODO: implement */ 229 usb_log_debug("Batch(%p) BULK IN initialized.\n", instance); 230 } 231 /*----------------------------------------------------------------------------*/ 232 /** Prepare bulk out transaction. 233 * 234 * @param[in] instance Batch structure to use. 235 * 236 * Data transaction with PID_OUT. 237 */ 238 void batch_bulk_out(batch_t *instance) 239 { 240 assert(instance); 241 /* We are data out, we are supposed to provide data */ 242 memcpy(instance->transport_buffer, instance->buffer, 243 instance->buffer_size); 244 instance->next_step = batch_call_out_and_dispose; 245 /* TODO: implement */ 246 usb_log_debug("Batch(%p) BULK OUT initialized.\n", instance); 247 } 248 /*----------------------------------------------------------------------------*/ 249 /** Prepare data, get error status and call callback in. 250 * 251 * @param[in] instance Batch structure to use. 252 * Copies data from transport buffer, and calls callback with appropriate 253 * parameters. 254 */ 255 void batch_call_in(batch_t *instance) 256 { 257 assert(instance); 258 assert(instance->callback_in); 259 260 /* We are data in, we need data */ 261 memcpy(instance->buffer, instance->transport_buffer, 262 instance->buffer_size); 263 264 int err = instance->error; 265 usb_log_debug("Batch(%p) callback IN(type:%d): %s(%d), %zu.\n", 266 instance, instance->transfer_type, str_error(err), err, 267 instance->transfered_size); 268 269 instance->callback_in( 270 instance->fun, err, instance->transfered_size, instance->arg); 271 } 272 /*----------------------------------------------------------------------------*/ 273 /** Get error status and call callback out. 274 * 275 * @param[in] instance Batch structure to use. 276 */ 277 void batch_call_out(batch_t *instance) 278 { 279 assert(instance); 280 assert(instance->callback_out); 281 282 int err = instance->error; 283 usb_log_debug("Batch(%p) callback OUT(type:%d): %s(%d).\n", 284 instance, instance->transfer_type, str_error(err), err); 285 instance->callback_out(instance->fun, 286 err, instance->arg); 287 } 288 /*----------------------------------------------------------------------------*/ 289 /** Helper function calls callback and correctly disposes of batch structure. 290 * 291 * @param[in] instance Batch structure to use. 292 */ 293 void batch_call_in_and_dispose(batch_t *instance) 294 { 295 assert(instance); 296 batch_call_in(instance); 297 batch_dispose(instance); 298 } 299 /*----------------------------------------------------------------------------*/ 300 /** Helper function calls callback and correctly disposes of batch structure. 301 * 302 * @param[in] instance Batch structure to use. 303 */ 304 void batch_call_out_and_dispose(batch_t *instance) 305 { 306 assert(instance); 307 batch_call_out(instance); 308 batch_dispose(instance); 309 } 310 /*----------------------------------------------------------------------------*/ 311 /** Correctly dispose all used data structures. 312 * 313 * @param[in] instance Batch structure to use. 314 */ 315 void batch_dispose(batch_t *instance) 316 { 317 assert(instance); 318 usb_log_debug("Batch(%p) disposing.\n", instance); 319 if (instance->setup_buffer) 320 free(instance->setup_buffer); 321 if (instance->transport_buffer) 322 free(instance->transport_buffer); 323 free(instance); 324 } 44 325 /** 45 326 * @}
Note:
See TracChangeset
for help on using the changeset viewer.