Changes in / [8c9e71a:d3a9ae74] in mainline
- Files:
-
- 5 added
- 3 deleted
- 13 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/arch/ia32/src/boot/boot.S
r8c9e71a rd3a9ae74 2 2 * Copyright (c) 2001 Jakub Jermar 3 3 * Copyright (c) 2005 Martin Decky 4 * Copyright (c) 2011 Martin Sucha5 4 * All rights reserved. 6 5 * … … 125 124 /* Map kernel and turn paging on */ 126 125 pm_status $status_non_pse 127 call map_kernel _non_pse126 call map_kernel 128 127 129 128 stack_init: … … 196 195 * 197 196 */ 198 map_kernel_non_pse: 197 .global map_kernel 198 map_kernel: 199 199 /* Paging features */ 200 200 movl %cr4, %ecx -
kernel/arch/ia32/src/smp/ap.S
r8c9e71a rd3a9ae74 28 28 # 29 29 30 /* 31 *Init code for application processors.32 */ 30 # 31 # Init code for application processors. 32 # 33 33 34 34 #include <arch/boot/boot.h> … … 46 46 KDATA=16 47 47 48 /* 49 * This piece of code is real-mode and is meant to be aligned at 4K boundary. 50 * The requirement for such an alignment comes from MP Specification's 51 * STARTUP IPI requirements. 52 */ 48 # This piece of code is real-mode and is meant to be aligned at 4K boundary. 49 # The requirement for such an alignment comes from MP Specification's STARTUP IPI 50 # requirements. 53 51 54 52 .align 4096 … … 59 57 movw %ax, %ds 60 58 61 /* initialize Global Descriptor Table register */ 62 lgdtl ap_gdtr 59 lgdtl ap_gdtr # initialize Global Descriptor Table register 63 60 64 /* switch to protected mode */65 61 movl %cr0, %eax 66 62 orl $1, %eax 67 movl %eax, %cr0 63 movl %eax, %cr0 # switch to protected mode 68 64 jmpl $KTEXT, $jump_to_kernel - BOOT_OFFSET + AP_BOOT_OFFSET 69 65 … … 74 70 movw %ax, %es 75 71 movw %ax, %ss 76 movl $KA2PA(ctx), %eax /* KA2PA((uintptr_t) &ctx) */72 movl $KA2PA(ctx), %eax # KA2PA((uintptr_t) &ctx) 77 73 movl (%eax), %esp 78 subl $0x80000000, %esp /* KA2PA(ctx.sp) */74 subl $0x80000000, %esp # KA2PA(ctx.sp) 79 75 80 /* 81 * Map kernel and turn paging on. 82 * We assume that when using SMP, PSE is always available 83 */ 84 call map_kernel_pse 76 call map_kernel # map kernel and turn paging on 85 77 86 addl $0x80000000, %esp /* PA2KA(ctx.sp) */78 addl $0x80000000, %esp # PA2KA(ctx.sp) 87 79 88 /* create the first stack frame */ 89 pushl $0 80 pushl $0 # create the first stack frame 90 81 movl %esp, %ebp 91 82 -
uspace/app/bdsh/cmds/modules/mkfile/mkfile.c
r8c9e71a rd3a9ae74 54 54 static struct option const long_options[] = { 55 55 {"size", required_argument, 0, 's'}, 56 {"sparse", no_argument, 0, 'p'},57 56 {"help", no_argument, 0, 'h'}, 58 57 {0, 0, 0, 0} … … 70 69 " -h, --help A short option summary\n" 71 70 " -s, --size sz Size of the file\n" 72 " -p, --sparse Create a sparse file\n"73 71 "\n" 74 72 "Size is a number followed by 'k', 'm' or 'g' for kB, MB, GB.\n" … … 117 115 ssize_t file_size; 118 116 ssize_t total_written; 119 ssize_t to_write, rc , rc2 = 0;117 ssize_t to_write, rc; 120 118 char *file_name; 121 119 void *buffer; 122 bool create_sparse = false;123 120 124 121 file_size = 0; … … 127 124 128 125 for (c = 0, optind = 0, opt_ind = 0; c != -1;) { 129 c = getopt_long(argc, argv, " ps:h", long_options, &opt_ind);126 c = getopt_long(argc, argv, "s:h", long_options, &opt_ind); 130 127 switch (c) { 131 128 case 'h': 132 129 help_cmd_mkfile(HELP_LONG); 133 130 return CMD_SUCCESS; 134 case 'p':135 create_sparse = true;136 break;137 131 case 's': 138 132 file_size = read_size(optarg); … … 162 156 } 163 157 164 if (create_sparse && file_size > 0) {165 const char byte = 0x00;166 167 if ((rc2 = lseek(fd, file_size - 1, SEEK_SET)) < 0)168 goto exit;169 170 rc2 = write(fd, &byte, sizeof(char));171 goto exit;172 }173 174 158 buffer = calloc(BUFFER_SIZE, 1); 175 159 if (buffer == NULL) { … … 190 174 } 191 175 192 free(buffer);193 exit:194 176 rc = close(fd); 195 196 if (rc != 0 || rc2 < 0) { 177 if (rc != 0) { 197 178 printf("%s: Error writing file (%zd).\n", cmdname, rc); 198 179 return CMD_FAILURE; 199 180 } 200 181 182 free(buffer); 183 201 184 return CMD_SUCCESS; 202 185 } -
uspace/drv/bus/usb/usbhub/Makefile
r8c9e71a rd3a9ae74 1 1 # 2 2 # Copyright (c) 2010 Vojtech Horky 3 # Copyright (c) 2011 Jan Vesely4 3 # All rights reserved. 5 4 # … … 44 43 SOURCES = \ 45 44 main.c \ 45 utils.c \ 46 46 usbhub.c \ 47 port .c47 ports.c 48 48 49 49 include $(USPACE_PREFIX)/Makefile.common -
uspace/drv/bus/usb/usbhub/main.c
r8c9e71a rd3a9ae74 1 1 /* 2 2 * Copyright (c) 2010 Vojtech Horky 3 * Copyright (c) 2011 Jan Vesely4 3 * All rights reserved. 5 4 * … … 39 38 #include <usb/dev/driver.h> 40 39 #include <usb/classes/classes.h> 41 #include <usb/debug.h>42 40 43 41 #include "usbhub.h" 42 #include "usbhub_private.h" 44 43 45 44 /** Hub status-change endpoint description. … … 57 56 58 57 /** 59 * USBhub driver operations58 * usb hub driver operations 60 59 * 61 60 * The most important one is add_device, which is set to usb_hub_add_device. … … 65 64 }; 66 65 67 /** Hub endpoints, excluding control endpoint. */ 66 /** 67 * hub endpoints, excluding control endpoint 68 */ 68 69 static usb_endpoint_description_t *usb_hub_endpoints[] = { 69 70 &hub_status_change_endpoint_description, 70 NULL ,71 NULL 71 72 }; 72 /** Static usb hub driver information. */ 73 74 /** 75 * static usb hub driver information 76 */ 73 77 static usb_driver_t usb_hub_driver = { 74 78 .name = NAME, … … 81 85 { 82 86 printf(NAME ": HelenOS USB hub driver.\n"); 87 83 88 usb_log_enable(USB_LOG_LEVEL_DEFAULT, NAME); 84 89 … … 89 94 * @} 90 95 */ 96 -
uspace/drv/bus/usb/usbhub/usbhub.c
r8c9e71a rd3a9ae74 1 1 /* 2 2 * Copyright (c) 2010 Matus Dekanek 3 * Copyright (c) 2011 Jan Vesely4 3 * All rights reserved. 5 4 * … … 39 38 #include <str_error.h> 40 39 #include <inttypes.h> 41 #include <stdio.h> 42 43 #include <usb/usb.h> 44 #include <usb/debug.h> 45 #include <usb/dev/pipes.h> 46 #include <usb/classes/classes.h> 40 41 #include <usb_iface.h> 47 42 #include <usb/ddfiface.h> 48 43 #include <usb/descriptor.h> … … 51 46 #include <usb/classes/hub.h> 52 47 #include <usb/dev/poll.h> 53 #include < usb_iface.h>48 #include <stdio.h> 54 49 55 50 #include "usbhub.h" 56 #include "status.h" 57 58 #define HUB_FNC_NAME "hub" 59 60 /** Standard get hub global status request */ 61 static const usb_device_request_setup_packet_t get_hub_status_request = { 62 .request_type = USB_HUB_REQ_TYPE_GET_HUB_STATUS, 63 .request = USB_HUB_REQUEST_GET_STATUS, 64 .index = 0, 65 .value = 0, 66 .length = sizeof(usb_hub_status_t), 67 }; 68 69 static int usb_set_first_configuration(usb_device_t *usb_device); 51 #include "usbhub_private.h" 52 #include "port_status.h" 53 #include <usb/usb.h> 54 #include <usb/dev/pipes.h> 55 #include <usb/classes/classes.h> 56 57 70 58 static usb_hub_info_t * usb_hub_info_create(usb_device_t *usb_dev); 59 71 60 static int usb_hub_process_hub_specific_info(usb_hub_info_t *hub_info); 72 static void usb_hub_over_current(const usb_hub_info_t *hub_info, 61 62 static int usb_hub_set_configuration(usb_hub_info_t *hub_info); 63 64 static int usb_hub_start_hub_fibril(usb_hub_info_t *hub_info); 65 66 static int usb_process_hub_over_current(usb_hub_info_t *hub_info, 73 67 usb_hub_status_t status); 74 static void usb_hub_global_interrupt(const usb_hub_info_t *hub_info); 68 69 static int usb_process_hub_local_power_change(usb_hub_info_t *hub_info, 70 usb_hub_status_t status); 71 72 static void usb_hub_process_global_interrupt(usb_hub_info_t *hub_info); 73 75 74 static void usb_hub_polling_terminated_callback(usb_device_t *device, 76 75 bool was_error, void *data); 77 76 77 78 //********************************************* 79 // 80 // hub driver code, initialization 81 // 82 //********************************************* 83 78 84 /** 79 85 * Initialize hub device driver fibril 80 86 * 81 * Creates hub representation and fibril that periodically checks hub 's status.87 * Creates hub representation and fibril that periodically checks hub`s status. 82 88 * Hub representation is passed to the fibril. 83 89 * @param usb_dev generic usb device information 84 90 * @return error code 85 91 */ 86 int usb_hub_add_device(usb_device_t *usb_dev) 87 { 88 assert(usb_dev); 89 /* Create driver soft-state structure */ 92 int usb_hub_add_device(usb_device_t *usb_dev) { 93 if (!usb_dev) return EINVAL; 90 94 usb_hub_info_t *hub_info = usb_hub_info_create(usb_dev); 91 if (hub_info == NULL) { 92 usb_log_error("Failed to create hun driver structure.\n"); 93 return ENOMEM; 94 } 95 96 /* Create hc connection */ 95 //create hc connection 97 96 usb_log_debug("Initializing USB wire abstraction.\n"); 98 97 int opResult = usb_hc_connection_initialize_from_device( 99 &hub_info->connection, hub_info->usb_device->ddf_dev); 100 if (opResult != EOK) { 101 usb_log_error("Could not initialize connection to device: %s\n", 98 &hub_info->connection, 99 hub_info->usb_device->ddf_dev); 100 if (opResult != EOK) { 101 usb_log_error("Could not initialize connection to device, " 102 " %s\n", 102 103 str_error(opResult)); 103 104 free(hub_info); … … 105 106 } 106 107 107 / * Set hub's first configuration. (There should be only one) */108 opResult = usb_ set_first_configuration(usb_dev);109 if (opResult != EOK) { 110 usb_log_error("Could not set hub configuration :%s\n",108 //set hub configuration 109 opResult = usb_hub_set_configuration(hub_info); 110 if (opResult != EOK) { 111 usb_log_error("Could not set hub configuration, %s\n", 111 112 str_error(opResult)); 112 113 free(hub_info); 113 114 return opResult; 114 115 } 115 116 116 //get port count and create attached_devs 117 117 opResult = usb_hub_process_hub_specific_info(hub_info); … … 123 123 } 124 124 125 usb_log_debug("Creating DDF function '" HUB_FNC_NAME "'.\n");125 usb_log_debug("Creating 'hub' function in DDF.\n"); 126 126 ddf_fun_t *hub_fun = ddf_fun_create(hub_info->usb_device->ddf_dev, 127 fun_exposed, HUB_FNC_NAME); 128 if (hub_fun == NULL) { 129 usb_log_error("Failed to create hub function.\n"); 127 fun_exposed, "hub"); 128 assert(hub_fun != NULL); 129 hub_fun->ops = NULL; 130 131 opResult = ddf_fun_bind(hub_fun); 132 assert(opResult == EOK); 133 134 opResult = usb_hub_start_hub_fibril(hub_info); 135 if (opResult != EOK) 130 136 free(hub_info); 131 return ENOMEM; 132 } 133 134 opResult = ddf_fun_bind(hub_fun); 135 if (opResult != EOK) { 136 usb_log_error("Failed to bind hub function: %s.\n", 137 str_error(opResult)); 138 free(hub_info); 139 ddf_fun_destroy(hub_fun); 140 return opResult; 141 } 142 143 opResult = usb_device_auto_poll(hub_info->usb_device, 0, 144 hub_port_changes_callback, ((hub_info->port_count + 1) / 8) + 1, 145 usb_hub_polling_terminated_callback, hub_info); 146 if (opResult != EOK) { 147 ddf_fun_destroy(hub_fun); 148 free(hub_info); 149 usb_log_error("Failed to create polling fibril: %s.\n", 150 str_error(opResult)); 151 return opResult; 152 } 153 usb_log_info("Controlling hub '%s' (%zu ports).\n", 154 hub_info->usb_device->ddf_dev->name, hub_info->port_count); 155 156 return EOK; 157 } 158 /*----------------------------------------------------------------------------*/ 137 return opResult; 138 } 139 159 140 /** Callback for polling hub for changes. 160 141 * … … 166 147 */ 167 148 bool hub_port_changes_callback(usb_device_t *dev, 168 uint8_t *change_bitmap, size_t change_bitmap_size, void *arg) 169 { 149 uint8_t *change_bitmap, size_t change_bitmap_size, void *arg) { 170 150 usb_log_debug("hub_port_changes_callback\n"); 171 usb_hub_info_t *hub = arg; 172 assert(hub); 173 174 /* It is an error condition if we didn't receive enough data */ 151 usb_hub_info_t *hub = (usb_hub_info_t *) arg; 152 153 /* FIXME: check that we received enough bytes. */ 175 154 if (change_bitmap_size == 0) { 176 return false;177 } 178 179 /* Lowest bit indicates global change */180 c onst bool change = change_bitmap[0] & 1;155 goto leave; 156 } 157 158 bool change; 159 change = ((uint8_t*) change_bitmap)[0] & 1; 181 160 if (change) { 182 usb_hub_global_interrupt(hub); 183 } 184 185 /* N + 1 bit indicates change on port N */ 186 size_t port = 1; 187 for (; port < hub->port_count + 1; port++) { 188 const bool change = (change_bitmap[port / 8] >> (port % 8)) & 1; 161 usb_hub_process_global_interrupt(hub); 162 } 163 164 size_t port; 165 for (port = 1; port < hub->port_count + 1; port++) { 166 bool change = (change_bitmap[port / 8] >> (port % 8)) % 2; 189 167 if (change) { 190 usb_hub_p ort_process_interrupt(&hub->ports[port], hub);168 usb_hub_process_port_interrupt(hub, port); 191 169 } 192 170 } 171 leave: 172 /* FIXME: proper interval. */ 173 async_usleep(1000 * 250); 174 193 175 return true; 194 176 } 195 /*----------------------------------------------------------------------------*/ 177 178 179 //********************************************* 180 // 181 // support functions 182 // 183 //********************************************* 184 196 185 /** 197 186 * create usb_hub_info_t structure … … 201 190 * @return basic usb_hub_info_t structure 202 191 */ 203 static usb_hub_info_t * usb_hub_info_create(usb_device_t *usb_dev) 204 { 205 assert(usb_dev);206 usb_hub_info_t *info = malloc(sizeof(usb_hub_info_t));207 if (!info)208 return NULL;209 210 info->usb_device = usb_dev; 211 212 info->ports = NULL;213 info->port_count = -1;214 fibril_mutex_initialize(&info->pending_ops_mutex); 215 fibril_ condvar_initialize(&info->pending_ops_cv);216 info->pending_ops_count = 0;217 218 return info;219 } 220 /*----------------------------------------------------------------------------*/ 192 static usb_hub_info_t * usb_hub_info_create(usb_device_t *usb_dev) { 193 usb_hub_info_t * result = malloc(sizeof (usb_hub_info_t)); 194 if (!result) return NULL; 195 result->usb_device = usb_dev; 196 result->status_change_pipe = usb_dev->pipes[0].pipe; 197 result->control_pipe = &usb_dev->ctrl_pipe; 198 result->is_default_address_used = false; 199 200 result->ports = NULL; 201 result->port_count = (size_t) - 1; 202 fibril_mutex_initialize(&result->port_mutex); 203 204 fibril_mutex_initialize(&result->pending_ops_mutex); 205 fibril_condvar_initialize(&result->pending_ops_cv); 206 result->pending_ops_count = 0; 207 return result; 208 } 209 221 210 /** 222 211 * Load hub-specific information into hub_info structure and process if needed 223 212 * 224 * Read port count and initialize structures holding per port information.225 * If there are anynon-removable devices, start initializing them.213 * Particularly read port count and initialize structure holding port 214 * information. If there are non-removable devices, start initializing them. 226 215 * This function is hub-specific and should be run only after the hub is 227 * configured using usb_ set_first_configuration function.216 * configured using usb_hub_set_configuration function. 228 217 * @param hub_info hub representation 229 218 * @return error code 230 219 */ 231 staticint usb_hub_process_hub_specific_info(usb_hub_info_t *hub_info)220 int usb_hub_process_hub_specific_info(usb_hub_info_t *hub_info) 232 221 { 233 assert(hub_info); 234 235 /* Get hub descriptor. */ 222 // get hub descriptor 236 223 usb_log_debug("Retrieving descriptor\n"); 237 u sb_pipe_t *control_pipe = &hub_info->usb_device->ctrl_pipe;238 239 usb_hub_descriptor_header_t descriptor; 224 uint8_t serialized_descriptor[USB_HUB_MAX_DESCRIPTOR_SIZE]; 225 int opResult; 226 240 227 size_t received_size; 241 int opResult = usb_request_get_descriptor(control_pipe,228 opResult = usb_request_get_descriptor(hub_info->control_pipe, 242 229 USB_REQUEST_TYPE_CLASS, USB_REQUEST_RECIPIENT_DEVICE, 243 USB_DESCTYPE_HUB, 0, 0, &descriptor, 244 sizeof(usb_hub_descriptor_t), &received_size); 230 USB_DESCTYPE_HUB, 0, 0, serialized_descriptor, 231 USB_HUB_MAX_DESCRIPTOR_SIZE, &received_size); 232 245 233 if (opResult != EOK) { 246 234 usb_log_error("Failed to receive hub descriptor: %s.\n", … … 248 236 return opResult; 249 237 } 250 251 usb_log_debug("Setting port count to %d.\n", descriptor.port_count); 252 hub_info->port_count = descriptor.port_count; 253 254 // TODO: +1 hack is no longer necessary 238 usb_log_debug2("Parsing descriptor\n"); 239 usb_hub_descriptor_t descriptor; 240 opResult = usb_deserialize_hub_desriptor( 241 serialized_descriptor, received_size, &descriptor); 242 if (opResult != EOK) { 243 usb_log_error("Could not parse descriptor: %s\n", 244 str_error(opResult)); 245 return opResult; 246 } 247 usb_log_debug("Setting port count to %d.\n", descriptor.ports_count); 248 hub_info->port_count = descriptor.ports_count; 249 255 250 hub_info->ports = 256 251 malloc(sizeof(usb_hub_port_t) * (hub_info->port_count + 1)); … … 261 256 size_t port; 262 257 for (port = 0; port < hub_info->port_count + 1; ++port) { 263 usb_hub_port_init(&hub_info->ports[port] , port, control_pipe);258 usb_hub_port_init(&hub_info->ports[port]); 264 259 } 265 260 266 261 const bool is_power_switched = 267 !(descriptor. characteristics & HUB_CHAR_NO_POWER_SWITCH_FLAG);262 !(descriptor.hub_characteristics & HUB_CHAR_NO_POWER_SWITCH_FLAG); 268 263 if (is_power_switched) { 269 264 usb_log_debug("Hub power switched\n"); 270 const bool per_port_power = descriptor. characteristics265 const bool per_port_power = descriptor.hub_characteristics 271 266 & HUB_CHAR_POWER_PER_PORT_FLAG; 272 267 273 268 for (port = 1; port <= hub_info->port_count; ++port) { 274 269 usb_log_debug("Powering port %zu.\n", port); 275 opResult = usb_hub_port_set_feature( 276 &hub_info->ports[port], USB_HUB_FEATURE_PORT_POWER); 270 opResult = usb_hub_set_port_feature( 271 hub_info->control_pipe, 272 port, USB_HUB_FEATURE_PORT_POWER); 277 273 if (opResult != EOK) { 278 274 usb_log_error("Cannot power on port %zu: %s.\n", … … 287 283 } 288 284 } 285 289 286 } else { 290 usb_log_debug("Power not switched, ports alwayspowered\n");287 usb_log_debug("Power not switched, not going to be powered\n"); 291 288 } 292 289 return EOK; 293 290 } 294 /*----------------------------------------------------------------------------*/ 295 /** 296 * Set configuration of and USB device291 292 /** 293 * Set configuration of hub 297 294 * 298 295 * Check whether there is at least one configuration and sets the first one. 299 296 * This function should be run prior to running any hub-specific action. 300 * @param usb_device usb devicerepresentation297 * @param hub_info hub representation 301 298 * @return error code 302 299 */ 303 static int usb_set_first_configuration(usb_device_t *usb_device) 304 { 305 assert(usb_device); 306 /* Get number of possible configurations from device descriptor */ 307 const size_t configuration_count = 308 usb_device->descriptors.device.configuration_count; 309 usb_log_debug("Hub has %d configurations.\n", configuration_count); 310 311 if (configuration_count < 1) { 300 static int usb_hub_set_configuration(usb_hub_info_t *hub_info) { 301 //device descriptor 302 usb_standard_device_descriptor_t *std_descriptor 303 = &hub_info->usb_device->descriptors.device; 304 usb_log_debug("Hub has %d configurations\n", 305 std_descriptor->configuration_count); 306 if (std_descriptor->configuration_count < 1) { 312 307 usb_log_error("There are no configurations available\n"); 313 308 return EINVAL; 314 309 } 315 310 316 // TODO: Make sure that there is enough data and the cast is correct317 311 usb_standard_configuration_descriptor_t *config_descriptor 318 312 = (usb_standard_configuration_descriptor_t *) 319 usb_device->descriptors.configuration; 320 321 /* Set configuration. Use the configuration that was in 322 * usb_device->descriptors.configuration i.e. The first one. */ 323 const int opResult = usb_request_set_configuration( 324 &usb_device->ctrl_pipe, config_descriptor->configuration_number); 313 hub_info->usb_device->descriptors.configuration; 314 315 /* Set configuration. */ 316 int opResult = usb_request_set_configuration( 317 &hub_info->usb_device->ctrl_pipe, 318 config_descriptor->configuration_number); 319 325 320 if (opResult != EOK) { 326 321 usb_log_error("Failed to set hub configuration: %s.\n", 327 322 str_error(opResult)); 328 } else { 329 usb_log_debug("\tUsed configuration %d\n", 330 config_descriptor->configuration_number); 331 } 332 return opResult; 333 } 334 /*----------------------------------------------------------------------------*/ 335 /** 336 * Process hub over current change 323 return opResult; 324 } 325 usb_log_debug("\tUsed configuration %d\n", 326 config_descriptor->configuration_number); 327 328 return EOK; 329 } 330 331 /** 332 * create and start fibril with hub control loop 333 * 334 * Before the fibril is started, the control pipe and host controller 335 * connection of the hub is open. 336 * 337 * @param hub_info hub representing structure 338 * @return error code 339 */ 340 static int usb_hub_start_hub_fibril(usb_hub_info_t *hub_info) { 341 int rc; 342 343 rc = usb_device_auto_poll(hub_info->usb_device, 0, 344 hub_port_changes_callback, ((hub_info->port_count + 1) / 8) + 1, 345 usb_hub_polling_terminated_callback, hub_info); 346 if (rc != EOK) { 347 usb_log_error("Failed to create polling fibril: %s.\n", 348 str_error(rc)); 349 free(hub_info); 350 return rc; 351 } 352 353 usb_log_info("Controlling hub `%s' (%zu ports).\n", 354 hub_info->usb_device->ddf_dev->name, hub_info->port_count); 355 return EOK; 356 } 357 358 //********************************************* 359 // 360 // change handling functions 361 // 362 //********************************************* 363 364 /** 365 * process hub over current change 337 366 * 338 367 * This means either to power off the hub or power it on. … … 341 370 * @return error code 342 371 */ 343 static void usb_hub_over_current(const usb_hub_info_t *hub_info, 344 usb_hub_status_t status) 345 { 346 if (status & USB_HUB_STATUS_OVER_CURRENT) { 347 /* Hub should remove power from all ports if it detects OC */ 348 usb_log_warning("Detected hub over-current condition, " 349 "all ports should be powered off."); 350 } else { 351 /* Over-current condition is gone, it is safe to turn the 352 * ports on. */ 353 size_t port; 372 static int usb_process_hub_over_current(usb_hub_info_t *hub_info, 373 usb_hub_status_t status) { 374 int opResult; 375 if (usb_hub_is_status(status, USB_HUB_FEATURE_HUB_OVER_CURRENT)) { 376 //poweroff all ports 377 unsigned int port; 354 378 for (port = 1; port <= hub_info->port_count; ++port) { 355 const int opResult = usb_hub_port_set_feature( 356 &hub_info->ports[port], USB_HUB_FEATURE_PORT_POWER); 379 opResult = usb_hub_clear_port_feature( 380 hub_info->control_pipe, port, 381 USB_HUB_FEATURE_PORT_POWER); 357 382 if (opResult != EOK) { 358 383 usb_log_warning( 359 "HUB OVER-CURRENT GONE: Cannot power on " 360 "port %d; %s\n", 384 "Cannot power off port %d; %s\n", 361 385 port, str_error(opResult)); 362 386 } 363 387 } 364 } 365 const int opResult = usb_request_clear_feature( 366 &hub_info->usb_device->ctrl_pipe, USB_REQUEST_TYPE_CLASS, 367 USB_REQUEST_RECIPIENT_DEVICE, 368 USB_HUB_FEATURE_C_HUB_LOCAL_POWER, 0); 369 if (opResult != EOK) { 370 usb_log_error( 371 "Failed to clear hub over-current change flag: %s.\n", 372 str_error(opResult)); 373 } 374 } 375 /*----------------------------------------------------------------------------*/ 376 /** 377 * Process hub interrupts. 378 * 379 * The change can be either in the over-current condition or local-power change. 388 } else { 389 //power all ports 390 unsigned int port; 391 for (port = 1; port <= hub_info->port_count; ++port) { 392 opResult = usb_hub_set_port_feature( 393 hub_info->control_pipe, port, 394 USB_HUB_FEATURE_PORT_POWER); 395 if (opResult != EOK) { 396 usb_log_warning( 397 "Cannot power off port %d; %s\n", 398 port, str_error(opResult)); 399 } 400 } 401 } 402 return opResult; 403 } 404 405 /** 406 * process hub local power change 407 * 408 * This change is ignored. 380 409 * @param hub_info hub instance 381 */ 382 static void usb_hub_global_interrupt(const usb_hub_info_t *hub_info) 383 { 384 assert(hub_info); 385 assert(hub_info->usb_device); 410 * @param status hub status bitmask 411 * @return error code 412 */ 413 static int usb_process_hub_local_power_change(usb_hub_info_t *hub_info, 414 usb_hub_status_t status) { 415 int opResult = EOK; 416 opResult = usb_hub_clear_feature(hub_info->control_pipe, 417 USB_HUB_FEATURE_C_HUB_LOCAL_POWER); 418 if (opResult != EOK) { 419 usb_log_error("Cannnot clear hub power change flag: " 420 "%s\n", 421 str_error(opResult)); 422 } 423 return opResult; 424 } 425 426 /** 427 * process hub interrupts 428 * 429 * The change can be either in the over-current condition or 430 * local-power change. 431 * @param hub_info hub instance 432 */ 433 static void usb_hub_process_global_interrupt(usb_hub_info_t *hub_info) { 386 434 usb_log_debug("Global interrupt on a hub\n"); 387 usb_pipe_t *control_pipe = &hub_info->usb_device->ctrl_pipe; 388 389 usb_hub_status_t status; 435 usb_pipe_t *pipe = hub_info->control_pipe; 436 int opResult; 437 438 usb_port_status_t status; 390 439 size_t rcvd_size; 391 /* NOTE: We can't use standard USB GET_STATUS request, because 392 * hubs reply is 4byte instead of 2 */ 393 const int opResult = usb_pipe_control_read(control_pipe, 394 &get_hub_status_request, sizeof(get_hub_status_request), 395 &status, sizeof(usb_hub_status_t), &rcvd_size); 440 usb_device_request_setup_packet_t request; 441 //int opResult; 442 usb_hub_set_hub_status_request(&request); 443 //endpoint 0 444 445 opResult = usb_pipe_control_read( 446 pipe, 447 &request, sizeof (usb_device_request_setup_packet_t), 448 &status, 4, &rcvd_size 449 ); 396 450 if (opResult != EOK) { 397 451 usb_log_error("Could not get hub status: %s\n", … … 399 453 return; 400 454 } 401 if (rcvd_size != sizeof (usb_hub_status_t)) {455 if (rcvd_size != sizeof (usb_port_status_t)) { 402 456 usb_log_error("Received status has incorrect size\n"); 403 457 return; 404 458 } 405 406 /* Handle status changes */ 407 if (status & USB_HUB_STATUS_C_OVER_CURRENT) { 408 usb_hub_over_current(hub_info, status); 409 } 410 411 if (status & USB_HUB_STATUS_C_LOCAL_POWER) { 412 /* NOTE: Handling this is more complicated. 413 * If the transition is from bus power to local power, all 414 * is good and we may signal the parent hub that we don't 415 * need the power. 416 * If the transition is from local power to bus power 417 * the hub should turn off all the ports and devices need 418 * to be reinitialized taking into account the limited power 419 * that is now available. 420 * There is no support for power distribution in HelenOS, 421 * (or other OSes/hub devices that I've seen) so this is not 422 * implemented. 423 * Just ACK the change. 424 */ 425 const int opResult = usb_request_clear_feature( 426 control_pipe, USB_REQUEST_TYPE_CLASS, 427 USB_REQUEST_RECIPIENT_DEVICE, 428 USB_HUB_FEATURE_C_HUB_LOCAL_POWER, 0); 429 if (opResult != EOK) { 430 usb_log_error( 431 "Failed to clear hub power change flag: %s.\n", 432 str_error(opResult)); 433 } 434 } 435 } 436 /*----------------------------------------------------------------------------*/ 459 //port reset 460 if ( 461 usb_hub_is_status(status, 16 + USB_HUB_FEATURE_C_HUB_OVER_CURRENT)) { 462 usb_process_hub_over_current(hub_info, status); 463 } 464 if ( 465 usb_hub_is_status(status, 16 + USB_HUB_FEATURE_C_HUB_LOCAL_POWER)) { 466 usb_process_hub_local_power_change(hub_info, status); 467 } 468 } 469 437 470 /** 438 471 * callback called from hub polling fibril when the fibril terminates … … 444 477 */ 445 478 static void usb_hub_polling_terminated_callback(usb_device_t *device, 446 bool was_error, void *data) 447 { 448 usb_hub_info_t *hub = data; 479 bool was_error, void *data) { 480 usb_hub_info_t * hub = data; 449 481 assert(hub); 450 482 … … 460 492 */ 461 493 if (hub->pending_ops_count > 0) { 494 fibril_mutex_lock(&hub->port_mutex); 462 495 size_t port; 463 496 for (port = 0; port < hub->port_count; port++) { 464 usb_hub_port_reset_fail(&hub->ports[port]); 497 usb_hub_port_t *the_port = hub->ports + port; 498 fibril_mutex_lock(&the_port->reset_mutex); 499 the_port->reset_completed = true; 500 the_port->reset_okay = false; 501 fibril_condvar_broadcast(&the_port->reset_cv); 502 fibril_mutex_unlock(&the_port->reset_mutex); 465 503 } 504 fibril_mutex_unlock(&hub->port_mutex); 466 505 } 467 506 /* And now wait for them. */ … … 477 516 free(hub); 478 517 } 518 519 520 521 479 522 /** 480 523 * @} -
uspace/drv/bus/usb/usbhub/usbhub.h
r8c9e71a rd3a9ae74 1 1 /* 2 2 * Copyright (c) 2010 Vojtech Horky 3 * Copyright (c) 2011 Vojtech Horky4 3 * All rights reserved. 5 4 * … … 27 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 27 */ 28 29 29 /** @addtogroup drvusbhub 30 30 * @{ … … 49 49 #define NAME "usbhub" 50 50 51 #include "port .h"51 #include "ports.h" 52 52 53 53 /** Information about attached hub. */ … … 56 56 size_t port_count; 57 57 58 /** Attached device handles, for each port one */58 /** attached device handles, for each port one */ 59 59 usb_hub_port_t *ports; 60 60 61 /** Connection to hcd */ 61 fibril_mutex_t port_mutex; 62 63 /** connection to hcd */ 62 64 usb_hc_connection_t connection; 63 65 64 /** Generic usb device data*/ 65 usb_device_t *usb_device; 66 /** default address is used indicator 67 * 68 * If default address is requested by this device, it cannot 69 * be requested by the same hub again, otherwise a deadlock will occur. 70 */ 71 bool is_default_address_used; 72 73 /** convenience pointer to status change pipe 74 * 75 * Status change pipe is initialized in usb_device structure. This is 76 * pointer into this structure, so that it does not have to be 77 * searched again and again for the 'right pipe'. 78 */ 79 usb_pipe_t * status_change_pipe; 80 81 /** convenience pointer to control pipe 82 * 83 * Control pipe is initialized in usb_device structure. This is 84 * pointer into this structure, so that it does not have to be 85 * searched again and again for the 'right pipe'. 86 */ 87 usb_pipe_t * control_pipe; 88 89 /** generic usb device data*/ 90 usb_device_t * usb_device; 66 91 67 92 /** Number of pending operations on the mutex to prevent shooting … … 76 101 /** Condition variable for pending_ops_count. */ 77 102 fibril_condvar_t pending_ops_cv; 103 78 104 }; 79 105 -
uspace/lib/usb/include/usb/classes/hub.h
r8c9e71a rd3a9ae74 72 72 uint8_t port_count; 73 73 /** Characteristics bitmask. */ 74 uint8_t characteristics; 75 #define HUB_CHAR_POWER_PER_PORT_FLAG (1 << 0) 76 #define HUB_CHAR_NO_POWER_SWITCH_FLAG (1 << 1) 77 /* Unused part of characteristics field */ 78 uint8_t characteristics_reserved; 74 uint16_t characteristics; 79 75 /** Time from power-on to stabilization of current on the port. */ 80 76 uint8_t power_good_time; … … 96 92 97 93 /** Number of downstream ports that this hub supports */ 98 uint8_t port _count;94 uint8_t ports_count; 99 95 100 96 /** … … 123 119 */ 124 120 uint16_t hub_characteristics; 121 #define HUB_CHAR_POWER_PER_PORT_FLAG (1 << 0) 122 #define HUB_CHAR_NO_POWER_SWITCH_FLAG (1 << 1) 125 123 126 124 /** … … 216 214 * Maximum size of usb hub descriptor in bytes 217 215 */ 218 /* 7 (basic size) + 2*32 (port bitmasks) */ 219 #define USB_HUB_MAX_DESCRIPTOR_SIZE 71 216 extern size_t USB_HUB_MAX_DESCRIPTOR_SIZE; 217 218 219 220 221 222 220 223 221 224 #endif -
uspace/lib/usbdev/include/usb/dev/pipes.h
r8c9e71a rd3a9ae74 183 183 int usb_pipe_write(usb_pipe_t *, void *, size_t); 184 184 185 int usb_pipe_control_read(usb_pipe_t *, constvoid *, size_t,185 int usb_pipe_control_read(usb_pipe_t *, void *, size_t, 186 186 void *, size_t, size_t *); 187 187 int usb_pipe_control_write(usb_pipe_t *, void *, size_t, -
uspace/lib/usbdev/src/pipesio.c
r8c9e71a rd3a9ae74 328 328 */ 329 329 static int usb_pipe_control_read_no_check(usb_pipe_t *pipe, 330 constvoid *setup_buffer, size_t setup_buffer_size,330 void *setup_buffer, size_t setup_buffer_size, 331 331 void *data_buffer, size_t data_buffer_size, size_t *data_transfered_size) 332 332 { … … 411 411 */ 412 412 int usb_pipe_control_read(usb_pipe_t *pipe, 413 constvoid *setup_buffer, size_t setup_buffer_size,413 void *setup_buffer, size_t setup_buffer_size, 414 414 void *data_buffer, size_t data_buffer_size, size_t *data_transfered_size) 415 415 { -
uspace/srv/fs/mfs/mfs_ops.c
r8c9e71a rd3a9ae74 143 143 { 144 144 enum cache_mode cmode; 145 struct mfs_superblock *sb = NULL;146 struct mfs3_superblock *sb3 = NULL;147 struct mfs_sb_info *sbi = NULL;148 struct mfs_instance *instance = NULL;145 struct mfs_superblock *sb; 146 struct mfs3_superblock *sb3; 147 struct mfs_sb_info *sbi; 148 struct mfs_instance *instance; 149 149 bool native, longnames; 150 150 mfs_version_t version; … … 166 166 sbi = malloc(sizeof(*sbi)); 167 167 if (!sbi) { 168 rc = ENOMEM;169 goto out_error;168 block_fini(service_id); 169 return ENOMEM; 170 170 } 171 171 … … 173 173 instance = malloc(sizeof(*instance)); 174 174 if (!instance) { 175 rc = ENOMEM; 176 goto out_error; 175 free(sbi); 176 block_fini(service_id); 177 return ENOMEM; 177 178 } 178 179 179 180 sb = malloc(MFS_SUPERBLOCK_SIZE); 180 181 if (!sb) { 181 rc = ENOMEM; 182 goto out_error; 182 free(instance); 183 free(sbi); 184 block_fini(service_id); 185 return ENOMEM; 183 186 } 184 187 185 188 /* Read the superblock */ 186 189 rc = block_read_direct(service_id, MFS_SUPERBLOCK << 1, 2, sb); 187 if (rc != EOK) 188 goto out_error; 190 if (rc != EOK) { 191 free(instance); 192 free(sbi); 193 free(sb); 194 block_fini(service_id); 195 return rc; 196 } 189 197 190 198 sb3 = (struct mfs3_superblock *) sb; … … 199 207 /*Not recognized*/ 200 208 mfsdebug("magic number not recognized\n"); 201 rc = ENOTSUP; 202 goto out_error; 209 free(instance); 210 free(sbi); 211 free(sb); 212 block_fini(service_id); 213 return ENOTSUP; 203 214 } 204 215 … … 245 256 MFS_MAX_NAME_LEN; 246 257 } 247 248 if (sbi->log2_zone_size != 0) {249 /* In MFS, file space is allocated per zones.250 * Zones are a collection of consecutive blocks on disk.251 *252 * The current MFS implementation supports only filesystems253 * where the size of a zone is equal to the254 * size of a block.255 */256 rc = ENOTSUP;257 goto out_error;258 }259 260 258 sbi->itable_off = 2 + sbi->ibmap_blocks + sbi->zbmap_blocks; 259 260 free(sb); 261 261 262 262 rc = block_cache_init(service_id, sbi->block_size, 0, cmode); 263 263 if (rc != EOK) { 264 free(instance); 265 free(sbi); 266 block_cache_fini(service_id); 267 block_fini(service_id); 264 268 mfsdebug("block cache initialization failed\n"); 265 rc = EINVAL; 266 goto out_error; 269 return EINVAL; 267 270 } 268 271 … … 292 295 *linkcnt = 1; 293 296 294 free(sb);295 296 297 return mfs_node_put(fn); 297 298 out_error:299 block_fini(service_id);300 if (sb)301 free(sb);302 if (sbi)303 free(sbi);304 if(instance)305 free(instance);306 return rc;307 298 } 308 299 … … 889 880 struct mfs_ino_info *ino_i = mnode->ino_i; 890 881 const size_t bs = sbi->block_size; 891 size_t bytes = min(len, bs - (pos % bs)); 882 size_t bytes = min(len, bs - pos % bs); 883 size_t boundary = ROUND_UP(ino_i->i_size, bs); 892 884 uint32_t block; 893 885 … … 895 887 flags = BLOCK_FLAGS_NOREAD; 896 888 897 r = mfs_read_map(&block, mnode, pos); 898 if (r != EOK) 899 goto out_err; 900 901 if (block == 0) { 902 /*Writing in a sparse block*/ 889 if (pos < boundary) { 890 r = mfs_read_map(&block, mnode, pos); 891 if (r != EOK) 892 goto out_err; 893 894 if (block == 0) { 895 /*Writing in a sparse block*/ 896 r = mfs_alloc_zone(mnode->instance, &block); 897 if (r != EOK) 898 goto out_err; 899 flags = BLOCK_FLAGS_NOREAD; 900 } 901 } else { 903 902 uint32_t dummy; 904 903 … … 906 905 if (r != EOK) 907 906 goto out_err; 908 907 909 908 r = mfs_write_map(mnode, pos, block, &dummy); 910 909 if (r != EOK) 911 910 goto out_err; 912 913 flags = BLOCK_FLAGS_NOREAD;914 911 } 915 912 … … 919 916 goto out_err; 920 917 921 if (flags == BLOCK_FLAGS_NOREAD) 922 memset(b->data, 0, sbi->block_size); 923 924 async_data_write_finalize(callid, b->data + (pos % bs), bytes); 918 async_data_write_finalize(callid, b->data + pos % bs, bytes); 925 919 b->dirty = true; 926 920 … … 931 925 } 932 926 933 if (pos + bytes > ino_i->i_size) { 934 ino_i->i_size = pos + bytes; 935 ino_i->dirty = true; 936 } 927 ino_i->i_size = pos + bytes; 928 ino_i->dirty = true; 937 929 r = mfs_node_put(fn); 938 *nsize = ino_i->i_size;930 *nsize = pos + bytes; 939 931 *wbytes = bytes; 940 932 return r; -
uspace/srv/fs/mfs/mfs_rw.c
r8c9e71a rd3a9ae74 31 31 */ 32 32 33 #include <align.h>34 33 #include "mfs.h" 35 34 … … 71 70 int rblock = pos / block_size; 72 71 73 if ( ROUND_UP(mnode->ino_i->i_size, sbi->block_size)< pos) {72 if (mnode->ino_i->i_size < pos) { 74 73 /*Trying to read beyond the end of file*/ 75 74 r = EOK; -
uspace/srv/hw/irc/apic/apic.c
r8c9e71a rd3a9ae74 206 206 } 207 207 208 int rc = pio_enable((void *) IO_APIC_BASE, IO_APIC_SIZE, 209 (void **) &io_apic); 210 if (rc != EOK) { 211 printf("%s: Failed to enable PIO for APIC: %d\n", NAME, rc); 208 if (pio_enable((void *) IO_APIC_BASE, IO_APIC_SIZE, 209 (void **) &io_apic) != EOK) 212 210 return false; 213 }214 211 215 212 async_set_client_connection(apic_connection);
Note:
See TracChangeset
for help on using the changeset viewer.