aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/firewire/fw-device.c93
1 files changed, 36 insertions, 57 deletions
diff --git a/drivers/firewire/fw-device.c b/drivers/firewire/fw-device.c
index a834221b7588..59451f524fc3 100644
--- a/drivers/firewire/fw-device.c
+++ b/drivers/firewire/fw-device.c
@@ -138,9 +138,6 @@ fw_unit_uevent(struct device *dev, char **envp, int num_envp,
138 int length = 0; 138 int length = 0;
139 int i = 0; 139 int i = 0;
140 140
141 if (!is_fw_unit(dev))
142 goto out;
143
144 get_modalias(unit, modalias, sizeof modalias); 141 get_modalias(unit, modalias, sizeof modalias);
145 142
146 if (add_uevent_var(envp, num_envp, &i, 143 if (add_uevent_var(envp, num_envp, &i,
@@ -148,7 +145,6 @@ fw_unit_uevent(struct device *dev, char **envp, int num_envp,
148 "MODALIAS=%s", modalias)) 145 "MODALIAS=%s", modalias))
149 return -ENOMEM; 146 return -ENOMEM;
150 147
151 out:
152 envp[i] = NULL; 148 envp[i] = NULL;
153 149
154 return 0; 150 return 0;
@@ -157,7 +153,6 @@ fw_unit_uevent(struct device *dev, char **envp, int num_envp,
157struct bus_type fw_bus_type = { 153struct bus_type fw_bus_type = {
158 .name = "firewire", 154 .name = "firewire",
159 .match = fw_unit_match, 155 .match = fw_unit_match,
160 .uevent = fw_unit_uevent,
161}; 156};
162EXPORT_SYMBOL(fw_bus_type); 157EXPORT_SYMBOL(fw_bus_type);
163 158
@@ -199,8 +194,8 @@ int fw_device_enable_phys_dma(struct fw_device *device)
199EXPORT_SYMBOL(fw_device_enable_phys_dma); 194EXPORT_SYMBOL(fw_device_enable_phys_dma);
200 195
201static ssize_t 196static ssize_t
202show_modalias_attribute(struct device *dev, 197modalias_show(struct device *dev,
203 struct device_attribute *attr, char *buf) 198 struct device_attribute *attr, char *buf)
204{ 199{
205 struct fw_unit *unit = fw_unit(dev); 200 struct fw_unit *unit = fw_unit(dev);
206 int length; 201 int length;
@@ -211,41 +206,37 @@ show_modalias_attribute(struct device *dev,
211 return length + 1; 206 return length + 1;
212} 207}
213 208
214static struct device_attribute modalias_attribute = {
215 .attr = { .name = "modalias", .mode = S_IRUGO, },
216 .show = show_modalias_attribute,
217};
218
219static ssize_t 209static ssize_t
220show_config_rom_attribute(struct device *dev, 210rom_index_show(struct device *dev,
221 struct device_attribute *attr, char *buf) 211 struct device_attribute *attr, char *buf)
222{ 212{
223 struct fw_device *device = fw_device(dev); 213 struct fw_device *device = fw_device(dev->parent);
224 214 struct fw_unit *unit = fw_unit(dev);
225 memcpy(buf, device->config_rom, device->config_rom_length * 4);
226 215
227 return device->config_rom_length * 4; 216 return snprintf(buf, PAGE_SIZE, "%d\n",
217 (int)(unit->directory - device->config_rom));
228} 218}
229 219
230static struct device_attribute config_rom_attribute = { 220static struct device_attribute fw_unit_attributes[] = {
231 .attr = {.name = "config_rom", .mode = S_IRUGO,}, 221 __ATTR_RO(modalias),
232 .show = show_config_rom_attribute, 222 __ATTR_RO(rom_index),
223 __ATTR_NULL,
233}; 224};
234 225
235static ssize_t 226static ssize_t
236show_rom_index_attribute(struct device *dev, 227config_rom_show(struct device *dev,
237 struct device_attribute *attr, char *buf) 228 struct device_attribute *attr, char *buf)
238{ 229{
239 struct fw_device *device = fw_device(dev->parent); 230 struct fw_device *device = fw_device(dev);
240 struct fw_unit *unit = fw_unit(dev);
241 231
242 return snprintf(buf, PAGE_SIZE, "%d\n", 232 memcpy(buf, device->config_rom, device->config_rom_length * 4);
243 (int)(unit->directory - device->config_rom)); 233
234 return device->config_rom_length * 4;
244} 235}
245 236
246static struct device_attribute rom_index_attribute = { 237static struct device_attribute fw_device_attributes[] = {
247 .attr = { .name = "rom_index", .mode = S_IRUGO, }, 238 __ATTR_RO(config_rom),
248 .show = show_rom_index_attribute, 239 __ATTR_NULL,
249}; 240};
250 241
251struct read_quadlet_callback_data { 242struct read_quadlet_callback_data {
@@ -370,9 +361,15 @@ static void fw_unit_release(struct device *dev)
370 kfree(unit); 361 kfree(unit);
371} 362}
372 363
364static struct device_type fw_unit_type = {
365 .attrs = fw_unit_attributes,
366 .uevent = fw_unit_uevent,
367 .release = fw_unit_release,
368};
369
373static int is_fw_unit(struct device *dev) 370static int is_fw_unit(struct device *dev)
374{ 371{
375 return dev->release == fw_unit_release; 372 return dev->type == &fw_unit_type;
376} 373}
377 374
378static void create_units(struct fw_device *device) 375static void create_units(struct fw_device *device)
@@ -397,7 +394,7 @@ static void create_units(struct fw_device *device)
397 394
398 unit->directory = ci.p + value - 1; 395 unit->directory = ci.p + value - 1;
399 unit->device.bus = &fw_bus_type; 396 unit->device.bus = &fw_bus_type;
400 unit->device.release = fw_unit_release; 397 unit->device.type = &fw_unit_type;
401 unit->device.parent = &device->device; 398 unit->device.parent = &device->device;
402 snprintf(unit->device.bus_id, sizeof unit->device.bus_id, 399 snprintf(unit->device.bus_id, sizeof unit->device.bus_id,
403 "%s.%d", device->device.bus_id, i++); 400 "%s.%d", device->device.bus_id, i++);
@@ -406,27 +403,12 @@ static void create_units(struct fw_device *device)
406 kfree(unit); 403 kfree(unit);
407 continue; 404 continue;
408 } 405 }
409
410 if (device_create_file(&unit->device, &modalias_attribute) < 0) {
411 device_unregister(&unit->device);
412 kfree(unit);
413 }
414
415 if (device_create_file(&unit->device, &rom_index_attribute) < 0) {
416 device_unregister(&unit->device);
417 kfree(unit);
418 }
419 } 406 }
420} 407}
421 408
422static int shutdown_unit(struct device *device, void *data) 409static int shutdown_unit(struct device *device, void *data)
423{ 410{
424 struct fw_unit *unit = fw_unit(device); 411 device_unregister(device);
425
426 if (is_fw_unit(device)) {
427 device_remove_file(&unit->device, &modalias_attribute);
428 device_unregister(&unit->device);
429 }
430 412
431 return 0; 413 return 0;
432} 414}
@@ -456,11 +438,15 @@ static void fw_device_shutdown(struct work_struct *work)
456 up_write(&fw_bus_type.subsys.rwsem); 438 up_write(&fw_bus_type.subsys.rwsem);
457 439
458 fw_device_cdev_remove(device); 440 fw_device_cdev_remove(device);
459 device_remove_file(&device->device, &config_rom_attribute);
460 device_for_each_child(&device->device, NULL, shutdown_unit); 441 device_for_each_child(&device->device, NULL, shutdown_unit);
461 device_unregister(&device->device); 442 device_unregister(&device->device);
462} 443}
463 444
445static struct device_type fw_device_type = {
446 .attrs = fw_device_attributes,
447 .release = fw_device_release,
448};
449
464/* These defines control the retry behavior for reading the config 450/* These defines control the retry behavior for reading the config
465 * rom. It shouldn't be necessary to tweak these; if the device 451 * rom. It shouldn't be necessary to tweak these; if the device
466 * doesn't respond to a config rom read within 10 seconds, it's not 452 * doesn't respond to a config rom read within 10 seconds, it's not
@@ -507,7 +493,7 @@ static void fw_device_init(struct work_struct *work)
507 goto error; 493 goto error;
508 494
509 device->device.bus = &fw_bus_type; 495 device->device.bus = &fw_bus_type;
510 device->device.release = fw_device_release; 496 device->device.type = &fw_device_type;
511 device->device.parent = device->card->device; 497 device->device.parent = device->card->device;
512 device->device.devt = MKDEV(fw_cdev_major, minor); 498 device->device.devt = MKDEV(fw_cdev_major, minor);
513 snprintf(device->device.bus_id, sizeof device->device.bus_id, 499 snprintf(device->device.bus_id, sizeof device->device.bus_id,
@@ -518,11 +504,6 @@ static void fw_device_init(struct work_struct *work)
518 goto error_with_cdev; 504 goto error_with_cdev;
519 } 505 }
520 506
521 if (device_create_file(&device->device, &config_rom_attribute) < 0) {
522 fw_error("Failed to create config rom file.\n");
523 goto error_with_device;
524 }
525
526 create_units(device); 507 create_units(device);
527 508
528 /* Transition the device to running state. If it got pulled 509 /* Transition the device to running state. If it got pulled
@@ -549,8 +530,6 @@ static void fw_device_init(struct work_struct *work)
549 530
550 return; 531 return;
551 532
552 error_with_device:
553 device_del(&device->device);
554 error_with_cdev: 533 error_with_cdev:
555 down_write(&fw_bus_type.subsys.rwsem); 534 down_write(&fw_bus_type.subsys.rwsem);
556 idr_remove(&fw_device_idr, minor); 535 idr_remove(&fw_device_idr, minor);