Changeset 25458
- Timestamp:
- 05/11/08 13:55:12 (6 days ago)
- Files:
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
haiku/trunk/src/add-ons/kernel/drivers/network/usb_ecm/Driver.h
r25439 r25458 36 36 } _PACKED ethernet_functional_descriptor; 37 37 38 /* notification definitions */ 39 #define CDC_NOTIFY_NETWORK_CONNECTION 0x00 40 #define CDC_NOTIFY_CONNECTION_SPEED_CHANGE 0x2a 41 42 typedef struct cdc_notification_s { 43 uint8 request_type; 44 uint8 notification_code; 45 uint16 value; 46 uint16 index; 47 uint16 data_length; 48 uint8 data[0]; 49 } _PACKED cdc_notification; 50 51 typedef struct cdc_connection_speed_s { 52 uint32 upstream_speed; /* in bits/s */ 53 uint32 downstream_speed; /* in bits/s */ 54 } _PACKED cdc_connection_speed; 55 38 56 extern usb_module_info *gUSBModule; 39 57 haiku/trunk/src/add-ons/kernel/drivers/network/usb_ecm/ECMDevice.cpp
r25439 r25458 5 5 */ 6 6 #include <ether_driver.h> 7 #include <net/if_media.h> 7 8 #include <string.h> 8 9 #include <stdlib.h> … … 21 22 fMACAddressIndex(0), 22 23 fMaxSegmentSize(0), 23 f ControlEndpoint(0),24 fNotifyEndpoint(0), 24 25 fReadEndpoint(0), 25 fWriteEndpoint(0) 26 fWriteEndpoint(0), 27 fNotifyReadSem(-1), 28 fNotifyWriteSem(-1), 29 fNotifyBuffer(NULL), 30 fNotifyBufferLength(0), 31 fLinkStateChangeSem(-1), 32 fHasConnection(false), 33 fDownstreamSpeed(0), 34 fUpstreamSpeed(0) 26 35 { 27 36 const usb_device_descriptor *deviceDescriptor … … 51 60 // try to find and interpret the union and ethernet functional 52 61 // descriptors 62 foundUnionDescriptor = foundEthernetDescriptor = false; 53 63 for (size_t j = 0; j < interface->generic_count; j++) { 54 64 usb_generic_descriptor *generic = &interface->generic[j]->generic; … … 104 114 105 115 fControlInterfaceIndex = controlIndex; 106 fControlEndpoint = interface->endpoint[0].handle; 116 fNotifyEndpoint = interface->endpoint[0].handle; 117 118 // setup notify buffer and try to schedule a notification transfer 119 fNotifyBufferLength = 64; 120 fNotifyBuffer = (uint8 *)malloc(fNotifyBufferLength); 121 if (fNotifyBuffer == NULL) { 122 TRACE_ALWAYS("out of memory for notify buffer allocation\n"); 123 return; 124 } 125 126 if (gUSBModule->queue_interrupt(fNotifyEndpoint, fNotifyBuffer, 127 fNotifyBufferLength, _NotifyCallback, this) != B_OK) { 128 // we cannot use notifications - hardcode to active connection 129 fHasConnection = true; 130 fDownstreamSpeed = 1000 * 1000 * 10; // 10Mbps 131 fUpstreamSpeed = 1000 * 1000 * 10; // 10Mbps 132 } 107 133 108 134 if (dataIndex >= config->interface_count) { … … 127 153 128 154 fDataInterfaceIndex = dataIndex; 129 fNotifyRead = create_sem(0, DRIVER_NAME"_notify_read");130 if (fNotifyRead < B_OK) {155 fNotifyReadSem = create_sem(0, DRIVER_NAME"_notify_read"); 156 if (fNotifyReadSem < B_OK) { 131 157 TRACE_ALWAYS("failed to create read notify sem\n"); 132 158 return; 133 159 } 134 160 135 fNotifyWrite = create_sem(0, DRIVER_NAME"_notify_write");136 if (fNotifyWrite < B_OK) {161 fNotifyWriteSem = create_sem(0, DRIVER_NAME"_notify_write"); 162 if (fNotifyWriteSem < B_OK) { 137 163 TRACE_ALWAYS("failed to create write notify sem\n"); 138 delete_sem(fNotifyRead);139 164 return; 140 165 } … … 146 171 ECMDevice::~ECMDevice() 147 172 { 148 delete_sem(fNotifyRead); 149 delete_sem(fNotifyWrite); 173 if (fNotifyReadSem >= B_OK) 174 delete_sem(fNotifyReadSem); 175 if (fNotifyWriteSem >= B_OK) 176 delete_sem(fNotifyWriteSem); 177 178 gUSBModule->cancel_queued_transfers(fNotifyEndpoint); 179 free(fNotifyBuffer); 150 180 } 151 181 … … 245 275 } 246 276 247 result = acquire_sem_etc(fNotifyRead , 1, B_CAN_INTERRUPT, 0);277 result = acquire_sem_etc(fNotifyReadSem, 1, B_CAN_INTERRUPT, 0); 248 278 if (result < B_OK) { 249 279 *numBytes = 0; … … 251 281 } 252 282 253 if (fStatusRead != B_OK ) {283 if (fStatusRead != B_OK && fStatusRead != B_CANCELED) { 254 284 TRACE_ALWAYS("device status error 0x%08lx\n", fStatusRead); 255 285 result = gUSBModule->clear_feature(fReadEndpoint, … … 282 312 } 283 313 284 result = acquire_sem_etc(fNotifyWrite , 1, B_CAN_INTERRUPT, 0);314 result = acquire_sem_etc(fNotifyWriteSem, 1, B_CAN_INTERRUPT, 0); 285 315 if (result < B_OK) { 286 316 *numBytes = 0; … … 288 318 } 289 319 290 if (fStatusWrite != B_OK ) {320 if (fStatusWrite != B_OK && fStatusWrite != B_CANCELED) { 291 321 TRACE_ALWAYS("device status error 0x%08lx\n", fStatusWrite); 292 322 result = gUSBModule->clear_feature(fWriteEndpoint, … … 319 349 return B_OK; 320 350 351 #if HAIKU_TARGET_PLATFORM_HAIKU 352 case ETHER_SET_LINK_STATE_SEM: 353 fLinkStateChangeSem = *(sem_id *)buffer; 354 return B_OK; 355 356 case ETHER_GET_LINK_STATE: 357 { 358 ether_link_state *state = (ether_link_state *)buffer; 359 state->media = IFM_ETHER | IFM_FULL_DUPLEX 360 | (fHasConnection ? IFM_ACTIVE : 0); 361 state->quality = 1000; 362 state->speed = fDownstreamSpeed / 1000; 363 return B_OK; 364 } 365 #endif 366 321 367 default: 322 368 TRACE_ALWAYS("unsupported ioctl %lu\n", op); … … 368 414 device->fActualLengthRead = actualLength; 369 415 device->fStatusRead = status; 370 release_sem_etc(device->fNotifyRead , 1, B_DO_NOT_RESCHEDULE);416 release_sem_etc(device->fNotifyReadSem, 1, B_DO_NOT_RESCHEDULE); 371 417 } 372 418 … … 379 425 device->fActualLengthWrite = actualLength; 380 426 device->fStatusWrite = status; 381 release_sem_etc(device->fNotifyWrite, 1, B_DO_NOT_RESCHEDULE); 382 } 427 release_sem_etc(device->fNotifyWriteSem, 1, B_DO_NOT_RESCHEDULE); 428 } 429 430 431 void 432 ECMDevice::_NotifyCallback(void *cookie, int32 status, void *data, 433 uint32 actualLength) 434 { 435 if (status == B_CANCELED) 436 return; 437 438 ECMDevice *device = (ECMDevice *)cookie; 439 if (status == B_OK && actualLength >= sizeof(cdc_notification)) { 440 bool linkStateChange = false; 441 cdc_notification *notification 442 = (cdc_notification *)device->fNotifyBuffer; 443 444 switch (notification->notification_code) { 445 case CDC_NOTIFY_NETWORK_CONNECTION: 446 TRACE("connection state change to %d\n", notification->value); 447 device->fHasConnection = notification->value > 0; 448 linkStateChange = true; 449 break; 450 451 case CDC_NOTIFY_CONNECTION_SPEED_CHANGE: 452 { 453 if (notification->data_length < sizeof(cdc_connection_speed) 454 || actualLength < sizeof(cdc_notification) 455 + sizeof(cdc_connection_speed)) { 456 TRACE_ALWAYS("not enough data in connection speed change\n"); 457 break; 458 } 459 460 cdc_connection_speed *speed; 461 speed = (cdc_connection_speed *)¬ification->data[0]; 462 device->fUpstreamSpeed = speed->upstream_speed; 463 device->fDownstreamSpeed = speed->downstream_speed; 464 device->fHasConnection = true; 465 TRACE("connection speed change to %ld/%ld\n", 466 speed->downstream_speed, speed->upstream_speed); 467 linkStateChange = true; 468 break; 469 } 470 471 default: 472 TRACE_ALWAYS("unsupported notification 0x%02x\n", 473 notification->notification_code); 474 break; 475 } 476 477 if (linkStateChange && device->fLinkStateChangeSem >= B_OK) 478 release_sem_etc(device->fLinkStateChangeSem, 1, B_DO_NOT_RESCHEDULE); 479 } 480 481 if (status != B_OK) { 482 TRACE_ALWAYS("device status error 0x%08lx\n", status); 483 if (gUSBModule->clear_feature(device->fNotifyEndpoint, 484 USB_FEATURE_ENDPOINT_HALT) != B_OK) 485 TRACE_ALWAYS("failed to clear halt state\n"); 486 } 487 488 // schedule next notification buffer 489 gUSBModule->queue_interrupt(device->fNotifyEndpoint, device->fNotifyBuffer, 490 device->fNotifyBufferLength, _NotifyCallback, device); 491 } haiku/trunk/src/add-ons/kernel/drivers/network/usb_ecm/ECMDevice.h
r25439 r25458 34 34 static void _WriteCallback(void *cookie, int32 status, 35 35 void *data, uint32 actualLength); 36 static void _NotifyCallback(void *cookie, int32 status, 37 void *data, uint32 actualLength); 36 38 37 39 status_t _ReadMACAddress(); 38 40 41 // state tracking 39 42 status_t fStatus; 40 43 bool fOpen; … … 42 45 usb_device fDevice; 43 46 44 uint8 fMACAddress[6]; 45 47 // interface and device infos 46 48 uint8 fControlInterfaceIndex; 47 49 uint8 fDataInterfaceIndex; … … 49 51 uint16 fMaxSegmentSize; 50 52 51 usb_pipe fControlEndpoint; 53 // pipes for notifications and data io 54 usb_pipe fNotifyEndpoint; 52 55 usb_pipe fReadEndpoint; 53 56 usb_pipe fWriteEndpoint; 54 57 58 // data stores for async usb transfers 55 59 uint32 fActualLengthRead; 56 60 uint32 fActualLengthWrite; 57 61 int32 fStatusRead; 58 62 int32 fStatusWrite; 59 sem_id fNotifyRead; 60 sem_id fNotifyWrite; 63 sem_id fNotifyReadSem; 64 sem_id fNotifyWriteSem; 65 66 uint8 * fNotifyBuffer; 67 uint32 fNotifyBufferLength; 68 69 // connection data 70 sem_id fLinkStateChangeSem; 71 uint8 fMACAddress[6]; 72 bool fHasConnection; 73 uint32 fDownstreamSpeed; 74 uint32 fUpstreamSpeed; 61 75 }; 62 76
