Changeset 6c741e1d in mainline
- Timestamp:
- 2010-10-20T23:15:48Z (14 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 34586183
- Parents:
- b8507a1
- Location:
- uspace/srv/hw/bus/usb/hcd/virtual
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/hw/bus/usb/hcd/virtual/hub.c
rb8507a1 r6c741e1d 140 140 .descriptors = &descriptors, 141 141 }; 142 142 143 143 hub_device_t hub_dev; 144 144 … … 147 147 size_t i; 148 148 for (i = 0; i < HUB_PORT_COUNT; i++) { 149 hub_dev.ports[i].device = NULL; 150 hub_dev.ports[i].state = HUB_PORT_STATE_NOT_CONFIGURED; 151 } 152 hub_dev.status_change_bitmap = 0; 149 hub_port_t *port = &hub_dev.ports[i]; 150 151 port->device = NULL; 152 port->state = HUB_PORT_STATE_NOT_CONFIGURED; 153 port->status_change = 0; 154 } 153 155 154 156 usbvirt_connect_local(&virthub_dev); … … 161 163 size_t i; 162 164 for (i = 0; i < HUB_PORT_COUNT; i++) { 163 if (hub_dev.ports[i].device != NULL) { 165 hub_port_t *port = &hub_dev.ports[i]; 166 167 if (port->device != NULL) { 164 168 continue; 165 169 } 166 hub_dev.ports[i].device = device; 167 // TODO - notify the host about change 168 // bad, bad but it will work somehow at least 169 hub_dev.ports[i].state = HUB_PORT_STATE_ENABLED; 170 hub_dev.status_change_bitmap |= (1 << (i+1)); 170 171 port->device = device; 172 173 /* 174 * TODO: 175 * If the hub was configured, we can normally 176 * announce the plug-in. 177 * Otherwise, we will wait until hub is configured 178 * and announce changes in single burst. 179 */ 180 //if (port->state == HUB_PORT_STATE_DISCONNECTED) { 181 port->state = HUB_PORT_STATE_DISABLED; 182 set_port_status_change(port, HUB_STATUS_C_PORT_CONNECTION); 183 //} 184 171 185 return i; 172 186 } … … 180 194 size_t i; 181 195 for (i = 0; i < HUB_PORT_COUNT; i++) { 182 if (hub_dev.ports[i].device != device) { 196 hub_port_t *port = &hub_dev.ports[i]; 197 198 if (port->device != device) { 183 199 continue; 184 200 } 185 hub_dev.ports[i].device = NULL; 186 hub_dev.ports[i].state = HUB_PORT_STATE_DISCONNECTED; 187 hub_dev.status_change_bitmap |= (1 << (i+1)); 188 // TODO - notify the host of the removal 201 202 port->device = NULL; 203 port->state = HUB_PORT_STATE_DISCONNECTED; 204 205 set_port_status_change(port, HUB_STATUS_C_PORT_CONNECTION); 189 206 } 190 207 } … … 202 219 } 203 220 221 void hub_check_port_changes(void) 222 { 223 /* FIXME - what if HUB_PORT_COUNT is greater than 8. */ 224 uint8_t change_map = 0; 225 226 size_t i; 227 for (i = 0; i < HUB_PORT_COUNT; i++) { 228 hub_port_t *port = &hub_dev.ports[i]; 229 230 if (port->status_change != 0) { 231 change_map |= (1 << (i + 1)); 232 } 233 } 234 235 /* FIXME - do not send when it has not changed since previous run. */ 236 if (change_map != 0) { 237 virthub_dev.send_data(&virthub_dev, HUB_STATUS_CHANGE_PIPE, 238 &change_map, 1); 239 } 240 } 204 241 205 242 /** -
uspace/srv/hw/bus/usb/hcd/virtual/hub.h
rb8507a1 r6c741e1d 51 51 void hub_remove_device(virtdev_connection_t *); 52 52 bool hub_can_device_signal(virtdev_connection_t *); 53 void hub_check_port_changes(void); 53 54 54 55 #endif -
uspace/srv/hw/bus/usb/hcd/virtual/hubintern.h
rb8507a1 r6c741e1d 78 78 } hub_port_state_t; 79 79 80 typedef enum { 81 HUB_STATUS_C_PORT_CONNECTION = (1 << 0), 82 HUB_STATUS_C_PORT_ENABLE = (1 << 1), 83 HUB_STATUS_C_PORT_SUSPEND = (1 << 2), 84 HUB_STATUS_C_PORT_OVER_CURRENT = (1 << 3), 85 HUB_STATUS_C_PORT_RESET = (1 << 4), 86 /* HUB_STATUS_C_ = (1 << ), */ 87 } hub_status_change_t; 88 80 89 typedef struct { 81 90 virtdev_connection_t *device; 82 91 hub_port_state_t state; 92 uint16_t status_change; 83 93 } hub_port_t; 84 94 85 95 typedef struct { 86 96 hub_port_t ports[HUB_PORT_COUNT]; 87 /* FIXME - assuming HUB_PORT_COUNT < 8 */88 uint8_t status_change_bitmap;89 97 } hub_device_t; 90 98 … … 95 103 extern usbvirt_device_ops_t hub_ops; 96 104 105 void clear_port_status_change(hub_port_t *, uint16_t); 106 void set_port_status_change(hub_port_t *, uint16_t); 107 108 97 109 #endif 98 110 /** -
uspace/srv/hw/bus/usb/hcd/virtual/hubops.c
rb8507a1 r6c741e1d 43 43 #include "hubintern.h" 44 44 45 #define MAKE_BYTE(b0, b1, b2, b3, b4, b5, b6, b7) \ 46 (( \ 47 ((b0) << 0) \ 48 | ((b1) << 1) \ 49 | ((b2) << 2) \ 50 | ((b3) << 3) \ 51 | ((b4) << 4) \ 52 | ((b5) << 5) \ 53 | ((b6) << 6) \ 54 | ((b7) << 7) \ 55 )) 56 45 57 static int on_get_descriptor(struct usbvirt_device *dev, 46 58 usb_device_request_setup_packet_t *request, uint8_t *data); … … 82 94 } 83 95 96 /** Change port status and updates status change status fields. 97 */ 98 static void set_port_state(hub_port_t *port, hub_port_state_t state) 99 { 100 port->state = state; 101 if (state == HUB_PORT_STATE_POWERED_OFF) { 102 clear_port_status_change(port, HUB_STATUS_C_PORT_CONNECTION); 103 clear_port_status_change(port, HUB_STATUS_C_PORT_ENABLE); 104 clear_port_status_change(port, HUB_STATUS_C_PORT_RESET); 105 } 106 if (state == HUB_PORT_STATE_RESUMING) { 107 async_usleep(10*1000); 108 if (port->state == state) { 109 set_port_state(port, HUB_PORT_STATE_ENABLED); 110 } 111 } 112 if (state == HUB_PORT_STATE_RESETTING) { 113 async_usleep(10*1000); 114 if (port->state == state) { 115 set_port_status_change(port, HUB_STATUS_C_PORT_RESET); 116 set_port_state(port, HUB_PORT_STATE_ENABLED); 117 } 118 } 119 } 120 121 #define _GET_PORT(portvar, index) \ 122 do { \ 123 if (virthub_dev.state != USBVIRT_STATE_CONFIGURED) { \ 124 return EINVAL; \ 125 } \ 126 if (((index) == 0) || ((index) > HUB_PORT_COUNT)) { \ 127 return EINVAL; \ 128 } \ 129 } while (false); \ 130 hub_port_t *portvar = &hub_dev.ports[index] 131 132 84 133 static int clear_hub_feature(uint16_t feature) 85 134 { … … 88 137 89 138 static int clear_port_feature(uint16_t feature, uint16_t portindex) 90 { 139 { 140 _GET_PORT(port, portindex); 141 142 switch (feature) { 143 case USB_HUB_FEATURE_PORT_ENABLE: 144 if ((port->state != HUB_PORT_STATE_NOT_CONFIGURED) 145 && (port->state != HUB_PORT_STATE_POWERED_OFF)) { 146 set_port_state(port, HUB_PORT_STATE_DISABLED); 147 } 148 return EOK; 149 150 case USB_HUB_FEATURE_PORT_SUSPEND: 151 if (port->state != HUB_PORT_STATE_SUSPENDED) { 152 return EOK; 153 } 154 set_port_state(port, HUB_PORT_STATE_RESUMING); 155 return EOK; 156 157 case USB_HUB_FEATURE_PORT_POWER: 158 if (port->state != HUB_PORT_STATE_NOT_CONFIGURED) { 159 set_port_state(port, HUB_PORT_STATE_POWERED_OFF); 160 } 161 return EOK; 162 163 case USB_HUB_FEATURE_C_PORT_CONNECTION: 164 clear_port_status_change(port, HUB_STATUS_C_PORT_CONNECTION); 165 return EOK; 166 167 case USB_HUB_FEATURE_C_PORT_ENABLE: 168 clear_port_status_change(port, HUB_STATUS_C_PORT_ENABLE); 169 return EOK; 170 171 case USB_HUB_FEATURE_C_PORT_SUSPEND: 172 clear_port_status_change(port, HUB_STATUS_C_PORT_SUSPEND); 173 return EOK; 174 175 case USB_HUB_FEATURE_C_PORT_OVER_CURRENT: 176 clear_port_status_change(port, HUB_STATUS_C_PORT_OVER_CURRENT); 177 return EOK; 178 } 179 91 180 return ENOTSUP; 92 181 } … … 105 194 static int get_hub_status(void) 106 195 { 107 return ENOTSUP; 196 uint32_t hub_status = 0; 197 198 return virthub_dev.send_data(&virthub_dev, 0, &hub_status, 4); 108 199 } 109 200 110 201 static int get_port_status(uint16_t portindex) 111 202 { 112 return ENOTSUP; 203 _GET_PORT(port, portindex); 204 205 uint32_t status; 206 status = MAKE_BYTE( 207 /* Current connect status. */ 208 port->device == NULL ? 0 : 1, 209 /* Port enabled/disabled. */ 210 port->state == HUB_PORT_STATE_ENABLED ? 1 : 0, 211 /* Suspend. */ 212 (port->state == HUB_PORT_STATE_SUSPENDED) 213 || (port->state == HUB_PORT_STATE_RESUMING) ? 1 : 0, 214 /* Over-current. */ 215 0, 216 /* Reset. */ 217 port->state == HUB_PORT_STATE_RESETTING ? 1 : 0, 218 /* Reserved. */ 219 0, 0, 0) 220 221 | (MAKE_BYTE( 222 /* Port power. */ 223 port->state == HUB_PORT_STATE_POWERED_OFF ? 0 : 1, 224 /* Full-speed device. */ 225 0, 226 /* Reserved. */ 227 0, 0, 0, 0, 0, 0 228 )) << 8; 229 230 status |= (port->status_change << 16); 231 232 return virthub_dev.send_data(&virthub_dev, 0, &status, 4); 113 233 } 114 234 … … 121 241 static int set_port_feature(uint16_t feature, uint16_t portindex) 122 242 { 123 return ENOTSUP; 124 } 243 _GET_PORT(port, portindex); 244 245 switch (feature) { 246 case USB_HUB_FEATURE_PORT_RESET: 247 if (port->state != HUB_PORT_STATE_POWERED_OFF) { 248 set_port_state(port, HUB_PORT_STATE_RESETTING); 249 } 250 return EOK; 251 252 case USB_HUB_FEATURE_PORT_SUSPEND: 253 if (port->state == HUB_PORT_STATE_ENABLED) { 254 set_port_state(port, HUB_PORT_STATE_SUSPENDED); 255 } 256 return EOK; 257 258 case USB_HUB_FEATURE_PORT_POWER: 259 if (port->state == HUB_PORT_STATE_POWERED_OFF) { 260 set_port_state(port, HUB_PORT_STATE_DISCONNECTED); 261 } 262 return EOK; 263 } 264 return ENOTSUP; 265 } 266 267 #undef _GET_PORT 268 269 125 270 126 271 … … 186 331 } 187 332 333 void clear_port_status_change(hub_port_t *port, uint16_t change) 334 { 335 port->status_change &= (~change); 336 hub_check_port_changes(); 337 } 338 339 void set_port_status_change(hub_port_t *port, uint16_t change) 340 { 341 port->status_change |= change; 342 } 343 188 344 /** 189 345 * @}
Note:
See TracChangeset
for help on using the changeset viewer.