Changeset 91db50ac in mainline
- Timestamp:
- 2010-11-19T21:50:46Z (14 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 7034be15
- Parents:
- 63b4f90
- Location:
- uspace
- Files:
-
- 3 added
- 11 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/usbkbd/main.c
r63b4f90 r91db50ac 30 30 #include <errno.h> 31 31 32 #define BUFFER_SIZE 32 33 34 /* Call this periodically to check keyboard status changes. */ 35 static void poll_keyboard(device_t *dev) 36 { 37 int rc; 38 usb_handle_t handle; 39 char buffer[BUFFER_SIZE]; 40 size_t actual_size; 41 usb_endpoint_t poll_endpoint = 1; 42 43 rc = usb_drv_async_interrupt_in(dev->parent_phone, poll_endpoint, 44 buffer, BUFFER_SIZE, &actual_size, &handle); 45 if (rc != EOK) { 46 return; 47 } 48 49 rc = usb_drv_async_wait_for(handle); 50 if (rc != EOK) { 51 return; 52 } 53 54 /* 55 * If the keyboard answered with NAK, it returned no data. 56 * This implies that no change happened since last query. 57 */ 58 if (actual_size == 0) { 59 return; 60 } 61 62 /* 63 * Process pressed keys. 64 */ 65 } 66 32 67 static int add_kbd_device(device_t *dev) 33 68 { … … 38 73 * When everything is okay, connect to "our" HC. 39 74 */ 40 int rc= usb_drv_hc_connect(dev, 0);41 if ( rc != EOK) {75 int phone = usb_drv_hc_connect(dev, 0); 76 if (phone < 0) { 42 77 /* 43 78 * Connecting to HC failed, roll-back and announce 44 79 * failure. 45 80 */ 46 return rc;81 return phone; 47 82 } 83 84 dev->parent_phone = phone; 85 86 /* 87 * Just for fun ;-). 88 */ 89 poll_keyboard(dev); 48 90 49 91 /* -
uspace/lib/c/include/ipc/dev_iface.h
r63b4f90 r91db50ac 38 38 HW_RES_DEV_IFACE = 0, 39 39 CHAR_DEV_IFACE, 40 USB_DEV_IFACE, 40 41 // TODO add more interfaces 41 42 DEV_IFACE_MAX -
uspace/lib/drv/Makefile
r63b4f90 r91db50ac 29 29 30 30 USPACE_PREFIX = ../.. 31 EXTRA_CFLAGS = -Iinclude 31 EXTRA_CFLAGS = -Iinclude -I$(LIB_PREFIX) 32 32 LIBRARY = libdrv 33 33 … … 36 36 generic/dev_iface.c \ 37 37 generic/remote_res.c \ 38 generic/remote_usb.c \ 38 39 generic/remote_char.c 39 40 -
uspace/lib/drv/generic/dev_iface.c
r63b4f90 r91db50ac 39 39 #include "remote_res.h" 40 40 #include "remote_char.h" 41 #include "remote_usb.h" 41 42 42 43 static iface_dipatch_table_t remote_ifaces = { 43 44 .ifaces = { 44 45 &remote_res_iface, 45 &remote_char_iface 46 &remote_char_iface, 47 &remote_usb_iface 46 48 } 47 49 }; -
uspace/lib/usb/Makefile
r63b4f90 r91db50ac 30 30 LIBRARY = libusb 31 31 LIBS = $(LIBDRV_PREFIX)/libdrv.a 32 EXTRA_CFLAGS += -I$(LIBDRV_PREFIX)/include 32 EXTRA_CFLAGS += -I$(LIBDRV_PREFIX)/include -I$(LIB_PREFIX) 33 33 34 34 SOURCES = \ -
uspace/lib/usb/hcd.c
r63b4f90 r91db50ac 58 58 #define NAMESPACE "usb" 59 59 60 61 /** String representation of USB transaction outcome. */62 const char * usb_str_transaction_outcome(usb_transaction_outcome_t o)63 {64 switch (o) {65 case USB_OUTCOME_OK:66 return "ok";67 case USB_OUTCOME_CRCERROR:68 return "CRC error";69 case USB_OUTCOME_BABBLE:70 return "babble";71 default:72 return "unknown";73 }74 }75 60 76 61 /** Create necessary phones for communicating with HCD. -
uspace/lib/usb/hcd.h
r63b4f90 r91db50ac 49 49 typedef ipcarg_t usb_transaction_handle_t; 50 50 51 /** USB transaction outcome. */52 typedef enum {53 USB_OUTCOME_OK,54 USB_OUTCOME_CRCERROR,55 USB_OUTCOME_BABBLE56 } usb_transaction_outcome_t;57 51 58 52 /** USB packet identifier. */ … … 83 77 } usb_packet_id; 84 78 85 const char * usb_str_transaction_outcome(usb_transaction_outcome_t o);86 87 79 /** IPC methods for HCD. 88 80 * -
uspace/lib/usb/usb.c
r63b4f90 r91db50ac 54 54 } 55 55 56 /** String representation of USB transaction outcome. */ 57 const char * usb_str_transaction_outcome(usb_transaction_outcome_t o) 58 { 59 switch (o) { 60 case USB_OUTCOME_OK: 61 return "ok"; 62 case USB_OUTCOME_CRCERROR: 63 return "CRC error"; 64 case USB_OUTCOME_BABBLE: 65 return "babble"; 66 default: 67 return "unknown"; 68 } 69 } 70 56 71 57 72 /** -
uspace/lib/usb/usb.h
r63b4f90 r91db50ac 55 55 } usb_direction_t; 56 56 57 /** USB transaction outcome. */ 58 typedef enum { 59 USB_OUTCOME_OK, 60 USB_OUTCOME_CRCERROR, 61 USB_OUTCOME_BABBLE 62 } usb_transaction_outcome_t; 63 64 const char * usb_str_transaction_outcome(usb_transaction_outcome_t o); 65 57 66 /** USB address type. 58 67 * Negative values could be used to indicate error. -
uspace/lib/usb/usbdrv.c
r63b4f90 r91db50ac 34 34 */ 35 35 #include "usbdrv.h" 36 #include <usb_iface.h> 36 37 #include <errno.h> 37 38 39 /** Information about pending transaction on HC. */ 40 typedef struct { 41 /** Phone to host controller driver. */ 42 int phone; 43 /** Data buffer. */ 44 void *buffer; 45 /** Buffer size. */ 46 size_t size; 47 /** Storage for actual number of bytes transferred. */ 48 size_t *size_transferred; 49 /** Initial call replay data. */ 50 ipc_call_t reply; 51 /** Initial call identifier. */ 52 aid_t request; 53 } transfer_info_t; 54 38 55 /** Connect to host controller the device is physically attached to. 39 * This function sets the phone_parent property in the device_t struct.40 56 * 41 57 * @param handle Device handle. 42 58 * @param flags Connection flags (blocking connection). 43 * @return Error code.59 * @return Phone to corresponding HC or error code. 44 60 */ 45 61 int usb_drv_hc_connect(device_t *dev, unsigned int flags) … … 51 67 } 52 68 69 /** Send data to HCD. 70 * 71 * @param phone Phone to HC. 72 * @param method Method used for calling. 73 * @param endpoint Device endpoint. 74 * @param buffer Data buffer (NULL to skip data transfer phase). 75 * @param size Buffer size (must be zero when @p buffer is NULL). 76 * @param handle Storage for transaction handle (cannot be NULL). 77 * @return Error status. 78 * @retval EINVAL Invalid parameter. 79 * @retval ENOMEM Not enough memory to complete the operation. 80 */ 81 static int async_send_buffer(int phone, int method, 82 usb_endpoint_t endpoint, 83 void *buffer, size_t size, 84 usb_handle_t *handle) 85 { 86 if (phone < 0) { 87 return EINVAL; 88 } 89 90 if ((buffer == NULL) && (size > 0)) { 91 return EINVAL; 92 } 93 94 if (handle == NULL) { 95 return EINVAL; 96 } 97 98 transfer_info_t *transfer 99 = (transfer_info_t *) malloc(sizeof(transfer_info_t)); 100 if (transfer == NULL) { 101 return ENOMEM; 102 } 103 104 transfer->size_transferred = NULL; 105 transfer->buffer = NULL; 106 transfer->size = 0; 107 transfer->phone = phone; 108 109 int rc; 110 111 transfer->request = async_send_3(phone, 112 DEV_IFACE_ID(USB_DEV_IFACE), 113 method, 114 endpoint, 115 size, 116 &transfer->reply); 117 118 if (size > 0) { 119 rc = async_data_write_start(phone, buffer, size); 120 if (rc != EOK) { 121 async_wait_for(transfer->request, NULL); 122 return rc; 123 } 124 } 125 126 *handle = (usb_handle_t) transfer; 127 128 return EOK; 129 } 130 131 /** Prepare data retrieval. 132 * 133 * @param phone Opened phone to HCD. 134 * @param method Method used for calling. 135 * @param endpoint Device endpoint. 136 * @param buffer Buffer where to store retrieved data 137 * (NULL to skip data transfer phase). 138 * @param size Buffer size (must be zero when @p buffer is NULL). 139 * @param actual_size Storage where actual number of bytes transferred will 140 * be stored. 141 * @param handle Storage for transaction handle (cannot be NULL). 142 * @return Error status. 143 * @retval EINVAL Invalid parameter. 144 * @retval ENOMEM Not enough memory to complete the operation. 145 */ 146 static int async_recv_buffer(int phone, int method, 147 usb_endpoint_t endpoint, 148 void *buffer, size_t size, size_t *actual_size, 149 usb_handle_t *handle) 150 { 151 if (phone < 0) { 152 return EINVAL; 153 } 154 155 if ((buffer == NULL) && (size > 0)) { 156 return EINVAL; 157 } 158 159 if (handle == NULL) { 160 return EINVAL; 161 } 162 163 transfer_info_t *transfer 164 = (transfer_info_t *) malloc(sizeof(transfer_info_t)); 165 if (transfer == NULL) { 166 return ENOMEM; 167 } 168 169 transfer->size_transferred = actual_size; 170 transfer->buffer = buffer; 171 transfer->size = size; 172 transfer->phone = phone; 173 174 transfer->request = async_send_3(phone, 175 DEV_IFACE_ID(USB_DEV_IFACE), 176 method, 177 endpoint, 178 size, 179 &transfer->reply); 180 181 *handle = (usb_handle_t) transfer; 182 183 return EOK; 184 } 185 186 /** Read buffer from HCD. 187 * 188 * @param phone Opened phone to HCD. 189 * @param hash Buffer hash (obtained after completing IN transaction). 190 * @param buffer Buffer where to store data data. 191 * @param size Buffer size. 192 * @param actual_size Storage where actual number of bytes transferred will 193 * be stored. 194 * @return Error status. 195 */ 196 static int read_buffer_in(int phone, ipcarg_t hash, 197 void *buffer, size_t size, size_t *actual_size) 198 { 199 ipc_call_t answer_data; 200 ipcarg_t answer_rc; 201 aid_t req; 202 int rc; 203 204 req = async_send_2(phone, 205 DEV_IFACE_ID(USB_DEV_IFACE), 206 IPC_M_USB_GET_BUFFER, 207 hash, 208 &answer_data); 209 210 rc = async_data_read_start(phone, buffer, size); 211 if (rc != EOK) { 212 async_wait_for(req, NULL); 213 return EINVAL; 214 } 215 216 async_wait_for(req, &answer_rc); 217 rc = (int)answer_rc; 218 219 if (rc != EOK) { 220 return rc; 221 } 222 223 *actual_size = IPC_GET_ARG1(answer_data); 224 225 return EOK; 226 } 227 228 /** Blocks caller until given USB transaction is finished. 229 * After the transaction is finished, the user can access all output data 230 * given to initial call function. 231 * 232 * @param handle Transaction handle. 233 * @return Error status. 234 * @retval EOK No error. 235 * @retval EBADMEM Invalid handle. 236 * @retval ENOENT Data buffer associated with transaction does not exist. 237 */ 238 int usb_drv_async_wait_for(usb_handle_t handle) 239 { 240 if (handle == 0) { 241 return EBADMEM; 242 } 243 244 int rc = EOK; 245 246 transfer_info_t *transfer = (transfer_info_t *) handle; 247 248 ipcarg_t answer_rc; 249 async_wait_for(transfer->request, &answer_rc); 250 251 if (answer_rc != EOK) { 252 rc = (int) answer_rc; 253 goto leave; 254 } 255 256 /* 257 * If the buffer is not NULL, we must accept some data. 258 */ 259 if ((transfer->buffer != NULL) && (transfer->size > 0)) { 260 /* 261 * The buffer hash identifies the data on the server 262 * side. 263 * We will use it when actually reading-in the data. 264 */ 265 ipcarg_t buffer_hash = IPC_GET_ARG1(transfer->reply); 266 if (buffer_hash == 0) { 267 rc = ENOENT; 268 goto leave; 269 } 270 271 size_t actual_size; 272 rc = read_buffer_in(transfer->phone, buffer_hash, 273 transfer->buffer, transfer->size, &actual_size); 274 275 if (rc != EOK) { 276 goto leave; 277 } 278 279 if (transfer->size_transferred) { 280 *(transfer->size_transferred) = actual_size; 281 } 282 } 283 284 leave: 285 free(transfer); 286 287 return rc; 288 } 289 290 /** Send interrupt data to device. */ 291 int usb_drv_async_interrupt_out(int phone, usb_endpoint_t endpoint, 292 void *buffer, size_t size, 293 usb_handle_t *handle) 294 { 295 return async_send_buffer(phone, 296 IPC_M_USB_INTERRUPT_OUT, 297 endpoint, 298 buffer, size, 299 handle); 300 } 301 302 /** Request interrupt data from device. */ 303 int usb_drv_async_interrupt_in(int phone, usb_endpoint_t endpoint, 304 void *buffer, size_t size, size_t *actual_size, 305 usb_handle_t *handle) 306 { 307 return async_recv_buffer(phone, 308 IPC_M_USB_INTERRUPT_IN, 309 endpoint, 310 buffer, size, actual_size, 311 handle); 312 } 53 313 54 314 /** -
uspace/lib/usb/usbdrv.h
r63b4f90 r91db50ac 41 41 int usb_drv_hc_connect(device_t *, unsigned int); 42 42 43 /** Set endpoint properties (direction, type). */ 44 int usb_drv_set_endpoint_properties(device_t *, usb_endpoint_t, 45 usb_transfer_type_t, usb_direction_t); 43 int usb_drv_async_interrupt_out(int, usb_endpoint_t, 44 void *, size_t, usb_handle_t *); 45 int usb_drv_async_interrupt_in(int, usb_endpoint_t, 46 void *, size_t, size_t *, usb_handle_t *); 46 47 47 /* First variant - repeat transfer type. */ 48 int usb_drv_interrupt_out(device_t *, usb_endpoint_t, 49 void *, size_t, usb_handle_t *); 50 51 /* Second variant - let the HC determine transfer type by endpoint number. */ 52 int usb_drv_transfer_out(device_t *, usb_endpoint_t, 53 void *, size_t, usb_handle_t *); 54 55 56 /** Wait for usb_drv_transfer_* to complete. */ 57 int usb_drv_wait_for(usb_handle_t); 48 int usb_drv_async_wait_for(usb_handle_t); 58 49 59 50 #endif
Note:
See TracChangeset
for help on using the changeset viewer.