diff options
author | Len Brown <len.brown@intel.com> | 2006-06-29 19:57:46 -0400 |
---|---|---|
committer | Len Brown <len.brown@intel.com> | 2006-06-29 19:57:46 -0400 |
commit | d120cfb544ed6161b9d32fb6c4648c471807ee6b (patch) | |
tree | 7757ad0198d8df76ff5c60f939a687687c41da00 /drivers | |
parent | 9dce0e950dbfab4148f35ac6f297d8638cdc63c4 (diff) | |
parent | bf7e8511088963078484132636839b59e25cf14f (diff) |
merge linus into release branch
Conflicts:
drivers/acpi/acpi_memhotplug.c
Diffstat (limited to 'drivers')
419 files changed, 18081 insertions, 4257 deletions
diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig index ce15aed1df3f..bc2652d72fdc 100644 --- a/drivers/acpi/Kconfig +++ b/drivers/acpi/Kconfig | |||
@@ -335,7 +335,7 @@ config ACPI_CONTAINER | |||
335 | config ACPI_HOTPLUG_MEMORY | 335 | config ACPI_HOTPLUG_MEMORY |
336 | tristate "Memory Hotplug" | 336 | tristate "Memory Hotplug" |
337 | depends on ACPI | 337 | depends on ACPI |
338 | depends on MEMORY_HOTPLUG || X86_64 | 338 | depends on MEMORY_HOTPLUG |
339 | default n | 339 | default n |
340 | help | 340 | help |
341 | This driver adds supports for ACPI Memory Hotplug. This driver | 341 | This driver adds supports for ACPI Memory Hotplug. This driver |
diff --git a/drivers/acpi/acpi_memhotplug.c b/drivers/acpi/acpi_memhotplug.c index b05469513842..6f5e395c78af 100644 --- a/drivers/acpi/acpi_memhotplug.c +++ b/drivers/acpi/acpi_memhotplug.c | |||
@@ -57,6 +57,7 @@ MODULE_LICENSE("GPL"); | |||
57 | 57 | ||
58 | static int acpi_memory_device_add(struct acpi_device *device); | 58 | static int acpi_memory_device_add(struct acpi_device *device); |
59 | static int acpi_memory_device_remove(struct acpi_device *device, int type); | 59 | static int acpi_memory_device_remove(struct acpi_device *device, int type); |
60 | static int acpi_memory_device_start(struct acpi_device *device); | ||
60 | 61 | ||
61 | static struct acpi_driver acpi_memory_device_driver = { | 62 | static struct acpi_driver acpi_memory_device_driver = { |
62 | .name = ACPI_MEMORY_DEVICE_DRIVER_NAME, | 63 | .name = ACPI_MEMORY_DEVICE_DRIVER_NAME, |
@@ -65,46 +66,77 @@ static struct acpi_driver acpi_memory_device_driver = { | |||
65 | .ops = { | 66 | .ops = { |
66 | .add = acpi_memory_device_add, | 67 | .add = acpi_memory_device_add, |
67 | .remove = acpi_memory_device_remove, | 68 | .remove = acpi_memory_device_remove, |
69 | .start = acpi_memory_device_start, | ||
68 | }, | 70 | }, |
69 | }; | 71 | }; |
70 | 72 | ||
73 | struct acpi_memory_info { | ||
74 | struct list_head list; | ||
75 | u64 start_addr; /* Memory Range start physical addr */ | ||
76 | u64 length; /* Memory Range length */ | ||
77 | unsigned short caching; /* memory cache attribute */ | ||
78 | unsigned short write_protect; /* memory read/write attribute */ | ||
79 | unsigned int enabled:1; | ||
80 | }; | ||
81 | |||
71 | struct acpi_memory_device { | 82 | struct acpi_memory_device { |
72 | acpi_handle handle; | 83 | acpi_handle handle; |
73 | unsigned int state; /* State of the memory device */ | 84 | unsigned int state; /* State of the memory device */ |
74 | unsigned short caching; /* memory cache attribute */ | 85 | struct list_head res_list; |
75 | unsigned short write_protect; /* memory read/write attribute */ | ||
76 | u64 start_addr; /* Memory Range start physical addr */ | ||
77 | u64 length; /* Memory Range length */ | ||
78 | }; | 86 | }; |
79 | 87 | ||
88 | static acpi_status | ||
89 | acpi_memory_get_resource(struct acpi_resource *resource, void *context) | ||
90 | { | ||
91 | struct acpi_memory_device *mem_device = context; | ||
92 | struct acpi_resource_address64 address64; | ||
93 | struct acpi_memory_info *info, *new; | ||
94 | acpi_status status; | ||
95 | |||
96 | status = acpi_resource_to_address64(resource, &address64); | ||
97 | if (ACPI_FAILURE(status) || | ||
98 | (address64.resource_type != ACPI_MEMORY_RANGE)) | ||
99 | return AE_OK; | ||
100 | |||
101 | list_for_each_entry(info, &mem_device->res_list, list) { | ||
102 | /* Can we combine the resource range information? */ | ||
103 | if ((info->caching == address64.info.mem.caching) && | ||
104 | (info->write_protect == address64.info.mem.write_protect) && | ||
105 | (info->start_addr + info->length == address64.minimum)) { | ||
106 | info->length += address64.address_length; | ||
107 | return AE_OK; | ||
108 | } | ||
109 | } | ||
110 | |||
111 | new = kzalloc(sizeof(struct acpi_memory_info), GFP_KERNEL); | ||
112 | if (!new) | ||
113 | return AE_ERROR; | ||
114 | |||
115 | INIT_LIST_HEAD(&new->list); | ||
116 | new->caching = address64.info.mem.caching; | ||
117 | new->write_protect = address64.info.mem.write_protect; | ||
118 | new->start_addr = address64.minimum; | ||
119 | new->length = address64.address_length; | ||
120 | list_add_tail(&new->list, &mem_device->res_list); | ||
121 | |||
122 | return AE_OK; | ||
123 | } | ||
124 | |||
80 | static int | 125 | static int |
81 | acpi_memory_get_device_resources(struct acpi_memory_device *mem_device) | 126 | acpi_memory_get_device_resources(struct acpi_memory_device *mem_device) |
82 | { | 127 | { |
83 | acpi_status status; | 128 | acpi_status status; |
84 | struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; | 129 | struct acpi_memory_info *info, *n; |
85 | struct acpi_resource *resource = NULL; | ||
86 | struct acpi_resource_address64 address64; | ||
87 | 130 | ||
88 | 131 | ||
89 | /* Get the range from the _CRS */ | 132 | status = acpi_walk_resources(mem_device->handle, METHOD_NAME__CRS, |
90 | status = acpi_get_current_resources(mem_device->handle, &buffer); | 133 | acpi_memory_get_resource, mem_device); |
91 | if (ACPI_FAILURE(status)) | 134 | if (ACPI_FAILURE(status)) { |
135 | list_for_each_entry_safe(info, n, &mem_device->res_list, list) | ||
136 | kfree(info); | ||
92 | return -EINVAL; | 137 | return -EINVAL; |
93 | |||
94 | resource = (struct acpi_resource *)buffer.pointer; | ||
95 | status = acpi_resource_to_address64(resource, &address64); | ||
96 | if (ACPI_SUCCESS(status)) { | ||
97 | if (address64.resource_type == ACPI_MEMORY_RANGE) { | ||
98 | /* Populate the structure */ | ||
99 | mem_device->caching = address64.info.mem.caching; | ||
100 | mem_device->write_protect = | ||
101 | address64.info.mem.write_protect; | ||
102 | mem_device->start_addr = address64.minimum; | ||
103 | mem_device->length = address64.address_length; | ||
104 | } | ||
105 | } | 138 | } |
106 | 139 | ||
107 | acpi_os_free(buffer.pointer); | ||
108 | return 0; | 140 | return 0; |
109 | } | 141 | } |
110 | 142 | ||
@@ -177,7 +209,9 @@ static int acpi_memory_check_device(struct acpi_memory_device *mem_device) | |||
177 | 209 | ||
178 | static int acpi_memory_enable_device(struct acpi_memory_device *mem_device) | 210 | static int acpi_memory_enable_device(struct acpi_memory_device *mem_device) |
179 | { | 211 | { |
180 | int result; | 212 | int result, num_enabled = 0; |
213 | struct acpi_memory_info *info; | ||
214 | int node; | ||
181 | 215 | ||
182 | 216 | ||
183 | /* Get the range from the _CRS */ | 217 | /* Get the range from the _CRS */ |
@@ -188,15 +222,35 @@ static int acpi_memory_enable_device(struct acpi_memory_device *mem_device) | |||
188 | return result; | 222 | return result; |
189 | } | 223 | } |
190 | 224 | ||
225 | node = acpi_get_node(mem_device->handle); | ||
191 | /* | 226 | /* |
192 | * Tell the VM there is more memory here... | 227 | * Tell the VM there is more memory here... |
193 | * Note: Assume that this function returns zero on success | 228 | * Note: Assume that this function returns zero on success |
229 | * We don't have memory-hot-add rollback function,now. | ||
230 | * (i.e. memory-hot-remove function) | ||
194 | */ | 231 | */ |
195 | result = add_memory(mem_device->start_addr, mem_device->length); | 232 | list_for_each_entry(info, &mem_device->res_list, list) { |
196 | if (result) { | 233 | u64 start_pfn, end_pfn; |
197 | printk(KERN_ERR PREFIX "add_memory failed\n"); | 234 | |
235 | start_pfn = info->start_addr >> PAGE_SHIFT; | ||
236 | end_pfn = (info->start_addr + info->length - 1) >> PAGE_SHIFT; | ||
237 | |||
238 | if (pfn_valid(start_pfn) || pfn_valid(end_pfn)) { | ||
239 | /* already enabled. try next area */ | ||
240 | num_enabled++; | ||
241 | continue; | ||
242 | } | ||
243 | |||
244 | result = add_memory(node, info->start_addr, info->length); | ||
245 | if (result) | ||
246 | continue; | ||
247 | info->enabled = 1; | ||
248 | num_enabled++; | ||
249 | } | ||
250 | if (!num_enabled) { | ||
251 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "\nadd_memory failed\n")); | ||
198 | mem_device->state = MEMORY_INVALID_STATE; | 252 | mem_device->state = MEMORY_INVALID_STATE; |
199 | return result; | 253 | return -EINVAL; |
200 | } | 254 | } |
201 | 255 | ||
202 | return result; | 256 | return result; |
@@ -239,17 +293,21 @@ static int acpi_memory_powerdown_device(struct acpi_memory_device *mem_device) | |||
239 | static int acpi_memory_disable_device(struct acpi_memory_device *mem_device) | 293 | static int acpi_memory_disable_device(struct acpi_memory_device *mem_device) |
240 | { | 294 | { |
241 | int result; | 295 | int result; |
242 | u64 start = mem_device->start_addr; | 296 | struct acpi_memory_info *info, *n; |
243 | u64 len = mem_device->length; | ||
244 | 297 | ||
245 | 298 | ||
246 | /* | 299 | /* |
247 | * Ask the VM to offline this memory range. | 300 | * Ask the VM to offline this memory range. |
248 | * Note: Assume that this function returns zero on success | 301 | * Note: Assume that this function returns zero on success |
249 | */ | 302 | */ |
250 | result = remove_memory(start, len); | 303 | list_for_each_entry_safe(info, n, &mem_device->res_list, list) { |
251 | if (result) | 304 | if (info->enabled) { |
252 | return result; | 305 | result = remove_memory(info->start_addr, info->length); |
306 | if (result) | ||
307 | return result; | ||
308 | } | ||
309 | kfree(info); | ||
310 | } | ||
253 | 311 | ||
254 | /* Power-off and eject the device */ | 312 | /* Power-off and eject the device */ |
255 | result = acpi_memory_powerdown_device(mem_device); | 313 | result = acpi_memory_powerdown_device(mem_device); |
@@ -339,6 +397,7 @@ static int acpi_memory_device_add(struct acpi_device *device) | |||
339 | return -ENOMEM; | 397 | return -ENOMEM; |
340 | memset(mem_device, 0, sizeof(struct acpi_memory_device)); | 398 | memset(mem_device, 0, sizeof(struct acpi_memory_device)); |
341 | 399 | ||
400 | INIT_LIST_HEAD(&mem_device->res_list); | ||
342 | mem_device->handle = device->handle; | 401 | mem_device->handle = device->handle; |
343 | sprintf(acpi_device_name(device), "%s", ACPI_MEMORY_DEVICE_NAME); | 402 | sprintf(acpi_device_name(device), "%s", ACPI_MEMORY_DEVICE_NAME); |
344 | sprintf(acpi_device_class(device), "%s", ACPI_MEMORY_DEVICE_CLASS); | 403 | sprintf(acpi_device_class(device), "%s", ACPI_MEMORY_DEVICE_CLASS); |
@@ -373,6 +432,23 @@ static int acpi_memory_device_remove(struct acpi_device *device, int type) | |||
373 | return 0; | 432 | return 0; |
374 | } | 433 | } |
375 | 434 | ||
435 | static int acpi_memory_device_start (struct acpi_device *device) | ||
436 | { | ||
437 | struct acpi_memory_device *mem_device; | ||
438 | int result = 0; | ||
439 | |||
440 | mem_device = acpi_driver_data(device); | ||
441 | |||
442 | if (!acpi_memory_check_device(mem_device)) { | ||
443 | /* call add_memory func */ | ||
444 | result = acpi_memory_enable_device(mem_device); | ||
445 | if (result) | ||
446 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, | ||
447 | "Error in acpi_memory_enable_device\n")); | ||
448 | } | ||
449 | return result; | ||
450 | } | ||
451 | |||
376 | /* | 452 | /* |
377 | * Helper function to check for memory device | 453 | * Helper function to check for memory device |
378 | */ | 454 | */ |
diff --git a/drivers/acpi/numa.c b/drivers/acpi/numa.c index e2c1a16078c9..13d6d5bdea26 100644 --- a/drivers/acpi/numa.c +++ b/drivers/acpi/numa.c | |||
@@ -254,5 +254,18 @@ int acpi_get_pxm(acpi_handle h) | |||
254 | } while (ACPI_SUCCESS(status)); | 254 | } while (ACPI_SUCCESS(status)); |
255 | return -1; | 255 | return -1; |
256 | } | 256 | } |
257 | |||
258 | EXPORT_SYMBOL(acpi_get_pxm); | 257 | EXPORT_SYMBOL(acpi_get_pxm); |
258 | |||
259 | int acpi_get_node(acpi_handle *handle) | ||
260 | { | ||
261 | int pxm, node = -1; | ||
262 | |||
263 | ACPI_FUNCTION_TRACE("acpi_get_node"); | ||
264 | |||
265 | pxm = acpi_get_pxm(handle); | ||
266 | if (pxm >= 0) | ||
267 | node = acpi_map_pxm_to_node(pxm); | ||
268 | |||
269 | return_VALUE(node); | ||
270 | } | ||
271 | EXPORT_SYMBOL(acpi_get_node); | ||
diff --git a/drivers/amba/bus.c b/drivers/amba/bus.c index 889855d8d9f9..9e3e2a69c03a 100644 --- a/drivers/amba/bus.c +++ b/drivers/amba/bus.c | |||
@@ -180,8 +180,9 @@ static DEVICE_ATTR(name, S_IRUGO, show_##name, NULL) | |||
180 | amba_attr(id, "%08x\n", dev->periphid); | 180 | amba_attr(id, "%08x\n", dev->periphid); |
181 | amba_attr(irq0, "%u\n", dev->irq[0]); | 181 | amba_attr(irq0, "%u\n", dev->irq[0]); |
182 | amba_attr(irq1, "%u\n", dev->irq[1]); | 182 | amba_attr(irq1, "%u\n", dev->irq[1]); |
183 | amba_attr(resource, "\t%08lx\t%08lx\t%08lx\n", | 183 | amba_attr(resource, "\t%016llx\t%016llx\t%016lx\n", |
184 | dev->res.start, dev->res.end, dev->res.flags); | 184 | (unsigned long long)dev->res.start, (unsigned long long)dev->res.end, |
185 | dev->res.flags); | ||
185 | 186 | ||
186 | /** | 187 | /** |
187 | * amba_device_register - register an AMBA device | 188 | * amba_device_register - register an AMBA device |
diff --git a/drivers/atm/ambassador.c b/drivers/atm/ambassador.c index 4b6bf19c39c0..4048681f36d5 100644 --- a/drivers/atm/ambassador.c +++ b/drivers/atm/ambassador.c | |||
@@ -2257,7 +2257,8 @@ static int __devinit amb_probe(struct pci_dev *pci_dev, const struct pci_device_ | |||
2257 | } | 2257 | } |
2258 | 2258 | ||
2259 | PRINTD (DBG_INFO, "found Madge ATM adapter (amb) at" | 2259 | PRINTD (DBG_INFO, "found Madge ATM adapter (amb) at" |
2260 | " IO %lx, IRQ %u, MEM %p", pci_resource_start(pci_dev, 1), | 2260 | " IO %llx, IRQ %u, MEM %p", |
2261 | (unsigned long long)pci_resource_start(pci_dev, 1), | ||
2261 | irq, bus_to_virt(pci_resource_start(pci_dev, 0))); | 2262 | irq, bus_to_virt(pci_resource_start(pci_dev, 0))); |
2262 | 2263 | ||
2263 | // check IO region | 2264 | // check IO region |
diff --git a/drivers/atm/firestream.c b/drivers/atm/firestream.c index f2eeaf9dc56a..d40605c1af73 100644 --- a/drivers/atm/firestream.c +++ b/drivers/atm/firestream.c | |||
@@ -33,6 +33,7 @@ | |||
33 | #include <linux/kernel.h> | 33 | #include <linux/kernel.h> |
34 | #include <linux/mm.h> | 34 | #include <linux/mm.h> |
35 | #include <linux/pci.h> | 35 | #include <linux/pci.h> |
36 | #include <linux/poison.h> | ||
36 | #include <linux/errno.h> | 37 | #include <linux/errno.h> |
37 | #include <linux/atm.h> | 38 | #include <linux/atm.h> |
38 | #include <linux/atmdev.h> | 39 | #include <linux/atmdev.h> |
@@ -754,7 +755,7 @@ static void process_txdone_queue (struct fs_dev *dev, struct queue *q) | |||
754 | fs_kfree_skb (skb); | 755 | fs_kfree_skb (skb); |
755 | 756 | ||
756 | fs_dprintk (FS_DEBUG_ALLOC, "Free trans-d: %p\n", td); | 757 | fs_dprintk (FS_DEBUG_ALLOC, "Free trans-d: %p\n", td); |
757 | memset (td, 0x12, sizeof (struct FS_BPENTRY)); | 758 | memset (td, ATM_POISON_FREE, sizeof(struct FS_BPENTRY)); |
758 | kfree (td); | 759 | kfree (td); |
759 | break; | 760 | break; |
760 | default: | 761 | default: |
@@ -1657,9 +1658,10 @@ static int __devinit fs_init (struct fs_dev *dev) | |||
1657 | func_enter (); | 1658 | func_enter (); |
1658 | pci_dev = dev->pci_dev; | 1659 | pci_dev = dev->pci_dev; |
1659 | 1660 | ||
1660 | printk (KERN_INFO "found a FireStream %d card, base %08lx, irq%d.\n", | 1661 | printk (KERN_INFO "found a FireStream %d card, base %16llx, irq%d.\n", |
1661 | IS_FS50(dev)?50:155, | 1662 | IS_FS50(dev)?50:155, |
1662 | pci_resource_start(pci_dev, 0), dev->pci_dev->irq); | 1663 | (unsigned long long)pci_resource_start(pci_dev, 0), |
1664 | dev->pci_dev->irq); | ||
1663 | 1665 | ||
1664 | if (fs_debug & FS_DEBUG_INIT) | 1666 | if (fs_debug & FS_DEBUG_INIT) |
1665 | my_hd ((unsigned char *) dev, sizeof (*dev)); | 1667 | my_hd ((unsigned char *) dev, sizeof (*dev)); |
diff --git a/drivers/base/cpu.c b/drivers/base/cpu.c index dd712b24ec91..4bef76a2f3f2 100644 --- a/drivers/base/cpu.c +++ b/drivers/base/cpu.c | |||
@@ -8,6 +8,7 @@ | |||
8 | #include <linux/cpu.h> | 8 | #include <linux/cpu.h> |
9 | #include <linux/topology.h> | 9 | #include <linux/topology.h> |
10 | #include <linux/device.h> | 10 | #include <linux/device.h> |
11 | #include <linux/node.h> | ||
11 | 12 | ||
12 | #include "base.h" | 13 | #include "base.h" |
13 | 14 | ||
@@ -57,13 +58,12 @@ static void __devinit register_cpu_control(struct cpu *cpu) | |||
57 | { | 58 | { |
58 | sysdev_create_file(&cpu->sysdev, &attr_online); | 59 | sysdev_create_file(&cpu->sysdev, &attr_online); |
59 | } | 60 | } |
60 | void unregister_cpu(struct cpu *cpu, struct node *root) | 61 | void unregister_cpu(struct cpu *cpu) |
61 | { | 62 | { |
62 | int logical_cpu = cpu->sysdev.id; | 63 | int logical_cpu = cpu->sysdev.id; |
63 | 64 | ||
64 | if (root) | 65 | unregister_cpu_under_node(logical_cpu, cpu_to_node(logical_cpu)); |
65 | sysfs_remove_link(&root->sysdev.kobj, | 66 | |
66 | kobject_name(&cpu->sysdev.kobj)); | ||
67 | sysdev_remove_file(&cpu->sysdev, &attr_online); | 67 | sysdev_remove_file(&cpu->sysdev, &attr_online); |
68 | 68 | ||
69 | sysdev_unregister(&cpu->sysdev); | 69 | sysdev_unregister(&cpu->sysdev); |
@@ -109,23 +109,21 @@ static SYSDEV_ATTR(crash_notes, 0400, show_crash_notes, NULL); | |||
109 | * | 109 | * |
110 | * Initialize and register the CPU device. | 110 | * Initialize and register the CPU device. |
111 | */ | 111 | */ |
112 | int __devinit register_cpu(struct cpu *cpu, int num, struct node *root) | 112 | int __devinit register_cpu(struct cpu *cpu, int num) |
113 | { | 113 | { |
114 | int error; | 114 | int error; |
115 | |||
116 | cpu->node_id = cpu_to_node(num); | 115 | cpu->node_id = cpu_to_node(num); |
117 | cpu->sysdev.id = num; | 116 | cpu->sysdev.id = num; |
118 | cpu->sysdev.cls = &cpu_sysdev_class; | 117 | cpu->sysdev.cls = &cpu_sysdev_class; |
119 | 118 | ||
120 | error = sysdev_register(&cpu->sysdev); | 119 | error = sysdev_register(&cpu->sysdev); |
121 | if (!error && root) | 120 | |
122 | error = sysfs_create_link(&root->sysdev.kobj, | ||
123 | &cpu->sysdev.kobj, | ||
124 | kobject_name(&cpu->sysdev.kobj)); | ||
125 | if (!error && !cpu->no_control) | 121 | if (!error && !cpu->no_control) |
126 | register_cpu_control(cpu); | 122 | register_cpu_control(cpu); |
127 | if (!error) | 123 | if (!error) |
128 | cpu_sys_devices[num] = &cpu->sysdev; | 124 | cpu_sys_devices[num] = &cpu->sysdev; |
125 | if (!error) | ||
126 | register_cpu_under_node(num, cpu_to_node(num)); | ||
129 | 127 | ||
130 | #ifdef CONFIG_KEXEC | 128 | #ifdef CONFIG_KEXEC |
131 | if (!error) | 129 | if (!error) |
@@ -145,5 +143,13 @@ EXPORT_SYMBOL_GPL(get_cpu_sysdev); | |||
145 | 143 | ||
146 | int __init cpu_dev_init(void) | 144 | int __init cpu_dev_init(void) |
147 | { | 145 | { |
148 | return sysdev_class_register(&cpu_sysdev_class); | 146 | int err; |
147 | |||
148 | err = sysdev_class_register(&cpu_sysdev_class); | ||
149 | #if defined(CONFIG_SCHED_MC) || defined(CONFIG_SCHED_SMT) | ||
150 | if (!err) | ||
151 | err = sched_create_sysfs_power_savings_entries(&cpu_sysdev_class); | ||
152 | #endif | ||
153 | |||
154 | return err; | ||
149 | } | 155 | } |
diff --git a/drivers/base/dmapool.c b/drivers/base/dmapool.c index e2f64f91ed05..33c5cce1560b 100644 --- a/drivers/base/dmapool.c +++ b/drivers/base/dmapool.c | |||
@@ -7,6 +7,7 @@ | |||
7 | #include <linux/dmapool.h> | 7 | #include <linux/dmapool.h> |
8 | #include <linux/slab.h> | 8 | #include <linux/slab.h> |
9 | #include <linux/module.h> | 9 | #include <linux/module.h> |
10 | #include <linux/poison.h> | ||
10 | 11 | ||
11 | /* | 12 | /* |
12 | * Pool allocator ... wraps the dma_alloc_coherent page allocator, so | 13 | * Pool allocator ... wraps the dma_alloc_coherent page allocator, so |
@@ -35,8 +36,6 @@ struct dma_page { /* cacheable header for 'allocation' bytes */ | |||
35 | }; | 36 | }; |
36 | 37 | ||
37 | #define POOL_TIMEOUT_JIFFIES ((100 /* msec */ * HZ) / 1000) | 38 | #define POOL_TIMEOUT_JIFFIES ((100 /* msec */ * HZ) / 1000) |
38 | #define POOL_POISON_FREED 0xa7 /* !inuse */ | ||
39 | #define POOL_POISON_ALLOCATED 0xa9 /* !initted */ | ||
40 | 39 | ||
41 | static DECLARE_MUTEX (pools_lock); | 40 | static DECLARE_MUTEX (pools_lock); |
42 | 41 | ||
diff --git a/drivers/base/memory.c b/drivers/base/memory.c index dd547af4681a..c6b7d9c4b651 100644 --- a/drivers/base/memory.c +++ b/drivers/base/memory.c | |||
@@ -306,11 +306,13 @@ static ssize_t | |||
306 | memory_probe_store(struct class *class, const char *buf, size_t count) | 306 | memory_probe_store(struct class *class, const char *buf, size_t count) |
307 | { | 307 | { |
308 | u64 phys_addr; | 308 | u64 phys_addr; |
309 | int nid; | ||
309 | int ret; | 310 | int ret; |
310 | 311 | ||
311 | phys_addr = simple_strtoull(buf, NULL, 0); | 312 | phys_addr = simple_strtoull(buf, NULL, 0); |
312 | 313 | ||
313 | ret = add_memory(phys_addr, PAGES_PER_SECTION << PAGE_SHIFT); | 314 | nid = memory_add_physaddr_to_nid(phys_addr); |
315 | ret = add_memory(nid, phys_addr, PAGES_PER_SECTION << PAGE_SHIFT); | ||
314 | 316 | ||
315 | if (ret) | 317 | if (ret) |
316 | count = ret; | 318 | count = ret; |
diff --git a/drivers/base/node.c b/drivers/base/node.c index c80c3aeed004..eae2bdc183bb 100644 --- a/drivers/base/node.c +++ b/drivers/base/node.c | |||
@@ -11,6 +11,7 @@ | |||
11 | #include <linux/cpumask.h> | 11 | #include <linux/cpumask.h> |
12 | #include <linux/topology.h> | 12 | #include <linux/topology.h> |
13 | #include <linux/nodemask.h> | 13 | #include <linux/nodemask.h> |
14 | #include <linux/cpu.h> | ||
14 | 15 | ||
15 | static struct sysdev_class node_class = { | 16 | static struct sysdev_class node_class = { |
16 | set_kset_name("node"), | 17 | set_kset_name("node"), |
@@ -190,6 +191,66 @@ void unregister_node(struct node *node) | |||
190 | sysdev_unregister(&node->sysdev); | 191 | sysdev_unregister(&node->sysdev); |
191 | } | 192 | } |
192 | 193 | ||
194 | struct node node_devices[MAX_NUMNODES]; | ||
195 | |||
196 | /* | ||
197 | * register cpu under node | ||
198 | */ | ||
199 | int register_cpu_under_node(unsigned int cpu, unsigned int nid) | ||
200 | { | ||
201 | if (node_online(nid)) { | ||
202 | struct sys_device *obj = get_cpu_sysdev(cpu); | ||
203 | if (!obj) | ||
204 | return 0; | ||
205 | return sysfs_create_link(&node_devices[nid].sysdev.kobj, | ||
206 | &obj->kobj, | ||
207 | kobject_name(&obj->kobj)); | ||
208 | } | ||
209 | |||
210 | return 0; | ||
211 | } | ||
212 | |||
213 | int unregister_cpu_under_node(unsigned int cpu, unsigned int nid) | ||
214 | { | ||
215 | if (node_online(nid)) { | ||
216 | struct sys_device *obj = get_cpu_sysdev(cpu); | ||
217 | if (obj) | ||
218 | sysfs_remove_link(&node_devices[nid].sysdev.kobj, | ||
219 | kobject_name(&obj->kobj)); | ||
220 | } | ||
221 | return 0; | ||
222 | } | ||
223 | |||
224 | int register_one_node(int nid) | ||
225 | { | ||
226 | int error = 0; | ||
227 | int cpu; | ||
228 | |||
229 | if (node_online(nid)) { | ||
230 | int p_node = parent_node(nid); | ||
231 | struct node *parent = NULL; | ||
232 | |||
233 | if (p_node != nid) | ||
234 | parent = &node_devices[p_node]; | ||
235 | |||
236 | error = register_node(&node_devices[nid], nid, parent); | ||
237 | |||
238 | /* link cpu under this node */ | ||
239 | for_each_present_cpu(cpu) { | ||
240 | if (cpu_to_node(cpu) == nid) | ||
241 | register_cpu_under_node(cpu, nid); | ||
242 | } | ||
243 | } | ||
244 | |||
245 | return error; | ||
246 | |||
247 | } | ||
248 | |||
249 | void unregister_one_node(int nid) | ||
250 | { | ||
251 | unregister_node(&node_devices[nid]); | ||
252 | } | ||
253 | |||
193 | static int __init register_node_type(void) | 254 | static int __init register_node_type(void) |
194 | { | 255 | { |
195 | return sysdev_class_register(&node_class); | 256 | return sysdev_class_register(&node_class); |
diff --git a/drivers/base/topology.c b/drivers/base/topology.c index 8c52421cbc54..c2d621632383 100644 --- a/drivers/base/topology.c +++ b/drivers/base/topology.c | |||
@@ -107,7 +107,7 @@ static int __cpuinit topology_remove_dev(struct sys_device * sys_dev) | |||
107 | return 0; | 107 | return 0; |
108 | } | 108 | } |
109 | 109 | ||
110 | static int topology_cpu_callback(struct notifier_block *nfb, | 110 | static int __cpuinit topology_cpu_callback(struct notifier_block *nfb, |
111 | unsigned long action, void *hcpu) | 111 | unsigned long action, void *hcpu) |
112 | { | 112 | { |
113 | unsigned int cpu = (unsigned long)hcpu; | 113 | unsigned int cpu = (unsigned long)hcpu; |
@@ -125,7 +125,7 @@ static int topology_cpu_callback(struct notifier_block *nfb, | |||
125 | return NOTIFY_OK; | 125 | return NOTIFY_OK; |
126 | } | 126 | } |
127 | 127 | ||
128 | static struct notifier_block topology_cpu_notifier = | 128 | static struct notifier_block __cpuinitdata topology_cpu_notifier = |
129 | { | 129 | { |
130 | .notifier_call = topology_cpu_callback, | 130 | .notifier_call = topology_cpu_callback, |
131 | }; | 131 | }; |
diff --git a/drivers/block/DAC960.c b/drivers/block/DAC960.c index dd8a1501142f..50ca1aa4ee3b 100644 --- a/drivers/block/DAC960.c +++ b/drivers/block/DAC960.c | |||
@@ -2530,7 +2530,6 @@ static boolean DAC960_RegisterBlockDevice(DAC960_Controller_T *Controller) | |||
2530 | blk_queue_max_sectors(RequestQueue, Controller->MaxBlocksPerCommand); | 2530 | blk_queue_max_sectors(RequestQueue, Controller->MaxBlocksPerCommand); |
2531 | disk->queue = RequestQueue; | 2531 | disk->queue = RequestQueue; |
2532 | sprintf(disk->disk_name, "rd/c%dd%d", Controller->ControllerNumber, n); | 2532 | sprintf(disk->disk_name, "rd/c%dd%d", Controller->ControllerNumber, n); |
2533 | sprintf(disk->devfs_name, "rd/host%d/target%d", Controller->ControllerNumber, n); | ||
2534 | disk->major = MajorNumber; | 2533 | disk->major = MajorNumber; |
2535 | disk->first_minor = n << DAC960_MaxPartitionsBits; | 2534 | disk->first_minor = n << DAC960_MaxPartitionsBits; |
2536 | disk->fops = &DAC960_BlockDeviceOperations; | 2535 | disk->fops = &DAC960_BlockDeviceOperations; |
diff --git a/drivers/block/acsi.c b/drivers/block/acsi.c index 196c0ec9cd54..a317e4303952 100644 --- a/drivers/block/acsi.c +++ b/drivers/block/acsi.c | |||
@@ -1732,13 +1732,10 @@ int acsi_init( void ) | |||
1732 | struct gendisk *disk = acsi_gendisk[i]; | 1732 | struct gendisk *disk = acsi_gendisk[i]; |
1733 | sprintf(disk->disk_name, "ad%c", 'a'+i); | 1733 | sprintf(disk->disk_name, "ad%c", 'a'+i); |
1734 | aip = &acsi_info[NDevices]; | 1734 | aip = &acsi_info[NDevices]; |
1735 | sprintf(disk->devfs_name, "ad/target%d/lun%d", aip->target, aip->lun); | ||
1736 | disk->major = ACSI_MAJOR; | 1735 | disk->major = ACSI_MAJOR; |
1737 | disk->first_minor = i << 4; | 1736 | disk->first_minor = i << 4; |
1738 | if (acsi_info[i].type != HARDDISK) { | 1737 | if (acsi_info[i].type != HARDDISK) |
1739 | disk->minors = 1; | 1738 | disk->minors = 1; |
1740 | strcat(disk->devfs_name, "/disc"); | ||
1741 | } | ||
1742 | disk->fops = &acsi_fops; | 1739 | disk->fops = &acsi_fops; |
1743 | disk->private_data = &acsi_info[i]; | 1740 | disk->private_data = &acsi_info[i]; |
1744 | set_capacity(disk, acsi_info[i].size); | 1741 | set_capacity(disk, acsi_info[i].size); |
diff --git a/drivers/block/acsi_slm.c b/drivers/block/acsi_slm.c index 4cb9c1336287..4030a8fd1187 100644 --- a/drivers/block/acsi_slm.c +++ b/drivers/block/acsi_slm.c | |||
@@ -65,7 +65,6 @@ not be guaranteed. There are several ways to assure this: | |||
65 | #include <linux/time.h> | 65 | #include <linux/time.h> |
66 | #include <linux/mm.h> | 66 | #include <linux/mm.h> |
67 | #include <linux/slab.h> | 67 | #include <linux/slab.h> |
68 | #include <linux/devfs_fs_kernel.h> | ||
69 | #include <linux/smp_lock.h> | 68 | #include <linux/smp_lock.h> |
70 | 69 | ||
71 | #include <asm/pgtable.h> | 70 | #include <asm/pgtable.h> |
@@ -1005,11 +1004,6 @@ int slm_init( void ) | |||
1005 | BufferP = SLMBuffer; | 1004 | BufferP = SLMBuffer; |
1006 | SLMState = IDLE; | 1005 | SLMState = IDLE; |
1007 | 1006 | ||
1008 | devfs_mk_dir("slm"); | ||
1009 | for (i = 0; i < MAX_SLM; i++) { | ||
1010 | devfs_mk_cdev(MKDEV(ACSI_MAJOR, i), | ||
1011 | S_IFCHR|S_IRUSR|S_IWUSR, "slm/%d", i); | ||
1012 | } | ||
1013 | return 0; | 1007 | return 0; |
1014 | } | 1008 | } |
1015 | 1009 | ||
@@ -1032,10 +1026,6 @@ int init_module(void) | |||
1032 | 1026 | ||
1033 | void cleanup_module(void) | 1027 | void cleanup_module(void) |
1034 | { | 1028 | { |
1035 | int i; | ||
1036 | for (i = 0; i < MAX_SLM; i++) | ||
1037 | devfs_remove("slm/%d", i); | ||
1038 | devfs_remove("slm"); | ||
1039 | if (unregister_chrdev( ACSI_MAJOR, "slm" ) != 0) | 1029 | if (unregister_chrdev( ACSI_MAJOR, "slm" ) != 0) |
1040 | printk( KERN_ERR "acsi_slm: cleanup_module failed\n"); | 1030 | printk( KERN_ERR "acsi_slm: cleanup_module failed\n"); |
1041 | atari_stram_free( SLMBuffer ); | 1031 | atari_stram_free( SLMBuffer ); |
diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c index 39b0f53186e8..05fb08312c01 100644 --- a/drivers/block/cciss.c +++ b/drivers/block/cciss.c | |||
@@ -3248,7 +3248,6 @@ static int __devinit cciss_init_one(struct pci_dev *pdev, | |||
3248 | 3248 | ||
3249 | q->queuedata = hba[i]; | 3249 | q->queuedata = hba[i]; |
3250 | sprintf(disk->disk_name, "cciss/c%dd%d", i, j); | 3250 | sprintf(disk->disk_name, "cciss/c%dd%d", i, j); |
3251 | sprintf(disk->devfs_name, "cciss/host%d/target%d", i, j); | ||
3252 | disk->major = hba[i]->major; | 3251 | disk->major = hba[i]->major; |
3253 | disk->first_minor = j << NWD_SHIFT; | 3252 | disk->first_minor = j << NWD_SHIFT; |
3254 | disk->fops = &cciss_fops; | 3253 | disk->fops = &cciss_fops; |
diff --git a/drivers/block/cpqarray.c b/drivers/block/cpqarray.c index 5eb6fb7b5cfa..bfd245df0a8c 100644 --- a/drivers/block/cpqarray.c +++ b/drivers/block/cpqarray.c | |||
@@ -33,7 +33,6 @@ | |||
33 | #include <linux/blkpg.h> | 33 | #include <linux/blkpg.h> |
34 | #include <linux/timer.h> | 34 | #include <linux/timer.h> |
35 | #include <linux/proc_fs.h> | 35 | #include <linux/proc_fs.h> |
36 | #include <linux/devfs_fs_kernel.h> | ||
37 | #include <linux/init.h> | 36 | #include <linux/init.h> |
38 | #include <linux/hdreg.h> | 37 | #include <linux/hdreg.h> |
39 | #include <linux/spinlock.h> | 38 | #include <linux/spinlock.h> |
@@ -348,7 +347,6 @@ static void __devexit cpqarray_remove_one(int i) | |||
348 | for(j = 0; j < NWD; j++) { | 347 | for(j = 0; j < NWD; j++) { |
349 | if (ida_gendisk[i][j]->flags & GENHD_FL_UP) | 348 | if (ida_gendisk[i][j]->flags & GENHD_FL_UP) |
350 | del_gendisk(ida_gendisk[i][j]); | 349 | del_gendisk(ida_gendisk[i][j]); |
351 | devfs_remove("ida/c%dd%d",i,j); | ||
352 | put_disk(ida_gendisk[i][j]); | 350 | put_disk(ida_gendisk[i][j]); |
353 | } | 351 | } |
354 | blk_cleanup_queue(hba[i]->queue); | 352 | blk_cleanup_queue(hba[i]->queue); |
@@ -1807,8 +1805,6 @@ static void getgeometry(int ctlr) | |||
1807 | 1805 | ||
1808 | } | 1806 | } |
1809 | 1807 | ||
1810 | sprintf(disk->devfs_name, "ida/c%dd%d", ctlr, log_unit); | ||
1811 | |||
1812 | info_p->phys_drives = | 1808 | info_p->phys_drives = |
1813 | sense_config_buf->ctlr_phys_drv; | 1809 | sense_config_buf->ctlr_phys_drv; |
1814 | info_p->drv_assign_map | 1810 | info_p->drv_assign_map |
@@ -1844,7 +1840,6 @@ static void __exit cpqarray_exit(void) | |||
1844 | } | 1840 | } |
1845 | } | 1841 | } |
1846 | 1842 | ||
1847 | devfs_remove("ida"); | ||
1848 | remove_proc_entry("cpqarray", proc_root_driver); | 1843 | remove_proc_entry("cpqarray", proc_root_driver); |
1849 | } | 1844 | } |
1850 | 1845 | ||
diff --git a/drivers/block/floppy.c b/drivers/block/floppy.c index dff1e67b1dd4..0242cbb86a87 100644 --- a/drivers/block/floppy.c +++ b/drivers/block/floppy.c | |||
@@ -177,7 +177,6 @@ static int print_unex = 1; | |||
177 | #include <linux/ioport.h> | 177 | #include <linux/ioport.h> |
178 | #include <linux/interrupt.h> | 178 | #include <linux/interrupt.h> |
179 | #include <linux/init.h> | 179 | #include <linux/init.h> |
180 | #include <linux/devfs_fs_kernel.h> | ||
181 | #include <linux/platform_device.h> | 180 | #include <linux/platform_device.h> |
182 | #include <linux/buffer_head.h> /* for invalidate_buffers() */ | 181 | #include <linux/buffer_head.h> /* for invalidate_buffers() */ |
183 | #include <linux/mutex.h> | 182 | #include <linux/mutex.h> |
@@ -224,7 +223,6 @@ static struct completion device_release; | |||
224 | static unsigned short virtual_dma_port = 0x3f0; | 223 | static unsigned short virtual_dma_port = 0x3f0; |
225 | irqreturn_t floppy_interrupt(int irq, void *dev_id, struct pt_regs *regs); | 224 | irqreturn_t floppy_interrupt(int irq, void *dev_id, struct pt_regs *regs); |
226 | static int set_dor(int fdc, char mask, char data); | 225 | static int set_dor(int fdc, char mask, char data); |
227 | static void register_devfs_entries(int drive) __init; | ||
228 | 226 | ||
229 | #define K_64 0x10000 /* 64KB */ | 227 | #define K_64 0x10000 /* 64KB */ |
230 | 228 | ||
@@ -3676,7 +3674,6 @@ static void __init config_types(void) | |||
3676 | first = 0; | 3674 | first = 0; |
3677 | } | 3675 | } |
3678 | printk("%s fd%d is %s", prepend, drive, name); | 3676 | printk("%s fd%d is %s", prepend, drive, name); |
3679 | register_devfs_entries(drive); | ||
3680 | } | 3677 | } |
3681 | *UDP = *params; | 3678 | *UDP = *params; |
3682 | } | 3679 | } |
@@ -3954,37 +3951,6 @@ static struct block_device_operations floppy_fops = { | |||
3954 | .media_changed = check_floppy_change, | 3951 | .media_changed = check_floppy_change, |
3955 | .revalidate_disk = floppy_revalidate, | 3952 | .revalidate_disk = floppy_revalidate, |
3956 | }; | 3953 | }; |
3957 | static char *table[] = { | ||
3958 | "", "d360", "h1200", "u360", "u720", "h360", "h720", | ||
3959 | "u1440", "u2880", "CompaQ", "h1440", "u1680", "h410", | ||
3960 | "u820", "h1476", "u1722", "h420", "u830", "h1494", "u1743", | ||
3961 | "h880", "u1040", "u1120", "h1600", "u1760", "u1920", | ||
3962 | "u3200", "u3520", "u3840", "u1840", "u800", "u1600", | ||
3963 | NULL | ||
3964 | }; | ||
3965 | static int t360[] = { 1, 0 }, | ||
3966 | t1200[] = { 2, 5, 6, 10, 12, 14, 16, 18, 20, 23, 0 }, | ||
3967 | t3in[] = { 8, 9, 26, 27, 28, 7, 11, 15, 19, 24, 25, 29, 31, 3, 4, 13, | ||
3968 | 17, 21, 22, 30, 0 }; | ||
3969 | static int *table_sup[] = | ||
3970 | { NULL, t360, t1200, t3in + 5 + 8, t3in + 5, t3in, t3in }; | ||
3971 | |||
3972 | static void __init register_devfs_entries(int drive) | ||
3973 | { | ||
3974 | int base_minor = (drive < 4) ? drive : (124 + drive); | ||
3975 | |||
3976 | if (UDP->cmos < ARRAY_SIZE(default_drive_params)) { | ||
3977 | int i = 0; | ||
3978 | do { | ||
3979 | int minor = base_minor + (table_sup[UDP->cmos][i] << 2); | ||
3980 | |||
3981 | devfs_mk_bdev(MKDEV(FLOPPY_MAJOR, minor), | ||
3982 | S_IFBLK | S_IRUSR | S_IWUSR | S_IRGRP | | ||
3983 | S_IWGRP, "floppy/%d%s", drive, | ||
3984 | table[table_sup[UDP->cmos][i]]); | ||
3985 | } while (table_sup[UDP->cmos][i++]); | ||
3986 | } | ||
3987 | } | ||
3988 | 3954 | ||
3989 | /* | 3955 | /* |
3990 | * Floppy Driver initialization | 3956 | * Floppy Driver initialization |
@@ -4261,11 +4227,9 @@ static int __init floppy_init(void) | |||
4261 | motor_off_timer[dr].function = motor_off_callback; | 4227 | motor_off_timer[dr].function = motor_off_callback; |
4262 | } | 4228 | } |
4263 | 4229 | ||
4264 | devfs_mk_dir("floppy"); | ||
4265 | |||
4266 | err = register_blkdev(FLOPPY_MAJOR, "fd"); | 4230 | err = register_blkdev(FLOPPY_MAJOR, "fd"); |
4267 | if (err) | 4231 | if (err) |
4268 | goto out_devfs_remove; | 4232 | goto out_put_disk; |
4269 | 4233 | ||
4270 | floppy_queue = blk_init_queue(do_fd_request, &floppy_lock); | 4234 | floppy_queue = blk_init_queue(do_fd_request, &floppy_lock); |
4271 | if (!floppy_queue) { | 4235 | if (!floppy_queue) { |
@@ -4424,8 +4388,6 @@ out_unreg_region: | |||
4424 | blk_cleanup_queue(floppy_queue); | 4388 | blk_cleanup_queue(floppy_queue); |
4425 | out_unreg_blkdev: | 4389 | out_unreg_blkdev: |
4426 | unregister_blkdev(FLOPPY_MAJOR, "fd"); | 4390 | unregister_blkdev(FLOPPY_MAJOR, "fd"); |
4427 | out_devfs_remove: | ||
4428 | devfs_remove("floppy"); | ||
4429 | out_put_disk: | 4391 | out_put_disk: |
4430 | while (dr--) { | 4392 | while (dr--) { |
4431 | del_timer(&motor_off_timer[dr]); | 4393 | del_timer(&motor_off_timer[dr]); |
@@ -4586,19 +4548,6 @@ static void floppy_release_irq_and_dma(void) | |||
4586 | 4548 | ||
4587 | static char *floppy; | 4549 | static char *floppy; |
4588 | 4550 | ||
4589 | static void unregister_devfs_entries(int drive) | ||
4590 | { | ||
4591 | int i; | ||
4592 | |||
4593 | if (UDP->cmos < ARRAY_SIZE(default_drive_params)) { | ||
4594 | i = 0; | ||
4595 | do { | ||
4596 | devfs_remove("floppy/%d%s", drive, | ||
4597 | table[table_sup[UDP->cmos][i]]); | ||
4598 | } while (table_sup[UDP->cmos][i++]); | ||
4599 | } | ||
4600 | } | ||
4601 | |||
4602 | static void __init parse_floppy_cfg_string(char *cfg) | 4551 | static void __init parse_floppy_cfg_string(char *cfg) |
4603 | { | 4552 | { |
4604 | char *ptr; | 4553 | char *ptr; |
@@ -4635,13 +4584,11 @@ void cleanup_module(void) | |||
4635 | if ((allowed_drive_mask & (1 << drive)) && | 4584 | if ((allowed_drive_mask & (1 << drive)) && |
4636 | fdc_state[FDC(drive)].version != FDC_NONE) { | 4585 | fdc_state[FDC(drive)].version != FDC_NONE) { |
4637 | del_gendisk(disks[drive]); | 4586 | del_gendisk(disks[drive]); |
4638 | unregister_devfs_entries(drive); | ||
4639 | device_remove_file(&floppy_device[drive].dev, &dev_attr_cmos); | 4587 | device_remove_file(&floppy_device[drive].dev, &dev_attr_cmos); |
4640 | platform_device_unregister(&floppy_device[drive]); | 4588 | platform_device_unregister(&floppy_device[drive]); |
4641 | } | 4589 | } |
4642 | put_disk(disks[drive]); | 4590 | put_disk(disks[drive]); |
4643 | } | 4591 | } |
4644 | devfs_remove("floppy"); | ||
4645 | 4592 | ||
4646 | del_timer_sync(&fd_timeout); | 4593 | del_timer_sync(&fd_timeout); |
4647 | del_timer_sync(&fd_timer); | 4594 | del_timer_sync(&fd_timer); |
diff --git a/drivers/block/loop.c b/drivers/block/loop.c index 3c74ea729fc7..013c5daddb0b 100644 --- a/drivers/block/loop.c +++ b/drivers/block/loop.c | |||
@@ -63,7 +63,6 @@ | |||
63 | #include <linux/blkdev.h> | 63 | #include <linux/blkdev.h> |
64 | #include <linux/blkpg.h> | 64 | #include <linux/blkpg.h> |
65 | #include <linux/init.h> | 65 | #include <linux/init.h> |
66 | #include <linux/devfs_fs_kernel.h> | ||
67 | #include <linux/smp_lock.h> | 66 | #include <linux/smp_lock.h> |
68 | #include <linux/swap.h> | 67 | #include <linux/swap.h> |
69 | #include <linux/slab.h> | 68 | #include <linux/slab.h> |
@@ -210,7 +209,7 @@ static int do_lo_send_aops(struct loop_device *lo, struct bio_vec *bvec, | |||
210 | { | 209 | { |
211 | struct file *file = lo->lo_backing_file; /* kudos to NFsckingS */ | 210 | struct file *file = lo->lo_backing_file; /* kudos to NFsckingS */ |
212 | struct address_space *mapping = file->f_mapping; | 211 | struct address_space *mapping = file->f_mapping; |
213 | struct address_space_operations *aops = mapping->a_ops; | 212 | const struct address_space_operations *aops = mapping->a_ops; |
214 | pgoff_t index; | 213 | pgoff_t index; |
215 | unsigned offset, bv_offs; | 214 | unsigned offset, bv_offs; |
216 | int len, ret; | 215 | int len, ret; |
@@ -784,7 +783,7 @@ static int loop_set_fd(struct loop_device *lo, struct file *lo_file, | |||
784 | 783 | ||
785 | error = -EINVAL; | 784 | error = -EINVAL; |
786 | if (S_ISREG(inode->i_mode) || S_ISBLK(inode->i_mode)) { | 785 | if (S_ISREG(inode->i_mode) || S_ISBLK(inode->i_mode)) { |
787 | struct address_space_operations *aops = mapping->a_ops; | 786 | const struct address_space_operations *aops = mapping->a_ops; |
788 | /* | 787 | /* |
789 | * If we can't read - sorry. If we only can't write - well, | 788 | * If we can't read - sorry. If we only can't write - well, |
790 | * it's going to be read-only. | 789 | * it's going to be read-only. |
@@ -1277,8 +1276,6 @@ static int __init loop_init(void) | |||
1277 | goto out_mem3; | 1276 | goto out_mem3; |
1278 | } | 1277 | } |
1279 | 1278 | ||
1280 | devfs_mk_dir("loop"); | ||
1281 | |||
1282 | for (i = 0; i < max_loop; i++) { | 1279 | for (i = 0; i < max_loop; i++) { |
1283 | struct loop_device *lo = &loop_dev[i]; | 1280 | struct loop_device *lo = &loop_dev[i]; |
1284 | struct gendisk *disk = disks[i]; | 1281 | struct gendisk *disk = disks[i]; |
@@ -1296,7 +1293,6 @@ static int __init loop_init(void) | |||
1296 | disk->first_minor = i; | 1293 | disk->first_minor = i; |
1297 | disk->fops = &lo_fops; | 1294 | disk->fops = &lo_fops; |
1298 | sprintf(disk->disk_name, "loop%d", i); | 1295 | sprintf(disk->disk_name, "loop%d", i); |
1299 | sprintf(disk->devfs_name, "loop/%d", i); | ||
1300 | disk->private_data = lo; | 1296 | disk->private_data = lo; |
1301 | disk->queue = lo->lo_queue; | 1297 | disk->queue = lo->lo_queue; |
1302 | } | 1298 | } |
@@ -1310,7 +1306,6 @@ static int __init loop_init(void) | |||
1310 | out_mem4: | 1306 | out_mem4: |
1311 | while (i--) | 1307 | while (i--) |
1312 | blk_cleanup_queue(loop_dev[i].lo_queue); | 1308 | blk_cleanup_queue(loop_dev[i].lo_queue); |
1313 | devfs_remove("loop"); | ||
1314 | i = max_loop; | 1309 | i = max_loop; |
1315 | out_mem3: | 1310 | out_mem3: |
1316 | while (i--) | 1311 | while (i--) |
@@ -1333,7 +1328,6 @@ static void loop_exit(void) | |||
1333 | blk_cleanup_queue(loop_dev[i].lo_queue); | 1328 | blk_cleanup_queue(loop_dev[i].lo_queue); |
1334 | put_disk(disks[i]); | 1329 | put_disk(disks[i]); |
1335 | } | 1330 | } |
1336 | devfs_remove("loop"); | ||
1337 | if (unregister_blkdev(LOOP_MAJOR, "loop")) | 1331 | if (unregister_blkdev(LOOP_MAJOR, "loop")) |
1338 | printk(KERN_WARNING "loop: cannot unregister blkdev\n"); | 1332 | printk(KERN_WARNING "loop: cannot unregister blkdev\n"); |
1339 | 1333 | ||
diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c index 7f554f2ed079..39662f0c9cce 100644 --- a/drivers/block/nbd.c +++ b/drivers/block/nbd.c | |||
@@ -29,8 +29,6 @@ | |||
29 | #include <linux/kernel.h> | 29 | #include <linux/kernel.h> |
30 | #include <net/sock.h> | 30 | #include <net/sock.h> |
31 | 31 | ||
32 | #include <linux/devfs_fs_kernel.h> | ||
33 | |||
34 | #include <asm/uaccess.h> | 32 | #include <asm/uaccess.h> |
35 | #include <asm/system.h> | 33 | #include <asm/system.h> |
36 | #include <asm/types.h> | 34 | #include <asm/types.h> |
@@ -642,7 +640,6 @@ static int __init nbd_init(void) | |||
642 | printk(KERN_INFO "nbd: registered device at major %d\n", NBD_MAJOR); | 640 | printk(KERN_INFO "nbd: registered device at major %d\n", NBD_MAJOR); |
643 | dprintk(DBG_INIT, "nbd: debugflags=0x%x\n", debugflags); | 641 | dprintk(DBG_INIT, "nbd: debugflags=0x%x\n", debugflags); |
644 | 642 | ||
645 | devfs_mk_dir("nbd"); | ||
646 | for (i = 0; i < nbds_max; i++) { | 643 | for (i = 0; i < nbds_max; i++) { |
647 | struct gendisk *disk = nbd_dev[i].disk; | 644 | struct gendisk *disk = nbd_dev[i].disk; |
648 | nbd_dev[i].file = NULL; | 645 | nbd_dev[i].file = NULL; |
@@ -660,7 +657,6 @@ static int __init nbd_init(void) | |||
660 | disk->private_data = &nbd_dev[i]; | 657 | disk->private_data = &nbd_dev[i]; |
661 | disk->flags |= GENHD_FL_SUPPRESS_PARTITION_INFO; | 658 | disk->flags |= GENHD_FL_SUPPRESS_PARTITION_INFO; |
662 | sprintf(disk->disk_name, "nbd%d", i); | 659 | sprintf(disk->disk_name, "nbd%d", i); |
663 | sprintf(disk->devfs_name, "nbd/%d", i); | ||
664 | set_capacity(disk, 0x7ffffc00ULL << 1); /* 2 TB */ | 660 | set_capacity(disk, 0x7ffffc00ULL << 1); /* 2 TB */ |
665 | add_disk(disk); | 661 | add_disk(disk); |
666 | } | 662 | } |
@@ -686,7 +682,6 @@ static void __exit nbd_cleanup(void) | |||
686 | put_disk(disk); | 682 | put_disk(disk); |
687 | } | 683 | } |
688 | } | 684 | } |
689 | devfs_remove("nbd"); | ||
690 | unregister_blkdev(NBD_MAJOR, "nbd"); | 685 | unregister_blkdev(NBD_MAJOR, "nbd"); |
691 | printk(KERN_INFO "nbd: unregistered device at major %d\n", NBD_MAJOR); | 686 | printk(KERN_INFO "nbd: unregistered device at major %d\n", NBD_MAJOR); |
692 | } | 687 | } |
diff --git a/drivers/block/paride/pf.c b/drivers/block/paride/pf.c index 852b564e903a..1a9dee19efcf 100644 --- a/drivers/block/paride/pf.c +++ b/drivers/block/paride/pf.c | |||
@@ -707,7 +707,7 @@ static int pf_detect(void) | |||
707 | if (pi_init(pf->pi, 0, conf[D_PRT], conf[D_MOD], | 707 | if (pi_init(pf->pi, 0, conf[D_PRT], conf[D_MOD], |
708 | conf[D_UNI], conf[D_PRO], conf[D_DLY], | 708 | conf[D_UNI], conf[D_PRO], conf[D_DLY], |
709 | pf_scratch, PI_PF, verbose, pf->name)) { | 709 | pf_scratch, PI_PF, verbose, pf->name)) { |
710 | if (!pf_probe(pf) && pf->disk) { | 710 | if (pf->disk && !pf_probe(pf)) { |
711 | pf->present = 1; | 711 | pf->present = 1; |
712 | k++; | 712 | k++; |
713 | } else | 713 | } else |
diff --git a/drivers/block/paride/pg.c b/drivers/block/paride/pg.c index 79b868254032..13f998aa1cd3 100644 --- a/drivers/block/paride/pg.c +++ b/drivers/block/paride/pg.c | |||
@@ -156,7 +156,6 @@ enum {D_PRT, D_PRO, D_UNI, D_MOD, D_SLV, D_DLY}; | |||
156 | #include <linux/module.h> | 156 | #include <linux/module.h> |
157 | #include <linux/init.h> | 157 | #include <linux/init.h> |
158 | #include <linux/fs.h> | 158 | #include <linux/fs.h> |
159 | #include <linux/devfs_fs_kernel.h> | ||
160 | #include <linux/delay.h> | 159 | #include <linux/delay.h> |
161 | #include <linux/slab.h> | 160 | #include <linux/slab.h> |
162 | #include <linux/mtio.h> | 161 | #include <linux/mtio.h> |
@@ -674,25 +673,15 @@ static int __init pg_init(void) | |||
674 | err = PTR_ERR(pg_class); | 673 | err = PTR_ERR(pg_class); |
675 | goto out_chrdev; | 674 | goto out_chrdev; |
676 | } | 675 | } |
677 | devfs_mk_dir("pg"); | ||
678 | for (unit = 0; unit < PG_UNITS; unit++) { | 676 | for (unit = 0; unit < PG_UNITS; unit++) { |
679 | struct pg *dev = &devices[unit]; | 677 | struct pg *dev = &devices[unit]; |
680 | if (dev->present) { | 678 | if (dev->present) |
681 | class_device_create(pg_class, NULL, MKDEV(major, unit), | 679 | class_device_create(pg_class, NULL, MKDEV(major, unit), |
682 | NULL, "pg%u", unit); | 680 | NULL, "pg%u", unit); |
683 | err = devfs_mk_cdev(MKDEV(major, unit), | ||
684 | S_IFCHR | S_IRUSR | S_IWUSR, "pg/%u", | ||
685 | unit); | ||
686 | if (err) | ||
687 | goto out_class; | ||
688 | } | ||
689 | } | 681 | } |
690 | err = 0; | 682 | err = 0; |
691 | goto out; | 683 | goto out; |
692 | 684 | ||
693 | out_class: | ||
694 | class_device_destroy(pg_class, MKDEV(major, unit)); | ||
695 | class_destroy(pg_class); | ||
696 | out_chrdev: | 685 | out_chrdev: |
697 | unregister_chrdev(major, "pg"); | 686 | unregister_chrdev(major, "pg"); |
698 | out: | 687 | out: |
@@ -705,13 +694,10 @@ static void __exit pg_exit(void) | |||
705 | 694 | ||
706 | for (unit = 0; unit < PG_UNITS; unit++) { | 695 | for (unit = 0; unit < PG_UNITS; unit++) { |
707 | struct pg *dev = &devices[unit]; | 696 | struct pg *dev = &devices[unit]; |
708 | if (dev->present) { | 697 | if (dev->present) |
709 | class_device_destroy(pg_class, MKDEV(major, unit)); | 698 | class_device_destroy(pg_class, MKDEV(major, unit)); |
710 | devfs_remove("pg/%u", unit); | ||
711 | } | ||
712 | } | 699 | } |
713 | class_destroy(pg_class); | 700 | class_destroy(pg_class); |
714 | devfs_remove("pg"); | ||
715 | unregister_chrdev(major, name); | 701 | unregister_chrdev(major, name); |
716 | 702 | ||
717 | for (unit = 0; unit < PG_UNITS; unit++) { | 703 | for (unit = 0; unit < PG_UNITS; unit++) { |
diff --git a/drivers/block/paride/pt.c b/drivers/block/paride/pt.c index d2013d362403..35fb26636721 100644 --- a/drivers/block/paride/pt.c +++ b/drivers/block/paride/pt.c | |||
@@ -141,7 +141,6 @@ static int (*drives[4])[6] = {&drive0, &drive1, &drive2, &drive3}; | |||
141 | #include <linux/module.h> | 141 | #include <linux/module.h> |
142 | #include <linux/init.h> | 142 | #include <linux/init.h> |
143 | #include <linux/fs.h> | 143 | #include <linux/fs.h> |
144 | #include <linux/devfs_fs_kernel.h> | ||
145 | #include <linux/delay.h> | 144 | #include <linux/delay.h> |
146 | #include <linux/slab.h> | 145 | #include <linux/slab.h> |
147 | #include <linux/mtio.h> | 146 | #include <linux/mtio.h> |
@@ -971,32 +970,15 @@ static int __init pt_init(void) | |||
971 | goto out_chrdev; | 970 | goto out_chrdev; |
972 | } | 971 | } |
973 | 972 | ||
974 | devfs_mk_dir("pt"); | ||
975 | for (unit = 0; unit < PT_UNITS; unit++) | 973 | for (unit = 0; unit < PT_UNITS; unit++) |
976 | if (pt[unit].present) { | 974 | if (pt[unit].present) { |
977 | class_device_create(pt_class, NULL, MKDEV(major, unit), | 975 | class_device_create(pt_class, NULL, MKDEV(major, unit), |
978 | NULL, "pt%d", unit); | 976 | NULL, "pt%d", unit); |
979 | err = devfs_mk_cdev(MKDEV(major, unit), | ||
980 | S_IFCHR | S_IRUSR | S_IWUSR, | ||
981 | "pt/%d", unit); | ||
982 | if (err) { | ||
983 | class_device_destroy(pt_class, MKDEV(major, unit)); | ||
984 | goto out_class; | ||
985 | } | ||
986 | class_device_create(pt_class, NULL, MKDEV(major, unit + 128), | 977 | class_device_create(pt_class, NULL, MKDEV(major, unit + 128), |
987 | NULL, "pt%dn", unit); | 978 | NULL, "pt%dn", unit); |
988 | err = devfs_mk_cdev(MKDEV(major, unit + 128), | ||
989 | S_IFCHR | S_IRUSR | S_IWUSR, | ||
990 | "pt/%dn", unit); | ||
991 | if (err) { | ||
992 | class_device_destroy(pt_class, MKDEV(major, unit + 128)); | ||
993 | goto out_class; | ||
994 | } | ||
995 | } | 979 | } |
996 | goto out; | 980 | goto out; |
997 | 981 | ||
998 | out_class: | ||
999 | class_destroy(pt_class); | ||
1000 | out_chrdev: | 982 | out_chrdev: |
1001 | unregister_chrdev(major, "pt"); | 983 | unregister_chrdev(major, "pt"); |
1002 | out: | 984 | out: |
@@ -1009,12 +991,9 @@ static void __exit pt_exit(void) | |||
1009 | for (unit = 0; unit < PT_UNITS; unit++) | 991 | for (unit = 0; unit < PT_UNITS; unit++) |
1010 | if (pt[unit].present) { | 992 | if (pt[unit].present) { |
1011 | class_device_destroy(pt_class, MKDEV(major, unit)); | 993 | class_device_destroy(pt_class, MKDEV(major, unit)); |
1012 | devfs_remove("pt/%d", unit); | ||
1013 | class_device_destroy(pt_class, MKDEV(major, unit + 128)); | 994 | class_device_destroy(pt_class, MKDEV(major, unit + 128)); |
1014 | devfs_remove("pt/%dn", unit); | ||
1015 | } | 995 | } |
1016 | class_destroy(pt_class); | 996 | class_destroy(pt_class); |
1017 | devfs_remove("pt"); | ||
1018 | unregister_chrdev(major, name); | 997 | unregister_chrdev(major, name); |
1019 | for (unit = 0; unit < PT_UNITS; unit++) | 998 | for (unit = 0; unit < PT_UNITS; unit++) |
1020 | if (pt[unit].present) | 999 | if (pt[unit].present) |
diff --git a/drivers/block/pktcdvd.c b/drivers/block/pktcdvd.c index a04f60693c39..3e4cce5e4736 100644 --- a/drivers/block/pktcdvd.c +++ b/drivers/block/pktcdvd.c | |||
@@ -2612,7 +2612,6 @@ static struct file_operations pkt_ctl_fops = { | |||
2612 | static struct miscdevice pkt_misc = { | 2612 | static struct miscdevice pkt_misc = { |
2613 | .minor = MISC_DYNAMIC_MINOR, | 2613 | .minor = MISC_DYNAMIC_MINOR, |
2614 | .name = "pktcdvd", | 2614 | .name = "pktcdvd", |
2615 | .devfs_name = "pktcdvd/control", | ||
2616 | .fops = &pkt_ctl_fops | 2615 | .fops = &pkt_ctl_fops |
2617 | }; | 2616 | }; |
2618 | 2617 | ||
diff --git a/drivers/block/ps2esdi.c b/drivers/block/ps2esdi.c index bea75f2cb211..a729013a3973 100644 --- a/drivers/block/ps2esdi.c +++ b/drivers/block/ps2esdi.c | |||
@@ -421,7 +421,6 @@ static int __init ps2esdi_geninit(void) | |||
421 | disk->major = PS2ESDI_MAJOR; | 421 | disk->major = PS2ESDI_MAJOR; |
422 | disk->first_minor = i<<6; | 422 | disk->first_minor = i<<6; |
423 | sprintf(disk->disk_name, "ed%c", 'a'+i); | 423 | sprintf(disk->disk_name, "ed%c", 'a'+i); |
424 | sprintf(disk->devfs_name, "ed/target%d", i); | ||
425 | disk->fops = &ps2esdi_fops; | 424 | disk->fops = &ps2esdi_fops; |
426 | ps2esdi_gendisk[i] = disk; | 425 | ps2esdi_gendisk[i] = disk; |
427 | } | 426 | } |
diff --git a/drivers/block/rd.c b/drivers/block/rd.c index 940bfd7951e5..a9e1c2524c2a 100644 --- a/drivers/block/rd.c +++ b/drivers/block/rd.c | |||
@@ -50,7 +50,6 @@ | |||
50 | #include <linux/module.h> | 50 | #include <linux/module.h> |
51 | #include <linux/moduleparam.h> | 51 | #include <linux/moduleparam.h> |
52 | #include <linux/init.h> | 52 | #include <linux/init.h> |
53 | #include <linux/devfs_fs_kernel.h> | ||
54 | #include <linux/pagemap.h> | 53 | #include <linux/pagemap.h> |
55 | #include <linux/blkdev.h> | 54 | #include <linux/blkdev.h> |
56 | #include <linux/genhd.h> | 55 | #include <linux/genhd.h> |
@@ -191,7 +190,7 @@ static int ramdisk_set_page_dirty(struct page *page) | |||
191 | return 0; | 190 | return 0; |
192 | } | 191 | } |
193 | 192 | ||
194 | static struct address_space_operations ramdisk_aops = { | 193 | static const struct address_space_operations ramdisk_aops = { |
195 | .readpage = ramdisk_readpage, | 194 | .readpage = ramdisk_readpage, |
196 | .prepare_write = ramdisk_prepare_write, | 195 | .prepare_write = ramdisk_prepare_write, |
197 | .commit_write = ramdisk_commit_write, | 196 | .commit_write = ramdisk_commit_write, |
@@ -412,7 +411,6 @@ static void __exit rd_cleanup(void) | |||
412 | put_disk(rd_disks[i]); | 411 | put_disk(rd_disks[i]); |
413 | blk_cleanup_queue(rd_queue[i]); | 412 | blk_cleanup_queue(rd_queue[i]); |
414 | } | 413 | } |
415 | devfs_remove("rd"); | ||
416 | unregister_blkdev(RAMDISK_MAJOR, "ramdisk"); | 414 | unregister_blkdev(RAMDISK_MAJOR, "ramdisk"); |
417 | } | 415 | } |
418 | 416 | ||
@@ -442,8 +440,6 @@ static int __init rd_init(void) | |||
442 | goto out; | 440 | goto out; |
443 | } | 441 | } |
444 | 442 | ||
445 | devfs_mk_dir("rd"); | ||
446 | |||
447 | for (i = 0; i < CONFIG_BLK_DEV_RAM_COUNT; i++) { | 443 | for (i = 0; i < CONFIG_BLK_DEV_RAM_COUNT; i++) { |
448 | struct gendisk *disk = rd_disks[i]; | 444 | struct gendisk *disk = rd_disks[i]; |
449 | 445 | ||
@@ -461,7 +457,6 @@ static int __init rd_init(void) | |||
461 | disk->queue = rd_queue[i]; | 457 | disk->queue = rd_queue[i]; |
462 | disk->flags |= GENHD_FL_SUPPRESS_PARTITION_INFO; | 458 | disk->flags |= GENHD_FL_SUPPRESS_PARTITION_INFO; |
463 | sprintf(disk->disk_name, "ram%d", i); | 459 | sprintf(disk->disk_name, "ram%d", i); |
464 | sprintf(disk->devfs_name, "rd/%d", i); | ||
465 | set_capacity(disk, rd_size * 2); | 460 | set_capacity(disk, rd_size * 2); |
466 | add_disk(rd_disks[i]); | 461 | add_disk(rd_disks[i]); |
467 | } | 462 | } |
diff --git a/drivers/block/swim3.c b/drivers/block/swim3.c index 01f042f6f1c4..628877945f9b 100644 --- a/drivers/block/swim3.c +++ b/drivers/block/swim3.c | |||
@@ -25,7 +25,6 @@ | |||
25 | #include <linux/fd.h> | 25 | #include <linux/fd.h> |
26 | #include <linux/ioctl.h> | 26 | #include <linux/ioctl.h> |
27 | #include <linux/blkdev.h> | 27 | #include <linux/blkdev.h> |
28 | #include <linux/devfs_fs_kernel.h> | ||
29 | #include <linux/interrupt.h> | 28 | #include <linux/interrupt.h> |
30 | #include <linux/module.h> | 29 | #include <linux/module.h> |
31 | #include <linux/spinlock.h> | 30 | #include <linux/spinlock.h> |
@@ -1019,8 +1018,6 @@ int swim3_init(void) | |||
1019 | int err = -ENOMEM; | 1018 | int err = -ENOMEM; |
1020 | int i; | 1019 | int i; |
1021 | 1020 | ||
1022 | devfs_mk_dir("floppy"); | ||
1023 | |||
1024 | swim = find_devices("floppy"); | 1021 | swim = find_devices("floppy"); |
1025 | while (swim && (floppy_count < MAX_FLOPPIES)) | 1022 | while (swim && (floppy_count < MAX_FLOPPIES)) |
1026 | { | 1023 | { |
@@ -1064,7 +1061,6 @@ int swim3_init(void) | |||
1064 | disk->queue = swim3_queue; | 1061 | disk->queue = swim3_queue; |
1065 | disk->flags |= GENHD_FL_REMOVABLE; | 1062 | disk->flags |= GENHD_FL_REMOVABLE; |
1066 | sprintf(disk->disk_name, "fd%d", i); | 1063 | sprintf(disk->disk_name, "fd%d", i); |
1067 | sprintf(disk->devfs_name, "floppy/%d", i); | ||
1068 | set_capacity(disk, 2880); | 1064 | set_capacity(disk, 2880); |
1069 | add_disk(disk); | 1065 | add_disk(disk); |
1070 | } | 1066 | } |
diff --git a/drivers/block/sx8.c b/drivers/block/sx8.c index 2ae08b343b93..10a4aa5fb54d 100644 --- a/drivers/block/sx8.c +++ b/drivers/block/sx8.c | |||
@@ -18,7 +18,6 @@ | |||
18 | #include <linux/spinlock.h> | 18 | #include <linux/spinlock.h> |
19 | #include <linux/blkdev.h> | 19 | #include <linux/blkdev.h> |
20 | #include <linux/sched.h> | 20 | #include <linux/sched.h> |
21 | #include <linux/devfs_fs_kernel.h> | ||
22 | #include <linux/interrupt.h> | 21 | #include <linux/interrupt.h> |
23 | #include <linux/compiler.h> | 22 | #include <linux/compiler.h> |
24 | #include <linux/workqueue.h> | 23 | #include <linux/workqueue.h> |
@@ -1510,7 +1509,6 @@ static int carm_init_disks(struct carm_host *host) | |||
1510 | port->disk = disk; | 1509 | port->disk = disk; |
1511 | sprintf(disk->disk_name, DRV_NAME "/%u", | 1510 | sprintf(disk->disk_name, DRV_NAME "/%u", |
1512 | (unsigned int) (host->id * CARM_MAX_PORTS) + i); | 1511 | (unsigned int) (host->id * CARM_MAX_PORTS) + i); |
1513 | sprintf(disk->devfs_name, DRV_NAME "/%u_%u", host->id, i); | ||
1514 | disk->major = host->major; | 1512 | disk->major = host->major; |
1515 | disk->first_minor = i * CARM_MINORS_PER_MAJOR; | 1513 | disk->first_minor = i * CARM_MINORS_PER_MAJOR; |
1516 | disk->fops = &carm_bd_ops; | 1514 | disk->fops = &carm_bd_ops; |
@@ -1672,8 +1670,6 @@ static int carm_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) | |||
1672 | if (host->flags & FL_DYN_MAJOR) | 1670 | if (host->flags & FL_DYN_MAJOR) |
1673 | host->major = rc; | 1671 | host->major = rc; |
1674 | 1672 | ||
1675 | devfs_mk_dir(DRV_NAME); | ||
1676 | |||
1677 | rc = carm_init_disks(host); | 1673 | rc = carm_init_disks(host); |
1678 | if (rc) | 1674 | if (rc) |
1679 | goto err_out_blkdev_disks; | 1675 | goto err_out_blkdev_disks; |
@@ -1694,9 +1690,10 @@ static int carm_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) | |||
1694 | DPRINTK("waiting for probe_comp\n"); | 1690 | DPRINTK("waiting for probe_comp\n"); |
1695 | wait_for_completion(&host->probe_comp); | 1691 | wait_for_completion(&host->probe_comp); |
1696 | 1692 | ||
1697 | printk(KERN_INFO "%s: pci %s, ports %d, io %lx, irq %u, major %d\n", | 1693 | printk(KERN_INFO "%s: pci %s, ports %d, io %llx, irq %u, major %d\n", |
1698 | host->name, pci_name(pdev), (int) CARM_MAX_PORTS, | 1694 | host->name, pci_name(pdev), (int) CARM_MAX_PORTS, |
1699 | pci_resource_start(pdev, 0), pdev->irq, host->major); | 1695 | (unsigned long long)pci_resource_start(pdev, 0), |
1696 | pdev->irq, host->major); | ||
1700 | 1697 | ||
1701 | carm_host_id++; | 1698 | carm_host_id++; |
1702 | pci_set_drvdata(pdev, host); | 1699 | pci_set_drvdata(pdev, host); |
@@ -1738,7 +1735,6 @@ static void carm_remove_one (struct pci_dev *pdev) | |||
1738 | 1735 | ||
1739 | free_irq(pdev->irq, host); | 1736 | free_irq(pdev->irq, host); |
1740 | carm_free_disks(host); | 1737 | carm_free_disks(host); |
1741 | devfs_remove(DRV_NAME); | ||
1742 | unregister_blkdev(host->major, host->name); | 1738 | unregister_blkdev(host->major, host->name); |
1743 | if (host->major == 160) | 1739 | if (host->major == 160) |
1744 | clear_bit(0, &carm_major_alloc); | 1740 | clear_bit(0, &carm_major_alloc); |
diff --git a/drivers/block/ub.c b/drivers/block/ub.c index 60e9a9457c6b..d62b49fbf10c 100644 --- a/drivers/block/ub.c +++ b/drivers/block/ub.c | |||
@@ -24,12 +24,10 @@ | |||
24 | #include <linux/usb.h> | 24 | #include <linux/usb.h> |
25 | #include <linux/usb_usual.h> | 25 | #include <linux/usb_usual.h> |
26 | #include <linux/blkdev.h> | 26 | #include <linux/blkdev.h> |
27 | #include <linux/devfs_fs_kernel.h> | ||
28 | #include <linux/timer.h> | 27 | #include <linux/timer.h> |
29 | #include <scsi/scsi.h> | 28 | #include <scsi/scsi.h> |
30 | 29 | ||
31 | #define DRV_NAME "ub" | 30 | #define DRV_NAME "ub" |
32 | #define DEVFS_NAME DRV_NAME | ||
33 | 31 | ||
34 | #define UB_MAJOR 180 | 32 | #define UB_MAJOR 180 |
35 | 33 | ||
@@ -2291,7 +2289,6 @@ static int ub_probe_lun(struct ub_dev *sc, int lnum) | |||
2291 | goto err_diskalloc; | 2289 | goto err_diskalloc; |
2292 | 2290 | ||
2293 | sprintf(disk->disk_name, DRV_NAME "%c", lun->id + 'a'); | 2291 | sprintf(disk->disk_name, DRV_NAME "%c", lun->id + 'a'); |
2294 | sprintf(disk->devfs_name, DEVFS_NAME "/%c", lun->id + 'a'); | ||
2295 | disk->major = UB_MAJOR; | 2292 | disk->major = UB_MAJOR; |
2296 | disk->first_minor = lun->id * UB_PARTS_PER_LUN; | 2293 | disk->first_minor = lun->id * UB_PARTS_PER_LUN; |
2297 | disk->fops = &ub_bd_fops; | 2294 | disk->fops = &ub_bd_fops; |
@@ -2445,7 +2442,6 @@ static int __init ub_init(void) | |||
2445 | 2442 | ||
2446 | if ((rc = register_blkdev(UB_MAJOR, DRV_NAME)) != 0) | 2443 | if ((rc = register_blkdev(UB_MAJOR, DRV_NAME)) != 0) |
2447 | goto err_regblkdev; | 2444 | goto err_regblkdev; |
2448 | devfs_mk_dir(DEVFS_NAME); | ||
2449 | 2445 | ||
2450 | if ((rc = usb_register(&ub_driver)) != 0) | 2446 | if ((rc = usb_register(&ub_driver)) != 0) |
2451 | goto err_register; | 2447 | goto err_register; |
@@ -2454,7 +2450,6 @@ static int __init ub_init(void) | |||
2454 | return 0; | 2450 | return 0; |
2455 | 2451 | ||
2456 | err_register: | 2452 | err_register: |
2457 | devfs_remove(DEVFS_NAME); | ||
2458 | unregister_blkdev(UB_MAJOR, DRV_NAME); | 2453 | unregister_blkdev(UB_MAJOR, DRV_NAME); |
2459 | err_regblkdev: | 2454 | err_regblkdev: |
2460 | return rc; | 2455 | return rc; |
@@ -2464,7 +2459,6 @@ static void __exit ub_exit(void) | |||
2464 | { | 2459 | { |
2465 | usb_deregister(&ub_driver); | 2460 | usb_deregister(&ub_driver); |
2466 | 2461 | ||
2467 | devfs_remove(DEVFS_NAME); | ||
2468 | unregister_blkdev(UB_MAJOR, DRV_NAME); | 2462 | unregister_blkdev(UB_MAJOR, DRV_NAME); |
2469 | usb_usual_clear_present(USB_US_TYPE_UB); | 2463 | usb_usual_clear_present(USB_US_TYPE_UB); |
2470 | } | 2464 | } |
diff --git a/drivers/block/umem.c b/drivers/block/umem.c index f7d4c65a7b8c..585197b95af7 100644 --- a/drivers/block/umem.c +++ b/drivers/block/umem.c | |||
@@ -1192,7 +1192,6 @@ static int __init mm_init(void) | |||
1192 | for (i = 0; i < num_cards; i++) { | 1192 | for (i = 0; i < num_cards; i++) { |
1193 | struct gendisk *disk = mm_gendisk[i]; | 1193 | struct gendisk *disk = mm_gendisk[i]; |
1194 | sprintf(disk->disk_name, "umem%c", 'a'+i); | 1194 | sprintf(disk->disk_name, "umem%c", 'a'+i); |
1195 | sprintf(disk->devfs_name, "umem/card%d", i); | ||
1196 | spin_lock_init(&cards[i].lock); | 1195 | spin_lock_init(&cards[i].lock); |
1197 | disk->major = major_nr; | 1196 | disk->major = major_nr; |
1198 | disk->first_minor = i << MM_SHIFT; | 1197 | disk->first_minor = i << MM_SHIFT; |
diff --git a/drivers/block/viodasd.c b/drivers/block/viodasd.c index b0df4f5ab97a..ec5a1b90a0a2 100644 --- a/drivers/block/viodasd.c +++ b/drivers/block/viodasd.c | |||
@@ -59,7 +59,6 @@ MODULE_LICENSE("GPL"); | |||
59 | * numbers 0-255 we get a maximum of 32 disks. | 59 | * numbers 0-255 we get a maximum of 32 disks. |
60 | */ | 60 | */ |
61 | #define VIOD_GENHD_NAME "iseries/vd" | 61 | #define VIOD_GENHD_NAME "iseries/vd" |
62 | #define VIOD_GENHD_DEVFS_NAME "iseries/disc" | ||
63 | 62 | ||
64 | #define VIOD_VERS "1.64" | 63 | #define VIOD_VERS "1.64" |
65 | 64 | ||
@@ -523,8 +522,6 @@ retry: | |||
523 | else | 522 | else |
524 | snprintf(g->disk_name, sizeof(g->disk_name), | 523 | snprintf(g->disk_name, sizeof(g->disk_name), |
525 | VIOD_GENHD_NAME "%c", 'a' + (dev_no % 26)); | 524 | VIOD_GENHD_NAME "%c", 'a' + (dev_no % 26)); |
526 | snprintf(g->devfs_name, sizeof(g->devfs_name), | ||
527 | "%s%d", VIOD_GENHD_DEVFS_NAME, dev_no); | ||
528 | g->fops = &viodasd_fops; | 525 | g->fops = &viodasd_fops; |
529 | g->queue = q; | 526 | g->queue = q; |
530 | g->private_data = d; | 527 | g->private_data = d; |
diff --git a/drivers/block/xd.c b/drivers/block/xd.c index cbce7c5e9445..e828e4cbd3e1 100644 --- a/drivers/block/xd.c +++ b/drivers/block/xd.c | |||
@@ -215,7 +215,6 @@ static int __init xd_init(void) | |||
215 | disk->major = XT_DISK_MAJOR; | 215 | disk->major = XT_DISK_MAJOR; |
216 | disk->first_minor = i<<6; | 216 | disk->first_minor = i<<6; |
217 | sprintf(disk->disk_name, "xd%c", i+'a'); | 217 | sprintf(disk->disk_name, "xd%c", i+'a'); |
218 | sprintf(disk->devfs_name, "xd/target%d", i); | ||
219 | disk->fops = &xd_fops; | 218 | disk->fops = &xd_fops; |
220 | disk->private_data = p; | 219 | disk->private_data = p; |
221 | disk->queue = xd_queue; | 220 | disk->queue = xd_queue; |
diff --git a/drivers/block/z2ram.c b/drivers/block/z2ram.c index bb5e8d665a2a..82ddbdd7bd4b 100644 --- a/drivers/block/z2ram.c +++ b/drivers/block/z2ram.c | |||
@@ -354,7 +354,6 @@ z2_init(void) | |||
354 | z2ram_gendisk->first_minor = 0; | 354 | z2ram_gendisk->first_minor = 0; |
355 | z2ram_gendisk->fops = &z2_fops; | 355 | z2ram_gendisk->fops = &z2_fops; |
356 | sprintf(z2ram_gendisk->disk_name, "z2ram"); | 356 | sprintf(z2ram_gendisk->disk_name, "z2ram"); |
357 | strcpy(z2ram_gendisk->devfs_name, z2ram_gendisk->disk_name); | ||
358 | 357 | ||
359 | z2ram_gendisk->queue = z2_queue; | 358 | z2ram_gendisk->queue = z2_queue; |
360 | add_disk(z2ram_gendisk); | 359 | add_disk(z2ram_gendisk); |
diff --git a/drivers/cdrom/aztcd.c b/drivers/cdrom/aztcd.c index ec004897b634..ec469497c10f 100644 --- a/drivers/cdrom/aztcd.c +++ b/drivers/cdrom/aztcd.c | |||
@@ -1918,7 +1918,6 @@ static int __init aztcd_init(void) | |||
1918 | azt_disk->first_minor = 0; | 1918 | azt_disk->first_minor = 0; |
1919 | azt_disk->fops = &azt_fops; | 1919 | azt_disk->fops = &azt_fops; |
1920 | sprintf(azt_disk->disk_name, "aztcd"); | 1920 | sprintf(azt_disk->disk_name, "aztcd"); |
1921 | sprintf(azt_disk->devfs_name, "aztcd"); | ||
1922 | azt_disk->queue = azt_queue; | 1921 | azt_disk->queue = azt_queue; |
1923 | add_disk(azt_disk); | 1922 | add_disk(azt_disk); |
1924 | azt_invalidate_buffers(); | 1923 | azt_invalidate_buffers(); |
diff --git a/drivers/cdrom/cdu31a.c b/drivers/cdrom/cdu31a.c index 72ffd64e8b1e..5f0f2027f29e 100644 --- a/drivers/cdrom/cdu31a.c +++ b/drivers/cdrom/cdu31a.c | |||
@@ -161,7 +161,6 @@ | |||
161 | #include <linux/hdreg.h> | 161 | #include <linux/hdreg.h> |
162 | #include <linux/genhd.h> | 162 | #include <linux/genhd.h> |
163 | #include <linux/ioport.h> | 163 | #include <linux/ioport.h> |
164 | #include <linux/devfs_fs_kernel.h> | ||
165 | #include <linux/string.h> | 164 | #include <linux/string.h> |
166 | #include <linux/slab.h> | 165 | #include <linux/slab.h> |
167 | #include <linux/init.h> | 166 | #include <linux/init.h> |
diff --git a/drivers/cdrom/cm206.c b/drivers/cdrom/cm206.c index f43a988dd413..4ee288688fed 100644 --- a/drivers/cdrom/cm206.c +++ b/drivers/cdrom/cm206.c | |||
@@ -187,7 +187,6 @@ History: | |||
187 | #include <linux/interrupt.h> | 187 | #include <linux/interrupt.h> |
188 | #include <linux/timer.h> | 188 | #include <linux/timer.h> |
189 | #include <linux/cdrom.h> | 189 | #include <linux/cdrom.h> |
190 | #include <linux/devfs_fs_kernel.h> | ||
191 | #include <linux/ioport.h> | 190 | #include <linux/ioport.h> |
192 | #include <linux/mm.h> | 191 | #include <linux/mm.h> |
193 | #include <linux/slab.h> | 192 | #include <linux/slab.h> |
diff --git a/drivers/cdrom/gscd.c b/drivers/cdrom/gscd.c index ad5464ab99bc..b6ee50a2916d 100644 --- a/drivers/cdrom/gscd.c +++ b/drivers/cdrom/gscd.c | |||
@@ -955,7 +955,6 @@ static int __init gscd_init(void) | |||
955 | gscd_disk->first_minor = 0; | 955 | gscd_disk->first_minor = 0; |
956 | gscd_disk->fops = &gscd_fops; | 956 | gscd_disk->fops = &gscd_fops; |
957 | sprintf(gscd_disk->disk_name, "gscd"); | 957 | sprintf(gscd_disk->disk_name, "gscd"); |
958 | sprintf(gscd_disk->devfs_name, "gscd"); | ||
959 | 958 | ||
960 | if (register_blkdev(MAJOR_NR, "gscd")) { | 959 | if (register_blkdev(MAJOR_NR, "gscd")) { |
961 | ret = -EIO; | 960 | ret = -EIO; |
diff --git a/drivers/cdrom/mcdx.c b/drivers/cdrom/mcdx.c index 0f6e7aab8d2c..788c7a0b2fe3 100644 --- a/drivers/cdrom/mcdx.c +++ b/drivers/cdrom/mcdx.c | |||
@@ -74,7 +74,6 @@ static const char *mcdx_c_version | |||
74 | #include <linux/major.h> | 74 | #include <linux/major.h> |
75 | #define MAJOR_NR MITSUMI_X_CDROM_MAJOR | 75 | #define MAJOR_NR MITSUMI_X_CDROM_MAJOR |
76 | #include <linux/blkdev.h> | 76 | #include <linux/blkdev.h> |
77 | #include <linux/devfs_fs_kernel.h> | ||
78 | 77 | ||
79 | #include "mcdx.h" | 78 | #include "mcdx.h" |
80 | 79 | ||
diff --git a/drivers/cdrom/optcd.c b/drivers/cdrom/optcd.c index 0b0eab4f40fa..25032d7edc55 100644 --- a/drivers/cdrom/optcd.c +++ b/drivers/cdrom/optcd.c | |||
@@ -2033,7 +2033,6 @@ static int __init optcd_init(void) | |||
2033 | optcd_disk->first_minor = 0; | 2033 | optcd_disk->first_minor = 0; |
2034 | optcd_disk->fops = &opt_fops; | 2034 | optcd_disk->fops = &opt_fops; |
2035 | sprintf(optcd_disk->disk_name, "optcd"); | 2035 | sprintf(optcd_disk->disk_name, "optcd"); |
2036 | sprintf(optcd_disk->devfs_name, "optcd"); | ||
2037 | 2036 | ||
2038 | if (!request_region(optcd_port, 4, "optcd")) { | 2037 | if (!request_region(optcd_port, 4, "optcd")) { |
2039 | printk(KERN_ERR "optcd: conflict, I/O port 0x%x already used\n", | 2038 | printk(KERN_ERR "optcd: conflict, I/O port 0x%x already used\n", |
diff --git a/drivers/cdrom/sbpcd.c b/drivers/cdrom/sbpcd.c index 05c9e865ecaf..2fc966c65a0e 100644 --- a/drivers/cdrom/sbpcd.c +++ b/drivers/cdrom/sbpcd.c | |||
@@ -371,7 +371,6 @@ | |||
371 | #include <linux/kernel.h> | 371 | #include <linux/kernel.h> |
372 | #include <linux/cdrom.h> | 372 | #include <linux/cdrom.h> |
373 | #include <linux/ioport.h> | 373 | #include <linux/ioport.h> |
374 | #include <linux/devfs_fs_kernel.h> | ||
375 | #include <linux/major.h> | 374 | #include <linux/major.h> |
376 | #include <linux/string.h> | 375 | #include <linux/string.h> |
377 | #include <linux/vmalloc.h> | 376 | #include <linux/vmalloc.h> |
@@ -5808,8 +5807,6 @@ int __init sbpcd_init(void) | |||
5808 | return -ENOMEM; | 5807 | return -ENOMEM; |
5809 | } | 5808 | } |
5810 | 5809 | ||
5811 | devfs_mk_dir("sbp"); | ||
5812 | |||
5813 | for (j=0;j<NR_SBPCD;j++) | 5810 | for (j=0;j<NR_SBPCD;j++) |
5814 | { | 5811 | { |
5815 | struct cdrom_device_info * sbpcd_infop; | 5812 | struct cdrom_device_info * sbpcd_infop; |
@@ -5871,7 +5868,6 @@ int __init sbpcd_init(void) | |||
5871 | disk->fops = &sbpcd_bdops; | 5868 | disk->fops = &sbpcd_bdops; |
5872 | strcpy(disk->disk_name, sbpcd_infop->name); | 5869 | strcpy(disk->disk_name, sbpcd_infop->name); |
5873 | disk->flags = GENHD_FL_CD; | 5870 | disk->flags = GENHD_FL_CD; |
5874 | sprintf(disk->devfs_name, "sbp/c0t%d", p->drv_id); | ||
5875 | p->disk = disk; | 5871 | p->disk = disk; |
5876 | if (register_cdrom(sbpcd_infop)) | 5872 | if (register_cdrom(sbpcd_infop)) |
5877 | { | 5873 | { |
@@ -5906,7 +5902,6 @@ static void sbpcd_exit(void) | |||
5906 | if (D_S[j].drv_id==-1) continue; | 5902 | if (D_S[j].drv_id==-1) continue; |
5907 | del_gendisk(D_S[j].disk); | 5903 | del_gendisk(D_S[j].disk); |
5908 | put_disk(D_S[j].disk); | 5904 | put_disk(D_S[j].disk); |
5909 | devfs_remove("sbp/c0t%d", j); | ||
5910 | vfree(D_S[j].sbp_buf); | 5905 | vfree(D_S[j].sbp_buf); |
5911 | if (D_S[j].sbp_audsiz>0) | 5906 | if (D_S[j].sbp_audsiz>0) |
5912 | vfree(D_S[j].aud_buf); | 5907 | vfree(D_S[j].aud_buf); |
@@ -5917,7 +5912,6 @@ static void sbpcd_exit(void) | |||
5917 | } | 5912 | } |
5918 | vfree(D_S[j].sbpcd_infop); | 5913 | vfree(D_S[j].sbpcd_infop); |
5919 | } | 5914 | } |
5920 | devfs_remove("sbp"); | ||
5921 | msg(DBG_INF, "%s module released.\n", major_name); | 5915 | msg(DBG_INF, "%s module released.\n", major_name); |
5922 | } | 5916 | } |
5923 | 5917 | ||
diff --git a/drivers/cdrom/sjcd.c b/drivers/cdrom/sjcd.c index 74b1cadbf161..bf5aef4e555b 100644 --- a/drivers/cdrom/sjcd.c +++ b/drivers/cdrom/sjcd.c | |||
@@ -1695,7 +1695,6 @@ static int __init sjcd_init(void) | |||
1695 | sjcd_disk->first_minor = 0, | 1695 | sjcd_disk->first_minor = 0, |
1696 | sjcd_disk->fops = &sjcd_fops, | 1696 | sjcd_disk->fops = &sjcd_fops, |
1697 | sprintf(sjcd_disk->disk_name, "sjcd"); | 1697 | sprintf(sjcd_disk->disk_name, "sjcd"); |
1698 | sprintf(sjcd_disk->devfs_name, "sjcd"); | ||
1699 | 1698 | ||
1700 | if (!request_region(sjcd_base, 4,"sjcd")) { | 1699 | if (!request_region(sjcd_base, 4,"sjcd")) { |
1701 | printk | 1700 | printk |
diff --git a/drivers/cdrom/sonycd535.c b/drivers/cdrom/sonycd535.c index e65659926432..8f7cc452af8d 100644 --- a/drivers/cdrom/sonycd535.c +++ b/drivers/cdrom/sonycd535.c | |||
@@ -1589,7 +1589,6 @@ static int __init sony535_init(void) | |||
1589 | cdu_disk->first_minor = 0; | 1589 | cdu_disk->first_minor = 0; |
1590 | cdu_disk->fops = &cdu_fops; | 1590 | cdu_disk->fops = &cdu_fops; |
1591 | sprintf(cdu_disk->disk_name, "cdu"); | 1591 | sprintf(cdu_disk->disk_name, "cdu"); |
1592 | sprintf(cdu_disk->devfs_name, "cdu535"); | ||
1593 | 1592 | ||
1594 | if (!request_region(sony535_cd_base_io, 4, CDU535_HANDLE)) { | 1593 | if (!request_region(sony535_cd_base_io, 4, CDU535_HANDLE)) { |
1595 | printk(KERN_WARNING"sonycd535: Unable to request region 0x%x\n", | 1594 | printk(KERN_WARNING"sonycd535: Unable to request region 0x%x\n", |
diff --git a/drivers/cdrom/viocd.c b/drivers/cdrom/viocd.c index af6b3bfd169b..54ca931e19ea 100644 --- a/drivers/cdrom/viocd.c +++ b/drivers/cdrom/viocd.c | |||
@@ -49,7 +49,6 @@ | |||
49 | #include <asm/iseries/vio.h> | 49 | #include <asm/iseries/vio.h> |
50 | 50 | ||
51 | #define VIOCD_DEVICE "iseries/vcd" | 51 | #define VIOCD_DEVICE "iseries/vcd" |
52 | #define VIOCD_DEVICE_DEVFS "iseries/vcd" | ||
53 | 52 | ||
54 | #define VIOCD_VERS "1.06" | 53 | #define VIOCD_VERS "1.06" |
55 | 54 | ||
@@ -688,8 +687,6 @@ static int viocd_probe(struct vio_dev *vdev, const struct vio_device_id *id) | |||
688 | gendisk->first_minor = deviceno; | 687 | gendisk->first_minor = deviceno; |
689 | strncpy(gendisk->disk_name, c->name, | 688 | strncpy(gendisk->disk_name, c->name, |
690 | sizeof(gendisk->disk_name)); | 689 | sizeof(gendisk->disk_name)); |
691 | snprintf(gendisk->devfs_name, sizeof(gendisk->devfs_name), | ||
692 | VIOCD_DEVICE_DEVFS "%d", deviceno); | ||
693 | blk_queue_max_hw_segments(q, 1); | 690 | blk_queue_max_hw_segments(q, 1); |
694 | blk_queue_max_phys_segments(q, 1); | 691 | blk_queue_max_phys_segments(q, 1); |
695 | blk_queue_max_sectors(q, 4096 / 512); | 692 | blk_queue_max_sectors(q, 4096 / 512); |
diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig index 3610c5729553..c40e487d9f5c 100644 --- a/drivers/char/Kconfig +++ b/drivers/char/Kconfig | |||
@@ -939,12 +939,36 @@ config MWAVE | |||
939 | config SCx200_GPIO | 939 | config SCx200_GPIO |
940 | tristate "NatSemi SCx200 GPIO Support" | 940 | tristate "NatSemi SCx200 GPIO Support" |
941 | depends on SCx200 | 941 | depends on SCx200 |
942 | select NSC_GPIO | ||
942 | help | 943 | help |
943 | Give userspace access to the GPIO pins on the National | 944 | Give userspace access to the GPIO pins on the National |
944 | Semiconductor SCx200 processors. | 945 | Semiconductor SCx200 processors. |
945 | 946 | ||
946 | If compiled as a module, it will be called scx200_gpio. | 947 | If compiled as a module, it will be called scx200_gpio. |
947 | 948 | ||
949 | config PC8736x_GPIO | ||
950 | tristate "NatSemi PC8736x GPIO Support" | ||
951 | depends on X86 | ||
952 | default SCx200_GPIO # mostly N | ||
953 | select NSC_GPIO # needed for support routines | ||
954 | help | ||
955 | Give userspace access to the GPIO pins on the National | ||
956 | Semiconductor PC-8736x (x=[03456]) SuperIO chip. The chip | ||
957 | has multiple functional units, inc several managed by | ||
958 | hwmon/pc87360 driver. Tested with PC-87366 | ||
959 | |||
960 | If compiled as a module, it will be called pc8736x_gpio. | ||
961 | |||
962 | config NSC_GPIO | ||
963 | tristate "NatSemi Base GPIO Support" | ||
964 | depends on X86_32 | ||
965 | # selected by SCx200_GPIO and PC8736x_GPIO | ||
966 | # what about 2 selectors differing: m != y | ||
967 | help | ||
968 | Common support used (and needed) by scx200_gpio and | ||
969 | pc8736x_gpio drivers. If those drivers are built as | ||
970 | modules, this one will be too, named nsc_gpio | ||
971 | |||
948 | config CS5535_GPIO | 972 | config CS5535_GPIO |
949 | tristate "AMD CS5535/CS5536 GPIO (Geode Companion Device)" | 973 | tristate "AMD CS5535/CS5536 GPIO (Geode Companion Device)" |
950 | depends on X86_32 | 974 | depends on X86_32 |
diff --git a/drivers/char/Makefile b/drivers/char/Makefile index 524105597ea7..6e0f4469d8bb 100644 --- a/drivers/char/Makefile +++ b/drivers/char/Makefile | |||
@@ -82,6 +82,8 @@ obj-$(CONFIG_PPDEV) += ppdev.o | |||
82 | obj-$(CONFIG_NWBUTTON) += nwbutton.o | 82 | obj-$(CONFIG_NWBUTTON) += nwbutton.o |
83 | obj-$(CONFIG_NWFLASH) += nwflash.o | 83 | obj-$(CONFIG_NWFLASH) += nwflash.o |
84 | obj-$(CONFIG_SCx200_GPIO) += scx200_gpio.o | 84 | obj-$(CONFIG_SCx200_GPIO) += scx200_gpio.o |
85 | obj-$(CONFIG_PC8736x_GPIO) += pc8736x_gpio.o | ||
86 | obj-$(CONFIG_NSC_GPIO) += nsc_gpio.o | ||
85 | obj-$(CONFIG_CS5535_GPIO) += cs5535_gpio.o | 87 | obj-$(CONFIG_CS5535_GPIO) += cs5535_gpio.o |
86 | obj-$(CONFIG_GPIO_VR41XX) += vr41xx_giu.o | 88 | obj-$(CONFIG_GPIO_VR41XX) += vr41xx_giu.o |
87 | obj-$(CONFIG_TANBAC_TB0219) += tb0219.o | 89 | obj-$(CONFIG_TANBAC_TB0219) += tb0219.o |
diff --git a/drivers/char/agp/Kconfig b/drivers/char/agp/Kconfig index 9826a399fa02..22f8cf218cc6 100644 --- a/drivers/char/agp/Kconfig +++ b/drivers/char/agp/Kconfig | |||
@@ -1,6 +1,7 @@ | |||
1 | config AGP | 1 | config AGP |
2 | tristate "/dev/agpgart (AGP Support)" | 2 | tristate "/dev/agpgart (AGP Support)" |
3 | depends on ALPHA || IA64 || PPC || X86 | 3 | depends on ALPHA || IA64 || PPC || X86 |
4 | depends on PCI | ||
4 | ---help--- | 5 | ---help--- |
5 | AGP (Accelerated Graphics Port) is a bus system mainly used to | 6 | AGP (Accelerated Graphics Port) is a bus system mainly used to |
6 | connect graphics cards to the rest of the system. | 7 | connect graphics cards to the rest of the system. |
diff --git a/drivers/char/agp/amd64-agp.c b/drivers/char/agp/amd64-agp.c index f690ee8cb732..f74eeeb8e377 100644 --- a/drivers/char/agp/amd64-agp.c +++ b/drivers/char/agp/amd64-agp.c | |||
@@ -734,7 +734,7 @@ int __init agp_amd64_init(void) | |||
734 | 734 | ||
735 | if (agp_off) | 735 | if (agp_off) |
736 | return -EINVAL; | 736 | return -EINVAL; |
737 | if (pci_register_driver(&agp_amd64_pci_driver) > 0) { | 737 | if (pci_register_driver(&agp_amd64_pci_driver) < 0) { |
738 | struct pci_dev *dev; | 738 | struct pci_dev *dev; |
739 | if (!agp_try_unsupported && !agp_try_unsupported_boot) { | 739 | if (!agp_try_unsupported && !agp_try_unsupported_boot) { |
740 | printk(KERN_INFO PFX "No supported AGP bridge found.\n"); | 740 | printk(KERN_INFO PFX "No supported AGP bridge found.\n"); |
diff --git a/drivers/char/agp/ati-agp.c b/drivers/char/agp/ati-agp.c index 160564345993..f244c6682738 100644 --- a/drivers/char/agp/ati-agp.c +++ b/drivers/char/agp/ati-agp.c | |||
@@ -41,7 +41,6 @@ static struct gatt_mask ati_generic_masks[] = | |||
41 | }; | 41 | }; |
42 | 42 | ||
43 | 43 | ||
44 | |||
45 | typedef struct _ati_page_map { | 44 | typedef struct _ati_page_map { |
46 | unsigned long *real; | 45 | unsigned long *real; |
47 | unsigned long __iomem *remapped; | 46 | unsigned long __iomem *remapped; |
@@ -141,7 +140,8 @@ static int ati_create_gatt_pages(int nr_tables) | |||
141 | ati_generic_private.num_tables = nr_tables; | 140 | ati_generic_private.num_tables = nr_tables; |
142 | ati_generic_private.gatt_pages = tables; | 141 | ati_generic_private.gatt_pages = tables; |
143 | 142 | ||
144 | if (retval != 0) ati_free_gatt_pages(); | 143 | if (retval != 0) |
144 | ati_free_gatt_pages(); | ||
145 | 145 | ||
146 | return retval; | 146 | return retval; |
147 | } | 147 | } |
@@ -219,16 +219,16 @@ static int ati_configure(void) | |||
219 | ati_generic_private.registers = (volatile u8 __iomem *) ioremap(temp, 4096); | 219 | ati_generic_private.registers = (volatile u8 __iomem *) ioremap(temp, 4096); |
220 | 220 | ||
221 | if (is_r200()) | 221 | if (is_r200()) |
222 | pci_write_config_dword(agp_bridge->dev, ATI_RS100_IG_AGPMODE, 0x20000); | 222 | pci_write_config_dword(agp_bridge->dev, ATI_RS100_IG_AGPMODE, 0x20000); |
223 | else | 223 | else |
224 | pci_write_config_dword(agp_bridge->dev, ATI_RS300_IG_AGPMODE, 0x20000); | 224 | pci_write_config_dword(agp_bridge->dev, ATI_RS300_IG_AGPMODE, 0x20000); |
225 | 225 | ||
226 | /* address to map too */ | 226 | /* address to map too */ |
227 | /* | 227 | /* |
228 | pci_read_config_dword(agp_bridge.dev, AGP_APBASE, &temp); | 228 | pci_read_config_dword(agp_bridge.dev, AGP_APBASE, &temp); |
229 | agp_bridge.gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK); | 229 | agp_bridge.gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK); |
230 | printk(KERN_INFO PFX "IGP320 gart_bus_addr: %x\n", agp_bridge.gart_bus_addr); | 230 | printk(KERN_INFO PFX "IGP320 gart_bus_addr: %x\n", agp_bridge.gart_bus_addr); |
231 | */ | 231 | */ |
232 | writel(0x60000, ati_generic_private.registers+ATI_GART_FEATURE_ID); | 232 | writel(0x60000, ati_generic_private.registers+ATI_GART_FEATURE_ID); |
233 | readl(ati_generic_private.registers+ATI_GART_FEATURE_ID); /* PCI Posting.*/ | 233 | readl(ati_generic_private.registers+ATI_GART_FEATURE_ID); /* PCI Posting.*/ |
234 | 234 | ||
@@ -245,18 +245,20 @@ static int ati_configure(void) | |||
245 | 245 | ||
246 | 246 | ||
247 | #ifdef CONFIG_PM | 247 | #ifdef CONFIG_PM |
248 | static int agp_ati_resume(struct pci_dev *dev) | 248 | static int agp_ati_suspend(struct pci_dev *dev, pm_message_t state) |
249 | { | 249 | { |
250 | pci_restore_state(dev); | 250 | pci_save_state(dev); |
251 | pci_set_power_state(dev, 3); | ||
251 | 252 | ||
252 | return ati_configure(); | 253 | return 0; |
253 | } | 254 | } |
254 | 255 | ||
255 | static int agp_ati_suspend(struct pci_dev *dev, pm_message_t state) | 256 | static int agp_ati_resume(struct pci_dev *dev) |
256 | { | 257 | { |
257 | pci_save_state(dev); | 258 | pci_set_power_state(dev, 0); |
259 | pci_restore_state(dev); | ||
258 | 260 | ||
259 | return 0; | 261 | return ati_configure(); |
260 | } | 262 | } |
261 | #endif | 263 | #endif |
262 | 264 | ||
@@ -321,9 +323,9 @@ static int ati_remove_memory(struct agp_memory * mem, off_t pg_start, | |||
321 | unsigned long __iomem *cur_gatt; | 323 | unsigned long __iomem *cur_gatt; |
322 | unsigned long addr; | 324 | unsigned long addr; |
323 | 325 | ||
324 | if (type != 0 || mem->type != 0) { | 326 | if (type != 0 || mem->type != 0) |
325 | return -EINVAL; | 327 | return -EINVAL; |
326 | } | 328 | |
327 | for (i = pg_start; i < (mem->page_count + pg_start); i++) { | 329 | for (i = pg_start; i < (mem->page_count + pg_start); i++) { |
328 | addr = (i * PAGE_SIZE) + agp_bridge->gart_bus_addr; | 330 | addr = (i * PAGE_SIZE) + agp_bridge->gart_bus_addr; |
329 | cur_gatt = GET_GATT(addr); | 331 | cur_gatt = GET_GATT(addr); |
@@ -502,9 +504,8 @@ found: | |||
502 | 504 | ||
503 | bridge->dev = pdev; | 505 | bridge->dev = pdev; |
504 | bridge->capndx = cap_ptr; | 506 | bridge->capndx = cap_ptr; |
505 | |||
506 | bridge->driver = &ati_generic_bridge; | ||
507 | 507 | ||
508 | bridge->driver = &ati_generic_bridge; | ||
508 | 509 | ||
509 | printk(KERN_INFO PFX "Detected Ati %s chipset\n", | 510 | printk(KERN_INFO PFX "Detected Ati %s chipset\n", |
510 | devs[j].chipset_name); | 511 | devs[j].chipset_name); |
@@ -546,8 +547,8 @@ static struct pci_driver agp_ati_pci_driver = { | |||
546 | .probe = agp_ati_probe, | 547 | .probe = agp_ati_probe, |
547 | .remove = agp_ati_remove, | 548 | .remove = agp_ati_remove, |
548 | #ifdef CONFIG_PM | 549 | #ifdef CONFIG_PM |
549 | .resume = agp_ati_resume, | ||
550 | .suspend = agp_ati_suspend, | 550 | .suspend = agp_ati_suspend, |
551 | .resume = agp_ati_resume, | ||
551 | #endif | 552 | #endif |
552 | }; | 553 | }; |
553 | 554 | ||
diff --git a/drivers/char/agp/nvidia-agp.c b/drivers/char/agp/nvidia-agp.c index 4c67135c12d8..df7f37b2739a 100644 --- a/drivers/char/agp/nvidia-agp.c +++ b/drivers/char/agp/nvidia-agp.c | |||
@@ -376,6 +376,29 @@ static void __devexit agp_nvidia_remove(struct pci_dev *pdev) | |||
376 | agp_put_bridge(bridge); | 376 | agp_put_bridge(bridge); |
377 | } | 377 | } |
378 | 378 | ||
379 | #ifdef CONFIG_PM | ||
380 | static int agp_nvidia_suspend(struct pci_dev *pdev, pm_message_t state) | ||
381 | { | ||
382 | pci_save_state (pdev); | ||
383 | pci_set_power_state (pdev, 3); | ||
384 | |||
385 | return 0; | ||
386 | } | ||
387 | |||
388 | static int agp_nvidia_resume(struct pci_dev *pdev) | ||
389 | { | ||
390 | /* set power state 0 and restore PCI space */ | ||
391 | pci_set_power_state (pdev, 0); | ||
392 | pci_restore_state(pdev); | ||
393 | |||
394 | /* reconfigure AGP hardware again */ | ||
395 | nvidia_configure(); | ||
396 | |||
397 | return 0; | ||
398 | } | ||
399 | #endif | ||
400 | |||
401 | |||
379 | static struct pci_device_id agp_nvidia_pci_table[] = { | 402 | static struct pci_device_id agp_nvidia_pci_table[] = { |
380 | { | 403 | { |
381 | .class = (PCI_CLASS_BRIDGE_HOST << 8), | 404 | .class = (PCI_CLASS_BRIDGE_HOST << 8), |
@@ -403,6 +426,10 @@ static struct pci_driver agp_nvidia_pci_driver = { | |||
403 | .id_table = agp_nvidia_pci_table, | 426 | .id_table = agp_nvidia_pci_table, |
404 | .probe = agp_nvidia_probe, | 427 | .probe = agp_nvidia_probe, |
405 | .remove = agp_nvidia_remove, | 428 | .remove = agp_nvidia_remove, |
429 | #ifdef CONFIG_PM | ||
430 | .suspend = agp_nvidia_suspend, | ||
431 | .resume = agp_nvidia_resume, | ||
432 | #endif | ||
406 | }; | 433 | }; |
407 | 434 | ||
408 | static int __init agp_nvidia_init(void) | 435 | static int __init agp_nvidia_init(void) |
diff --git a/drivers/char/agp/sgi-agp.c b/drivers/char/agp/sgi-agp.c index cfa7922cb431..d73be4c2db8a 100644 --- a/drivers/char/agp/sgi-agp.c +++ b/drivers/char/agp/sgi-agp.c | |||
@@ -329,9 +329,8 @@ static int __devinit agp_sgi_init(void) | |||
329 | 329 | ||
330 | static void __devexit agp_sgi_cleanup(void) | 330 | static void __devexit agp_sgi_cleanup(void) |
331 | { | 331 | { |
332 | if (sgi_tioca_agp_bridges) | 332 | kfree(sgi_tioca_agp_bridges); |
333 | kfree(sgi_tioca_agp_bridges); | 333 | sgi_tioca_agp_bridges = NULL; |
334 | sgi_tioca_agp_bridges=NULL; | ||
335 | } | 334 | } |
336 | 335 | ||
337 | module_init(agp_sgi_init); | 336 | module_init(agp_sgi_init); |
diff --git a/drivers/char/applicom.c b/drivers/char/applicom.c index 9275d5e52e6d..72fb60765c45 100644 --- a/drivers/char/applicom.c +++ b/drivers/char/applicom.c | |||
@@ -209,13 +209,16 @@ static int __init applicom_init(void) | |||
209 | RamIO = ioremap(dev->resource[0].start, LEN_RAM_IO); | 209 | RamIO = ioremap(dev->resource[0].start, LEN_RAM_IO); |
210 | 210 | ||
211 | if (!RamIO) { | 211 | if (!RamIO) { |
212 | printk(KERN_INFO "ac.o: Failed to ioremap PCI memory space at 0x%lx\n", dev->resource[0].start); | 212 | printk(KERN_INFO "ac.o: Failed to ioremap PCI memory " |
213 | "space at 0x%llx\n", | ||
214 | (unsigned long long)dev->resource[0].start); | ||
213 | pci_disable_device(dev); | 215 | pci_disable_device(dev); |
214 | return -EIO; | 216 | return -EIO; |
215 | } | 217 | } |
216 | 218 | ||
217 | printk(KERN_INFO "Applicom %s found at mem 0x%lx, irq %d\n", | 219 | printk(KERN_INFO "Applicom %s found at mem 0x%llx, irq %d\n", |
218 | applicom_pci_devnames[dev->device-1], dev->resource[0].start, | 220 | applicom_pci_devnames[dev->device-1], |
221 | (unsigned long long)dev->resource[0].start, | ||
219 | dev->irq); | 222 | dev->irq); |
220 | 223 | ||
221 | boardno = ac_register_board(dev->resource[0].start, RamIO,0); | 224 | boardno = ac_register_board(dev->resource[0].start, RamIO,0); |
diff --git a/drivers/char/cyclades.c b/drivers/char/cyclades.c index 122e7a72a4e1..2657eeba7da6 100644 --- a/drivers/char/cyclades.c +++ b/drivers/char/cyclades.c | |||
@@ -5250,7 +5250,6 @@ cy_init(void) | |||
5250 | cy_serial_driver->owner = THIS_MODULE; | 5250 | cy_serial_driver->owner = THIS_MODULE; |
5251 | cy_serial_driver->driver_name = "cyclades"; | 5251 | cy_serial_driver->driver_name = "cyclades"; |
5252 | cy_serial_driver->name = "ttyC"; | 5252 | cy_serial_driver->name = "ttyC"; |
5253 | cy_serial_driver->devfs_name = "tts/C"; | ||
5254 | cy_serial_driver->major = CYCLADES_MAJOR; | 5253 | cy_serial_driver->major = CYCLADES_MAJOR; |
5255 | cy_serial_driver->minor_start = 0; | 5254 | cy_serial_driver->minor_start = 0; |
5256 | cy_serial_driver->type = TTY_DRIVER_TYPE_SERIAL; | 5255 | cy_serial_driver->type = TTY_DRIVER_TYPE_SERIAL; |
diff --git a/drivers/char/drm/drm_memory_debug.h b/drivers/char/drm/drm_memory_debug.h index 6543b9a14c42..d117cc997192 100644 --- a/drivers/char/drm/drm_memory_debug.h +++ b/drivers/char/drm/drm_memory_debug.h | |||
@@ -43,7 +43,7 @@ typedef struct drm_mem_stats { | |||
43 | unsigned long bytes_freed; | 43 | unsigned long bytes_freed; |
44 | } drm_mem_stats_t; | 44 | } drm_mem_stats_t; |
45 | 45 | ||
46 | static spinlock_t drm_mem_lock = SPIN_LOCK_UNLOCKED; | 46 | static DEFINE_SPINLOCK(drm_mem_lock); |
47 | static unsigned long drm_ram_available = 0; /* In pages */ | 47 | static unsigned long drm_ram_available = 0; /* In pages */ |
48 | static unsigned long drm_ram_used = 0; | 48 | static unsigned long drm_ram_used = 0; |
49 | static drm_mem_stats_t drm_mem_stats[] = | 49 | static drm_mem_stats_t drm_mem_stats[] = |
diff --git a/drivers/char/drm/via_dmablit.c b/drivers/char/drm/via_dmablit.c index b7f17457b424..78a81a4a99c5 100644 --- a/drivers/char/drm/via_dmablit.c +++ b/drivers/char/drm/via_dmablit.c | |||
@@ -557,7 +557,7 @@ via_init_dmablit(drm_device_t *dev) | |||
557 | blitq->num_outstanding = 0; | 557 | blitq->num_outstanding = 0; |
558 | blitq->is_active = 0; | 558 | blitq->is_active = 0; |
559 | blitq->aborting = 0; | 559 | blitq->aborting = 0; |
560 | blitq->blit_lock = SPIN_LOCK_UNLOCKED; | 560 | spin_lock_init(&blitq->blit_lock); |
561 | for (j=0; j<VIA_NUM_BLIT_SLOTS; ++j) { | 561 | for (j=0; j<VIA_NUM_BLIT_SLOTS; ++j) { |
562 | DRM_INIT_WAITQUEUE(blitq->blit_queue + j); | 562 | DRM_INIT_WAITQUEUE(blitq->blit_queue + j); |
563 | } | 563 | } |
diff --git a/drivers/char/dsp56k.c b/drivers/char/dsp56k.c index e233cf280bc0..09b413618b57 100644 --- a/drivers/char/dsp56k.c +++ b/drivers/char/dsp56k.c | |||
@@ -33,7 +33,6 @@ | |||
33 | #include <linux/fs.h> | 33 | #include <linux/fs.h> |
34 | #include <linux/mm.h> | 34 | #include <linux/mm.h> |
35 | #include <linux/init.h> | 35 | #include <linux/init.h> |
36 | #include <linux/devfs_fs_kernel.h> | ||
37 | #include <linux/smp_lock.h> | 36 | #include <linux/smp_lock.h> |
38 | #include <linux/device.h> | 37 | #include <linux/device.h> |
39 | 38 | ||
@@ -518,17 +517,9 @@ static int __init dsp56k_init_driver(void) | |||
518 | } | 517 | } |
519 | class_device_create(dsp56k_class, NULL, MKDEV(DSP56K_MAJOR, 0), NULL, "dsp56k"); | 518 | class_device_create(dsp56k_class, NULL, MKDEV(DSP56K_MAJOR, 0), NULL, "dsp56k"); |
520 | 519 | ||
521 | err = devfs_mk_cdev(MKDEV(DSP56K_MAJOR, 0), | ||
522 | S_IFCHR | S_IRUSR | S_IWUSR, "dsp56k"); | ||
523 | if(err) | ||
524 | goto out_class; | ||
525 | |||
526 | printk(banner); | 520 | printk(banner); |
527 | goto out; | 521 | goto out; |
528 | 522 | ||
529 | out_class: | ||
530 | class_device_destroy(dsp56k_class, MKDEV(DSP56K_MAJOR, 0)); | ||
531 | class_destroy(dsp56k_class); | ||
532 | out_chrdev: | 523 | out_chrdev: |
533 | unregister_chrdev(DSP56K_MAJOR, "dsp56k"); | 524 | unregister_chrdev(DSP56K_MAJOR, "dsp56k"); |
534 | out: | 525 | out: |
@@ -541,7 +532,6 @@ static void __exit dsp56k_cleanup_driver(void) | |||
541 | class_device_destroy(dsp56k_class, MKDEV(DSP56K_MAJOR, 0)); | 532 | class_device_destroy(dsp56k_class, MKDEV(DSP56K_MAJOR, 0)); |
542 | class_destroy(dsp56k_class); | 533 | class_destroy(dsp56k_class); |
543 | unregister_chrdev(DSP56K_MAJOR, "dsp56k"); | 534 | unregister_chrdev(DSP56K_MAJOR, "dsp56k"); |
544 | devfs_remove("dsp56k"); | ||
545 | } | 535 | } |
546 | module_exit(dsp56k_cleanup_driver); | 536 | module_exit(dsp56k_cleanup_driver); |
547 | 537 | ||
diff --git a/drivers/char/dtlk.c b/drivers/char/dtlk.c index 87dcaa237f07..da2c89f1b8bc 100644 --- a/drivers/char/dtlk.c +++ b/drivers/char/dtlk.c | |||
@@ -62,7 +62,6 @@ | |||
62 | #include <linux/init.h> /* for __init, module_{init,exit} */ | 62 | #include <linux/init.h> /* for __init, module_{init,exit} */ |
63 | #include <linux/poll.h> /* for POLLIN, etc. */ | 63 | #include <linux/poll.h> /* for POLLIN, etc. */ |
64 | #include <linux/dtlk.h> /* local header file for DoubleTalk values */ | 64 | #include <linux/dtlk.h> /* local header file for DoubleTalk values */ |
65 | #include <linux/devfs_fs_kernel.h> | ||
66 | #include <linux/smp_lock.h> | 65 | #include <linux/smp_lock.h> |
67 | 66 | ||
68 | #ifdef TRACING | 67 | #ifdef TRACING |
@@ -337,9 +336,6 @@ static int __init dtlk_init(void) | |||
337 | if (dtlk_dev_probe() == 0) | 336 | if (dtlk_dev_probe() == 0) |
338 | printk(", MAJOR %d\n", dtlk_major); | 337 | printk(", MAJOR %d\n", dtlk_major); |
339 | 338 | ||
340 | devfs_mk_cdev(MKDEV(dtlk_major, DTLK_MINOR), | ||
341 | S_IFCHR | S_IRUSR | S_IWUSR, "dtlk"); | ||
342 | |||
343 | init_timer(&dtlk_timer); | 339 | init_timer(&dtlk_timer); |
344 | dtlk_timer.function = dtlk_timer_tick; | 340 | dtlk_timer.function = dtlk_timer_tick; |
345 | init_waitqueue_head(&dtlk_process_list); | 341 | init_waitqueue_head(&dtlk_process_list); |
@@ -357,7 +353,6 @@ static void __exit dtlk_cleanup (void) | |||
357 | 353 | ||
358 | dtlk_write_tts(DTLK_CLEAR); | 354 | dtlk_write_tts(DTLK_CLEAR); |
359 | unregister_chrdev(dtlk_major, "dtlk"); | 355 | unregister_chrdev(dtlk_major, "dtlk"); |
360 | devfs_remove("dtlk"); | ||
361 | release_region(dtlk_port_lpc, DTLK_IO_EXTENT); | 356 | release_region(dtlk_port_lpc, DTLK_IO_EXTENT); |
362 | } | 357 | } |
363 | 358 | ||
diff --git a/drivers/char/epca.c b/drivers/char/epca.c index 9cad8501d62c..d0b3890d9302 100644 --- a/drivers/char/epca.c +++ b/drivers/char/epca.c | |||
@@ -80,7 +80,7 @@ static int invalid_lilo_config; | |||
80 | /* The ISA boards do window flipping into the same spaces so its only sane | 80 | /* The ISA boards do window flipping into the same spaces so its only sane |
81 | with a single lock. It's still pretty efficient */ | 81 | with a single lock. It's still pretty efficient */ |
82 | 82 | ||
83 | static spinlock_t epca_lock = SPIN_LOCK_UNLOCKED; | 83 | static DEFINE_SPINLOCK(epca_lock); |
84 | 84 | ||
85 | /* ----------------------------------------------------------------------- | 85 | /* ----------------------------------------------------------------------- |
86 | MAXBOARDS is typically 12, but ISA and EISA cards are restricted to | 86 | MAXBOARDS is typically 12, but ISA and EISA cards are restricted to |
@@ -1232,7 +1232,6 @@ static int __init pc_init(void) | |||
1232 | 1232 | ||
1233 | pc_driver->owner = THIS_MODULE; | 1233 | pc_driver->owner = THIS_MODULE; |
1234 | pc_driver->name = "ttyD"; | 1234 | pc_driver->name = "ttyD"; |
1235 | pc_driver->devfs_name = "tts/D"; | ||
1236 | pc_driver->major = DIGI_MAJOR; | 1235 | pc_driver->major = DIGI_MAJOR; |
1237 | pc_driver->minor_start = 0; | 1236 | pc_driver->minor_start = 0; |
1238 | pc_driver->type = TTY_DRIVER_TYPE_SERIAL; | 1237 | pc_driver->type = TTY_DRIVER_TYPE_SERIAL; |
diff --git a/drivers/char/esp.c b/drivers/char/esp.c index 922174d527ae..9827d170ca17 100644 --- a/drivers/char/esp.c +++ b/drivers/char/esp.c | |||
@@ -2449,7 +2449,6 @@ static int __init espserial_init(void) | |||
2449 | 2449 | ||
2450 | esp_driver->owner = THIS_MODULE; | 2450 | esp_driver->owner = THIS_MODULE; |
2451 | esp_driver->name = "ttyP"; | 2451 | esp_driver->name = "ttyP"; |
2452 | esp_driver->devfs_name = "tts/P"; | ||
2453 | esp_driver->major = ESP_IN_MAJOR; | 2452 | esp_driver->major = ESP_IN_MAJOR; |
2454 | esp_driver->minor_start = 0; | 2453 | esp_driver->minor_start = 0; |
2455 | esp_driver->type = TTY_DRIVER_TYPE_SERIAL; | 2454 | esp_driver->type = TTY_DRIVER_TYPE_SERIAL; |
diff --git a/drivers/char/ftape/zftape/zftape-init.c b/drivers/char/ftape/zftape/zftape-init.c index 821357ce7e0e..3eeb869a9a11 100644 --- a/drivers/char/ftape/zftape/zftape-init.c +++ b/drivers/char/ftape/zftape/zftape-init.c | |||
@@ -33,7 +33,6 @@ | |||
33 | #endif | 33 | #endif |
34 | #include <linux/fcntl.h> | 34 | #include <linux/fcntl.h> |
35 | #include <linux/smp_lock.h> | 35 | #include <linux/smp_lock.h> |
36 | #include <linux/devfs_fs_kernel.h> | ||
37 | 36 | ||
38 | #include <linux/zftape.h> | 37 | #include <linux/zftape.h> |
39 | #include <linux/init.h> | 38 | #include <linux/init.h> |
@@ -332,29 +331,11 @@ KERN_INFO | |||
332 | zft_class = class_create(THIS_MODULE, "zft"); | 331 | zft_class = class_create(THIS_MODULE, "zft"); |
333 | for (i = 0; i < 4; i++) { | 332 | for (i = 0; i < 4; i++) { |
334 | class_device_create(zft_class, NULL, MKDEV(QIC117_TAPE_MAJOR, i), NULL, "qft%i", i); | 333 | class_device_create(zft_class, NULL, MKDEV(QIC117_TAPE_MAJOR, i), NULL, "qft%i", i); |
335 | devfs_mk_cdev(MKDEV(QIC117_TAPE_MAJOR, i), | ||
336 | S_IFCHR | S_IRUSR | S_IWUSR, | ||
337 | "qft%i", i); | ||
338 | class_device_create(zft_class, NULL, MKDEV(QIC117_TAPE_MAJOR, i + 4), NULL, "nqft%i", i); | 334 | class_device_create(zft_class, NULL, MKDEV(QIC117_TAPE_MAJOR, i + 4), NULL, "nqft%i", i); |
339 | devfs_mk_cdev(MKDEV(QIC117_TAPE_MAJOR, i + 4), | ||
340 | S_IFCHR | S_IRUSR | S_IWUSR, | ||
341 | "nqft%i", i); | ||
342 | class_device_create(zft_class, NULL, MKDEV(QIC117_TAPE_MAJOR, i + 16), NULL, "zqft%i", i); | 335 | class_device_create(zft_class, NULL, MKDEV(QIC117_TAPE_MAJOR, i + 16), NULL, "zqft%i", i); |
343 | devfs_mk_cdev(MKDEV(QIC117_TAPE_MAJOR, i + 16), | ||
344 | S_IFCHR | S_IRUSR | S_IWUSR, | ||
345 | "zqft%i", i); | ||
346 | class_device_create(zft_class, NULL, MKDEV(QIC117_TAPE_MAJOR, i + 20), NULL, "nzqft%i", i); | 336 | class_device_create(zft_class, NULL, MKDEV(QIC117_TAPE_MAJOR, i + 20), NULL, "nzqft%i", i); |
347 | devfs_mk_cdev(MKDEV(QIC117_TAPE_MAJOR, i + 20), | ||
348 | S_IFCHR | S_IRUSR | S_IWUSR, | ||
349 | "nzqft%i", i); | ||
350 | class_device_create(zft_class, NULL, MKDEV(QIC117_TAPE_MAJOR, i + 32), NULL, "rawqft%i", i); | 337 | class_device_create(zft_class, NULL, MKDEV(QIC117_TAPE_MAJOR, i + 32), NULL, "rawqft%i", i); |
351 | devfs_mk_cdev(MKDEV(QIC117_TAPE_MAJOR, i + 32), | ||
352 | S_IFCHR | S_IRUSR | S_IWUSR, | ||
353 | "rawqft%i", i); | ||
354 | class_device_create(zft_class, NULL, MKDEV(QIC117_TAPE_MAJOR, i + 36), NULL, "nrawrawqft%i", i); | 338 | class_device_create(zft_class, NULL, MKDEV(QIC117_TAPE_MAJOR, i + 36), NULL, "nrawrawqft%i", i); |
355 | devfs_mk_cdev(MKDEV(QIC117_TAPE_MAJOR, i + 36), | ||
356 | S_IFCHR | S_IRUSR | S_IWUSR, | ||
357 | "nrawqft%i", i); | ||
358 | } | 339 | } |
359 | 340 | ||
360 | #ifdef CONFIG_ZFT_COMPRESSOR | 341 | #ifdef CONFIG_ZFT_COMPRESSOR |
@@ -380,17 +361,11 @@ static void zft_exit(void) | |||
380 | TRACE(ft_t_info, "successful"); | 361 | TRACE(ft_t_info, "successful"); |
381 | } | 362 | } |
382 | for (i = 0; i < 4; i++) { | 363 | for (i = 0; i < 4; i++) { |
383 | devfs_remove("qft%i", i); | ||
384 | class_device_destroy(zft_class, MKDEV(QIC117_TAPE_MAJOR, i)); | 364 | class_device_destroy(zft_class, MKDEV(QIC117_TAPE_MAJOR, i)); |
385 | devfs_remove("nqft%i", i); | ||
386 | class_device_destroy(zft_class, MKDEV(QIC117_TAPE_MAJOR, i + 4)); | 365 | class_device_destroy(zft_class, MKDEV(QIC117_TAPE_MAJOR, i + 4)); |
387 | devfs_remove("zqft%i", i); | ||
388 | class_device_destroy(zft_class, MKDEV(QIC117_TAPE_MAJOR, i + 16)); | 366 | class_device_destroy(zft_class, MKDEV(QIC117_TAPE_MAJOR, i + 16)); |
389 | devfs_remove("nzqft%i", i); | ||
390 | class_device_destroy(zft_class, MKDEV(QIC117_TAPE_MAJOR, i + 20)); | 367 | class_device_destroy(zft_class, MKDEV(QIC117_TAPE_MAJOR, i + 20)); |
391 | devfs_remove("rawqft%i", i); | ||
392 | class_device_destroy(zft_class, MKDEV(QIC117_TAPE_MAJOR, i + 32)); | 368 | class_device_destroy(zft_class, MKDEV(QIC117_TAPE_MAJOR, i + 32)); |
393 | devfs_remove("nrawqft%i", i); | ||
394 | class_device_destroy(zft_class, MKDEV(QIC117_TAPE_MAJOR, i + 36)); | 369 | class_device_destroy(zft_class, MKDEV(QIC117_TAPE_MAJOR, i + 36)); |
395 | } | 370 | } |
396 | class_destroy(zft_class); | 371 | class_destroy(zft_class); |
diff --git a/drivers/char/hvc_console.c b/drivers/char/hvc_console.c index a5c6a9d7ff08..6e380aecea6a 100644 --- a/drivers/char/hvc_console.c +++ b/drivers/char/hvc_console.c | |||
@@ -820,7 +820,6 @@ int __init hvc_init(void) | |||
820 | return -ENOMEM; | 820 | return -ENOMEM; |
821 | 821 | ||
822 | drv->owner = THIS_MODULE; | 822 | drv->owner = THIS_MODULE; |
823 | drv->devfs_name = "hvc/"; | ||
824 | drv->driver_name = "hvc"; | 823 | drv->driver_name = "hvc"; |
825 | drv->name = "hvc"; | 824 | drv->name = "hvc"; |
826 | drv->major = HVC_MAJOR; | 825 | drv->major = HVC_MAJOR; |
diff --git a/drivers/char/hvcs.c b/drivers/char/hvcs.c index 8d97b3911293..130dedc37568 100644 --- a/drivers/char/hvcs.c +++ b/drivers/char/hvcs.c | |||
@@ -1320,11 +1320,12 @@ static struct tty_operations hvcs_ops = { | |||
1320 | static int hvcs_alloc_index_list(int n) | 1320 | static int hvcs_alloc_index_list(int n) |
1321 | { | 1321 | { |
1322 | int i; | 1322 | int i; |
1323 | |||
1323 | hvcs_index_list = kmalloc(n * sizeof(hvcs_index_count),GFP_KERNEL); | 1324 | hvcs_index_list = kmalloc(n * sizeof(hvcs_index_count),GFP_KERNEL); |
1324 | if (!hvcs_index_list) | 1325 | if (!hvcs_index_list) |
1325 | return -ENOMEM; | 1326 | return -ENOMEM; |
1326 | hvcs_index_count = n; | 1327 | hvcs_index_count = n; |
1327 | for(i = 0; i < hvcs_index_count; i++) | 1328 | for (i = 0; i < hvcs_index_count; i++) |
1328 | hvcs_index_list[i] = -1; | 1329 | hvcs_index_list[i] = -1; |
1329 | return 0; | 1330 | return 0; |
1330 | } | 1331 | } |
@@ -1332,11 +1333,9 @@ static int hvcs_alloc_index_list(int n) | |||
1332 | static void hvcs_free_index_list(void) | 1333 | static void hvcs_free_index_list(void) |
1333 | { | 1334 | { |
1334 | /* Paranoia check to be thorough. */ | 1335 | /* Paranoia check to be thorough. */ |
1335 | if (hvcs_index_list) { | 1336 | kfree(hvcs_index_list); |
1336 | kfree(hvcs_index_list); | 1337 | hvcs_index_list = NULL; |
1337 | hvcs_index_list = NULL; | 1338 | hvcs_index_count = 0; |
1338 | hvcs_index_count = 0; | ||
1339 | } | ||
1340 | } | 1339 | } |
1341 | 1340 | ||
1342 | static int __init hvcs_module_init(void) | 1341 | static int __init hvcs_module_init(void) |
@@ -1364,7 +1363,6 @@ static int __init hvcs_module_init(void) | |||
1364 | 1363 | ||
1365 | hvcs_tty_driver->driver_name = hvcs_driver_name; | 1364 | hvcs_tty_driver->driver_name = hvcs_driver_name; |
1366 | hvcs_tty_driver->name = hvcs_device_node; | 1365 | hvcs_tty_driver->name = hvcs_device_node; |
1367 | hvcs_tty_driver->devfs_name = hvcs_device_node; | ||
1368 | 1366 | ||
1369 | /* | 1367 | /* |
1370 | * We'll let the system assign us a major number, indicated by leaving | 1368 | * We'll let the system assign us a major number, indicated by leaving |
diff --git a/drivers/char/hvsi.c b/drivers/char/hvsi.c index a0370ed752ce..7b04eb153205 100644 --- a/drivers/char/hvsi.c +++ b/drivers/char/hvsi.c | |||
@@ -1154,7 +1154,6 @@ static int __init hvsi_init(void) | |||
1154 | return -ENOMEM; | 1154 | return -ENOMEM; |
1155 | 1155 | ||
1156 | hvsi_driver->owner = THIS_MODULE; | 1156 | hvsi_driver->owner = THIS_MODULE; |
1157 | hvsi_driver->devfs_name = "hvsi/"; | ||
1158 | hvsi_driver->driver_name = "hvsi"; | 1157 | hvsi_driver->driver_name = "hvsi"; |
1159 | hvsi_driver->name = "hvsi"; | 1158 | hvsi_driver->name = "hvsi"; |
1160 | hvsi_driver->major = HVSI_MAJOR; | 1159 | hvsi_driver->major = HVSI_MAJOR; |
diff --git a/drivers/char/ip2/ip2main.c b/drivers/char/ip2/ip2main.c index 9ab33c3d359f..8619542766cb 100644 --- a/drivers/char/ip2/ip2main.c +++ b/drivers/char/ip2/ip2main.c | |||
@@ -91,7 +91,6 @@ | |||
91 | #include <linux/module.h> | 91 | #include <linux/module.h> |
92 | #include <linux/signal.h> | 92 | #include <linux/signal.h> |
93 | #include <linux/sched.h> | 93 | #include <linux/sched.h> |
94 | #include <linux/devfs_fs_kernel.h> | ||
95 | #include <linux/timer.h> | 94 | #include <linux/timer.h> |
96 | #include <linux/interrupt.h> | 95 | #include <linux/interrupt.h> |
97 | #include <linux/pci.h> | 96 | #include <linux/pci.h> |
@@ -414,9 +413,7 @@ cleanup_module(void) | |||
414 | /* free io addresses and Tibet */ | 413 | /* free io addresses and Tibet */ |
415 | release_region( ip2config.addr[i], 8 ); | 414 | release_region( ip2config.addr[i], 8 ); |
416 | class_device_destroy(ip2_class, MKDEV(IP2_IPL_MAJOR, 4 * i)); | 415 | class_device_destroy(ip2_class, MKDEV(IP2_IPL_MAJOR, 4 * i)); |
417 | devfs_remove("ip2/ipl%d", i); | ||
418 | class_device_destroy(ip2_class, MKDEV(IP2_IPL_MAJOR, 4 * i + 1)); | 416 | class_device_destroy(ip2_class, MKDEV(IP2_IPL_MAJOR, 4 * i + 1)); |
419 | devfs_remove("ip2/stat%d", i); | ||
420 | } | 417 | } |
421 | /* Disable and remove interrupt handler. */ | 418 | /* Disable and remove interrupt handler. */ |
422 | if ( (ip2config.irq[i] > 0) && have_requested_irq(ip2config.irq[i]) ) { | 419 | if ( (ip2config.irq[i] > 0) && have_requested_irq(ip2config.irq[i]) ) { |
@@ -425,7 +422,6 @@ cleanup_module(void) | |||
425 | } | 422 | } |
426 | } | 423 | } |
427 | class_destroy(ip2_class); | 424 | class_destroy(ip2_class); |
428 | devfs_remove("ip2"); | ||
429 | if ( ( err = tty_unregister_driver ( ip2_tty_driver ) ) ) { | 425 | if ( ( err = tty_unregister_driver ( ip2_tty_driver ) ) ) { |
430 | printk(KERN_ERR "IP2: failed to unregister tty driver (%d)\n", err); | 426 | printk(KERN_ERR "IP2: failed to unregister tty driver (%d)\n", err); |
431 | } | 427 | } |
@@ -675,7 +671,6 @@ ip2_loadmain(int *iop, int *irqp, unsigned char *firmware, int firmsize) | |||
675 | 671 | ||
676 | ip2_tty_driver->owner = THIS_MODULE; | 672 | ip2_tty_driver->owner = THIS_MODULE; |
677 | ip2_tty_driver->name = "ttyF"; | 673 | ip2_tty_driver->name = "ttyF"; |
678 | ip2_tty_driver->devfs_name = "tts/F"; | ||
679 | ip2_tty_driver->driver_name = pcDriver_name; | 674 | ip2_tty_driver->driver_name = pcDriver_name; |
680 | ip2_tty_driver->major = IP2_TTY_MAJOR; | 675 | ip2_tty_driver->major = IP2_TTY_MAJOR; |
681 | ip2_tty_driver->minor_start = 0; | 676 | ip2_tty_driver->minor_start = 0; |
@@ -683,7 +678,7 @@ ip2_loadmain(int *iop, int *irqp, unsigned char *firmware, int firmsize) | |||
683 | ip2_tty_driver->subtype = SERIAL_TYPE_NORMAL; | 678 | ip2_tty_driver->subtype = SERIAL_TYPE_NORMAL; |
684 | ip2_tty_driver->init_termios = tty_std_termios; | 679 | ip2_tty_driver->init_termios = tty_std_termios; |
685 | ip2_tty_driver->init_termios.c_cflag = B9600|CS8|CREAD|HUPCL|CLOCAL; | 680 | ip2_tty_driver->init_termios.c_cflag = B9600|CS8|CREAD|HUPCL|CLOCAL; |
686 | ip2_tty_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_NO_DEVFS; | 681 | ip2_tty_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV; |
687 | tty_set_operations(ip2_tty_driver, &ip2_ops); | 682 | tty_set_operations(ip2_tty_driver, &ip2_ops); |
688 | 683 | ||
689 | ip2trace (ITRC_NO_PORT, ITRC_INIT, 3, 0 ); | 684 | ip2trace (ITRC_NO_PORT, ITRC_INIT, 3, 0 ); |
@@ -724,26 +719,9 @@ ip2_loadmain(int *iop, int *irqp, unsigned char *firmware, int firmsize) | |||
724 | class_device_create(ip2_class, NULL, | 719 | class_device_create(ip2_class, NULL, |
725 | MKDEV(IP2_IPL_MAJOR, 4 * i), | 720 | MKDEV(IP2_IPL_MAJOR, 4 * i), |
726 | NULL, "ipl%d", i); | 721 | NULL, "ipl%d", i); |
727 | err = devfs_mk_cdev(MKDEV(IP2_IPL_MAJOR, 4 * i), | ||
728 | S_IRUSR | S_IWUSR | S_IRGRP | S_IFCHR, | ||
729 | "ip2/ipl%d", i); | ||
730 | if (err) { | ||
731 | class_device_destroy(ip2_class, | ||
732 | MKDEV(IP2_IPL_MAJOR, 4 * i)); | ||
733 | goto out_class; | ||
734 | } | ||
735 | |||
736 | class_device_create(ip2_class, NULL, | 722 | class_device_create(ip2_class, NULL, |
737 | MKDEV(IP2_IPL_MAJOR, 4 * i + 1), | 723 | MKDEV(IP2_IPL_MAJOR, 4 * i + 1), |
738 | NULL, "stat%d", i); | 724 | NULL, "stat%d", i); |
739 | err = devfs_mk_cdev(MKDEV(IP2_IPL_MAJOR, 4 * i + 1), | ||
740 | S_IRUSR | S_IWUSR | S_IRGRP | S_IFCHR, | ||
741 | "ip2/stat%d", i); | ||
742 | if (err) { | ||
743 | class_device_destroy(ip2_class, | ||
744 | MKDEV(IP2_IPL_MAJOR, 4 * i + 1)); | ||
745 | goto out_class; | ||
746 | } | ||
747 | 725 | ||
748 | for ( box = 0; box < ABS_MAX_BOXES; ++box ) | 726 | for ( box = 0; box < ABS_MAX_BOXES; ++box ) |
749 | { | 727 | { |
diff --git a/drivers/char/ipmi/ipmi_devintf.c b/drivers/char/ipmi/ipmi_devintf.c index e1c95374984c..da637adbbfaa 100644 --- a/drivers/char/ipmi/ipmi_devintf.c +++ b/drivers/char/ipmi/ipmi_devintf.c | |||
@@ -40,7 +40,6 @@ | |||
40 | #include <linux/poll.h> | 40 | #include <linux/poll.h> |
41 | #include <linux/spinlock.h> | 41 | #include <linux/spinlock.h> |
42 | #include <linux/slab.h> | 42 | #include <linux/slab.h> |
43 | #include <linux/devfs_fs_kernel.h> | ||
44 | #include <linux/ipmi.h> | 43 | #include <linux/ipmi.h> |
45 | #include <linux/mutex.h> | 44 | #include <linux/mutex.h> |
46 | #include <linux/init.h> | 45 | #include <linux/init.h> |
@@ -804,9 +803,6 @@ static void ipmi_new_smi(int if_num, struct device *device) | |||
804 | dev_t dev = MKDEV(ipmi_major, if_num); | 803 | dev_t dev = MKDEV(ipmi_major, if_num); |
805 | struct ipmi_reg_list *entry; | 804 | struct ipmi_reg_list *entry; |
806 | 805 | ||
807 | devfs_mk_cdev(dev, S_IFCHR | S_IRUSR | S_IWUSR, | ||
808 | "ipmidev/%d", if_num); | ||
809 | |||
810 | entry = kmalloc(sizeof(*entry), GFP_KERNEL); | 806 | entry = kmalloc(sizeof(*entry), GFP_KERNEL); |
811 | if (!entry) { | 807 | if (!entry) { |
812 | printk(KERN_ERR "ipmi_devintf: Unable to create the" | 808 | printk(KERN_ERR "ipmi_devintf: Unable to create the" |
@@ -836,7 +832,6 @@ static void ipmi_smi_gone(int if_num) | |||
836 | } | 832 | } |
837 | class_device_destroy(ipmi_class, dev); | 833 | class_device_destroy(ipmi_class, dev); |
838 | mutex_unlock(®_list_mutex); | 834 | mutex_unlock(®_list_mutex); |
839 | devfs_remove("ipmidev/%d", if_num); | ||
840 | } | 835 | } |
841 | 836 | ||
842 | static struct ipmi_smi_watcher smi_watcher = | 837 | static struct ipmi_smi_watcher smi_watcher = |
@@ -872,8 +867,6 @@ static __init int init_ipmi_devintf(void) | |||
872 | ipmi_major = rv; | 867 | ipmi_major = rv; |
873 | } | 868 | } |
874 | 869 | ||
875 | devfs_mk_dir(DEVICE_NAME); | ||
876 | |||
877 | rv = ipmi_smi_watcher_register(&smi_watcher); | 870 | rv = ipmi_smi_watcher_register(&smi_watcher); |
878 | if (rv) { | 871 | if (rv) { |
879 | unregister_chrdev(ipmi_major, DEVICE_NAME); | 872 | unregister_chrdev(ipmi_major, DEVICE_NAME); |
@@ -898,7 +891,6 @@ static __exit void cleanup_ipmi(void) | |||
898 | mutex_unlock(®_list_mutex); | 891 | mutex_unlock(®_list_mutex); |
899 | class_destroy(ipmi_class); | 892 | class_destroy(ipmi_class); |
900 | ipmi_smi_watcher_unregister(&smi_watcher); | 893 | ipmi_smi_watcher_unregister(&smi_watcher); |
901 | devfs_remove(DEVICE_NAME); | ||
902 | unregister_chrdev(ipmi_major, DEVICE_NAME); | 894 | unregister_chrdev(ipmi_major, DEVICE_NAME); |
903 | } | 895 | } |
904 | module_exit(cleanup_ipmi); | 896 | module_exit(cleanup_ipmi); |
diff --git a/drivers/char/ipmi/ipmi_msghandler.c b/drivers/char/ipmi/ipmi_msghandler.c index b03ddab1bef5..ad26f4b997c5 100644 --- a/drivers/char/ipmi/ipmi_msghandler.c +++ b/drivers/char/ipmi/ipmi_msghandler.c | |||
@@ -57,8 +57,7 @@ static int ipmi_init_msghandler(void); | |||
57 | static int initialized = 0; | 57 | static int initialized = 0; |
58 | 58 | ||
59 | #ifdef CONFIG_PROC_FS | 59 | #ifdef CONFIG_PROC_FS |
60 | struct proc_dir_entry *proc_ipmi_root = NULL; | 60 | static struct proc_dir_entry *proc_ipmi_root = NULL; |
61 | EXPORT_SYMBOL(proc_ipmi_root); | ||
62 | #endif /* CONFIG_PROC_FS */ | 61 | #endif /* CONFIG_PROC_FS */ |
63 | 62 | ||
64 | #define MAX_EVENTS_IN_QUEUE 25 | 63 | #define MAX_EVENTS_IN_QUEUE 25 |
@@ -3739,11 +3738,8 @@ static int ipmi_init_msghandler(void) | |||
3739 | proc_ipmi_root->owner = THIS_MODULE; | 3738 | proc_ipmi_root->owner = THIS_MODULE; |
3740 | #endif /* CONFIG_PROC_FS */ | 3739 | #endif /* CONFIG_PROC_FS */ |
3741 | 3740 | ||
3742 | init_timer(&ipmi_timer); | 3741 | setup_timer(&ipmi_timer, ipmi_timeout, 0); |
3743 | ipmi_timer.data = 0; | 3742 | mod_timer(&ipmi_timer, jiffies + IPMI_TIMEOUT_JIFFIES); |
3744 | ipmi_timer.function = ipmi_timeout; | ||
3745 | ipmi_timer.expires = jiffies + IPMI_TIMEOUT_JIFFIES; | ||
3746 | add_timer(&ipmi_timer); | ||
3747 | 3743 | ||
3748 | atomic_notifier_chain_register(&panic_notifier_list, &panic_block); | 3744 | atomic_notifier_chain_register(&panic_notifier_list, &panic_block); |
3749 | 3745 | ||
diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c index 02a7dd7a8a55..bd4f2248b758 100644 --- a/drivers/char/ipmi/ipmi_si_intf.c +++ b/drivers/char/ipmi/ipmi_si_intf.c | |||
@@ -55,23 +55,6 @@ | |||
55 | #include <linux/mutex.h> | 55 | #include <linux/mutex.h> |
56 | #include <linux/kthread.h> | 56 | #include <linux/kthread.h> |
57 | #include <asm/irq.h> | 57 | #include <asm/irq.h> |
58 | #ifdef CONFIG_HIGH_RES_TIMERS | ||
59 | #include <linux/hrtime.h> | ||
60 | # if defined(schedule_next_int) | ||
61 | /* Old high-res timer code, do translations. */ | ||
62 | # define get_arch_cycles(a) quick_update_jiffies_sub(a) | ||
63 | # define arch_cycles_per_jiffy cycles_per_jiffies | ||
64 | # endif | ||
65 | static inline void add_usec_to_timer(struct timer_list *t, long v) | ||
66 | { | ||
67 | t->arch_cycle_expires += nsec_to_arch_cycle(v * 1000); | ||
68 | while (t->arch_cycle_expires >= arch_cycles_per_jiffy) | ||
69 | { | ||
70 | t->expires++; | ||
71 | t->arch_cycle_expires -= arch_cycles_per_jiffy; | ||
72 | } | ||
73 | } | ||
74 | #endif | ||
75 | #include <linux/interrupt.h> | 58 | #include <linux/interrupt.h> |
76 | #include <linux/rcupdate.h> | 59 | #include <linux/rcupdate.h> |
77 | #include <linux/ipmi_smi.h> | 60 | #include <linux/ipmi_smi.h> |
@@ -243,8 +226,6 @@ static int register_xaction_notifier(struct notifier_block * nb) | |||
243 | return atomic_notifier_chain_register(&xaction_notifier_list, nb); | 226 | return atomic_notifier_chain_register(&xaction_notifier_list, nb); |
244 | } | 227 | } |
245 | 228 | ||
246 | static void si_restart_short_timer(struct smi_info *smi_info); | ||
247 | |||
248 | static void deliver_recv_msg(struct smi_info *smi_info, | 229 | static void deliver_recv_msg(struct smi_info *smi_info, |
249 | struct ipmi_smi_msg *msg) | 230 | struct ipmi_smi_msg *msg) |
250 | { | 231 | { |
@@ -768,7 +749,6 @@ static void sender(void *send_info, | |||
768 | && (smi_info->curr_msg == NULL)) | 749 | && (smi_info->curr_msg == NULL)) |
769 | { | 750 | { |
770 | start_next_msg(smi_info); | 751 | start_next_msg(smi_info); |
771 | si_restart_short_timer(smi_info); | ||
772 | } | 752 | } |
773 | spin_unlock_irqrestore(&(smi_info->si_lock), flags); | 753 | spin_unlock_irqrestore(&(smi_info->si_lock), flags); |
774 | } | 754 | } |
@@ -809,7 +789,7 @@ static int ipmi_thread(void *data) | |||
809 | /* do nothing */ | 789 | /* do nothing */ |
810 | } | 790 | } |
811 | else if (smi_result == SI_SM_CALL_WITH_DELAY) | 791 | else if (smi_result == SI_SM_CALL_WITH_DELAY) |
812 | udelay(1); | 792 | schedule(); |
813 | else | 793 | else |
814 | schedule_timeout_interruptible(1); | 794 | schedule_timeout_interruptible(1); |
815 | } | 795 | } |
@@ -833,37 +813,6 @@ static void request_events(void *send_info) | |||
833 | 813 | ||
834 | static int initialized = 0; | 814 | static int initialized = 0; |
835 | 815 | ||
836 | /* Must be called with interrupts off and with the si_lock held. */ | ||
837 | static void si_restart_short_timer(struct smi_info *smi_info) | ||
838 | { | ||
839 | #if defined(CONFIG_HIGH_RES_TIMERS) | ||
840 | unsigned long flags; | ||
841 | unsigned long jiffies_now; | ||
842 | unsigned long seq; | ||
843 | |||
844 | if (del_timer(&(smi_info->si_timer))) { | ||
845 | /* If we don't delete the timer, then it will go off | ||
846 | immediately, anyway. So we only process if we | ||
847 | actually delete the timer. */ | ||
848 | |||
849 | do { | ||
850 | seq = read_seqbegin_irqsave(&xtime_lock, flags); | ||
851 | jiffies_now = jiffies; | ||
852 | smi_info->si_timer.expires = jiffies_now; | ||
853 | smi_info->si_timer.arch_cycle_expires | ||
854 | = get_arch_cycles(jiffies_now); | ||
855 | } while (read_seqretry_irqrestore(&xtime_lock, seq, flags)); | ||
856 | |||
857 | add_usec_to_timer(&smi_info->si_timer, SI_SHORT_TIMEOUT_USEC); | ||
858 | |||
859 | add_timer(&(smi_info->si_timer)); | ||
860 | spin_lock_irqsave(&smi_info->count_lock, flags); | ||
861 | smi_info->timeout_restarts++; | ||
862 | spin_unlock_irqrestore(&smi_info->count_lock, flags); | ||
863 | } | ||
864 | #endif | ||
865 | } | ||
866 | |||
867 | static void smi_timeout(unsigned long data) | 816 | static void smi_timeout(unsigned long data) |
868 | { | 817 | { |
869 | struct smi_info *smi_info = (struct smi_info *) data; | 818 | struct smi_info *smi_info = (struct smi_info *) data; |
@@ -904,31 +853,15 @@ static void smi_timeout(unsigned long data) | |||
904 | /* If the state machine asks for a short delay, then shorten | 853 | /* If the state machine asks for a short delay, then shorten |
905 | the timer timeout. */ | 854 | the timer timeout. */ |
906 | if (smi_result == SI_SM_CALL_WITH_DELAY) { | 855 | if (smi_result == SI_SM_CALL_WITH_DELAY) { |
907 | #if defined(CONFIG_HIGH_RES_TIMERS) | ||
908 | unsigned long seq; | ||
909 | #endif | ||
910 | spin_lock_irqsave(&smi_info->count_lock, flags); | 856 | spin_lock_irqsave(&smi_info->count_lock, flags); |
911 | smi_info->short_timeouts++; | 857 | smi_info->short_timeouts++; |
912 | spin_unlock_irqrestore(&smi_info->count_lock, flags); | 858 | spin_unlock_irqrestore(&smi_info->count_lock, flags); |
913 | #if defined(CONFIG_HIGH_RES_TIMERS) | ||
914 | do { | ||
915 | seq = read_seqbegin_irqsave(&xtime_lock, flags); | ||
916 | smi_info->si_timer.expires = jiffies; | ||
917 | smi_info->si_timer.arch_cycle_expires | ||
918 | = get_arch_cycles(smi_info->si_timer.expires); | ||
919 | } while (read_seqretry_irqrestore(&xtime_lock, seq, flags)); | ||
920 | add_usec_to_timer(&smi_info->si_timer, SI_SHORT_TIMEOUT_USEC); | ||
921 | #else | ||
922 | smi_info->si_timer.expires = jiffies + 1; | 859 | smi_info->si_timer.expires = jiffies + 1; |
923 | #endif | ||
924 | } else { | 860 | } else { |
925 | spin_lock_irqsave(&smi_info->count_lock, flags); | 861 | spin_lock_irqsave(&smi_info->count_lock, flags); |
926 | smi_info->long_timeouts++; | 862 | smi_info->long_timeouts++; |
927 | spin_unlock_irqrestore(&smi_info->count_lock, flags); | 863 | spin_unlock_irqrestore(&smi_info->count_lock, flags); |
928 | smi_info->si_timer.expires = jiffies + SI_TIMEOUT_JIFFIES; | 864 | smi_info->si_timer.expires = jiffies + SI_TIMEOUT_JIFFIES; |
929 | #if defined(CONFIG_HIGH_RES_TIMERS) | ||
930 | smi_info->si_timer.arch_cycle_expires = 0; | ||
931 | #endif | ||
932 | } | 865 | } |
933 | 866 | ||
934 | do_add_timer: | 867 | do_add_timer: |
diff --git a/drivers/char/ipmi/ipmi_watchdog.c b/drivers/char/ipmi/ipmi_watchdog.c index 8f8867170973..1a0a19c53605 100644 --- a/drivers/char/ipmi/ipmi_watchdog.c +++ b/drivers/char/ipmi/ipmi_watchdog.c | |||
@@ -949,9 +949,10 @@ static int wdog_reboot_handler(struct notifier_block *this, | |||
949 | /* Disable the WDT if we are shutting down. */ | 949 | /* Disable the WDT if we are shutting down. */ |
950 | ipmi_watchdog_state = WDOG_TIMEOUT_NONE; | 950 | ipmi_watchdog_state = WDOG_TIMEOUT_NONE; |
951 | panic_halt_ipmi_set_timeout(); | 951 | panic_halt_ipmi_set_timeout(); |
952 | } else { | 952 | } else if (ipmi_watchdog_state != WDOG_TIMEOUT_NONE) { |
953 | /* Set a long timer to let the reboot happens, but | 953 | /* Set a long timer to let the reboot happens, but |
954 | reboot if it hangs. */ | 954 | reboot if it hangs, but only if the watchdog |
955 | timer was already running. */ | ||
955 | timeout = 120; | 956 | timeout = 120; |
956 | pretimeout = 0; | 957 | pretimeout = 0; |
957 | ipmi_watchdog_state = WDOG_TIMEOUT_RESET; | 958 | ipmi_watchdog_state = WDOG_TIMEOUT_RESET; |
@@ -973,16 +974,17 @@ static int wdog_panic_handler(struct notifier_block *this, | |||
973 | { | 974 | { |
974 | static int panic_event_handled = 0; | 975 | static int panic_event_handled = 0; |
975 | 976 | ||
976 | /* On a panic, if we have a panic timeout, make sure that the thing | 977 | /* On a panic, if we have a panic timeout, make sure to extend |
977 | reboots, even if it hangs during that panic. */ | 978 | the watchdog timer to a reasonable value to complete the |
978 | if (watchdog_user && !panic_event_handled) { | 979 | panic, if the watchdog timer is running. Plus the |
979 | /* Make sure the panic doesn't hang, and make sure we | 980 | pretimeout is meaningless at panic time. */ |
980 | do this only once. */ | 981 | if (watchdog_user && !panic_event_handled && |
982 | ipmi_watchdog_state != WDOG_TIMEOUT_NONE) { | ||
983 | /* Make sure we do this only once. */ | ||
981 | panic_event_handled = 1; | 984 | panic_event_handled = 1; |
982 | 985 | ||
983 | timeout = 255; | 986 | timeout = 255; |
984 | pretimeout = 0; | 987 | pretimeout = 0; |
985 | ipmi_watchdog_state = WDOG_TIMEOUT_RESET; | ||
986 | panic_halt_ipmi_set_timeout(); | 988 | panic_halt_ipmi_set_timeout(); |
987 | } | 989 | } |
988 | 990 | ||
diff --git a/drivers/char/isicom.c b/drivers/char/isicom.c index efaaa1937ab6..478bf4d7d065 100644 --- a/drivers/char/isicom.c +++ b/drivers/char/isicom.c | |||
@@ -1581,7 +1581,6 @@ static int __devinit isicom_register_tty_driver(void) | |||
1581 | 1581 | ||
1582 | isicom_normal->owner = THIS_MODULE; | 1582 | isicom_normal->owner = THIS_MODULE; |
1583 | isicom_normal->name = "ttyM"; | 1583 | isicom_normal->name = "ttyM"; |
1584 | isicom_normal->devfs_name = "isicom/"; | ||
1585 | isicom_normal->major = ISICOM_NMAJOR; | 1584 | isicom_normal->major = ISICOM_NMAJOR; |
1586 | isicom_normal->minor_start = 0; | 1585 | isicom_normal->minor_start = 0; |
1587 | isicom_normal->type = TTY_DRIVER_TYPE_SERIAL; | 1586 | isicom_normal->type = TTY_DRIVER_TYPE_SERIAL; |
diff --git a/drivers/char/istallion.c b/drivers/char/istallion.c index ef20c1fc9c4c..c74e5660a9b7 100644 --- a/drivers/char/istallion.c +++ b/drivers/char/istallion.c | |||
@@ -39,16 +39,14 @@ | |||
39 | #include <linux/ioport.h> | 39 | #include <linux/ioport.h> |
40 | #include <linux/delay.h> | 40 | #include <linux/delay.h> |
41 | #include <linux/init.h> | 41 | #include <linux/init.h> |
42 | #include <linux/devfs_fs_kernel.h> | ||
43 | #include <linux/device.h> | 42 | #include <linux/device.h> |
44 | #include <linux/wait.h> | 43 | #include <linux/wait.h> |
44 | #include <linux/eisa.h> | ||
45 | 45 | ||
46 | #include <asm/io.h> | 46 | #include <asm/io.h> |
47 | #include <asm/uaccess.h> | 47 | #include <asm/uaccess.h> |
48 | 48 | ||
49 | #ifdef CONFIG_PCI | ||
50 | #include <linux/pci.h> | 49 | #include <linux/pci.h> |
51 | #endif | ||
52 | 50 | ||
53 | /*****************************************************************************/ | 51 | /*****************************************************************************/ |
54 | 52 | ||
@@ -137,6 +135,10 @@ static stlconf_t stli_brdconf[] = { | |||
137 | 135 | ||
138 | static int stli_nrbrds = ARRAY_SIZE(stli_brdconf); | 136 | static int stli_nrbrds = ARRAY_SIZE(stli_brdconf); |
139 | 137 | ||
138 | /* stli_lock must NOT be taken holding brd_lock */ | ||
139 | static spinlock_t stli_lock; /* TTY logic lock */ | ||
140 | static spinlock_t brd_lock; /* Board logic lock */ | ||
141 | |||
140 | /* | 142 | /* |
141 | * There is some experimental EISA board detection code in this driver. | 143 | * There is some experimental EISA board detection code in this driver. |
142 | * By default it is disabled, but for those that want to try it out, | 144 | * By default it is disabled, but for those that want to try it out, |
@@ -173,14 +175,6 @@ static char *stli_serialname = "ttyE"; | |||
173 | 175 | ||
174 | static struct tty_driver *stli_serial; | 176 | static struct tty_driver *stli_serial; |
175 | 177 | ||
176 | /* | ||
177 | * We will need to allocate a temporary write buffer for chars that | ||
178 | * come direct from user space. The problem is that a copy from user | ||
179 | * space might cause a page fault (typically on a system that is | ||
180 | * swapping!). All ports will share one buffer - since if the system | ||
181 | * is already swapping a shared buffer won't make things any worse. | ||
182 | */ | ||
183 | static char *stli_tmpwritebuf; | ||
184 | 178 | ||
185 | #define STLI_TXBUFSIZE 4096 | 179 | #define STLI_TXBUFSIZE 4096 |
186 | 180 | ||
@@ -419,7 +413,7 @@ static int stli_eisamempsize = ARRAY_SIZE(stli_eisamemprobeaddrs); | |||
419 | #endif | 413 | #endif |
420 | 414 | ||
421 | static struct pci_device_id istallion_pci_tbl[] = { | 415 | static struct pci_device_id istallion_pci_tbl[] = { |
422 | { PCI_VENDOR_ID_STALLION, PCI_DEVICE_ID_ECRA, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, | 416 | { PCI_DEVICE(PCI_VENDOR_ID_STALLION, PCI_DEVICE_ID_ECRA), }, |
423 | { 0 } | 417 | { 0 } |
424 | }; | 418 | }; |
425 | MODULE_DEVICE_TABLE(pci, istallion_pci_tbl); | 419 | MODULE_DEVICE_TABLE(pci, istallion_pci_tbl); |
@@ -682,7 +676,7 @@ static int stli_startbrd(stlibrd_t *brdp); | |||
682 | static ssize_t stli_memread(struct file *fp, char __user *buf, size_t count, loff_t *offp); | 676 | static ssize_t stli_memread(struct file *fp, char __user *buf, size_t count, loff_t *offp); |
683 | static ssize_t stli_memwrite(struct file *fp, const char __user *buf, size_t count, loff_t *offp); | 677 | static ssize_t stli_memwrite(struct file *fp, const char __user *buf, size_t count, loff_t *offp); |
684 | static int stli_memioctl(struct inode *ip, struct file *fp, unsigned int cmd, unsigned long arg); | 678 | static int stli_memioctl(struct inode *ip, struct file *fp, unsigned int cmd, unsigned long arg); |
685 | static void stli_brdpoll(stlibrd_t *brdp, volatile cdkhdr_t *hdrp); | 679 | static void stli_brdpoll(stlibrd_t *brdp, cdkhdr_t __iomem *hdrp); |
686 | static void stli_poll(unsigned long arg); | 680 | static void stli_poll(unsigned long arg); |
687 | static int stli_hostcmd(stlibrd_t *brdp, stliport_t *portp); | 681 | static int stli_hostcmd(stlibrd_t *brdp, stliport_t *portp); |
688 | static int stli_initopen(stlibrd_t *brdp, stliport_t *portp); | 682 | static int stli_initopen(stlibrd_t *brdp, stliport_t *portp); |
@@ -693,7 +687,8 @@ static void stli_dohangup(void *arg); | |||
693 | static int stli_setport(stliport_t *portp); | 687 | static int stli_setport(stliport_t *portp); |
694 | static int stli_cmdwait(stlibrd_t *brdp, stliport_t *portp, unsigned long cmd, void *arg, int size, int copyback); | 688 | static int stli_cmdwait(stlibrd_t *brdp, stliport_t *portp, unsigned long cmd, void *arg, int size, int copyback); |
695 | static void stli_sendcmd(stlibrd_t *brdp, stliport_t *portp, unsigned long cmd, void *arg, int size, int copyback); | 689 | static void stli_sendcmd(stlibrd_t *brdp, stliport_t *portp, unsigned long cmd, void *arg, int size, int copyback); |
696 | static void stli_dodelaycmd(stliport_t *portp, volatile cdkctrl_t *cp); | 690 | static void __stli_sendcmd(stlibrd_t *brdp, stliport_t *portp, unsigned long cmd, void *arg, int size, int copyback); |
691 | static void stli_dodelaycmd(stliport_t *portp, cdkctrl_t __iomem *cp); | ||
697 | static void stli_mkasyport(stliport_t *portp, asyport_t *pp, struct termios *tiosp); | 692 | static void stli_mkasyport(stliport_t *portp, asyport_t *pp, struct termios *tiosp); |
698 | static void stli_mkasysigs(asysigs_t *sp, int dtr, int rts); | 693 | static void stli_mkasysigs(asysigs_t *sp, int dtr, int rts); |
699 | static long stli_mktiocm(unsigned long sigvalue); | 694 | static long stli_mktiocm(unsigned long sigvalue); |
@@ -799,18 +794,8 @@ static struct class *istallion_class; | |||
799 | 794 | ||
800 | static int __init istallion_module_init(void) | 795 | static int __init istallion_module_init(void) |
801 | { | 796 | { |
802 | unsigned long flags; | ||
803 | |||
804 | #ifdef DEBUG | ||
805 | printk("init_module()\n"); | ||
806 | #endif | ||
807 | |||
808 | save_flags(flags); | ||
809 | cli(); | ||
810 | stli_init(); | 797 | stli_init(); |
811 | restore_flags(flags); | 798 | return 0; |
812 | |||
813 | return(0); | ||
814 | } | 799 | } |
815 | 800 | ||
816 | /*****************************************************************************/ | 801 | /*****************************************************************************/ |
@@ -819,56 +804,43 @@ static void __exit istallion_module_exit(void) | |||
819 | { | 804 | { |
820 | stlibrd_t *brdp; | 805 | stlibrd_t *brdp; |
821 | stliport_t *portp; | 806 | stliport_t *portp; |
822 | unsigned long flags; | ||
823 | int i, j; | 807 | int i, j; |
824 | 808 | ||
825 | #ifdef DEBUG | ||
826 | printk("cleanup_module()\n"); | ||
827 | #endif | ||
828 | |||
829 | printk(KERN_INFO "Unloading %s: version %s\n", stli_drvtitle, | 809 | printk(KERN_INFO "Unloading %s: version %s\n", stli_drvtitle, |
830 | stli_drvversion); | 810 | stli_drvversion); |
831 | 811 | ||
832 | save_flags(flags); | 812 | /* |
833 | cli(); | 813 | * Free up all allocated resources used by the ports. This includes |
834 | 814 | * memory and interrupts. | |
835 | /* | 815 | */ |
836 | * Free up all allocated resources used by the ports. This includes | ||
837 | * memory and interrupts. | ||
838 | */ | ||
839 | if (stli_timeron) { | 816 | if (stli_timeron) { |
840 | stli_timeron = 0; | 817 | stli_timeron = 0; |
841 | del_timer(&stli_timerlist); | 818 | del_timer_sync(&stli_timerlist); |
842 | } | 819 | } |
843 | 820 | ||
844 | i = tty_unregister_driver(stli_serial); | 821 | i = tty_unregister_driver(stli_serial); |
845 | if (i) { | 822 | if (i) { |
846 | printk("STALLION: failed to un-register tty driver, " | 823 | printk("STALLION: failed to un-register tty driver, " |
847 | "errno=%d\n", -i); | 824 | "errno=%d\n", -i); |
848 | restore_flags(flags); | ||
849 | return; | 825 | return; |
850 | } | 826 | } |
851 | put_tty_driver(stli_serial); | 827 | put_tty_driver(stli_serial); |
852 | for (i = 0; i < 4; i++) { | 828 | for (i = 0; i < 4; i++) |
853 | devfs_remove("staliomem/%d", i); | ||
854 | class_device_destroy(istallion_class, MKDEV(STL_SIOMEMMAJOR, i)); | 829 | class_device_destroy(istallion_class, MKDEV(STL_SIOMEMMAJOR, i)); |
855 | } | ||
856 | devfs_remove("staliomem"); | ||
857 | class_destroy(istallion_class); | 830 | class_destroy(istallion_class); |
858 | if ((i = unregister_chrdev(STL_SIOMEMMAJOR, "staliomem"))) | 831 | if ((i = unregister_chrdev(STL_SIOMEMMAJOR, "staliomem"))) |
859 | printk("STALLION: failed to un-register serial memory device, " | 832 | printk("STALLION: failed to un-register serial memory device, " |
860 | "errno=%d\n", -i); | 833 | "errno=%d\n", -i); |
861 | 834 | ||
862 | kfree(stli_tmpwritebuf); | ||
863 | kfree(stli_txcookbuf); | 835 | kfree(stli_txcookbuf); |
864 | 836 | ||
865 | for (i = 0; (i < stli_nrbrds); i++) { | 837 | for (i = 0; (i < stli_nrbrds); i++) { |
866 | if ((brdp = stli_brds[i]) == (stlibrd_t *) NULL) | 838 | if ((brdp = stli_brds[i]) == NULL) |
867 | continue; | 839 | continue; |
868 | for (j = 0; (j < STL_MAXPORTS); j++) { | 840 | for (j = 0; (j < STL_MAXPORTS); j++) { |
869 | portp = brdp->ports[j]; | 841 | portp = brdp->ports[j]; |
870 | if (portp != (stliport_t *) NULL) { | 842 | if (portp != NULL) { |
871 | if (portp->tty != (struct tty_struct *) NULL) | 843 | if (portp->tty != NULL) |
872 | tty_hangup(portp->tty); | 844 | tty_hangup(portp->tty); |
873 | kfree(portp); | 845 | kfree(portp); |
874 | } | 846 | } |
@@ -878,10 +850,8 @@ static void __exit istallion_module_exit(void) | |||
878 | if (brdp->iosize > 0) | 850 | if (brdp->iosize > 0) |
879 | release_region(brdp->iobase, brdp->iosize); | 851 | release_region(brdp->iobase, brdp->iosize); |
880 | kfree(brdp); | 852 | kfree(brdp); |
881 | stli_brds[i] = (stlibrd_t *) NULL; | 853 | stli_brds[i] = NULL; |
882 | } | 854 | } |
883 | |||
884 | restore_flags(flags); | ||
885 | } | 855 | } |
886 | 856 | ||
887 | module_init(istallion_module_init); | 857 | module_init(istallion_module_init); |
@@ -895,19 +865,15 @@ module_exit(istallion_module_exit); | |||
895 | 865 | ||
896 | static void stli_argbrds(void) | 866 | static void stli_argbrds(void) |
897 | { | 867 | { |
898 | stlconf_t conf; | 868 | stlconf_t conf; |
899 | stlibrd_t *brdp; | 869 | stlibrd_t *brdp; |
900 | int i; | 870 | int i; |
901 | |||
902 | #ifdef DEBUG | ||
903 | printk("stli_argbrds()\n"); | ||
904 | #endif | ||
905 | 871 | ||
906 | for (i = stli_nrbrds; i < ARRAY_SIZE(stli_brdsp); i++) { | 872 | for (i = stli_nrbrds; i < ARRAY_SIZE(stli_brdsp); i++) { |
907 | memset(&conf, 0, sizeof(conf)); | 873 | memset(&conf, 0, sizeof(conf)); |
908 | if (stli_parsebrd(&conf, stli_brdsp[i]) == 0) | 874 | if (stli_parsebrd(&conf, stli_brdsp[i]) == 0) |
909 | continue; | 875 | continue; |
910 | if ((brdp = stli_allocbrd()) == (stlibrd_t *) NULL) | 876 | if ((brdp = stli_allocbrd()) == NULL) |
911 | continue; | 877 | continue; |
912 | stli_nrbrds = i + 1; | 878 | stli_nrbrds = i + 1; |
913 | brdp->brdnr = i; | 879 | brdp->brdnr = i; |
@@ -926,9 +892,9 @@ static void stli_argbrds(void) | |||
926 | 892 | ||
927 | static unsigned long stli_atol(char *str) | 893 | static unsigned long stli_atol(char *str) |
928 | { | 894 | { |
929 | unsigned long val; | 895 | unsigned long val; |
930 | int base, c; | 896 | int base, c; |
931 | char *sp; | 897 | char *sp; |
932 | 898 | ||
933 | val = 0; | 899 | val = 0; |
934 | sp = str; | 900 | sp = str; |
@@ -962,15 +928,11 @@ static unsigned long stli_atol(char *str) | |||
962 | 928 | ||
963 | static int stli_parsebrd(stlconf_t *confp, char **argp) | 929 | static int stli_parsebrd(stlconf_t *confp, char **argp) |
964 | { | 930 | { |
965 | char *sp; | 931 | char *sp; |
966 | int i; | 932 | int i; |
967 | |||
968 | #ifdef DEBUG | ||
969 | printk("stli_parsebrd(confp=%x,argp=%x)\n", (int) confp, (int) argp); | ||
970 | #endif | ||
971 | 933 | ||
972 | if ((argp[0] == (char *) NULL) || (*argp[0] == 0)) | 934 | if (argp[0] == NULL || *argp[0] == 0) |
973 | return(0); | 935 | return 0; |
974 | 936 | ||
975 | for (sp = argp[0], i = 0; ((*sp != 0) && (i < 25)); sp++, i++) | 937 | for (sp = argp[0], i = 0; ((*sp != 0) && (i < 25)); sp++, i++) |
976 | *sp = TOLOWER(*sp); | 938 | *sp = TOLOWER(*sp); |
@@ -985,9 +947,9 @@ static int stli_parsebrd(stlconf_t *confp, char **argp) | |||
985 | } | 947 | } |
986 | 948 | ||
987 | confp->brdtype = stli_brdstr[i].type; | 949 | confp->brdtype = stli_brdstr[i].type; |
988 | if ((argp[1] != (char *) NULL) && (*argp[1] != 0)) | 950 | if (argp[1] != NULL && *argp[1] != 0) |
989 | confp->ioaddr1 = stli_atol(argp[1]); | 951 | confp->ioaddr1 = stli_atol(argp[1]); |
990 | if ((argp[2] != (char *) NULL) && (*argp[2] != 0)) | 952 | if (argp[2] != NULL && *argp[2] != 0) |
991 | confp->memaddr = stli_atol(argp[2]); | 953 | confp->memaddr = stli_atol(argp[2]); |
992 | return(1); | 954 | return(1); |
993 | } | 955 | } |
@@ -998,34 +960,29 @@ static int stli_parsebrd(stlconf_t *confp, char **argp) | |||
998 | 960 | ||
999 | static int stli_open(struct tty_struct *tty, struct file *filp) | 961 | static int stli_open(struct tty_struct *tty, struct file *filp) |
1000 | { | 962 | { |
1001 | stlibrd_t *brdp; | 963 | stlibrd_t *brdp; |
1002 | stliport_t *portp; | 964 | stliport_t *portp; |
1003 | unsigned int minordev; | 965 | unsigned int minordev; |
1004 | int brdnr, portnr, rc; | 966 | int brdnr, portnr, rc; |
1005 | |||
1006 | #ifdef DEBUG | ||
1007 | printk("stli_open(tty=%x,filp=%x): device=%s\n", (int) tty, | ||
1008 | (int) filp, tty->name); | ||
1009 | #endif | ||
1010 | 967 | ||
1011 | minordev = tty->index; | 968 | minordev = tty->index; |
1012 | brdnr = MINOR2BRD(minordev); | 969 | brdnr = MINOR2BRD(minordev); |
1013 | if (brdnr >= stli_nrbrds) | 970 | if (brdnr >= stli_nrbrds) |
1014 | return(-ENODEV); | 971 | return -ENODEV; |
1015 | brdp = stli_brds[brdnr]; | 972 | brdp = stli_brds[brdnr]; |
1016 | if (brdp == (stlibrd_t *) NULL) | 973 | if (brdp == NULL) |
1017 | return(-ENODEV); | 974 | return -ENODEV; |
1018 | if ((brdp->state & BST_STARTED) == 0) | 975 | if ((brdp->state & BST_STARTED) == 0) |
1019 | return(-ENODEV); | 976 | return -ENODEV; |
1020 | portnr = MINOR2PORT(minordev); | 977 | portnr = MINOR2PORT(minordev); |
1021 | if ((portnr < 0) || (portnr > brdp->nrports)) | 978 | if ((portnr < 0) || (portnr > brdp->nrports)) |
1022 | return(-ENODEV); | 979 | return -ENODEV; |
1023 | 980 | ||
1024 | portp = brdp->ports[portnr]; | 981 | portp = brdp->ports[portnr]; |
1025 | if (portp == (stliport_t *) NULL) | 982 | if (portp == NULL) |
1026 | return(-ENODEV); | 983 | return -ENODEV; |
1027 | if (portp->devnr < 1) | 984 | if (portp->devnr < 1) |
1028 | return(-ENODEV); | 985 | return -ENODEV; |
1029 | 986 | ||
1030 | 987 | ||
1031 | /* | 988 | /* |
@@ -1037,8 +994,8 @@ static int stli_open(struct tty_struct *tty, struct file *filp) | |||
1037 | if (portp->flags & ASYNC_CLOSING) { | 994 | if (portp->flags & ASYNC_CLOSING) { |
1038 | interruptible_sleep_on(&portp->close_wait); | 995 | interruptible_sleep_on(&portp->close_wait); |
1039 | if (portp->flags & ASYNC_HUP_NOTIFY) | 996 | if (portp->flags & ASYNC_HUP_NOTIFY) |
1040 | return(-EAGAIN); | 997 | return -EAGAIN; |
1041 | return(-ERESTARTSYS); | 998 | return -ERESTARTSYS; |
1042 | } | 999 | } |
1043 | 1000 | ||
1044 | /* | 1001 | /* |
@@ -1054,7 +1011,7 @@ static int stli_open(struct tty_struct *tty, struct file *filp) | |||
1054 | wait_event_interruptible(portp->raw_wait, | 1011 | wait_event_interruptible(portp->raw_wait, |
1055 | !test_bit(ST_INITIALIZING, &portp->state)); | 1012 | !test_bit(ST_INITIALIZING, &portp->state)); |
1056 | if (signal_pending(current)) | 1013 | if (signal_pending(current)) |
1057 | return(-ERESTARTSYS); | 1014 | return -ERESTARTSYS; |
1058 | 1015 | ||
1059 | if ((portp->flags & ASYNC_INITIALIZED) == 0) { | 1016 | if ((portp->flags & ASYNC_INITIALIZED) == 0) { |
1060 | set_bit(ST_INITIALIZING, &portp->state); | 1017 | set_bit(ST_INITIALIZING, &portp->state); |
@@ -1065,7 +1022,7 @@ static int stli_open(struct tty_struct *tty, struct file *filp) | |||
1065 | clear_bit(ST_INITIALIZING, &portp->state); | 1022 | clear_bit(ST_INITIALIZING, &portp->state); |
1066 | wake_up_interruptible(&portp->raw_wait); | 1023 | wake_up_interruptible(&portp->raw_wait); |
1067 | if (rc < 0) | 1024 | if (rc < 0) |
1068 | return(rc); | 1025 | return rc; |
1069 | } | 1026 | } |
1070 | 1027 | ||
1071 | /* | 1028 | /* |
@@ -1077,8 +1034,8 @@ static int stli_open(struct tty_struct *tty, struct file *filp) | |||
1077 | if (portp->flags & ASYNC_CLOSING) { | 1034 | if (portp->flags & ASYNC_CLOSING) { |
1078 | interruptible_sleep_on(&portp->close_wait); | 1035 | interruptible_sleep_on(&portp->close_wait); |
1079 | if (portp->flags & ASYNC_HUP_NOTIFY) | 1036 | if (portp->flags & ASYNC_HUP_NOTIFY) |
1080 | return(-EAGAIN); | 1037 | return -EAGAIN; |
1081 | return(-ERESTARTSYS); | 1038 | return -ERESTARTSYS; |
1082 | } | 1039 | } |
1083 | 1040 | ||
1084 | /* | 1041 | /* |
@@ -1088,38 +1045,33 @@ static int stli_open(struct tty_struct *tty, struct file *filp) | |||
1088 | */ | 1045 | */ |
1089 | if (!(filp->f_flags & O_NONBLOCK)) { | 1046 | if (!(filp->f_flags & O_NONBLOCK)) { |
1090 | if ((rc = stli_waitcarrier(brdp, portp, filp)) != 0) | 1047 | if ((rc = stli_waitcarrier(brdp, portp, filp)) != 0) |
1091 | return(rc); | 1048 | return rc; |
1092 | } | 1049 | } |
1093 | portp->flags |= ASYNC_NORMAL_ACTIVE; | 1050 | portp->flags |= ASYNC_NORMAL_ACTIVE; |
1094 | return(0); | 1051 | return 0; |
1095 | } | 1052 | } |
1096 | 1053 | ||
1097 | /*****************************************************************************/ | 1054 | /*****************************************************************************/ |
1098 | 1055 | ||
1099 | static void stli_close(struct tty_struct *tty, struct file *filp) | 1056 | static void stli_close(struct tty_struct *tty, struct file *filp) |
1100 | { | 1057 | { |
1101 | stlibrd_t *brdp; | 1058 | stlibrd_t *brdp; |
1102 | stliport_t *portp; | 1059 | stliport_t *portp; |
1103 | unsigned long flags; | 1060 | unsigned long flags; |
1104 | |||
1105 | #ifdef DEBUG | ||
1106 | printk("stli_close(tty=%x,filp=%x)\n", (int) tty, (int) filp); | ||
1107 | #endif | ||
1108 | 1061 | ||
1109 | portp = tty->driver_data; | 1062 | portp = tty->driver_data; |
1110 | if (portp == (stliport_t *) NULL) | 1063 | if (portp == NULL) |
1111 | return; | 1064 | return; |
1112 | 1065 | ||
1113 | save_flags(flags); | 1066 | spin_lock_irqsave(&stli_lock, flags); |
1114 | cli(); | ||
1115 | if (tty_hung_up_p(filp)) { | 1067 | if (tty_hung_up_p(filp)) { |
1116 | restore_flags(flags); | 1068 | spin_unlock_irqrestore(&stli_lock, flags); |
1117 | return; | 1069 | return; |
1118 | } | 1070 | } |
1119 | if ((tty->count == 1) && (portp->refcount != 1)) | 1071 | if ((tty->count == 1) && (portp->refcount != 1)) |
1120 | portp->refcount = 1; | 1072 | portp->refcount = 1; |
1121 | if (portp->refcount-- > 1) { | 1073 | if (portp->refcount-- > 1) { |
1122 | restore_flags(flags); | 1074 | spin_unlock_irqrestore(&stli_lock, flags); |
1123 | return; | 1075 | return; |
1124 | } | 1076 | } |
1125 | 1077 | ||
@@ -1134,6 +1086,8 @@ static void stli_close(struct tty_struct *tty, struct file *filp) | |||
1134 | if (tty == stli_txcooktty) | 1086 | if (tty == stli_txcooktty) |
1135 | stli_flushchars(tty); | 1087 | stli_flushchars(tty); |
1136 | tty->closing = 1; | 1088 | tty->closing = 1; |
1089 | spin_unlock_irqrestore(&stli_lock, flags); | ||
1090 | |||
1137 | if (portp->closing_wait != ASYNC_CLOSING_WAIT_NONE) | 1091 | if (portp->closing_wait != ASYNC_CLOSING_WAIT_NONE) |
1138 | tty_wait_until_sent(tty, portp->closing_wait); | 1092 | tty_wait_until_sent(tty, portp->closing_wait); |
1139 | 1093 | ||
@@ -1157,7 +1111,7 @@ static void stli_close(struct tty_struct *tty, struct file *filp) | |||
1157 | stli_flushbuffer(tty); | 1111 | stli_flushbuffer(tty); |
1158 | 1112 | ||
1159 | tty->closing = 0; | 1113 | tty->closing = 0; |
1160 | portp->tty = (struct tty_struct *) NULL; | 1114 | portp->tty = NULL; |
1161 | 1115 | ||
1162 | if (portp->openwaitcnt) { | 1116 | if (portp->openwaitcnt) { |
1163 | if (portp->close_delay) | 1117 | if (portp->close_delay) |
@@ -1167,7 +1121,6 @@ static void stli_close(struct tty_struct *tty, struct file *filp) | |||
1167 | 1121 | ||
1168 | portp->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING); | 1122 | portp->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING); |
1169 | wake_up_interruptible(&portp->close_wait); | 1123 | wake_up_interruptible(&portp->close_wait); |
1170 | restore_flags(flags); | ||
1171 | } | 1124 | } |
1172 | 1125 | ||
1173 | /*****************************************************************************/ | 1126 | /*****************************************************************************/ |
@@ -1182,45 +1135,41 @@ static void stli_close(struct tty_struct *tty, struct file *filp) | |||
1182 | 1135 | ||
1183 | static int stli_initopen(stlibrd_t *brdp, stliport_t *portp) | 1136 | static int stli_initopen(stlibrd_t *brdp, stliport_t *portp) |
1184 | { | 1137 | { |
1185 | struct tty_struct *tty; | 1138 | struct tty_struct *tty; |
1186 | asynotify_t nt; | 1139 | asynotify_t nt; |
1187 | asyport_t aport; | 1140 | asyport_t aport; |
1188 | int rc; | 1141 | int rc; |
1189 | |||
1190 | #ifdef DEBUG | ||
1191 | printk("stli_initopen(brdp=%x,portp=%x)\n", (int) brdp, (int) portp); | ||
1192 | #endif | ||
1193 | 1142 | ||
1194 | if ((rc = stli_rawopen(brdp, portp, 0, 1)) < 0) | 1143 | if ((rc = stli_rawopen(brdp, portp, 0, 1)) < 0) |
1195 | return(rc); | 1144 | return rc; |
1196 | 1145 | ||
1197 | memset(&nt, 0, sizeof(asynotify_t)); | 1146 | memset(&nt, 0, sizeof(asynotify_t)); |
1198 | nt.data = (DT_TXLOW | DT_TXEMPTY | DT_RXBUSY | DT_RXBREAK); | 1147 | nt.data = (DT_TXLOW | DT_TXEMPTY | DT_RXBUSY | DT_RXBREAK); |
1199 | nt.signal = SG_DCD; | 1148 | nt.signal = SG_DCD; |
1200 | if ((rc = stli_cmdwait(brdp, portp, A_SETNOTIFY, &nt, | 1149 | if ((rc = stli_cmdwait(brdp, portp, A_SETNOTIFY, &nt, |
1201 | sizeof(asynotify_t), 0)) < 0) | 1150 | sizeof(asynotify_t), 0)) < 0) |
1202 | return(rc); | 1151 | return rc; |
1203 | 1152 | ||
1204 | tty = portp->tty; | 1153 | tty = portp->tty; |
1205 | if (tty == (struct tty_struct *) NULL) | 1154 | if (tty == NULL) |
1206 | return(-ENODEV); | 1155 | return -ENODEV; |
1207 | stli_mkasyport(portp, &aport, tty->termios); | 1156 | stli_mkasyport(portp, &aport, tty->termios); |
1208 | if ((rc = stli_cmdwait(brdp, portp, A_SETPORT, &aport, | 1157 | if ((rc = stli_cmdwait(brdp, portp, A_SETPORT, &aport, |
1209 | sizeof(asyport_t), 0)) < 0) | 1158 | sizeof(asyport_t), 0)) < 0) |
1210 | return(rc); | 1159 | return rc; |
1211 | 1160 | ||
1212 | set_bit(ST_GETSIGS, &portp->state); | 1161 | set_bit(ST_GETSIGS, &portp->state); |
1213 | if ((rc = stli_cmdwait(brdp, portp, A_GETSIGNALS, &portp->asig, | 1162 | if ((rc = stli_cmdwait(brdp, portp, A_GETSIGNALS, &portp->asig, |
1214 | sizeof(asysigs_t), 1)) < 0) | 1163 | sizeof(asysigs_t), 1)) < 0) |
1215 | return(rc); | 1164 | return rc; |
1216 | if (test_and_clear_bit(ST_GETSIGS, &portp->state)) | 1165 | if (test_and_clear_bit(ST_GETSIGS, &portp->state)) |
1217 | portp->sigs = stli_mktiocm(portp->asig.sigvalue); | 1166 | portp->sigs = stli_mktiocm(portp->asig.sigvalue); |
1218 | stli_mkasysigs(&portp->asig, 1, 1); | 1167 | stli_mkasysigs(&portp->asig, 1, 1); |
1219 | if ((rc = stli_cmdwait(brdp, portp, A_SETSIGNALS, &portp->asig, | 1168 | if ((rc = stli_cmdwait(brdp, portp, A_SETSIGNALS, &portp->asig, |
1220 | sizeof(asysigs_t), 0)) < 0) | 1169 | sizeof(asysigs_t), 0)) < 0) |
1221 | return(rc); | 1170 | return rc; |
1222 | 1171 | ||
1223 | return(0); | 1172 | return 0; |
1224 | } | 1173 | } |
1225 | 1174 | ||
1226 | /*****************************************************************************/ | 1175 | /*****************************************************************************/ |
@@ -1234,22 +1183,15 @@ static int stli_initopen(stlibrd_t *brdp, stliport_t *portp) | |||
1234 | 1183 | ||
1235 | static int stli_rawopen(stlibrd_t *brdp, stliport_t *portp, unsigned long arg, int wait) | 1184 | static int stli_rawopen(stlibrd_t *brdp, stliport_t *portp, unsigned long arg, int wait) |
1236 | { | 1185 | { |
1237 | volatile cdkhdr_t *hdrp; | 1186 | cdkhdr_t __iomem *hdrp; |
1238 | volatile cdkctrl_t *cp; | 1187 | cdkctrl_t __iomem *cp; |
1239 | volatile unsigned char *bits; | 1188 | unsigned char __iomem *bits; |
1240 | unsigned long flags; | 1189 | unsigned long flags; |
1241 | int rc; | 1190 | int rc; |
1242 | |||
1243 | #ifdef DEBUG | ||
1244 | printk("stli_rawopen(brdp=%x,portp=%x,arg=%x,wait=%d)\n", | ||
1245 | (int) brdp, (int) portp, (int) arg, wait); | ||
1246 | #endif | ||
1247 | 1191 | ||
1248 | /* | 1192 | /* |
1249 | * Send a message to the slave to open this port. | 1193 | * Send a message to the slave to open this port. |
1250 | */ | 1194 | */ |
1251 | save_flags(flags); | ||
1252 | cli(); | ||
1253 | 1195 | ||
1254 | /* | 1196 | /* |
1255 | * Slave is already closing this port. This can happen if a hangup | 1197 | * Slave is already closing this port. This can happen if a hangup |
@@ -1260,7 +1202,6 @@ static int stli_rawopen(stlibrd_t *brdp, stliport_t *portp, unsigned long arg, i | |||
1260 | wait_event_interruptible(portp->raw_wait, | 1202 | wait_event_interruptible(portp->raw_wait, |
1261 | !test_bit(ST_CLOSING, &portp->state)); | 1203 | !test_bit(ST_CLOSING, &portp->state)); |
1262 | if (signal_pending(current)) { | 1204 | if (signal_pending(current)) { |
1263 | restore_flags(flags); | ||
1264 | return -ERESTARTSYS; | 1205 | return -ERESTARTSYS; |
1265 | } | 1206 | } |
1266 | 1207 | ||
@@ -1269,19 +1210,20 @@ static int stli_rawopen(stlibrd_t *brdp, stliport_t *portp, unsigned long arg, i | |||
1269 | * memory. Once the message is in set the service bits to say that | 1210 | * memory. Once the message is in set the service bits to say that |
1270 | * this port wants service. | 1211 | * this port wants service. |
1271 | */ | 1212 | */ |
1213 | spin_lock_irqsave(&brd_lock, flags); | ||
1272 | EBRDENABLE(brdp); | 1214 | EBRDENABLE(brdp); |
1273 | cp = &((volatile cdkasy_t *) EBRDGETMEMPTR(brdp, portp->addr))->ctrl; | 1215 | cp = &((cdkasy_t __iomem *) EBRDGETMEMPTR(brdp, portp->addr))->ctrl; |
1274 | cp->openarg = arg; | 1216 | writel(arg, &cp->openarg); |
1275 | cp->open = 1; | 1217 | writeb(1, &cp->open); |
1276 | hdrp = (volatile cdkhdr_t *) EBRDGETMEMPTR(brdp, CDK_CDKADDR); | 1218 | hdrp = (cdkhdr_t __iomem *) EBRDGETMEMPTR(brdp, CDK_CDKADDR); |
1277 | bits = ((volatile unsigned char *) hdrp) + brdp->slaveoffset + | 1219 | bits = ((unsigned char __iomem *) hdrp) + brdp->slaveoffset + |
1278 | portp->portidx; | 1220 | portp->portidx; |
1279 | *bits |= portp->portbit; | 1221 | writeb(readb(bits) | portp->portbit, bits); |
1280 | EBRDDISABLE(brdp); | 1222 | EBRDDISABLE(brdp); |
1281 | 1223 | ||
1282 | if (wait == 0) { | 1224 | if (wait == 0) { |
1283 | restore_flags(flags); | 1225 | spin_unlock_irqrestore(&brd_lock, flags); |
1284 | return(0); | 1226 | return 0; |
1285 | } | 1227 | } |
1286 | 1228 | ||
1287 | /* | 1229 | /* |
@@ -1290,15 +1232,16 @@ static int stli_rawopen(stlibrd_t *brdp, stliport_t *portp, unsigned long arg, i | |||
1290 | */ | 1232 | */ |
1291 | rc = 0; | 1233 | rc = 0; |
1292 | set_bit(ST_OPENING, &portp->state); | 1234 | set_bit(ST_OPENING, &portp->state); |
1235 | spin_unlock_irqrestore(&brd_lock, flags); | ||
1236 | |||
1293 | wait_event_interruptible(portp->raw_wait, | 1237 | wait_event_interruptible(portp->raw_wait, |
1294 | !test_bit(ST_OPENING, &portp->state)); | 1238 | !test_bit(ST_OPENING, &portp->state)); |
1295 | if (signal_pending(current)) | 1239 | if (signal_pending(current)) |
1296 | rc = -ERESTARTSYS; | 1240 | rc = -ERESTARTSYS; |
1297 | restore_flags(flags); | ||
1298 | 1241 | ||
1299 | if ((rc == 0) && (portp->rc != 0)) | 1242 | if ((rc == 0) && (portp->rc != 0)) |
1300 | rc = -EIO; | 1243 | rc = -EIO; |
1301 | return(rc); | 1244 | return rc; |
1302 | } | 1245 | } |
1303 | 1246 | ||
1304 | /*****************************************************************************/ | 1247 | /*****************************************************************************/ |
@@ -1311,19 +1254,11 @@ static int stli_rawopen(stlibrd_t *brdp, stliport_t *portp, unsigned long arg, i | |||
1311 | 1254 | ||
1312 | static int stli_rawclose(stlibrd_t *brdp, stliport_t *portp, unsigned long arg, int wait) | 1255 | static int stli_rawclose(stlibrd_t *brdp, stliport_t *portp, unsigned long arg, int wait) |
1313 | { | 1256 | { |
1314 | volatile cdkhdr_t *hdrp; | 1257 | cdkhdr_t __iomem *hdrp; |
1315 | volatile cdkctrl_t *cp; | 1258 | cdkctrl_t __iomem *cp; |
1316 | volatile unsigned char *bits; | 1259 | unsigned char __iomem *bits; |
1317 | unsigned long flags; | 1260 | unsigned long flags; |
1318 | int rc; | 1261 | int rc; |
1319 | |||
1320 | #ifdef DEBUG | ||
1321 | printk("stli_rawclose(brdp=%x,portp=%x,arg=%x,wait=%d)\n", | ||
1322 | (int) brdp, (int) portp, (int) arg, wait); | ||
1323 | #endif | ||
1324 | |||
1325 | save_flags(flags); | ||
1326 | cli(); | ||
1327 | 1262 | ||
1328 | /* | 1263 | /* |
1329 | * Slave is already closing this port. This can happen if a hangup | 1264 | * Slave is already closing this port. This can happen if a hangup |
@@ -1333,7 +1268,6 @@ static int stli_rawclose(stlibrd_t *brdp, stliport_t *portp, unsigned long arg, | |||
1333 | wait_event_interruptible(portp->raw_wait, | 1268 | wait_event_interruptible(portp->raw_wait, |
1334 | !test_bit(ST_CLOSING, &portp->state)); | 1269 | !test_bit(ST_CLOSING, &portp->state)); |
1335 | if (signal_pending(current)) { | 1270 | if (signal_pending(current)) { |
1336 | restore_flags(flags); | ||
1337 | return -ERESTARTSYS; | 1271 | return -ERESTARTSYS; |
1338 | } | 1272 | } |
1339 | } | 1273 | } |
@@ -1341,21 +1275,22 @@ static int stli_rawclose(stlibrd_t *brdp, stliport_t *portp, unsigned long arg, | |||
1341 | /* | 1275 | /* |
1342 | * Write the close command into shared memory. | 1276 | * Write the close command into shared memory. |
1343 | */ | 1277 | */ |
1278 | spin_lock_irqsave(&brd_lock, flags); | ||
1344 | EBRDENABLE(brdp); | 1279 | EBRDENABLE(brdp); |
1345 | cp = &((volatile cdkasy_t *) EBRDGETMEMPTR(brdp, portp->addr))->ctrl; | 1280 | cp = &((cdkasy_t __iomem *) EBRDGETMEMPTR(brdp, portp->addr))->ctrl; |
1346 | cp->closearg = arg; | 1281 | writel(arg, &cp->closearg); |
1347 | cp->close = 1; | 1282 | writeb(1, &cp->close); |
1348 | hdrp = (volatile cdkhdr_t *) EBRDGETMEMPTR(brdp, CDK_CDKADDR); | 1283 | hdrp = (cdkhdr_t __iomem *) EBRDGETMEMPTR(brdp, CDK_CDKADDR); |
1349 | bits = ((volatile unsigned char *) hdrp) + brdp->slaveoffset + | 1284 | bits = ((unsigned char __iomem *) hdrp) + brdp->slaveoffset + |
1350 | portp->portidx; | 1285 | portp->portidx; |
1351 | *bits |= portp->portbit; | 1286 | writeb(readb(bits) |portp->portbit, bits); |
1352 | EBRDDISABLE(brdp); | 1287 | EBRDDISABLE(brdp); |
1353 | 1288 | ||
1354 | set_bit(ST_CLOSING, &portp->state); | 1289 | set_bit(ST_CLOSING, &portp->state); |
1355 | if (wait == 0) { | 1290 | spin_unlock_irqrestore(&brd_lock, flags); |
1356 | restore_flags(flags); | 1291 | |
1357 | return(0); | 1292 | if (wait == 0) |
1358 | } | 1293 | return 0; |
1359 | 1294 | ||
1360 | /* | 1295 | /* |
1361 | * Slave is in action, so now we must wait for the open acknowledgment | 1296 | * Slave is in action, so now we must wait for the open acknowledgment |
@@ -1366,11 +1301,10 @@ static int stli_rawclose(stlibrd_t *brdp, stliport_t *portp, unsigned long arg, | |||
1366 | !test_bit(ST_CLOSING, &portp->state)); | 1301 | !test_bit(ST_CLOSING, &portp->state)); |
1367 | if (signal_pending(current)) | 1302 | if (signal_pending(current)) |
1368 | rc = -ERESTARTSYS; | 1303 | rc = -ERESTARTSYS; |
1369 | restore_flags(flags); | ||
1370 | 1304 | ||
1371 | if ((rc == 0) && (portp->rc != 0)) | 1305 | if ((rc == 0) && (portp->rc != 0)) |
1372 | rc = -EIO; | 1306 | rc = -EIO; |
1373 | return(rc); | 1307 | return rc; |
1374 | } | 1308 | } |
1375 | 1309 | ||
1376 | /*****************************************************************************/ | 1310 | /*****************************************************************************/ |
@@ -1384,36 +1318,21 @@ static int stli_rawclose(stlibrd_t *brdp, stliport_t *portp, unsigned long arg, | |||
1384 | 1318 | ||
1385 | static int stli_cmdwait(stlibrd_t *brdp, stliport_t *portp, unsigned long cmd, void *arg, int size, int copyback) | 1319 | static int stli_cmdwait(stlibrd_t *brdp, stliport_t *portp, unsigned long cmd, void *arg, int size, int copyback) |
1386 | { | 1320 | { |
1387 | unsigned long flags; | ||
1388 | |||
1389 | #ifdef DEBUG | ||
1390 | printk("stli_cmdwait(brdp=%x,portp=%x,cmd=%x,arg=%x,size=%d," | ||
1391 | "copyback=%d)\n", (int) brdp, (int) portp, (int) cmd, | ||
1392 | (int) arg, size, copyback); | ||
1393 | #endif | ||
1394 | |||
1395 | save_flags(flags); | ||
1396 | cli(); | ||
1397 | wait_event_interruptible(portp->raw_wait, | 1321 | wait_event_interruptible(portp->raw_wait, |
1398 | !test_bit(ST_CMDING, &portp->state)); | 1322 | !test_bit(ST_CMDING, &portp->state)); |
1399 | if (signal_pending(current)) { | 1323 | if (signal_pending(current)) |
1400 | restore_flags(flags); | ||
1401 | return -ERESTARTSYS; | 1324 | return -ERESTARTSYS; |
1402 | } | ||
1403 | 1325 | ||
1404 | stli_sendcmd(brdp, portp, cmd, arg, size, copyback); | 1326 | stli_sendcmd(brdp, portp, cmd, arg, size, copyback); |
1405 | 1327 | ||
1406 | wait_event_interruptible(portp->raw_wait, | 1328 | wait_event_interruptible(portp->raw_wait, |
1407 | !test_bit(ST_CMDING, &portp->state)); | 1329 | !test_bit(ST_CMDING, &portp->state)); |
1408 | if (signal_pending(current)) { | 1330 | if (signal_pending(current)) |
1409 | restore_flags(flags); | ||
1410 | return -ERESTARTSYS; | 1331 | return -ERESTARTSYS; |
1411 | } | ||
1412 | restore_flags(flags); | ||
1413 | 1332 | ||
1414 | if (portp->rc != 0) | 1333 | if (portp->rc != 0) |
1415 | return(-EIO); | 1334 | return -EIO; |
1416 | return(0); | 1335 | return 0; |
1417 | } | 1336 | } |
1418 | 1337 | ||
1419 | /*****************************************************************************/ | 1338 | /*****************************************************************************/ |
@@ -1425,22 +1344,18 @@ static int stli_cmdwait(stlibrd_t *brdp, stliport_t *portp, unsigned long cmd, v | |||
1425 | 1344 | ||
1426 | static int stli_setport(stliport_t *portp) | 1345 | static int stli_setport(stliport_t *portp) |
1427 | { | 1346 | { |
1428 | stlibrd_t *brdp; | 1347 | stlibrd_t *brdp; |
1429 | asyport_t aport; | 1348 | asyport_t aport; |
1430 | |||
1431 | #ifdef DEBUG | ||
1432 | printk("stli_setport(portp=%x)\n", (int) portp); | ||
1433 | #endif | ||
1434 | 1349 | ||
1435 | if (portp == (stliport_t *) NULL) | 1350 | if (portp == NULL) |
1436 | return(-ENODEV); | 1351 | return -ENODEV; |
1437 | if (portp->tty == (struct tty_struct *) NULL) | 1352 | if (portp->tty == NULL) |
1438 | return(-ENODEV); | 1353 | return -ENODEV; |
1439 | if ((portp->brdnr < 0) && (portp->brdnr >= stli_nrbrds)) | 1354 | if (portp->brdnr < 0 && portp->brdnr >= stli_nrbrds) |
1440 | return(-ENODEV); | 1355 | return -ENODEV; |
1441 | brdp = stli_brds[portp->brdnr]; | 1356 | brdp = stli_brds[portp->brdnr]; |
1442 | if (brdp == (stlibrd_t *) NULL) | 1357 | if (brdp == NULL) |
1443 | return(-ENODEV); | 1358 | return -ENODEV; |
1444 | 1359 | ||
1445 | stli_mkasyport(portp, &aport, portp->tty->termios); | 1360 | stli_mkasyport(portp, &aport, portp->tty->termios); |
1446 | return(stli_cmdwait(brdp, portp, A_SETPORT, &aport, sizeof(asyport_t), 0)); | 1361 | return(stli_cmdwait(brdp, portp, A_SETPORT, &aport, sizeof(asyport_t), 0)); |
@@ -1455,13 +1370,8 @@ static int stli_setport(stliport_t *portp) | |||
1455 | 1370 | ||
1456 | static int stli_waitcarrier(stlibrd_t *brdp, stliport_t *portp, struct file *filp) | 1371 | static int stli_waitcarrier(stlibrd_t *brdp, stliport_t *portp, struct file *filp) |
1457 | { | 1372 | { |
1458 | unsigned long flags; | 1373 | unsigned long flags; |
1459 | int rc, doclocal; | 1374 | int rc, doclocal; |
1460 | |||
1461 | #ifdef DEBUG | ||
1462 | printk("stli_waitcarrier(brdp=%x,portp=%x,filp=%x)\n", | ||
1463 | (int) brdp, (int) portp, (int) filp); | ||
1464 | #endif | ||
1465 | 1375 | ||
1466 | rc = 0; | 1376 | rc = 0; |
1467 | doclocal = 0; | 1377 | doclocal = 0; |
@@ -1469,11 +1379,11 @@ static int stli_waitcarrier(stlibrd_t *brdp, stliport_t *portp, struct file *fil | |||
1469 | if (portp->tty->termios->c_cflag & CLOCAL) | 1379 | if (portp->tty->termios->c_cflag & CLOCAL) |
1470 | doclocal++; | 1380 | doclocal++; |
1471 | 1381 | ||
1472 | save_flags(flags); | 1382 | spin_lock_irqsave(&stli_lock, flags); |
1473 | cli(); | ||
1474 | portp->openwaitcnt++; | 1383 | portp->openwaitcnt++; |
1475 | if (! tty_hung_up_p(filp)) | 1384 | if (! tty_hung_up_p(filp)) |
1476 | portp->refcount--; | 1385 | portp->refcount--; |
1386 | spin_unlock_irqrestore(&stli_lock, flags); | ||
1477 | 1387 | ||
1478 | for (;;) { | 1388 | for (;;) { |
1479 | stli_mkasysigs(&portp->asig, 1, 1); | 1389 | stli_mkasysigs(&portp->asig, 1, 1); |
@@ -1499,12 +1409,13 @@ static int stli_waitcarrier(stlibrd_t *brdp, stliport_t *portp, struct file *fil | |||
1499 | interruptible_sleep_on(&portp->open_wait); | 1409 | interruptible_sleep_on(&portp->open_wait); |
1500 | } | 1410 | } |
1501 | 1411 | ||
1412 | spin_lock_irqsave(&stli_lock, flags); | ||
1502 | if (! tty_hung_up_p(filp)) | 1413 | if (! tty_hung_up_p(filp)) |
1503 | portp->refcount++; | 1414 | portp->refcount++; |
1504 | portp->openwaitcnt--; | 1415 | portp->openwaitcnt--; |
1505 | restore_flags(flags); | 1416 | spin_unlock_irqrestore(&stli_lock, flags); |
1506 | 1417 | ||
1507 | return(rc); | 1418 | return rc; |
1508 | } | 1419 | } |
1509 | 1420 | ||
1510 | /*****************************************************************************/ | 1421 | /*****************************************************************************/ |
@@ -1517,46 +1428,38 @@ static int stli_waitcarrier(stlibrd_t *brdp, stliport_t *portp, struct file *fil | |||
1517 | 1428 | ||
1518 | static int stli_write(struct tty_struct *tty, const unsigned char *buf, int count) | 1429 | static int stli_write(struct tty_struct *tty, const unsigned char *buf, int count) |
1519 | { | 1430 | { |
1520 | volatile cdkasy_t *ap; | 1431 | cdkasy_t __iomem *ap; |
1521 | volatile cdkhdr_t *hdrp; | 1432 | cdkhdr_t __iomem *hdrp; |
1522 | volatile unsigned char *bits; | 1433 | unsigned char __iomem *bits; |
1523 | unsigned char *shbuf, *chbuf; | 1434 | unsigned char __iomem *shbuf; |
1524 | stliport_t *portp; | 1435 | unsigned char *chbuf; |
1525 | stlibrd_t *brdp; | 1436 | stliport_t *portp; |
1526 | unsigned int len, stlen, head, tail, size; | 1437 | stlibrd_t *brdp; |
1527 | unsigned long flags; | 1438 | unsigned int len, stlen, head, tail, size; |
1528 | 1439 | unsigned long flags; | |
1529 | #ifdef DEBUG | ||
1530 | printk("stli_write(tty=%x,buf=%x,count=%d)\n", | ||
1531 | (int) tty, (int) buf, count); | ||
1532 | #endif | ||
1533 | 1440 | ||
1534 | if ((tty == (struct tty_struct *) NULL) || | ||
1535 | (stli_tmpwritebuf == (char *) NULL)) | ||
1536 | return(0); | ||
1537 | if (tty == stli_txcooktty) | 1441 | if (tty == stli_txcooktty) |
1538 | stli_flushchars(tty); | 1442 | stli_flushchars(tty); |
1539 | portp = tty->driver_data; | 1443 | portp = tty->driver_data; |
1540 | if (portp == (stliport_t *) NULL) | 1444 | if (portp == NULL) |
1541 | return(0); | 1445 | return 0; |
1542 | if ((portp->brdnr < 0) || (portp->brdnr >= stli_nrbrds)) | 1446 | if ((portp->brdnr < 0) || (portp->brdnr >= stli_nrbrds)) |
1543 | return(0); | 1447 | return 0; |
1544 | brdp = stli_brds[portp->brdnr]; | 1448 | brdp = stli_brds[portp->brdnr]; |
1545 | if (brdp == (stlibrd_t *) NULL) | 1449 | if (brdp == NULL) |
1546 | return(0); | 1450 | return 0; |
1547 | chbuf = (unsigned char *) buf; | 1451 | chbuf = (unsigned char *) buf; |
1548 | 1452 | ||
1549 | /* | 1453 | /* |
1550 | * All data is now local, shove as much as possible into shared memory. | 1454 | * All data is now local, shove as much as possible into shared memory. |
1551 | */ | 1455 | */ |
1552 | save_flags(flags); | 1456 | spin_lock_irqsave(&brd_lock, flags); |
1553 | cli(); | ||
1554 | EBRDENABLE(brdp); | 1457 | EBRDENABLE(brdp); |
1555 | ap = (volatile cdkasy_t *) EBRDGETMEMPTR(brdp, portp->addr); | 1458 | ap = (cdkasy_t __iomem *) EBRDGETMEMPTR(brdp, portp->addr); |
1556 | head = (unsigned int) ap->txq.head; | 1459 | head = (unsigned int) readw(&ap->txq.head); |
1557 | tail = (unsigned int) ap->txq.tail; | 1460 | tail = (unsigned int) readw(&ap->txq.tail); |
1558 | if (tail != ((unsigned int) ap->txq.tail)) | 1461 | if (tail != ((unsigned int) readw(&ap->txq.tail))) |
1559 | tail = (unsigned int) ap->txq.tail; | 1462 | tail = (unsigned int) readw(&ap->txq.tail); |
1560 | size = portp->txsize; | 1463 | size = portp->txsize; |
1561 | if (head >= tail) { | 1464 | if (head >= tail) { |
1562 | len = size - (head - tail) - 1; | 1465 | len = size - (head - tail) - 1; |
@@ -1568,11 +1471,11 @@ static int stli_write(struct tty_struct *tty, const unsigned char *buf, int coun | |||
1568 | 1471 | ||
1569 | len = MIN(len, count); | 1472 | len = MIN(len, count); |
1570 | count = 0; | 1473 | count = 0; |
1571 | shbuf = (char *) EBRDGETMEMPTR(brdp, portp->txoffset); | 1474 | shbuf = (char __iomem *) EBRDGETMEMPTR(brdp, portp->txoffset); |
1572 | 1475 | ||
1573 | while (len > 0) { | 1476 | while (len > 0) { |
1574 | stlen = MIN(len, stlen); | 1477 | stlen = MIN(len, stlen); |
1575 | memcpy((shbuf + head), chbuf, stlen); | 1478 | memcpy_toio(shbuf + head, chbuf, stlen); |
1576 | chbuf += stlen; | 1479 | chbuf += stlen; |
1577 | len -= stlen; | 1480 | len -= stlen; |
1578 | count += stlen; | 1481 | count += stlen; |
@@ -1583,20 +1486,19 @@ static int stli_write(struct tty_struct *tty, const unsigned char *buf, int coun | |||
1583 | } | 1486 | } |
1584 | } | 1487 | } |
1585 | 1488 | ||
1586 | ap = (volatile cdkasy_t *) EBRDGETMEMPTR(brdp, portp->addr); | 1489 | ap = (cdkasy_t __iomem *) EBRDGETMEMPTR(brdp, portp->addr); |
1587 | ap->txq.head = head; | 1490 | writew(head, &ap->txq.head); |
1588 | if (test_bit(ST_TXBUSY, &portp->state)) { | 1491 | if (test_bit(ST_TXBUSY, &portp->state)) { |
1589 | if (ap->changed.data & DT_TXEMPTY) | 1492 | if (readl(&ap->changed.data) & DT_TXEMPTY) |
1590 | ap->changed.data &= ~DT_TXEMPTY; | 1493 | writel(readl(&ap->changed.data) & ~DT_TXEMPTY, &ap->changed.data); |
1591 | } | 1494 | } |
1592 | hdrp = (volatile cdkhdr_t *) EBRDGETMEMPTR(brdp, CDK_CDKADDR); | 1495 | hdrp = (cdkhdr_t __iomem *) EBRDGETMEMPTR(brdp, CDK_CDKADDR); |
1593 | bits = ((volatile unsigned char *) hdrp) + brdp->slaveoffset + | 1496 | bits = ((unsigned char __iomem *) hdrp) + brdp->slaveoffset + |
1594 | portp->portidx; | 1497 | portp->portidx; |
1595 | *bits |= portp->portbit; | 1498 | writeb(readb(bits) | portp->portbit, bits); |
1596 | set_bit(ST_TXBUSY, &portp->state); | 1499 | set_bit(ST_TXBUSY, &portp->state); |
1597 | EBRDDISABLE(brdp); | 1500 | EBRDDISABLE(brdp); |
1598 | 1501 | spin_unlock_irqrestore(&brd_lock, flags); | |
1599 | restore_flags(flags); | ||
1600 | 1502 | ||
1601 | return(count); | 1503 | return(count); |
1602 | } | 1504 | } |
@@ -1613,14 +1515,8 @@ static int stli_write(struct tty_struct *tty, const unsigned char *buf, int coun | |||
1613 | 1515 | ||
1614 | static void stli_putchar(struct tty_struct *tty, unsigned char ch) | 1516 | static void stli_putchar(struct tty_struct *tty, unsigned char ch) |
1615 | { | 1517 | { |
1616 | #ifdef DEBUG | ||
1617 | printk("stli_putchar(tty=%x,ch=%x)\n", (int) tty, (int) ch); | ||
1618 | #endif | ||
1619 | |||
1620 | if (tty == (struct tty_struct *) NULL) | ||
1621 | return; | ||
1622 | if (tty != stli_txcooktty) { | 1518 | if (tty != stli_txcooktty) { |
1623 | if (stli_txcooktty != (struct tty_struct *) NULL) | 1519 | if (stli_txcooktty != NULL) |
1624 | stli_flushchars(stli_txcooktty); | 1520 | stli_flushchars(stli_txcooktty); |
1625 | stli_txcooktty = tty; | 1521 | stli_txcooktty = tty; |
1626 | } | 1522 | } |
@@ -1640,29 +1536,26 @@ static void stli_putchar(struct tty_struct *tty, unsigned char ch) | |||
1640 | 1536 | ||
1641 | static void stli_flushchars(struct tty_struct *tty) | 1537 | static void stli_flushchars(struct tty_struct *tty) |
1642 | { | 1538 | { |
1643 | volatile cdkhdr_t *hdrp; | 1539 | cdkhdr_t __iomem *hdrp; |
1644 | volatile unsigned char *bits; | 1540 | unsigned char __iomem *bits; |
1645 | volatile cdkasy_t *ap; | 1541 | cdkasy_t __iomem *ap; |
1646 | struct tty_struct *cooktty; | 1542 | struct tty_struct *cooktty; |
1647 | stliport_t *portp; | 1543 | stliport_t *portp; |
1648 | stlibrd_t *brdp; | 1544 | stlibrd_t *brdp; |
1649 | unsigned int len, stlen, head, tail, size, count, cooksize; | 1545 | unsigned int len, stlen, head, tail, size, count, cooksize; |
1650 | unsigned char *buf, *shbuf; | 1546 | unsigned char *buf; |
1651 | unsigned long flags; | 1547 | unsigned char __iomem *shbuf; |
1652 | 1548 | unsigned long flags; | |
1653 | #ifdef DEBUG | ||
1654 | printk("stli_flushchars(tty=%x)\n", (int) tty); | ||
1655 | #endif | ||
1656 | 1549 | ||
1657 | cooksize = stli_txcooksize; | 1550 | cooksize = stli_txcooksize; |
1658 | cooktty = stli_txcooktty; | 1551 | cooktty = stli_txcooktty; |
1659 | stli_txcooksize = 0; | 1552 | stli_txcooksize = 0; |
1660 | stli_txcookrealsize = 0; | 1553 | stli_txcookrealsize = 0; |
1661 | stli_txcooktty = (struct tty_struct *) NULL; | 1554 | stli_txcooktty = NULL; |
1662 | 1555 | ||
1663 | if (tty == (struct tty_struct *) NULL) | 1556 | if (tty == NULL) |
1664 | return; | 1557 | return; |
1665 | if (cooktty == (struct tty_struct *) NULL) | 1558 | if (cooktty == NULL) |
1666 | return; | 1559 | return; |
1667 | if (tty != cooktty) | 1560 | if (tty != cooktty) |
1668 | tty = cooktty; | 1561 | tty = cooktty; |
@@ -1670,23 +1563,22 @@ static void stli_flushchars(struct tty_struct *tty) | |||
1670 | return; | 1563 | return; |
1671 | 1564 | ||
1672 | portp = tty->driver_data; | 1565 | portp = tty->driver_data; |
1673 | if (portp == (stliport_t *) NULL) | 1566 | if (portp == NULL) |
1674 | return; | 1567 | return; |
1675 | if ((portp->brdnr < 0) || (portp->brdnr >= stli_nrbrds)) | 1568 | if ((portp->brdnr < 0) || (portp->brdnr >= stli_nrbrds)) |
1676 | return; | 1569 | return; |
1677 | brdp = stli_brds[portp->brdnr]; | 1570 | brdp = stli_brds[portp->brdnr]; |
1678 | if (brdp == (stlibrd_t *) NULL) | 1571 | if (brdp == NULL) |
1679 | return; | 1572 | return; |
1680 | 1573 | ||
1681 | save_flags(flags); | 1574 | spin_lock_irqsave(&brd_lock, flags); |
1682 | cli(); | ||
1683 | EBRDENABLE(brdp); | 1575 | EBRDENABLE(brdp); |
1684 | 1576 | ||
1685 | ap = (volatile cdkasy_t *) EBRDGETMEMPTR(brdp, portp->addr); | 1577 | ap = (cdkasy_t __iomem *) EBRDGETMEMPTR(brdp, portp->addr); |
1686 | head = (unsigned int) ap->txq.head; | 1578 | head = (unsigned int) readw(&ap->txq.head); |
1687 | tail = (unsigned int) ap->txq.tail; | 1579 | tail = (unsigned int) readw(&ap->txq.tail); |
1688 | if (tail != ((unsigned int) ap->txq.tail)) | 1580 | if (tail != ((unsigned int) readw(&ap->txq.tail))) |
1689 | tail = (unsigned int) ap->txq.tail; | 1581 | tail = (unsigned int) readw(&ap->txq.tail); |
1690 | size = portp->txsize; | 1582 | size = portp->txsize; |
1691 | if (head >= tail) { | 1583 | if (head >= tail) { |
1692 | len = size - (head - tail) - 1; | 1584 | len = size - (head - tail) - 1; |
@@ -1703,7 +1595,7 @@ static void stli_flushchars(struct tty_struct *tty) | |||
1703 | 1595 | ||
1704 | while (len > 0) { | 1596 | while (len > 0) { |
1705 | stlen = MIN(len, stlen); | 1597 | stlen = MIN(len, stlen); |
1706 | memcpy((shbuf + head), buf, stlen); | 1598 | memcpy_toio(shbuf + head, buf, stlen); |
1707 | buf += stlen; | 1599 | buf += stlen; |
1708 | len -= stlen; | 1600 | len -= stlen; |
1709 | count += stlen; | 1601 | count += stlen; |
@@ -1714,73 +1606,66 @@ static void stli_flushchars(struct tty_struct *tty) | |||
1714 | } | 1606 | } |
1715 | } | 1607 | } |
1716 | 1608 | ||
1717 | ap = (volatile cdkasy_t *) EBRDGETMEMPTR(brdp, portp->addr); | 1609 | ap = (cdkasy_t __iomem *) EBRDGETMEMPTR(brdp, portp->addr); |
1718 | ap->txq.head = head; | 1610 | writew(head, &ap->txq.head); |
1719 | 1611 | ||
1720 | if (test_bit(ST_TXBUSY, &portp->state)) { | 1612 | if (test_bit(ST_TXBUSY, &portp->state)) { |
1721 | if (ap->changed.data & DT_TXEMPTY) | 1613 | if (readl(&ap->changed.data) & DT_TXEMPTY) |
1722 | ap->changed.data &= ~DT_TXEMPTY; | 1614 | writel(readl(&ap->changed.data) & ~DT_TXEMPTY, &ap->changed.data); |
1723 | } | 1615 | } |
1724 | hdrp = (volatile cdkhdr_t *) EBRDGETMEMPTR(brdp, CDK_CDKADDR); | 1616 | hdrp = (cdkhdr_t __iomem *) EBRDGETMEMPTR(brdp, CDK_CDKADDR); |
1725 | bits = ((volatile unsigned char *) hdrp) + brdp->slaveoffset + | 1617 | bits = ((unsigned char __iomem *) hdrp) + brdp->slaveoffset + |
1726 | portp->portidx; | 1618 | portp->portidx; |
1727 | *bits |= portp->portbit; | 1619 | writeb(readb(bits) | portp->portbit, bits); |
1728 | set_bit(ST_TXBUSY, &portp->state); | 1620 | set_bit(ST_TXBUSY, &portp->state); |
1729 | 1621 | ||
1730 | EBRDDISABLE(brdp); | 1622 | EBRDDISABLE(brdp); |
1731 | restore_flags(flags); | 1623 | spin_unlock_irqrestore(&brd_lock, flags); |
1732 | } | 1624 | } |
1733 | 1625 | ||
1734 | /*****************************************************************************/ | 1626 | /*****************************************************************************/ |
1735 | 1627 | ||
1736 | static int stli_writeroom(struct tty_struct *tty) | 1628 | static int stli_writeroom(struct tty_struct *tty) |
1737 | { | 1629 | { |
1738 | volatile cdkasyrq_t *rp; | 1630 | cdkasyrq_t __iomem *rp; |
1739 | stliport_t *portp; | 1631 | stliport_t *portp; |
1740 | stlibrd_t *brdp; | 1632 | stlibrd_t *brdp; |
1741 | unsigned int head, tail, len; | 1633 | unsigned int head, tail, len; |
1742 | unsigned long flags; | 1634 | unsigned long flags; |
1743 | |||
1744 | #ifdef DEBUG | ||
1745 | printk("stli_writeroom(tty=%x)\n", (int) tty); | ||
1746 | #endif | ||
1747 | 1635 | ||
1748 | if (tty == (struct tty_struct *) NULL) | ||
1749 | return(0); | ||
1750 | if (tty == stli_txcooktty) { | 1636 | if (tty == stli_txcooktty) { |
1751 | if (stli_txcookrealsize != 0) { | 1637 | if (stli_txcookrealsize != 0) { |
1752 | len = stli_txcookrealsize - stli_txcooksize; | 1638 | len = stli_txcookrealsize - stli_txcooksize; |
1753 | return(len); | 1639 | return len; |
1754 | } | 1640 | } |
1755 | } | 1641 | } |
1756 | 1642 | ||
1757 | portp = tty->driver_data; | 1643 | portp = tty->driver_data; |
1758 | if (portp == (stliport_t *) NULL) | 1644 | if (portp == NULL) |
1759 | return(0); | 1645 | return 0; |
1760 | if ((portp->brdnr < 0) || (portp->brdnr >= stli_nrbrds)) | 1646 | if ((portp->brdnr < 0) || (portp->brdnr >= stli_nrbrds)) |
1761 | return(0); | 1647 | return 0; |
1762 | brdp = stli_brds[portp->brdnr]; | 1648 | brdp = stli_brds[portp->brdnr]; |
1763 | if (brdp == (stlibrd_t *) NULL) | 1649 | if (brdp == NULL) |
1764 | return(0); | 1650 | return 0; |
1765 | 1651 | ||
1766 | save_flags(flags); | 1652 | spin_lock_irqsave(&brd_lock, flags); |
1767 | cli(); | ||
1768 | EBRDENABLE(brdp); | 1653 | EBRDENABLE(brdp); |
1769 | rp = &((volatile cdkasy_t *) EBRDGETMEMPTR(brdp, portp->addr))->txq; | 1654 | rp = &((cdkasy_t __iomem *) EBRDGETMEMPTR(brdp, portp->addr))->txq; |
1770 | head = (unsigned int) rp->head; | 1655 | head = (unsigned int) readw(&rp->head); |
1771 | tail = (unsigned int) rp->tail; | 1656 | tail = (unsigned int) readw(&rp->tail); |
1772 | if (tail != ((unsigned int) rp->tail)) | 1657 | if (tail != ((unsigned int) readw(&rp->tail))) |
1773 | tail = (unsigned int) rp->tail; | 1658 | tail = (unsigned int) readw(&rp->tail); |
1774 | len = (head >= tail) ? (portp->txsize - (head - tail)) : (tail - head); | 1659 | len = (head >= tail) ? (portp->txsize - (head - tail)) : (tail - head); |
1775 | len--; | 1660 | len--; |
1776 | EBRDDISABLE(brdp); | 1661 | EBRDDISABLE(brdp); |
1777 | restore_flags(flags); | 1662 | spin_unlock_irqrestore(&brd_lock, flags); |
1778 | 1663 | ||
1779 | if (tty == stli_txcooktty) { | 1664 | if (tty == stli_txcooktty) { |
1780 | stli_txcookrealsize = len; | 1665 | stli_txcookrealsize = len; |
1781 | len -= stli_txcooksize; | 1666 | len -= stli_txcooksize; |
1782 | } | 1667 | } |
1783 | return(len); | 1668 | return len; |
1784 | } | 1669 | } |
1785 | 1670 | ||
1786 | /*****************************************************************************/ | 1671 | /*****************************************************************************/ |
@@ -1795,44 +1680,37 @@ static int stli_writeroom(struct tty_struct *tty) | |||
1795 | 1680 | ||
1796 | static int stli_charsinbuffer(struct tty_struct *tty) | 1681 | static int stli_charsinbuffer(struct tty_struct *tty) |
1797 | { | 1682 | { |
1798 | volatile cdkasyrq_t *rp; | 1683 | cdkasyrq_t __iomem *rp; |
1799 | stliport_t *portp; | 1684 | stliport_t *portp; |
1800 | stlibrd_t *brdp; | 1685 | stlibrd_t *brdp; |
1801 | unsigned int head, tail, len; | 1686 | unsigned int head, tail, len; |
1802 | unsigned long flags; | 1687 | unsigned long flags; |
1803 | |||
1804 | #ifdef DEBUG | ||
1805 | printk("stli_charsinbuffer(tty=%x)\n", (int) tty); | ||
1806 | #endif | ||
1807 | 1688 | ||
1808 | if (tty == (struct tty_struct *) NULL) | ||
1809 | return(0); | ||
1810 | if (tty == stli_txcooktty) | 1689 | if (tty == stli_txcooktty) |
1811 | stli_flushchars(tty); | 1690 | stli_flushchars(tty); |
1812 | portp = tty->driver_data; | 1691 | portp = tty->driver_data; |
1813 | if (portp == (stliport_t *) NULL) | 1692 | if (portp == NULL) |
1814 | return(0); | 1693 | return 0; |
1815 | if ((portp->brdnr < 0) || (portp->brdnr >= stli_nrbrds)) | 1694 | if ((portp->brdnr < 0) || (portp->brdnr >= stli_nrbrds)) |
1816 | return(0); | 1695 | return 0; |
1817 | brdp = stli_brds[portp->brdnr]; | 1696 | brdp = stli_brds[portp->brdnr]; |
1818 | if (brdp == (stlibrd_t *) NULL) | 1697 | if (brdp == NULL) |
1819 | return(0); | 1698 | return 0; |
1820 | 1699 | ||
1821 | save_flags(flags); | 1700 | spin_lock_irqsave(&brd_lock, flags); |
1822 | cli(); | ||
1823 | EBRDENABLE(brdp); | 1701 | EBRDENABLE(brdp); |
1824 | rp = &((volatile cdkasy_t *) EBRDGETMEMPTR(brdp, portp->addr))->txq; | 1702 | rp = &((cdkasy_t __iomem *) EBRDGETMEMPTR(brdp, portp->addr))->txq; |
1825 | head = (unsigned int) rp->head; | 1703 | head = (unsigned int) readw(&rp->head); |
1826 | tail = (unsigned int) rp->tail; | 1704 | tail = (unsigned int) readw(&rp->tail); |
1827 | if (tail != ((unsigned int) rp->tail)) | 1705 | if (tail != ((unsigned int) readw(&rp->tail))) |
1828 | tail = (unsigned int) rp->tail; | 1706 | tail = (unsigned int) readw(&rp->tail); |
1829 | len = (head >= tail) ? (head - tail) : (portp->txsize - (tail - head)); | 1707 | len = (head >= tail) ? (head - tail) : (portp->txsize - (tail - head)); |
1830 | if ((len == 0) && test_bit(ST_TXBUSY, &portp->state)) | 1708 | if ((len == 0) && test_bit(ST_TXBUSY, &portp->state)) |
1831 | len = 1; | 1709 | len = 1; |
1832 | EBRDDISABLE(brdp); | 1710 | EBRDDISABLE(brdp); |
1833 | restore_flags(flags); | 1711 | spin_unlock_irqrestore(&brd_lock, flags); |
1834 | 1712 | ||
1835 | return(len); | 1713 | return len; |
1836 | } | 1714 | } |
1837 | 1715 | ||
1838 | /*****************************************************************************/ | 1716 | /*****************************************************************************/ |
@@ -1843,12 +1721,8 @@ static int stli_charsinbuffer(struct tty_struct *tty) | |||
1843 | 1721 | ||
1844 | static int stli_getserial(stliport_t *portp, struct serial_struct __user *sp) | 1722 | static int stli_getserial(stliport_t *portp, struct serial_struct __user *sp) |
1845 | { | 1723 | { |
1846 | struct serial_struct sio; | 1724 | struct serial_struct sio; |
1847 | stlibrd_t *brdp; | 1725 | stlibrd_t *brdp; |
1848 | |||
1849 | #ifdef DEBUG | ||
1850 | printk("stli_getserial(portp=%x,sp=%x)\n", (int) portp, (int) sp); | ||
1851 | #endif | ||
1852 | 1726 | ||
1853 | memset(&sio, 0, sizeof(struct serial_struct)); | 1727 | memset(&sio, 0, sizeof(struct serial_struct)); |
1854 | sio.type = PORT_UNKNOWN; | 1728 | sio.type = PORT_UNKNOWN; |
@@ -1863,7 +1737,7 @@ static int stli_getserial(stliport_t *portp, struct serial_struct __user *sp) | |||
1863 | sio.hub6 = 0; | 1737 | sio.hub6 = 0; |
1864 | 1738 | ||
1865 | brdp = stli_brds[portp->brdnr]; | 1739 | brdp = stli_brds[portp->brdnr]; |
1866 | if (brdp != (stlibrd_t *) NULL) | 1740 | if (brdp != NULL) |
1867 | sio.port = brdp->iobase; | 1741 | sio.port = brdp->iobase; |
1868 | 1742 | ||
1869 | return copy_to_user(sp, &sio, sizeof(struct serial_struct)) ? | 1743 | return copy_to_user(sp, &sio, sizeof(struct serial_struct)) ? |
@@ -1880,12 +1754,8 @@ static int stli_getserial(stliport_t *portp, struct serial_struct __user *sp) | |||
1880 | 1754 | ||
1881 | static int stli_setserial(stliport_t *portp, struct serial_struct __user *sp) | 1755 | static int stli_setserial(stliport_t *portp, struct serial_struct __user *sp) |
1882 | { | 1756 | { |
1883 | struct serial_struct sio; | 1757 | struct serial_struct sio; |
1884 | int rc; | 1758 | int rc; |
1885 | |||
1886 | #ifdef DEBUG | ||
1887 | printk("stli_setserial(portp=%p,sp=%p)\n", portp, sp); | ||
1888 | #endif | ||
1889 | 1759 | ||
1890 | if (copy_from_user(&sio, sp, sizeof(struct serial_struct))) | 1760 | if (copy_from_user(&sio, sp, sizeof(struct serial_struct))) |
1891 | return -EFAULT; | 1761 | return -EFAULT; |
@@ -1894,7 +1764,7 @@ static int stli_setserial(stliport_t *portp, struct serial_struct __user *sp) | |||
1894 | (sio.close_delay != portp->close_delay) || | 1764 | (sio.close_delay != portp->close_delay) || |
1895 | ((sio.flags & ~ASYNC_USR_MASK) != | 1765 | ((sio.flags & ~ASYNC_USR_MASK) != |
1896 | (portp->flags & ~ASYNC_USR_MASK))) | 1766 | (portp->flags & ~ASYNC_USR_MASK))) |
1897 | return(-EPERM); | 1767 | return -EPERM; |
1898 | } | 1768 | } |
1899 | 1769 | ||
1900 | portp->flags = (portp->flags & ~ASYNC_USR_MASK) | | 1770 | portp->flags = (portp->flags & ~ASYNC_USR_MASK) | |
@@ -1905,8 +1775,8 @@ static int stli_setserial(stliport_t *portp, struct serial_struct __user *sp) | |||
1905 | portp->custom_divisor = sio.custom_divisor; | 1775 | portp->custom_divisor = sio.custom_divisor; |
1906 | 1776 | ||
1907 | if ((rc = stli_setport(portp)) < 0) | 1777 | if ((rc = stli_setport(portp)) < 0) |
1908 | return(rc); | 1778 | return rc; |
1909 | return(0); | 1779 | return 0; |
1910 | } | 1780 | } |
1911 | 1781 | ||
1912 | /*****************************************************************************/ | 1782 | /*****************************************************************************/ |
@@ -1917,19 +1787,19 @@ static int stli_tiocmget(struct tty_struct *tty, struct file *file) | |||
1917 | stlibrd_t *brdp; | 1787 | stlibrd_t *brdp; |
1918 | int rc; | 1788 | int rc; |
1919 | 1789 | ||
1920 | if (portp == (stliport_t *) NULL) | 1790 | if (portp == NULL) |
1921 | return(-ENODEV); | 1791 | return -ENODEV; |
1922 | if ((portp->brdnr < 0) || (portp->brdnr >= stli_nrbrds)) | 1792 | if (portp->brdnr < 0 || portp->brdnr >= stli_nrbrds) |
1923 | return(0); | 1793 | return 0; |
1924 | brdp = stli_brds[portp->brdnr]; | 1794 | brdp = stli_brds[portp->brdnr]; |
1925 | if (brdp == (stlibrd_t *) NULL) | 1795 | if (brdp == NULL) |
1926 | return(0); | 1796 | return 0; |
1927 | if (tty->flags & (1 << TTY_IO_ERROR)) | 1797 | if (tty->flags & (1 << TTY_IO_ERROR)) |
1928 | return(-EIO); | 1798 | return -EIO; |
1929 | 1799 | ||
1930 | if ((rc = stli_cmdwait(brdp, portp, A_GETSIGNALS, | 1800 | if ((rc = stli_cmdwait(brdp, portp, A_GETSIGNALS, |
1931 | &portp->asig, sizeof(asysigs_t), 1)) < 0) | 1801 | &portp->asig, sizeof(asysigs_t), 1)) < 0) |
1932 | return(rc); | 1802 | return rc; |
1933 | 1803 | ||
1934 | return stli_mktiocm(portp->asig.sigvalue); | 1804 | return stli_mktiocm(portp->asig.sigvalue); |
1935 | } | 1805 | } |
@@ -1941,15 +1811,15 @@ static int stli_tiocmset(struct tty_struct *tty, struct file *file, | |||
1941 | stlibrd_t *brdp; | 1811 | stlibrd_t *brdp; |
1942 | int rts = -1, dtr = -1; | 1812 | int rts = -1, dtr = -1; |
1943 | 1813 | ||
1944 | if (portp == (stliport_t *) NULL) | 1814 | if (portp == NULL) |
1945 | return(-ENODEV); | 1815 | return -ENODEV; |
1946 | if ((portp->brdnr < 0) || (portp->brdnr >= stli_nrbrds)) | 1816 | if (portp->brdnr < 0 || portp->brdnr >= stli_nrbrds) |
1947 | return(0); | 1817 | return 0; |
1948 | brdp = stli_brds[portp->brdnr]; | 1818 | brdp = stli_brds[portp->brdnr]; |
1949 | if (brdp == (stlibrd_t *) NULL) | 1819 | if (brdp == NULL) |
1950 | return(0); | 1820 | return 0; |
1951 | if (tty->flags & (1 << TTY_IO_ERROR)) | 1821 | if (tty->flags & (1 << TTY_IO_ERROR)) |
1952 | return(-EIO); | 1822 | return -EIO; |
1953 | 1823 | ||
1954 | if (set & TIOCM_RTS) | 1824 | if (set & TIOCM_RTS) |
1955 | rts = 1; | 1825 | rts = 1; |
@@ -1968,32 +1838,25 @@ static int stli_tiocmset(struct tty_struct *tty, struct file *file, | |||
1968 | 1838 | ||
1969 | static int stli_ioctl(struct tty_struct *tty, struct file *file, unsigned int cmd, unsigned long arg) | 1839 | static int stli_ioctl(struct tty_struct *tty, struct file *file, unsigned int cmd, unsigned long arg) |
1970 | { | 1840 | { |
1971 | stliport_t *portp; | 1841 | stliport_t *portp; |
1972 | stlibrd_t *brdp; | 1842 | stlibrd_t *brdp; |
1973 | unsigned int ival; | 1843 | unsigned int ival; |
1974 | int rc; | 1844 | int rc; |
1975 | void __user *argp = (void __user *)arg; | 1845 | void __user *argp = (void __user *)arg; |
1976 | 1846 | ||
1977 | #ifdef DEBUG | ||
1978 | printk("stli_ioctl(tty=%x,file=%x,cmd=%x,arg=%x)\n", | ||
1979 | (int) tty, (int) file, cmd, (int) arg); | ||
1980 | #endif | ||
1981 | |||
1982 | if (tty == (struct tty_struct *) NULL) | ||
1983 | return(-ENODEV); | ||
1984 | portp = tty->driver_data; | 1847 | portp = tty->driver_data; |
1985 | if (portp == (stliport_t *) NULL) | 1848 | if (portp == NULL) |
1986 | return(-ENODEV); | 1849 | return -ENODEV; |
1987 | if ((portp->brdnr < 0) || (portp->brdnr >= stli_nrbrds)) | 1850 | if (portp->brdnr < 0 || portp->brdnr >= stli_nrbrds) |
1988 | return(0); | 1851 | return 0; |
1989 | brdp = stli_brds[portp->brdnr]; | 1852 | brdp = stli_brds[portp->brdnr]; |
1990 | if (brdp == (stlibrd_t *) NULL) | 1853 | if (brdp == NULL) |
1991 | return(0); | 1854 | return 0; |
1992 | 1855 | ||
1993 | if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) && | 1856 | if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) && |
1994 | (cmd != COM_GETPORTSTATS) && (cmd != COM_CLRPORTSTATS)) { | 1857 | (cmd != COM_GETPORTSTATS) && (cmd != COM_CLRPORTSTATS)) { |
1995 | if (tty->flags & (1 << TTY_IO_ERROR)) | 1858 | if (tty->flags & (1 << TTY_IO_ERROR)) |
1996 | return(-EIO); | 1859 | return -EIO; |
1997 | } | 1860 | } |
1998 | 1861 | ||
1999 | rc = 0; | 1862 | rc = 0; |
@@ -2040,7 +1903,7 @@ static int stli_ioctl(struct tty_struct *tty, struct file *file, unsigned int cm | |||
2040 | break; | 1903 | break; |
2041 | } | 1904 | } |
2042 | 1905 | ||
2043 | return(rc); | 1906 | return rc; |
2044 | } | 1907 | } |
2045 | 1908 | ||
2046 | /*****************************************************************************/ | 1909 | /*****************************************************************************/ |
@@ -2052,24 +1915,20 @@ static int stli_ioctl(struct tty_struct *tty, struct file *file, unsigned int cm | |||
2052 | 1915 | ||
2053 | static void stli_settermios(struct tty_struct *tty, struct termios *old) | 1916 | static void stli_settermios(struct tty_struct *tty, struct termios *old) |
2054 | { | 1917 | { |
2055 | stliport_t *portp; | 1918 | stliport_t *portp; |
2056 | stlibrd_t *brdp; | 1919 | stlibrd_t *brdp; |
2057 | struct termios *tiosp; | 1920 | struct termios *tiosp; |
2058 | asyport_t aport; | 1921 | asyport_t aport; |
2059 | |||
2060 | #ifdef DEBUG | ||
2061 | printk("stli_settermios(tty=%x,old=%x)\n", (int) tty, (int) old); | ||
2062 | #endif | ||
2063 | 1922 | ||
2064 | if (tty == (struct tty_struct *) NULL) | 1923 | if (tty == NULL) |
2065 | return; | 1924 | return; |
2066 | portp = tty->driver_data; | 1925 | portp = tty->driver_data; |
2067 | if (portp == (stliport_t *) NULL) | 1926 | if (portp == NULL) |
2068 | return; | 1927 | return; |
2069 | if ((portp->brdnr < 0) || (portp->brdnr >= stli_nrbrds)) | 1928 | if (portp->brdnr < 0 || portp->brdnr >= stli_nrbrds) |
2070 | return; | 1929 | return; |
2071 | brdp = stli_brds[portp->brdnr]; | 1930 | brdp = stli_brds[portp->brdnr]; |
2072 | if (brdp == (stlibrd_t *) NULL) | 1931 | if (brdp == NULL) |
2073 | return; | 1932 | return; |
2074 | 1933 | ||
2075 | tiosp = tty->termios; | 1934 | tiosp = tty->termios; |
@@ -2102,18 +1961,9 @@ static void stli_settermios(struct tty_struct *tty, struct termios *old) | |||
2102 | 1961 | ||
2103 | static void stli_throttle(struct tty_struct *tty) | 1962 | static void stli_throttle(struct tty_struct *tty) |
2104 | { | 1963 | { |
2105 | stliport_t *portp; | 1964 | stliport_t *portp = tty->driver_data; |
2106 | 1965 | if (portp == NULL) | |
2107 | #ifdef DEBUG | ||
2108 | printk("stli_throttle(tty=%x)\n", (int) tty); | ||
2109 | #endif | ||
2110 | |||
2111 | if (tty == (struct tty_struct *) NULL) | ||
2112 | return; | 1966 | return; |
2113 | portp = tty->driver_data; | ||
2114 | if (portp == (stliport_t *) NULL) | ||
2115 | return; | ||
2116 | |||
2117 | set_bit(ST_RXSTOP, &portp->state); | 1967 | set_bit(ST_RXSTOP, &portp->state); |
2118 | } | 1968 | } |
2119 | 1969 | ||
@@ -2127,88 +1977,30 @@ static void stli_throttle(struct tty_struct *tty) | |||
2127 | 1977 | ||
2128 | static void stli_unthrottle(struct tty_struct *tty) | 1978 | static void stli_unthrottle(struct tty_struct *tty) |
2129 | { | 1979 | { |
2130 | stliport_t *portp; | 1980 | stliport_t *portp = tty->driver_data; |
2131 | 1981 | if (portp == NULL) | |
2132 | #ifdef DEBUG | ||
2133 | printk("stli_unthrottle(tty=%x)\n", (int) tty); | ||
2134 | #endif | ||
2135 | |||
2136 | if (tty == (struct tty_struct *) NULL) | ||
2137 | return; | ||
2138 | portp = tty->driver_data; | ||
2139 | if (portp == (stliport_t *) NULL) | ||
2140 | return; | 1982 | return; |
2141 | |||
2142 | clear_bit(ST_RXSTOP, &portp->state); | 1983 | clear_bit(ST_RXSTOP, &portp->state); |
2143 | } | 1984 | } |
2144 | 1985 | ||
2145 | /*****************************************************************************/ | 1986 | /*****************************************************************************/ |
2146 | 1987 | ||
2147 | /* | 1988 | /* |
2148 | * Stop the transmitter. Basically to do this we will just turn TX | 1989 | * Stop the transmitter. |
2149 | * interrupts off. | ||
2150 | */ | 1990 | */ |
2151 | 1991 | ||
2152 | static void stli_stop(struct tty_struct *tty) | 1992 | static void stli_stop(struct tty_struct *tty) |
2153 | { | 1993 | { |
2154 | stlibrd_t *brdp; | ||
2155 | stliport_t *portp; | ||
2156 | asyctrl_t actrl; | ||
2157 | |||
2158 | #ifdef DEBUG | ||
2159 | printk("stli_stop(tty=%x)\n", (int) tty); | ||
2160 | #endif | ||
2161 | |||
2162 | if (tty == (struct tty_struct *) NULL) | ||
2163 | return; | ||
2164 | portp = tty->driver_data; | ||
2165 | if (portp == (stliport_t *) NULL) | ||
2166 | return; | ||
2167 | if ((portp->brdnr < 0) || (portp->brdnr >= stli_nrbrds)) | ||
2168 | return; | ||
2169 | brdp = stli_brds[portp->brdnr]; | ||
2170 | if (brdp == (stlibrd_t *) NULL) | ||
2171 | return; | ||
2172 | |||
2173 | memset(&actrl, 0, sizeof(asyctrl_t)); | ||
2174 | actrl.txctrl = CT_STOPFLOW; | ||
2175 | #if 0 | ||
2176 | stli_cmdwait(brdp, portp, A_PORTCTRL, &actrl, sizeof(asyctrl_t), 0); | ||
2177 | #endif | ||
2178 | } | 1994 | } |
2179 | 1995 | ||
2180 | /*****************************************************************************/ | 1996 | /*****************************************************************************/ |
2181 | 1997 | ||
2182 | /* | 1998 | /* |
2183 | * Start the transmitter again. Just turn TX interrupts back on. | 1999 | * Start the transmitter again. |
2184 | */ | 2000 | */ |
2185 | 2001 | ||
2186 | static void stli_start(struct tty_struct *tty) | 2002 | static void stli_start(struct tty_struct *tty) |
2187 | { | 2003 | { |
2188 | stliport_t *portp; | ||
2189 | stlibrd_t *brdp; | ||
2190 | asyctrl_t actrl; | ||
2191 | |||
2192 | #ifdef DEBUG | ||
2193 | printk("stli_start(tty=%x)\n", (int) tty); | ||
2194 | #endif | ||
2195 | |||
2196 | if (tty == (struct tty_struct *) NULL) | ||
2197 | return; | ||
2198 | portp = tty->driver_data; | ||
2199 | if (portp == (stliport_t *) NULL) | ||
2200 | return; | ||
2201 | if ((portp->brdnr < 0) || (portp->brdnr >= stli_nrbrds)) | ||
2202 | return; | ||
2203 | brdp = stli_brds[portp->brdnr]; | ||
2204 | if (brdp == (stlibrd_t *) NULL) | ||
2205 | return; | ||
2206 | |||
2207 | memset(&actrl, 0, sizeof(asyctrl_t)); | ||
2208 | actrl.txctrl = CT_STARTFLOW; | ||
2209 | #if 0 | ||
2210 | stli_cmdwait(brdp, portp, A_PORTCTRL, &actrl, sizeof(asyctrl_t), 0); | ||
2211 | #endif | ||
2212 | } | 2004 | } |
2213 | 2005 | ||
2214 | /*****************************************************************************/ | 2006 | /*****************************************************************************/ |
@@ -2224,22 +2016,9 @@ static void stli_start(struct tty_struct *tty) | |||
2224 | 2016 | ||
2225 | static void stli_dohangup(void *arg) | 2017 | static void stli_dohangup(void *arg) |
2226 | { | 2018 | { |
2227 | stliport_t *portp; | 2019 | stliport_t *portp = (stliport_t *) arg; |
2228 | 2020 | if (portp->tty != NULL) { | |
2229 | #ifdef DEBUG | 2021 | tty_hangup(portp->tty); |
2230 | printk(KERN_DEBUG "stli_dohangup(portp=%x)\n", (int) arg); | ||
2231 | #endif | ||
2232 | |||
2233 | /* | ||
2234 | * FIXME: There's a module removal race here: tty_hangup | ||
2235 | * calls schedule_work which will call into this | ||
2236 | * driver later. | ||
2237 | */ | ||
2238 | portp = (stliport_t *) arg; | ||
2239 | if (portp != (stliport_t *) NULL) { | ||
2240 | if (portp->tty != (struct tty_struct *) NULL) { | ||
2241 | tty_hangup(portp->tty); | ||
2242 | } | ||
2243 | } | 2022 | } |
2244 | } | 2023 | } |
2245 | 2024 | ||
@@ -2254,31 +2033,25 @@ static void stli_dohangup(void *arg) | |||
2254 | 2033 | ||
2255 | static void stli_hangup(struct tty_struct *tty) | 2034 | static void stli_hangup(struct tty_struct *tty) |
2256 | { | 2035 | { |
2257 | stliport_t *portp; | 2036 | stliport_t *portp; |
2258 | stlibrd_t *brdp; | 2037 | stlibrd_t *brdp; |
2259 | unsigned long flags; | 2038 | unsigned long flags; |
2260 | |||
2261 | #ifdef DEBUG | ||
2262 | printk(KERN_DEBUG "stli_hangup(tty=%x)\n", (int) tty); | ||
2263 | #endif | ||
2264 | 2039 | ||
2265 | if (tty == (struct tty_struct *) NULL) | ||
2266 | return; | ||
2267 | portp = tty->driver_data; | 2040 | portp = tty->driver_data; |
2268 | if (portp == (stliport_t *) NULL) | 2041 | if (portp == NULL) |
2269 | return; | 2042 | return; |
2270 | if ((portp->brdnr < 0) || (portp->brdnr >= stli_nrbrds)) | 2043 | if (portp->brdnr < 0 || portp->brdnr >= stli_nrbrds) |
2271 | return; | 2044 | return; |
2272 | brdp = stli_brds[portp->brdnr]; | 2045 | brdp = stli_brds[portp->brdnr]; |
2273 | if (brdp == (stlibrd_t *) NULL) | 2046 | if (brdp == NULL) |
2274 | return; | 2047 | return; |
2275 | 2048 | ||
2276 | portp->flags &= ~ASYNC_INITIALIZED; | 2049 | portp->flags &= ~ASYNC_INITIALIZED; |
2277 | 2050 | ||
2278 | save_flags(flags); | 2051 | if (!test_bit(ST_CLOSING, &portp->state)) |
2279 | cli(); | ||
2280 | if (! test_bit(ST_CLOSING, &portp->state)) | ||
2281 | stli_rawclose(brdp, portp, 0, 0); | 2052 | stli_rawclose(brdp, portp, 0, 0); |
2053 | |||
2054 | spin_lock_irqsave(&stli_lock, flags); | ||
2282 | if (tty->termios->c_cflag & HUPCL) { | 2055 | if (tty->termios->c_cflag & HUPCL) { |
2283 | stli_mkasysigs(&portp->asig, 0, 0); | 2056 | stli_mkasysigs(&portp->asig, 0, 0); |
2284 | if (test_bit(ST_CMDING, &portp->state)) { | 2057 | if (test_bit(ST_CMDING, &portp->state)) { |
@@ -2290,14 +2063,15 @@ static void stli_hangup(struct tty_struct *tty) | |||
2290 | &portp->asig, sizeof(asysigs_t), 0); | 2063 | &portp->asig, sizeof(asysigs_t), 0); |
2291 | } | 2064 | } |
2292 | } | 2065 | } |
2293 | restore_flags(flags); | ||
2294 | 2066 | ||
2295 | clear_bit(ST_TXBUSY, &portp->state); | 2067 | clear_bit(ST_TXBUSY, &portp->state); |
2296 | clear_bit(ST_RXSTOP, &portp->state); | 2068 | clear_bit(ST_RXSTOP, &portp->state); |
2297 | set_bit(TTY_IO_ERROR, &tty->flags); | 2069 | set_bit(TTY_IO_ERROR, &tty->flags); |
2298 | portp->tty = (struct tty_struct *) NULL; | 2070 | portp->tty = NULL; |
2299 | portp->flags &= ~ASYNC_NORMAL_ACTIVE; | 2071 | portp->flags &= ~ASYNC_NORMAL_ACTIVE; |
2300 | portp->refcount = 0; | 2072 | portp->refcount = 0; |
2073 | spin_unlock_irqrestore(&stli_lock, flags); | ||
2074 | |||
2301 | wake_up_interruptible(&portp->open_wait); | 2075 | wake_up_interruptible(&portp->open_wait); |
2302 | } | 2076 | } |
2303 | 2077 | ||
@@ -2312,29 +2086,22 @@ static void stli_hangup(struct tty_struct *tty) | |||
2312 | 2086 | ||
2313 | static void stli_flushbuffer(struct tty_struct *tty) | 2087 | static void stli_flushbuffer(struct tty_struct *tty) |
2314 | { | 2088 | { |
2315 | stliport_t *portp; | 2089 | stliport_t *portp; |
2316 | stlibrd_t *brdp; | 2090 | stlibrd_t *brdp; |
2317 | unsigned long ftype, flags; | 2091 | unsigned long ftype, flags; |
2318 | |||
2319 | #ifdef DEBUG | ||
2320 | printk(KERN_DEBUG "stli_flushbuffer(tty=%x)\n", (int) tty); | ||
2321 | #endif | ||
2322 | 2092 | ||
2323 | if (tty == (struct tty_struct *) NULL) | ||
2324 | return; | ||
2325 | portp = tty->driver_data; | 2093 | portp = tty->driver_data; |
2326 | if (portp == (stliport_t *) NULL) | 2094 | if (portp == NULL) |
2327 | return; | 2095 | return; |
2328 | if ((portp->brdnr < 0) || (portp->brdnr >= stli_nrbrds)) | 2096 | if (portp->brdnr < 0 || portp->brdnr >= stli_nrbrds) |
2329 | return; | 2097 | return; |
2330 | brdp = stli_brds[portp->brdnr]; | 2098 | brdp = stli_brds[portp->brdnr]; |
2331 | if (brdp == (stlibrd_t *) NULL) | 2099 | if (brdp == NULL) |
2332 | return; | 2100 | return; |
2333 | 2101 | ||
2334 | save_flags(flags); | 2102 | spin_lock_irqsave(&brd_lock, flags); |
2335 | cli(); | ||
2336 | if (tty == stli_txcooktty) { | 2103 | if (tty == stli_txcooktty) { |
2337 | stli_txcooktty = (struct tty_struct *) NULL; | 2104 | stli_txcooktty = NULL; |
2338 | stli_txcooksize = 0; | 2105 | stli_txcooksize = 0; |
2339 | stli_txcookrealsize = 0; | 2106 | stli_txcookrealsize = 0; |
2340 | } | 2107 | } |
@@ -2346,15 +2113,10 @@ static void stli_flushbuffer(struct tty_struct *tty) | |||
2346 | ftype |= FLUSHRX; | 2113 | ftype |= FLUSHRX; |
2347 | clear_bit(ST_DOFLUSHRX, &portp->state); | 2114 | clear_bit(ST_DOFLUSHRX, &portp->state); |
2348 | } | 2115 | } |
2349 | stli_sendcmd(brdp, portp, A_FLUSH, &ftype, | 2116 | __stli_sendcmd(brdp, portp, A_FLUSH, &ftype, sizeof(u32), 0); |
2350 | sizeof(unsigned long), 0); | ||
2351 | } | 2117 | } |
2352 | restore_flags(flags); | 2118 | spin_unlock_irqrestore(&brd_lock, flags); |
2353 | 2119 | tty_wakeup(tty); | |
2354 | wake_up_interruptible(&tty->write_wait); | ||
2355 | if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && | ||
2356 | tty->ldisc.write_wakeup) | ||
2357 | (tty->ldisc.write_wakeup)(tty); | ||
2358 | } | 2120 | } |
2359 | 2121 | ||
2360 | /*****************************************************************************/ | 2122 | /*****************************************************************************/ |
@@ -2364,55 +2126,31 @@ static void stli_breakctl(struct tty_struct *tty, int state) | |||
2364 | stlibrd_t *brdp; | 2126 | stlibrd_t *brdp; |
2365 | stliport_t *portp; | 2127 | stliport_t *portp; |
2366 | long arg; | 2128 | long arg; |
2367 | /* long savestate, savetime; */ | ||
2368 | 2129 | ||
2369 | #ifdef DEBUG | ||
2370 | printk(KERN_DEBUG "stli_breakctl(tty=%x,state=%d)\n", (int) tty, state); | ||
2371 | #endif | ||
2372 | |||
2373 | if (tty == (struct tty_struct *) NULL) | ||
2374 | return; | ||
2375 | portp = tty->driver_data; | 2130 | portp = tty->driver_data; |
2376 | if (portp == (stliport_t *) NULL) | 2131 | if (portp == NULL) |
2377 | return; | 2132 | return; |
2378 | if ((portp->brdnr < 0) || (portp->brdnr >= stli_nrbrds)) | 2133 | if (portp->brdnr < 0 || portp->brdnr >= stli_nrbrds) |
2379 | return; | 2134 | return; |
2380 | brdp = stli_brds[portp->brdnr]; | 2135 | brdp = stli_brds[portp->brdnr]; |
2381 | if (brdp == (stlibrd_t *) NULL) | 2136 | if (brdp == NULL) |
2382 | return; | 2137 | return; |
2383 | 2138 | ||
2384 | /* | ||
2385 | * Due to a bug in the tty send_break() code we need to preserve | ||
2386 | * the current process state and timeout... | ||
2387 | savetime = current->timeout; | ||
2388 | savestate = current->state; | ||
2389 | */ | ||
2390 | |||
2391 | arg = (state == -1) ? BREAKON : BREAKOFF; | 2139 | arg = (state == -1) ? BREAKON : BREAKOFF; |
2392 | stli_cmdwait(brdp, portp, A_BREAK, &arg, sizeof(long), 0); | 2140 | stli_cmdwait(brdp, portp, A_BREAK, &arg, sizeof(long), 0); |
2393 | |||
2394 | /* | ||
2395 | * | ||
2396 | current->timeout = savetime; | ||
2397 | current->state = savestate; | ||
2398 | */ | ||
2399 | } | 2141 | } |
2400 | 2142 | ||
2401 | /*****************************************************************************/ | 2143 | /*****************************************************************************/ |
2402 | 2144 | ||
2403 | static void stli_waituntilsent(struct tty_struct *tty, int timeout) | 2145 | static void stli_waituntilsent(struct tty_struct *tty, int timeout) |
2404 | { | 2146 | { |
2405 | stliport_t *portp; | 2147 | stliport_t *portp; |
2406 | unsigned long tend; | 2148 | unsigned long tend; |
2407 | 2149 | ||
2408 | #ifdef DEBUG | 2150 | if (tty == NULL) |
2409 | printk(KERN_DEBUG "stli_waituntilsent(tty=%x,timeout=%x)\n", (int) tty, timeout); | ||
2410 | #endif | ||
2411 | |||
2412 | if (tty == (struct tty_struct *) NULL) | ||
2413 | return; | 2151 | return; |
2414 | portp = tty->driver_data; | 2152 | portp = tty->driver_data; |
2415 | if (portp == (stliport_t *) NULL) | 2153 | if (portp == NULL) |
2416 | return; | 2154 | return; |
2417 | 2155 | ||
2418 | if (timeout == 0) | 2156 | if (timeout == 0) |
@@ -2436,19 +2174,13 @@ static void stli_sendxchar(struct tty_struct *tty, char ch) | |||
2436 | stliport_t *portp; | 2174 | stliport_t *portp; |
2437 | asyctrl_t actrl; | 2175 | asyctrl_t actrl; |
2438 | 2176 | ||
2439 | #ifdef DEBUG | ||
2440 | printk(KERN_DEBUG "stli_sendxchar(tty=%x,ch=%x)\n", (int) tty, ch); | ||
2441 | #endif | ||
2442 | |||
2443 | if (tty == (struct tty_struct *) NULL) | ||
2444 | return; | ||
2445 | portp = tty->driver_data; | 2177 | portp = tty->driver_data; |
2446 | if (portp == (stliport_t *) NULL) | 2178 | if (portp == NULL) |
2447 | return; | 2179 | return; |
2448 | if ((portp->brdnr < 0) || (portp->brdnr >= stli_nrbrds)) | 2180 | if (portp->brdnr < 0 || portp->brdnr >= stli_nrbrds) |
2449 | return; | 2181 | return; |
2450 | brdp = stli_brds[portp->brdnr]; | 2182 | brdp = stli_brds[portp->brdnr]; |
2451 | if (brdp == (stlibrd_t *) NULL) | 2183 | if (brdp == NULL) |
2452 | return; | 2184 | return; |
2453 | 2185 | ||
2454 | memset(&actrl, 0, sizeof(asyctrl_t)); | 2186 | memset(&actrl, 0, sizeof(asyctrl_t)); |
@@ -2460,7 +2192,6 @@ static void stli_sendxchar(struct tty_struct *tty, char ch) | |||
2460 | actrl.txctrl = CT_SENDCHR; | 2192 | actrl.txctrl = CT_SENDCHR; |
2461 | actrl.tximdch = ch; | 2193 | actrl.tximdch = ch; |
2462 | } | 2194 | } |
2463 | |||
2464 | stli_cmdwait(brdp, portp, A_PORTCTRL, &actrl, sizeof(asyctrl_t), 0); | 2195 | stli_cmdwait(brdp, portp, A_PORTCTRL, &actrl, sizeof(asyctrl_t), 0); |
2465 | } | 2196 | } |
2466 | 2197 | ||
@@ -2476,17 +2207,17 @@ static void stli_sendxchar(struct tty_struct *tty, char ch) | |||
2476 | 2207 | ||
2477 | static int stli_portinfo(stlibrd_t *brdp, stliport_t *portp, int portnr, char *pos) | 2208 | static int stli_portinfo(stlibrd_t *brdp, stliport_t *portp, int portnr, char *pos) |
2478 | { | 2209 | { |
2479 | char *sp, *uart; | 2210 | char *sp, *uart; |
2480 | int rc, cnt; | 2211 | int rc, cnt; |
2481 | 2212 | ||
2482 | rc = stli_portcmdstats(portp); | 2213 | rc = stli_portcmdstats(portp); |
2483 | 2214 | ||
2484 | uart = "UNKNOWN"; | 2215 | uart = "UNKNOWN"; |
2485 | if (brdp->state & BST_STARTED) { | 2216 | if (brdp->state & BST_STARTED) { |
2486 | switch (stli_comstats.hwid) { | 2217 | switch (stli_comstats.hwid) { |
2487 | case 0: uart = "2681"; break; | 2218 | case 0: uart = "2681"; break; |
2488 | case 1: uart = "SC26198"; break; | 2219 | case 1: uart = "SC26198"; break; |
2489 | default: uart = "CD1400"; break; | 2220 | default:uart = "CD1400"; break; |
2490 | } | 2221 | } |
2491 | } | 2222 | } |
2492 | 2223 | ||
@@ -2537,17 +2268,11 @@ static int stli_portinfo(stlibrd_t *brdp, stliport_t *portp, int portnr, char *p | |||
2537 | 2268 | ||
2538 | static int stli_readproc(char *page, char **start, off_t off, int count, int *eof, void *data) | 2269 | static int stli_readproc(char *page, char **start, off_t off, int count, int *eof, void *data) |
2539 | { | 2270 | { |
2540 | stlibrd_t *brdp; | 2271 | stlibrd_t *brdp; |
2541 | stliport_t *portp; | 2272 | stliport_t *portp; |
2542 | int brdnr, portnr, totalport; | 2273 | int brdnr, portnr, totalport; |
2543 | int curoff, maxoff; | 2274 | int curoff, maxoff; |
2544 | char *pos; | 2275 | char *pos; |
2545 | |||
2546 | #ifdef DEBUG | ||
2547 | printk(KERN_DEBUG "stli_readproc(page=%x,start=%x,off=%x,count=%d,eof=%x," | ||
2548 | "data=%x\n", (int) page, (int) start, (int) off, count, | ||
2549 | (int) eof, (int) data); | ||
2550 | #endif | ||
2551 | 2276 | ||
2552 | pos = page; | 2277 | pos = page; |
2553 | totalport = 0; | 2278 | totalport = 0; |
@@ -2568,7 +2293,7 @@ static int stli_readproc(char *page, char **start, off_t off, int count, int *eo | |||
2568 | */ | 2293 | */ |
2569 | for (brdnr = 0; (brdnr < stli_nrbrds); brdnr++) { | 2294 | for (brdnr = 0; (brdnr < stli_nrbrds); brdnr++) { |
2570 | brdp = stli_brds[brdnr]; | 2295 | brdp = stli_brds[brdnr]; |
2571 | if (brdp == (stlibrd_t *) NULL) | 2296 | if (brdp == NULL) |
2572 | continue; | 2297 | continue; |
2573 | if (brdp->state == 0) | 2298 | if (brdp->state == 0) |
2574 | continue; | 2299 | continue; |
@@ -2583,7 +2308,7 @@ static int stli_readproc(char *page, char **start, off_t off, int count, int *eo | |||
2583 | for (portnr = 0; (portnr < brdp->nrports); portnr++, | 2308 | for (portnr = 0; (portnr < brdp->nrports); portnr++, |
2584 | totalport++) { | 2309 | totalport++) { |
2585 | portp = brdp->ports[portnr]; | 2310 | portp = brdp->ports[portnr]; |
2586 | if (portp == (stliport_t *) NULL) | 2311 | if (portp == NULL) |
2587 | continue; | 2312 | continue; |
2588 | if (off >= (curoff += MAXLINE)) | 2313 | if (off >= (curoff += MAXLINE)) |
2589 | continue; | 2314 | continue; |
@@ -2610,49 +2335,54 @@ stli_readdone: | |||
2610 | * a poll routine that does not have user context. Therefore you cannot | 2335 | * a poll routine that does not have user context. Therefore you cannot |
2611 | * copy back directly into user space, or to the kernel stack of a | 2336 | * copy back directly into user space, or to the kernel stack of a |
2612 | * process. This routine does not sleep, so can be called from anywhere. | 2337 | * process. This routine does not sleep, so can be called from anywhere. |
2338 | * | ||
2339 | * The caller must hold the brd_lock (see also stli_sendcmd the usual | ||
2340 | * entry point) | ||
2613 | */ | 2341 | */ |
2614 | 2342 | ||
2615 | static void stli_sendcmd(stlibrd_t *brdp, stliport_t *portp, unsigned long cmd, void *arg, int size, int copyback) | 2343 | static void __stli_sendcmd(stlibrd_t *brdp, stliport_t *portp, unsigned long cmd, void *arg, int size, int copyback) |
2616 | { | 2344 | { |
2617 | volatile cdkhdr_t *hdrp; | 2345 | cdkhdr_t __iomem *hdrp; |
2618 | volatile cdkctrl_t *cp; | 2346 | cdkctrl_t __iomem *cp; |
2619 | volatile unsigned char *bits; | 2347 | unsigned char __iomem *bits; |
2620 | unsigned long flags; | 2348 | unsigned long flags; |
2621 | 2349 | ||
2622 | #ifdef DEBUG | 2350 | spin_lock_irqsave(&brd_lock, flags); |
2623 | printk(KERN_DEBUG "stli_sendcmd(brdp=%x,portp=%x,cmd=%x,arg=%x,size=%d," | ||
2624 | "copyback=%d)\n", (int) brdp, (int) portp, (int) cmd, | ||
2625 | (int) arg, size, copyback); | ||
2626 | #endif | ||
2627 | |||
2628 | save_flags(flags); | ||
2629 | cli(); | ||
2630 | 2351 | ||
2631 | if (test_bit(ST_CMDING, &portp->state)) { | 2352 | if (test_bit(ST_CMDING, &portp->state)) { |
2632 | printk(KERN_ERR "STALLION: command already busy, cmd=%x!\n", | 2353 | printk(KERN_ERR "STALLION: command already busy, cmd=%x!\n", |
2633 | (int) cmd); | 2354 | (int) cmd); |
2634 | restore_flags(flags); | 2355 | spin_unlock_irqrestore(&brd_lock, flags); |
2635 | return; | 2356 | return; |
2636 | } | 2357 | } |
2637 | 2358 | ||
2638 | EBRDENABLE(brdp); | 2359 | EBRDENABLE(brdp); |
2639 | cp = &((volatile cdkasy_t *) EBRDGETMEMPTR(brdp, portp->addr))->ctrl; | 2360 | cp = &((cdkasy_t __iomem *) EBRDGETMEMPTR(brdp, portp->addr))->ctrl; |
2640 | if (size > 0) { | 2361 | if (size > 0) { |
2641 | memcpy((void *) &(cp->args[0]), arg, size); | 2362 | memcpy_toio((void __iomem *) &(cp->args[0]), arg, size); |
2642 | if (copyback) { | 2363 | if (copyback) { |
2643 | portp->argp = arg; | 2364 | portp->argp = arg; |
2644 | portp->argsize = size; | 2365 | portp->argsize = size; |
2645 | } | 2366 | } |
2646 | } | 2367 | } |
2647 | cp->status = 0; | 2368 | writel(0, &cp->status); |
2648 | cp->cmd = cmd; | 2369 | writel(cmd, &cp->cmd); |
2649 | hdrp = (volatile cdkhdr_t *) EBRDGETMEMPTR(brdp, CDK_CDKADDR); | 2370 | hdrp = (cdkhdr_t __iomem *) EBRDGETMEMPTR(brdp, CDK_CDKADDR); |
2650 | bits = ((volatile unsigned char *) hdrp) + brdp->slaveoffset + | 2371 | bits = ((unsigned char __iomem *) hdrp) + brdp->slaveoffset + |
2651 | portp->portidx; | 2372 | portp->portidx; |
2652 | *bits |= portp->portbit; | 2373 | writeb(readb(bits) | portp->portbit, bits); |
2653 | set_bit(ST_CMDING, &portp->state); | 2374 | set_bit(ST_CMDING, &portp->state); |
2654 | EBRDDISABLE(brdp); | 2375 | EBRDDISABLE(brdp); |
2655 | restore_flags(flags); | 2376 | spin_unlock_irqrestore(&brd_lock, flags); |
2377 | } | ||
2378 | |||
2379 | static void stli_sendcmd(stlibrd_t *brdp, stliport_t *portp, unsigned long cmd, void *arg, int size, int copyback) | ||
2380 | { | ||
2381 | unsigned long flags; | ||
2382 | |||
2383 | spin_lock_irqsave(&brd_lock, flags); | ||
2384 | __stli_sendcmd(brdp, portp, cmd, arg, size, copyback); | ||
2385 | spin_unlock_irqrestore(&brd_lock, flags); | ||
2656 | } | 2386 | } |
2657 | 2387 | ||
2658 | /*****************************************************************************/ | 2388 | /*****************************************************************************/ |
@@ -2667,28 +2397,23 @@ static void stli_sendcmd(stlibrd_t *brdp, stliport_t *portp, unsigned long cmd, | |||
2667 | 2397 | ||
2668 | static void stli_read(stlibrd_t *brdp, stliport_t *portp) | 2398 | static void stli_read(stlibrd_t *brdp, stliport_t *portp) |
2669 | { | 2399 | { |
2670 | volatile cdkasyrq_t *rp; | 2400 | cdkasyrq_t __iomem *rp; |
2671 | volatile char *shbuf; | 2401 | char __iomem *shbuf; |
2672 | struct tty_struct *tty; | 2402 | struct tty_struct *tty; |
2673 | unsigned int head, tail, size; | 2403 | unsigned int head, tail, size; |
2674 | unsigned int len, stlen; | 2404 | unsigned int len, stlen; |
2675 | |||
2676 | #ifdef DEBUG | ||
2677 | printk(KERN_DEBUG "stli_read(brdp=%x,portp=%d)\n", | ||
2678 | (int) brdp, (int) portp); | ||
2679 | #endif | ||
2680 | 2405 | ||
2681 | if (test_bit(ST_RXSTOP, &portp->state)) | 2406 | if (test_bit(ST_RXSTOP, &portp->state)) |
2682 | return; | 2407 | return; |
2683 | tty = portp->tty; | 2408 | tty = portp->tty; |
2684 | if (tty == (struct tty_struct *) NULL) | 2409 | if (tty == NULL) |
2685 | return; | 2410 | return; |
2686 | 2411 | ||
2687 | rp = &((volatile cdkasy_t *) EBRDGETMEMPTR(brdp, portp->addr))->rxq; | 2412 | rp = &((cdkasy_t __iomem *) EBRDGETMEMPTR(brdp, portp->addr))->rxq; |
2688 | head = (unsigned int) rp->head; | 2413 | head = (unsigned int) readw(&rp->head); |
2689 | if (head != ((unsigned int) rp->head)) | 2414 | if (head != ((unsigned int) readw(&rp->head))) |
2690 | head = (unsigned int) rp->head; | 2415 | head = (unsigned int) readw(&rp->head); |
2691 | tail = (unsigned int) rp->tail; | 2416 | tail = (unsigned int) readw(&rp->tail); |
2692 | size = portp->rxsize; | 2417 | size = portp->rxsize; |
2693 | if (head >= tail) { | 2418 | if (head >= tail) { |
2694 | len = head - tail; | 2419 | len = head - tail; |
@@ -2699,12 +2424,15 @@ static void stli_read(stlibrd_t *brdp, stliport_t *portp) | |||
2699 | } | 2424 | } |
2700 | 2425 | ||
2701 | len = tty_buffer_request_room(tty, len); | 2426 | len = tty_buffer_request_room(tty, len); |
2702 | /* FIXME : iomap ? */ | 2427 | |
2703 | shbuf = (volatile char *) EBRDGETMEMPTR(brdp, portp->rxoffset); | 2428 | shbuf = (char __iomem *) EBRDGETMEMPTR(brdp, portp->rxoffset); |
2704 | 2429 | ||
2705 | while (len > 0) { | 2430 | while (len > 0) { |
2431 | unsigned char *cptr; | ||
2432 | |||
2706 | stlen = MIN(len, stlen); | 2433 | stlen = MIN(len, stlen); |
2707 | tty_insert_flip_string(tty, (char *)(shbuf + tail), stlen); | 2434 | tty_prepare_flip_string(tty, &cptr, stlen); |
2435 | memcpy_fromio(cptr, shbuf + tail, stlen); | ||
2708 | len -= stlen; | 2436 | len -= stlen; |
2709 | tail += stlen; | 2437 | tail += stlen; |
2710 | if (tail >= size) { | 2438 | if (tail >= size) { |
@@ -2712,8 +2440,8 @@ static void stli_read(stlibrd_t *brdp, stliport_t *portp) | |||
2712 | stlen = head; | 2440 | stlen = head; |
2713 | } | 2441 | } |
2714 | } | 2442 | } |
2715 | rp = &((volatile cdkasy_t *) EBRDGETMEMPTR(brdp, portp->addr))->rxq; | 2443 | rp = &((cdkasy_t __iomem *) EBRDGETMEMPTR(brdp, portp->addr))->rxq; |
2716 | rp->tail = tail; | 2444 | writew(tail, &rp->tail); |
2717 | 2445 | ||
2718 | if (head != tail) | 2446 | if (head != tail) |
2719 | set_bit(ST_RXING, &portp->state); | 2447 | set_bit(ST_RXING, &portp->state); |
@@ -2729,9 +2457,9 @@ static void stli_read(stlibrd_t *brdp, stliport_t *portp) | |||
2729 | * difficult to deal with them here. | 2457 | * difficult to deal with them here. |
2730 | */ | 2458 | */ |
2731 | 2459 | ||
2732 | static void stli_dodelaycmd(stliport_t *portp, volatile cdkctrl_t *cp) | 2460 | static void stli_dodelaycmd(stliport_t *portp, cdkctrl_t __iomem *cp) |
2733 | { | 2461 | { |
2734 | int cmd; | 2462 | int cmd; |
2735 | 2463 | ||
2736 | if (test_bit(ST_DOSIGS, &portp->state)) { | 2464 | if (test_bit(ST_DOSIGS, &portp->state)) { |
2737 | if (test_bit(ST_DOFLUSHTX, &portp->state) && | 2465 | if (test_bit(ST_DOFLUSHTX, &portp->state) && |
@@ -2746,10 +2474,10 @@ static void stli_dodelaycmd(stliport_t *portp, volatile cdkctrl_t *cp) | |||
2746 | clear_bit(ST_DOFLUSHTX, &portp->state); | 2474 | clear_bit(ST_DOFLUSHTX, &portp->state); |
2747 | clear_bit(ST_DOFLUSHRX, &portp->state); | 2475 | clear_bit(ST_DOFLUSHRX, &portp->state); |
2748 | clear_bit(ST_DOSIGS, &portp->state); | 2476 | clear_bit(ST_DOSIGS, &portp->state); |
2749 | memcpy((void *) &(cp->args[0]), (void *) &portp->asig, | 2477 | memcpy_toio((void __iomem *) &(cp->args[0]), (void *) &portp->asig, |
2750 | sizeof(asysigs_t)); | 2478 | sizeof(asysigs_t)); |
2751 | cp->status = 0; | 2479 | writel(0, &cp->status); |
2752 | cp->cmd = cmd; | 2480 | writel(cmd, &cp->cmd); |
2753 | set_bit(ST_CMDING, &portp->state); | 2481 | set_bit(ST_CMDING, &portp->state); |
2754 | } else if (test_bit(ST_DOFLUSHTX, &portp->state) || | 2482 | } else if (test_bit(ST_DOFLUSHTX, &portp->state) || |
2755 | test_bit(ST_DOFLUSHRX, &portp->state)) { | 2483 | test_bit(ST_DOFLUSHRX, &portp->state)) { |
@@ -2757,9 +2485,9 @@ static void stli_dodelaycmd(stliport_t *portp, volatile cdkctrl_t *cp) | |||
2757 | cmd |= ((test_bit(ST_DOFLUSHRX, &portp->state)) ? FLUSHRX : 0); | 2485 | cmd |= ((test_bit(ST_DOFLUSHRX, &portp->state)) ? FLUSHRX : 0); |
2758 | clear_bit(ST_DOFLUSHTX, &portp->state); | 2486 | clear_bit(ST_DOFLUSHTX, &portp->state); |
2759 | clear_bit(ST_DOFLUSHRX, &portp->state); | 2487 | clear_bit(ST_DOFLUSHRX, &portp->state); |
2760 | memcpy((void *) &(cp->args[0]), (void *) &cmd, sizeof(int)); | 2488 | memcpy_toio((void __iomem *) &(cp->args[0]), (void *) &cmd, sizeof(int)); |
2761 | cp->status = 0; | 2489 | writel(0, &cp->status); |
2762 | cp->cmd = A_FLUSH; | 2490 | writel(A_FLUSH, &cp->cmd); |
2763 | set_bit(ST_CMDING, &portp->state); | 2491 | set_bit(ST_CMDING, &portp->state); |
2764 | } | 2492 | } |
2765 | } | 2493 | } |
@@ -2779,30 +2507,25 @@ static void stli_dodelaycmd(stliport_t *portp, volatile cdkctrl_t *cp) | |||
2779 | 2507 | ||
2780 | static int stli_hostcmd(stlibrd_t *brdp, stliport_t *portp) | 2508 | static int stli_hostcmd(stlibrd_t *brdp, stliport_t *portp) |
2781 | { | 2509 | { |
2782 | volatile cdkasy_t *ap; | 2510 | cdkasy_t __iomem *ap; |
2783 | volatile cdkctrl_t *cp; | 2511 | cdkctrl_t __iomem *cp; |
2784 | struct tty_struct *tty; | 2512 | struct tty_struct *tty; |
2785 | asynotify_t nt; | 2513 | asynotify_t nt; |
2786 | unsigned long oldsigs; | 2514 | unsigned long oldsigs; |
2787 | int rc, donerx; | 2515 | int rc, donerx; |
2788 | 2516 | ||
2789 | #ifdef DEBUG | 2517 | ap = (cdkasy_t __iomem *) EBRDGETMEMPTR(brdp, portp->addr); |
2790 | printk(KERN_DEBUG "stli_hostcmd(brdp=%x,channr=%d)\n", | ||
2791 | (int) brdp, channr); | ||
2792 | #endif | ||
2793 | |||
2794 | ap = (volatile cdkasy_t *) EBRDGETMEMPTR(brdp, portp->addr); | ||
2795 | cp = &ap->ctrl; | 2518 | cp = &ap->ctrl; |
2796 | 2519 | ||
2797 | /* | 2520 | /* |
2798 | * Check if we are waiting for an open completion message. | 2521 | * Check if we are waiting for an open completion message. |
2799 | */ | 2522 | */ |
2800 | if (test_bit(ST_OPENING, &portp->state)) { | 2523 | if (test_bit(ST_OPENING, &portp->state)) { |
2801 | rc = (int) cp->openarg; | 2524 | rc = readl(&cp->openarg); |
2802 | if ((cp->open == 0) && (rc != 0)) { | 2525 | if (readb(&cp->open) == 0 && rc != 0) { |
2803 | if (rc > 0) | 2526 | if (rc > 0) |
2804 | rc--; | 2527 | rc--; |
2805 | cp->openarg = 0; | 2528 | writel(0, &cp->openarg); |
2806 | portp->rc = rc; | 2529 | portp->rc = rc; |
2807 | clear_bit(ST_OPENING, &portp->state); | 2530 | clear_bit(ST_OPENING, &portp->state); |
2808 | wake_up_interruptible(&portp->raw_wait); | 2531 | wake_up_interruptible(&portp->raw_wait); |
@@ -2813,11 +2536,11 @@ static int stli_hostcmd(stlibrd_t *brdp, stliport_t *portp) | |||
2813 | * Check if we are waiting for a close completion message. | 2536 | * Check if we are waiting for a close completion message. |
2814 | */ | 2537 | */ |
2815 | if (test_bit(ST_CLOSING, &portp->state)) { | 2538 | if (test_bit(ST_CLOSING, &portp->state)) { |
2816 | rc = (int) cp->closearg; | 2539 | rc = (int) readl(&cp->closearg); |
2817 | if ((cp->close == 0) && (rc != 0)) { | 2540 | if (readb(&cp->close) == 0 && rc != 0) { |
2818 | if (rc > 0) | 2541 | if (rc > 0) |
2819 | rc--; | 2542 | rc--; |
2820 | cp->closearg = 0; | 2543 | writel(0, &cp->closearg); |
2821 | portp->rc = rc; | 2544 | portp->rc = rc; |
2822 | clear_bit(ST_CLOSING, &portp->state); | 2545 | clear_bit(ST_CLOSING, &portp->state); |
2823 | wake_up_interruptible(&portp->raw_wait); | 2546 | wake_up_interruptible(&portp->raw_wait); |
@@ -2829,16 +2552,16 @@ static int stli_hostcmd(stlibrd_t *brdp, stliport_t *portp) | |||
2829 | * need to copy out the command results associated with this command. | 2552 | * need to copy out the command results associated with this command. |
2830 | */ | 2553 | */ |
2831 | if (test_bit(ST_CMDING, &portp->state)) { | 2554 | if (test_bit(ST_CMDING, &portp->state)) { |
2832 | rc = cp->status; | 2555 | rc = readl(&cp->status); |
2833 | if ((cp->cmd == 0) && (rc != 0)) { | 2556 | if (readl(&cp->cmd) == 0 && rc != 0) { |
2834 | if (rc > 0) | 2557 | if (rc > 0) |
2835 | rc--; | 2558 | rc--; |
2836 | if (portp->argp != (void *) NULL) { | 2559 | if (portp->argp != NULL) { |
2837 | memcpy(portp->argp, (void *) &(cp->args[0]), | 2560 | memcpy_fromio(portp->argp, (void __iomem *) &(cp->args[0]), |
2838 | portp->argsize); | 2561 | portp->argsize); |
2839 | portp->argp = (void *) NULL; | 2562 | portp->argp = NULL; |
2840 | } | 2563 | } |
2841 | cp->status = 0; | 2564 | writel(0, &cp->status); |
2842 | portp->rc = rc; | 2565 | portp->rc = rc; |
2843 | clear_bit(ST_CMDING, &portp->state); | 2566 | clear_bit(ST_CMDING, &portp->state); |
2844 | stli_dodelaycmd(portp, cp); | 2567 | stli_dodelaycmd(portp, cp); |
@@ -2877,18 +2600,15 @@ static int stli_hostcmd(stlibrd_t *brdp, stliport_t *portp) | |||
2877 | if (nt.data & DT_TXEMPTY) | 2600 | if (nt.data & DT_TXEMPTY) |
2878 | clear_bit(ST_TXBUSY, &portp->state); | 2601 | clear_bit(ST_TXBUSY, &portp->state); |
2879 | if (nt.data & (DT_TXEMPTY | DT_TXLOW)) { | 2602 | if (nt.data & (DT_TXEMPTY | DT_TXLOW)) { |
2880 | if (tty != (struct tty_struct *) NULL) { | 2603 | if (tty != NULL) { |
2881 | if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && | 2604 | tty_wakeup(tty); |
2882 | tty->ldisc.write_wakeup) { | 2605 | EBRDENABLE(brdp); |
2883 | (tty->ldisc.write_wakeup)(tty); | ||
2884 | EBRDENABLE(brdp); | ||
2885 | } | ||
2886 | wake_up_interruptible(&tty->write_wait); | 2606 | wake_up_interruptible(&tty->write_wait); |
2887 | } | 2607 | } |
2888 | } | 2608 | } |
2889 | 2609 | ||
2890 | if ((nt.data & DT_RXBREAK) && (portp->rxmarkmsk & BRKINT)) { | 2610 | if ((nt.data & DT_RXBREAK) && (portp->rxmarkmsk & BRKINT)) { |
2891 | if (tty != (struct tty_struct *) NULL) { | 2611 | if (tty != NULL) { |
2892 | tty_insert_flip_char(tty, 0, TTY_BREAK); | 2612 | tty_insert_flip_char(tty, 0, TTY_BREAK); |
2893 | if (portp->flags & ASYNC_SAK) { | 2613 | if (portp->flags & ASYNC_SAK) { |
2894 | do_SAK(tty); | 2614 | do_SAK(tty); |
@@ -2932,14 +2652,14 @@ static int stli_hostcmd(stlibrd_t *brdp, stliport_t *portp) | |||
2932 | * at the cdk header structure. | 2652 | * at the cdk header structure. |
2933 | */ | 2653 | */ |
2934 | 2654 | ||
2935 | static void stli_brdpoll(stlibrd_t *brdp, volatile cdkhdr_t *hdrp) | 2655 | static void stli_brdpoll(stlibrd_t *brdp, cdkhdr_t __iomem *hdrp) |
2936 | { | 2656 | { |
2937 | stliport_t *portp; | 2657 | stliport_t *portp; |
2938 | unsigned char hostbits[(STL_MAXCHANS / 8) + 1]; | 2658 | unsigned char hostbits[(STL_MAXCHANS / 8) + 1]; |
2939 | unsigned char slavebits[(STL_MAXCHANS / 8) + 1]; | 2659 | unsigned char slavebits[(STL_MAXCHANS / 8) + 1]; |
2940 | unsigned char *slavep; | 2660 | unsigned char __iomem *slavep; |
2941 | int bitpos, bitat, bitsize; | 2661 | int bitpos, bitat, bitsize; |
2942 | int channr, nrdevs, slavebitchange; | 2662 | int channr, nrdevs, slavebitchange; |
2943 | 2663 | ||
2944 | bitsize = brdp->bitsize; | 2664 | bitsize = brdp->bitsize; |
2945 | nrdevs = brdp->nrdevs; | 2665 | nrdevs = brdp->nrdevs; |
@@ -2951,7 +2671,7 @@ static void stli_brdpoll(stlibrd_t *brdp, volatile cdkhdr_t *hdrp) | |||
2951 | * 8 service bits at a time in the inner loop, so we can bypass | 2671 | * 8 service bits at a time in the inner loop, so we can bypass |
2952 | * the lot if none of them want service. | 2672 | * the lot if none of them want service. |
2953 | */ | 2673 | */ |
2954 | memcpy(&hostbits[0], (((unsigned char *) hdrp) + brdp->hostoffset), | 2674 | memcpy_fromio(&hostbits[0], (((unsigned char __iomem *) hdrp) + brdp->hostoffset), |
2955 | bitsize); | 2675 | bitsize); |
2956 | 2676 | ||
2957 | memset(&slavebits[0], 0, bitsize); | 2677 | memset(&slavebits[0], 0, bitsize); |
@@ -2978,11 +2698,11 @@ static void stli_brdpoll(stlibrd_t *brdp, volatile cdkhdr_t *hdrp) | |||
2978 | * service may initiate more slave requests. | 2698 | * service may initiate more slave requests. |
2979 | */ | 2699 | */ |
2980 | if (slavebitchange) { | 2700 | if (slavebitchange) { |
2981 | hdrp = (volatile cdkhdr_t *) EBRDGETMEMPTR(brdp, CDK_CDKADDR); | 2701 | hdrp = (cdkhdr_t __iomem *) EBRDGETMEMPTR(brdp, CDK_CDKADDR); |
2982 | slavep = ((unsigned char *) hdrp) + brdp->slaveoffset; | 2702 | slavep = ((unsigned char __iomem *) hdrp) + brdp->slaveoffset; |
2983 | for (bitpos = 0; (bitpos < bitsize); bitpos++) { | 2703 | for (bitpos = 0; (bitpos < bitsize); bitpos++) { |
2984 | if (slavebits[bitpos]) | 2704 | if (readb(slavebits + bitpos)) |
2985 | slavep[bitpos] &= ~slavebits[bitpos]; | 2705 | writeb(readb(slavep + bitpos) & ~slavebits[bitpos], slavebits + bitpos); |
2986 | } | 2706 | } |
2987 | } | 2707 | } |
2988 | } | 2708 | } |
@@ -3000,9 +2720,9 @@ static void stli_brdpoll(stlibrd_t *brdp, volatile cdkhdr_t *hdrp) | |||
3000 | 2720 | ||
3001 | static void stli_poll(unsigned long arg) | 2721 | static void stli_poll(unsigned long arg) |
3002 | { | 2722 | { |
3003 | volatile cdkhdr_t *hdrp; | 2723 | cdkhdr_t __iomem *hdrp; |
3004 | stlibrd_t *brdp; | 2724 | stlibrd_t *brdp; |
3005 | int brdnr; | 2725 | int brdnr; |
3006 | 2726 | ||
3007 | stli_timerlist.expires = STLI_TIMEOUT; | 2727 | stli_timerlist.expires = STLI_TIMEOUT; |
3008 | add_timer(&stli_timerlist); | 2728 | add_timer(&stli_timerlist); |
@@ -3012,16 +2732,18 @@ static void stli_poll(unsigned long arg) | |||
3012 | */ | 2732 | */ |
3013 | for (brdnr = 0; (brdnr < stli_nrbrds); brdnr++) { | 2733 | for (brdnr = 0; (brdnr < stli_nrbrds); brdnr++) { |
3014 | brdp = stli_brds[brdnr]; | 2734 | brdp = stli_brds[brdnr]; |
3015 | if (brdp == (stlibrd_t *) NULL) | 2735 | if (brdp == NULL) |
3016 | continue; | 2736 | continue; |
3017 | if ((brdp->state & BST_STARTED) == 0) | 2737 | if ((brdp->state & BST_STARTED) == 0) |
3018 | continue; | 2738 | continue; |
3019 | 2739 | ||
2740 | spin_lock(&brd_lock); | ||
3020 | EBRDENABLE(brdp); | 2741 | EBRDENABLE(brdp); |
3021 | hdrp = (volatile cdkhdr_t *) EBRDGETMEMPTR(brdp, CDK_CDKADDR); | 2742 | hdrp = (cdkhdr_t __iomem *) EBRDGETMEMPTR(brdp, CDK_CDKADDR); |
3022 | if (hdrp->hostreq) | 2743 | if (readb(&hdrp->hostreq)) |
3023 | stli_brdpoll(brdp, hdrp); | 2744 | stli_brdpoll(brdp, hdrp); |
3024 | EBRDDISABLE(brdp); | 2745 | EBRDDISABLE(brdp); |
2746 | spin_unlock(&brd_lock); | ||
3025 | } | 2747 | } |
3026 | } | 2748 | } |
3027 | 2749 | ||
@@ -3034,11 +2756,6 @@ static void stli_poll(unsigned long arg) | |||
3034 | 2756 | ||
3035 | static void stli_mkasyport(stliport_t *portp, asyport_t *pp, struct termios *tiosp) | 2757 | static void stli_mkasyport(stliport_t *portp, asyport_t *pp, struct termios *tiosp) |
3036 | { | 2758 | { |
3037 | #ifdef DEBUG | ||
3038 | printk(KERN_DEBUG "stli_mkasyport(portp=%x,pp=%x,tiosp=%d)\n", | ||
3039 | (int) portp, (int) pp, (int) tiosp); | ||
3040 | #endif | ||
3041 | |||
3042 | memset(pp, 0, sizeof(asyport_t)); | 2759 | memset(pp, 0, sizeof(asyport_t)); |
3043 | 2760 | ||
3044 | /* | 2761 | /* |
@@ -3157,11 +2874,6 @@ static void stli_mkasyport(stliport_t *portp, asyport_t *pp, struct termios *tio | |||
3157 | 2874 | ||
3158 | static void stli_mkasysigs(asysigs_t *sp, int dtr, int rts) | 2875 | static void stli_mkasysigs(asysigs_t *sp, int dtr, int rts) |
3159 | { | 2876 | { |
3160 | #ifdef DEBUG | ||
3161 | printk(KERN_DEBUG "stli_mkasysigs(sp=%x,dtr=%d,rts=%d)\n", | ||
3162 | (int) sp, dtr, rts); | ||
3163 | #endif | ||
3164 | |||
3165 | memset(sp, 0, sizeof(asysigs_t)); | 2877 | memset(sp, 0, sizeof(asysigs_t)); |
3166 | if (dtr >= 0) { | 2878 | if (dtr >= 0) { |
3167 | sp->signal |= SG_DTR; | 2879 | sp->signal |= SG_DTR; |
@@ -3182,13 +2894,7 @@ static void stli_mkasysigs(asysigs_t *sp, int dtr, int rts) | |||
3182 | 2894 | ||
3183 | static long stli_mktiocm(unsigned long sigvalue) | 2895 | static long stli_mktiocm(unsigned long sigvalue) |
3184 | { | 2896 | { |
3185 | long tiocm; | 2897 | long tiocm = 0; |
3186 | |||
3187 | #ifdef DEBUG | ||
3188 | printk(KERN_DEBUG "stli_mktiocm(sigvalue=%x)\n", (int) sigvalue); | ||
3189 | #endif | ||
3190 | |||
3191 | tiocm = 0; | ||
3192 | tiocm |= ((sigvalue & SG_DCD) ? TIOCM_CD : 0); | 2898 | tiocm |= ((sigvalue & SG_DCD) ? TIOCM_CD : 0); |
3193 | tiocm |= ((sigvalue & SG_CTS) ? TIOCM_CTS : 0); | 2899 | tiocm |= ((sigvalue & SG_CTS) ? TIOCM_CTS : 0); |
3194 | tiocm |= ((sigvalue & SG_RI) ? TIOCM_RI : 0); | 2900 | tiocm |= ((sigvalue & SG_RI) ? TIOCM_RI : 0); |
@@ -3210,10 +2916,6 @@ static int stli_initports(stlibrd_t *brdp) | |||
3210 | stliport_t *portp; | 2916 | stliport_t *portp; |
3211 | int i, panelnr, panelport; | 2917 | int i, panelnr, panelport; |
3212 | 2918 | ||
3213 | #ifdef DEBUG | ||
3214 | printk(KERN_DEBUG "stli_initports(brdp=%x)\n", (int) brdp); | ||
3215 | #endif | ||
3216 | |||
3217 | for (i = 0, panelnr = 0, panelport = 0; (i < brdp->nrports); i++) { | 2919 | for (i = 0, panelnr = 0, panelport = 0; (i < brdp->nrports); i++) { |
3218 | portp = kzalloc(sizeof(stliport_t), GFP_KERNEL); | 2920 | portp = kzalloc(sizeof(stliport_t), GFP_KERNEL); |
3219 | if (!portp) { | 2921 | if (!portp) { |
@@ -3240,7 +2942,7 @@ static int stli_initports(stlibrd_t *brdp) | |||
3240 | brdp->ports[i] = portp; | 2942 | brdp->ports[i] = portp; |
3241 | } | 2943 | } |
3242 | 2944 | ||
3243 | return(0); | 2945 | return 0; |
3244 | } | 2946 | } |
3245 | 2947 | ||
3246 | /*****************************************************************************/ | 2948 | /*****************************************************************************/ |
@@ -3253,10 +2955,6 @@ static void stli_ecpinit(stlibrd_t *brdp) | |||
3253 | { | 2955 | { |
3254 | unsigned long memconf; | 2956 | unsigned long memconf; |
3255 | 2957 | ||
3256 | #ifdef DEBUG | ||
3257 | printk(KERN_DEBUG "stli_ecpinit(brdp=%d)\n", (int) brdp); | ||
3258 | #endif | ||
3259 | |||
3260 | outb(ECP_ATSTOP, (brdp->iobase + ECP_ATCONFR)); | 2958 | outb(ECP_ATSTOP, (brdp->iobase + ECP_ATCONFR)); |
3261 | udelay(10); | 2959 | udelay(10); |
3262 | outb(ECP_ATDISABLE, (brdp->iobase + ECP_ATCONFR)); | 2960 | outb(ECP_ATDISABLE, (brdp->iobase + ECP_ATCONFR)); |
@@ -3270,9 +2968,6 @@ static void stli_ecpinit(stlibrd_t *brdp) | |||
3270 | 2968 | ||
3271 | static void stli_ecpenable(stlibrd_t *brdp) | 2969 | static void stli_ecpenable(stlibrd_t *brdp) |
3272 | { | 2970 | { |
3273 | #ifdef DEBUG | ||
3274 | printk(KERN_DEBUG "stli_ecpenable(brdp=%x)\n", (int) brdp); | ||
3275 | #endif | ||
3276 | outb(ECP_ATENABLE, (brdp->iobase + ECP_ATCONFR)); | 2971 | outb(ECP_ATENABLE, (brdp->iobase + ECP_ATCONFR)); |
3277 | } | 2972 | } |
3278 | 2973 | ||
@@ -3280,9 +2975,6 @@ static void stli_ecpenable(stlibrd_t *brdp) | |||
3280 | 2975 | ||
3281 | static void stli_ecpdisable(stlibrd_t *brdp) | 2976 | static void stli_ecpdisable(stlibrd_t *brdp) |
3282 | { | 2977 | { |
3283 | #ifdef DEBUG | ||
3284 | printk(KERN_DEBUG "stli_ecpdisable(brdp=%x)\n", (int) brdp); | ||
3285 | #endif | ||
3286 | outb(ECP_ATDISABLE, (brdp->iobase + ECP_ATCONFR)); | 2978 | outb(ECP_ATDISABLE, (brdp->iobase + ECP_ATCONFR)); |
3287 | } | 2979 | } |
3288 | 2980 | ||
@@ -3290,13 +2982,8 @@ static void stli_ecpdisable(stlibrd_t *brdp) | |||
3290 | 2982 | ||
3291 | static char *stli_ecpgetmemptr(stlibrd_t *brdp, unsigned long offset, int line) | 2983 | static char *stli_ecpgetmemptr(stlibrd_t *brdp, unsigned long offset, int line) |
3292 | { | 2984 | { |
3293 | void *ptr; | 2985 | void *ptr; |
3294 | unsigned char val; | 2986 | unsigned char val; |
3295 | |||
3296 | #ifdef DEBUG | ||
3297 | printk(KERN_DEBUG "stli_ecpgetmemptr(brdp=%x,offset=%x)\n", (int) brdp, | ||
3298 | (int) offset); | ||
3299 | #endif | ||
3300 | 2987 | ||
3301 | if (offset > brdp->memsize) { | 2988 | if (offset > brdp->memsize) { |
3302 | printk(KERN_ERR "STALLION: shared memory pointer=%x out of " | 2989 | printk(KERN_ERR "STALLION: shared memory pointer=%x out of " |
@@ -3316,10 +3003,6 @@ static char *stli_ecpgetmemptr(stlibrd_t *brdp, unsigned long offset, int line) | |||
3316 | 3003 | ||
3317 | static void stli_ecpreset(stlibrd_t *brdp) | 3004 | static void stli_ecpreset(stlibrd_t *brdp) |
3318 | { | 3005 | { |
3319 | #ifdef DEBUG | ||
3320 | printk(KERN_DEBUG "stli_ecpreset(brdp=%x)\n", (int) brdp); | ||
3321 | #endif | ||
3322 | |||
3323 | outb(ECP_ATSTOP, (brdp->iobase + ECP_ATCONFR)); | 3006 | outb(ECP_ATSTOP, (brdp->iobase + ECP_ATCONFR)); |
3324 | udelay(10); | 3007 | udelay(10); |
3325 | outb(ECP_ATDISABLE, (brdp->iobase + ECP_ATCONFR)); | 3008 | outb(ECP_ATDISABLE, (brdp->iobase + ECP_ATCONFR)); |
@@ -3330,9 +3013,6 @@ static void stli_ecpreset(stlibrd_t *brdp) | |||
3330 | 3013 | ||
3331 | static void stli_ecpintr(stlibrd_t *brdp) | 3014 | static void stli_ecpintr(stlibrd_t *brdp) |
3332 | { | 3015 | { |
3333 | #ifdef DEBUG | ||
3334 | printk(KERN_DEBUG "stli_ecpintr(brdp=%x)\n", (int) brdp); | ||
3335 | #endif | ||
3336 | outb(0x1, brdp->iobase); | 3016 | outb(0x1, brdp->iobase); |
3337 | } | 3017 | } |
3338 | 3018 | ||
@@ -3346,10 +3026,6 @@ static void stli_ecpeiinit(stlibrd_t *brdp) | |||
3346 | { | 3026 | { |
3347 | unsigned long memconf; | 3027 | unsigned long memconf; |
3348 | 3028 | ||
3349 | #ifdef DEBUG | ||
3350 | printk(KERN_DEBUG "stli_ecpeiinit(brdp=%x)\n", (int) brdp); | ||
3351 | #endif | ||
3352 | |||
3353 | outb(0x1, (brdp->iobase + ECP_EIBRDENAB)); | 3029 | outb(0x1, (brdp->iobase + ECP_EIBRDENAB)); |
3354 | outb(ECP_EISTOP, (brdp->iobase + ECP_EICONFR)); | 3030 | outb(ECP_EISTOP, (brdp->iobase + ECP_EICONFR)); |
3355 | udelay(10); | 3031 | udelay(10); |
@@ -3383,11 +3059,6 @@ static char *stli_ecpeigetmemptr(stlibrd_t *brdp, unsigned long offset, int line | |||
3383 | void *ptr; | 3059 | void *ptr; |
3384 | unsigned char val; | 3060 | unsigned char val; |
3385 | 3061 | ||
3386 | #ifdef DEBUG | ||
3387 | printk(KERN_DEBUG "stli_ecpeigetmemptr(brdp=%x,offset=%x,line=%d)\n", | ||
3388 | (int) brdp, (int) offset, line); | ||
3389 | #endif | ||
3390 | |||
3391 | if (offset > brdp->memsize) { | 3062 | if (offset > brdp->memsize) { |
3392 | printk(KERN_ERR "STALLION: shared memory pointer=%x out of " | 3063 | printk(KERN_ERR "STALLION: shared memory pointer=%x out of " |
3393 | "range at line=%d(%d), brd=%d\n", | 3064 | "range at line=%d(%d), brd=%d\n", |
@@ -3437,8 +3108,8 @@ static void stli_ecpmcdisable(stlibrd_t *brdp) | |||
3437 | 3108 | ||
3438 | static char *stli_ecpmcgetmemptr(stlibrd_t *brdp, unsigned long offset, int line) | 3109 | static char *stli_ecpmcgetmemptr(stlibrd_t *brdp, unsigned long offset, int line) |
3439 | { | 3110 | { |
3440 | void *ptr; | 3111 | void *ptr; |
3441 | unsigned char val; | 3112 | unsigned char val; |
3442 | 3113 | ||
3443 | if (offset > brdp->memsize) { | 3114 | if (offset > brdp->memsize) { |
3444 | printk(KERN_ERR "STALLION: shared memory pointer=%x out of " | 3115 | printk(KERN_ERR "STALLION: shared memory pointer=%x out of " |
@@ -3472,10 +3143,6 @@ static void stli_ecpmcreset(stlibrd_t *brdp) | |||
3472 | 3143 | ||
3473 | static void stli_ecppciinit(stlibrd_t *brdp) | 3144 | static void stli_ecppciinit(stlibrd_t *brdp) |
3474 | { | 3145 | { |
3475 | #ifdef DEBUG | ||
3476 | printk(KERN_DEBUG "stli_ecppciinit(brdp=%x)\n", (int) brdp); | ||
3477 | #endif | ||
3478 | |||
3479 | outb(ECP_PCISTOP, (brdp->iobase + ECP_PCICONFR)); | 3146 | outb(ECP_PCISTOP, (brdp->iobase + ECP_PCICONFR)); |
3480 | udelay(10); | 3147 | udelay(10); |
3481 | outb(0, (brdp->iobase + ECP_PCICONFR)); | 3148 | outb(0, (brdp->iobase + ECP_PCICONFR)); |
@@ -3489,11 +3156,6 @@ static char *stli_ecppcigetmemptr(stlibrd_t *brdp, unsigned long offset, int lin | |||
3489 | void *ptr; | 3156 | void *ptr; |
3490 | unsigned char val; | 3157 | unsigned char val; |
3491 | 3158 | ||
3492 | #ifdef DEBUG | ||
3493 | printk(KERN_DEBUG "stli_ecppcigetmemptr(brdp=%x,offset=%x,line=%d)\n", | ||
3494 | (int) brdp, (int) offset, line); | ||
3495 | #endif | ||
3496 | |||
3497 | if (offset > brdp->memsize) { | 3159 | if (offset > brdp->memsize) { |
3498 | printk(KERN_ERR "STALLION: shared memory pointer=%x out of " | 3160 | printk(KERN_ERR "STALLION: shared memory pointer=%x out of " |
3499 | "range at line=%d(%d), board=%d\n", | 3161 | "range at line=%d(%d), board=%d\n", |
@@ -3528,10 +3190,6 @@ static void stli_onbinit(stlibrd_t *brdp) | |||
3528 | { | 3190 | { |
3529 | unsigned long memconf; | 3191 | unsigned long memconf; |
3530 | 3192 | ||
3531 | #ifdef DEBUG | ||
3532 | printk(KERN_DEBUG "stli_onbinit(brdp=%d)\n", (int) brdp); | ||
3533 | #endif | ||
3534 | |||
3535 | outb(ONB_ATSTOP, (brdp->iobase + ONB_ATCONFR)); | 3193 | outb(ONB_ATSTOP, (brdp->iobase + ONB_ATCONFR)); |
3536 | udelay(10); | 3194 | udelay(10); |
3537 | outb(ONB_ATDISABLE, (brdp->iobase + ONB_ATCONFR)); | 3195 | outb(ONB_ATDISABLE, (brdp->iobase + ONB_ATCONFR)); |
@@ -3547,9 +3205,6 @@ static void stli_onbinit(stlibrd_t *brdp) | |||
3547 | 3205 | ||
3548 | static void stli_onbenable(stlibrd_t *brdp) | 3206 | static void stli_onbenable(stlibrd_t *brdp) |
3549 | { | 3207 | { |
3550 | #ifdef DEBUG | ||
3551 | printk(KERN_DEBUG "stli_onbenable(brdp=%x)\n", (int) brdp); | ||
3552 | #endif | ||
3553 | outb((brdp->enabval | ONB_ATENABLE), (brdp->iobase + ONB_ATCONFR)); | 3208 | outb((brdp->enabval | ONB_ATENABLE), (brdp->iobase + ONB_ATCONFR)); |
3554 | } | 3209 | } |
3555 | 3210 | ||
@@ -3557,9 +3212,6 @@ static void stli_onbenable(stlibrd_t *brdp) | |||
3557 | 3212 | ||
3558 | static void stli_onbdisable(stlibrd_t *brdp) | 3213 | static void stli_onbdisable(stlibrd_t *brdp) |
3559 | { | 3214 | { |
3560 | #ifdef DEBUG | ||
3561 | printk(KERN_DEBUG "stli_onbdisable(brdp=%x)\n", (int) brdp); | ||
3562 | #endif | ||
3563 | outb((brdp->enabval | ONB_ATDISABLE), (brdp->iobase + ONB_ATCONFR)); | 3215 | outb((brdp->enabval | ONB_ATDISABLE), (brdp->iobase + ONB_ATCONFR)); |
3564 | } | 3216 | } |
3565 | 3217 | ||
@@ -3569,11 +3221,6 @@ static char *stli_onbgetmemptr(stlibrd_t *brdp, unsigned long offset, int line) | |||
3569 | { | 3221 | { |
3570 | void *ptr; | 3222 | void *ptr; |
3571 | 3223 | ||
3572 | #ifdef DEBUG | ||
3573 | printk(KERN_DEBUG "stli_onbgetmemptr(brdp=%x,offset=%x)\n", (int) brdp, | ||
3574 | (int) offset); | ||
3575 | #endif | ||
3576 | |||
3577 | if (offset > brdp->memsize) { | 3224 | if (offset > brdp->memsize) { |
3578 | printk(KERN_ERR "STALLION: shared memory pointer=%x out of " | 3225 | printk(KERN_ERR "STALLION: shared memory pointer=%x out of " |
3579 | "range at line=%d(%d), brd=%d\n", | 3226 | "range at line=%d(%d), brd=%d\n", |
@@ -3589,11 +3236,6 @@ static char *stli_onbgetmemptr(stlibrd_t *brdp, unsigned long offset, int line) | |||
3589 | 3236 | ||
3590 | static void stli_onbreset(stlibrd_t *brdp) | 3237 | static void stli_onbreset(stlibrd_t *brdp) |
3591 | { | 3238 | { |
3592 | |||
3593 | #ifdef DEBUG | ||
3594 | printk(KERN_DEBUG "stli_onbreset(brdp=%x)\n", (int) brdp); | ||
3595 | #endif | ||
3596 | |||
3597 | outb(ONB_ATSTOP, (brdp->iobase + ONB_ATCONFR)); | 3239 | outb(ONB_ATSTOP, (brdp->iobase + ONB_ATCONFR)); |
3598 | udelay(10); | 3240 | udelay(10); |
3599 | outb(ONB_ATDISABLE, (brdp->iobase + ONB_ATCONFR)); | 3241 | outb(ONB_ATDISABLE, (brdp->iobase + ONB_ATCONFR)); |
@@ -3610,10 +3252,6 @@ static void stli_onbeinit(stlibrd_t *brdp) | |||
3610 | { | 3252 | { |
3611 | unsigned long memconf; | 3253 | unsigned long memconf; |
3612 | 3254 | ||
3613 | #ifdef DEBUG | ||
3614 | printk(KERN_DEBUG "stli_onbeinit(brdp=%d)\n", (int) brdp); | ||
3615 | #endif | ||
3616 | |||
3617 | outb(0x1, (brdp->iobase + ONB_EIBRDENAB)); | 3255 | outb(0x1, (brdp->iobase + ONB_EIBRDENAB)); |
3618 | outb(ONB_EISTOP, (brdp->iobase + ONB_EICONFR)); | 3256 | outb(ONB_EISTOP, (brdp->iobase + ONB_EICONFR)); |
3619 | udelay(10); | 3257 | udelay(10); |
@@ -3632,9 +3270,6 @@ static void stli_onbeinit(stlibrd_t *brdp) | |||
3632 | 3270 | ||
3633 | static void stli_onbeenable(stlibrd_t *brdp) | 3271 | static void stli_onbeenable(stlibrd_t *brdp) |
3634 | { | 3272 | { |
3635 | #ifdef DEBUG | ||
3636 | printk(KERN_DEBUG "stli_onbeenable(brdp=%x)\n", (int) brdp); | ||
3637 | #endif | ||
3638 | outb(ONB_EIENABLE, (brdp->iobase + ONB_EICONFR)); | 3273 | outb(ONB_EIENABLE, (brdp->iobase + ONB_EICONFR)); |
3639 | } | 3274 | } |
3640 | 3275 | ||
@@ -3642,9 +3277,6 @@ static void stli_onbeenable(stlibrd_t *brdp) | |||
3642 | 3277 | ||
3643 | static void stli_onbedisable(stlibrd_t *brdp) | 3278 | static void stli_onbedisable(stlibrd_t *brdp) |
3644 | { | 3279 | { |
3645 | #ifdef DEBUG | ||
3646 | printk(KERN_DEBUG "stli_onbedisable(brdp=%x)\n", (int) brdp); | ||
3647 | #endif | ||
3648 | outb(ONB_EIDISABLE, (brdp->iobase + ONB_EICONFR)); | 3280 | outb(ONB_EIDISABLE, (brdp->iobase + ONB_EICONFR)); |
3649 | } | 3281 | } |
3650 | 3282 | ||
@@ -3652,13 +3284,8 @@ static void stli_onbedisable(stlibrd_t *brdp) | |||
3652 | 3284 | ||
3653 | static char *stli_onbegetmemptr(stlibrd_t *brdp, unsigned long offset, int line) | 3285 | static char *stli_onbegetmemptr(stlibrd_t *brdp, unsigned long offset, int line) |
3654 | { | 3286 | { |
3655 | void *ptr; | 3287 | void *ptr; |
3656 | unsigned char val; | 3288 | unsigned char val; |
3657 | |||
3658 | #ifdef DEBUG | ||
3659 | printk(KERN_DEBUG "stli_onbegetmemptr(brdp=%x,offset=%x,line=%d)\n", | ||
3660 | (int) brdp, (int) offset, line); | ||
3661 | #endif | ||
3662 | 3289 | ||
3663 | if (offset > brdp->memsize) { | 3290 | if (offset > brdp->memsize) { |
3664 | printk(KERN_ERR "STALLION: shared memory pointer=%x out of " | 3291 | printk(KERN_ERR "STALLION: shared memory pointer=%x out of " |
@@ -3681,11 +3308,6 @@ static char *stli_onbegetmemptr(stlibrd_t *brdp, unsigned long offset, int line) | |||
3681 | 3308 | ||
3682 | static void stli_onbereset(stlibrd_t *brdp) | 3309 | static void stli_onbereset(stlibrd_t *brdp) |
3683 | { | 3310 | { |
3684 | |||
3685 | #ifdef DEBUG | ||
3686 | printk(KERN_ERR "stli_onbereset(brdp=%x)\n", (int) brdp); | ||
3687 | #endif | ||
3688 | |||
3689 | outb(ONB_EISTOP, (brdp->iobase + ONB_EICONFR)); | 3311 | outb(ONB_EISTOP, (brdp->iobase + ONB_EICONFR)); |
3690 | udelay(10); | 3312 | udelay(10); |
3691 | outb(ONB_EIDISABLE, (brdp->iobase + ONB_EICONFR)); | 3313 | outb(ONB_EIDISABLE, (brdp->iobase + ONB_EICONFR)); |
@@ -3700,11 +3322,6 @@ static void stli_onbereset(stlibrd_t *brdp) | |||
3700 | 3322 | ||
3701 | static void stli_bbyinit(stlibrd_t *brdp) | 3323 | static void stli_bbyinit(stlibrd_t *brdp) |
3702 | { | 3324 | { |
3703 | |||
3704 | #ifdef DEBUG | ||
3705 | printk(KERN_ERR "stli_bbyinit(brdp=%d)\n", (int) brdp); | ||
3706 | #endif | ||
3707 | |||
3708 | outb(BBY_ATSTOP, (brdp->iobase + BBY_ATCONFR)); | 3325 | outb(BBY_ATSTOP, (brdp->iobase + BBY_ATCONFR)); |
3709 | udelay(10); | 3326 | udelay(10); |
3710 | outb(0, (brdp->iobase + BBY_ATCONFR)); | 3327 | outb(0, (brdp->iobase + BBY_ATCONFR)); |
@@ -3717,24 +3334,13 @@ static void stli_bbyinit(stlibrd_t *brdp) | |||
3717 | 3334 | ||
3718 | static char *stli_bbygetmemptr(stlibrd_t *brdp, unsigned long offset, int line) | 3335 | static char *stli_bbygetmemptr(stlibrd_t *brdp, unsigned long offset, int line) |
3719 | { | 3336 | { |
3720 | void *ptr; | 3337 | void *ptr; |
3721 | unsigned char val; | 3338 | unsigned char val; |
3722 | 3339 | ||
3723 | #ifdef DEBUG | 3340 | BUG_ON(offset > brdp->memsize); |
3724 | printk(KERN_ERR "stli_bbygetmemptr(brdp=%x,offset=%x)\n", (int) brdp, | ||
3725 | (int) offset); | ||
3726 | #endif | ||
3727 | 3341 | ||
3728 | if (offset > brdp->memsize) { | 3342 | ptr = brdp->membase + (offset % BBY_PAGESIZE); |
3729 | printk(KERN_ERR "STALLION: shared memory pointer=%x out of " | 3343 | val = (unsigned char) (offset / BBY_PAGESIZE); |
3730 | "range at line=%d(%d), brd=%d\n", | ||
3731 | (int) offset, line, __LINE__, brdp->brdnr); | ||
3732 | ptr = NULL; | ||
3733 | val = 0; | ||
3734 | } else { | ||
3735 | ptr = brdp->membase + (offset % BBY_PAGESIZE); | ||
3736 | val = (unsigned char) (offset / BBY_PAGESIZE); | ||
3737 | } | ||
3738 | outb(val, (brdp->iobase + BBY_ATCONFR)); | 3344 | outb(val, (brdp->iobase + BBY_ATCONFR)); |
3739 | return(ptr); | 3345 | return(ptr); |
3740 | } | 3346 | } |
@@ -3743,11 +3349,6 @@ static char *stli_bbygetmemptr(stlibrd_t *brdp, unsigned long offset, int line) | |||
3743 | 3349 | ||
3744 | static void stli_bbyreset(stlibrd_t *brdp) | 3350 | static void stli_bbyreset(stlibrd_t *brdp) |
3745 | { | 3351 | { |
3746 | |||
3747 | #ifdef DEBUG | ||
3748 | printk(KERN_DEBUG "stli_bbyreset(brdp=%x)\n", (int) brdp); | ||
3749 | #endif | ||
3750 | |||
3751 | outb(BBY_ATSTOP, (brdp->iobase + BBY_ATCONFR)); | 3352 | outb(BBY_ATSTOP, (brdp->iobase + BBY_ATCONFR)); |
3752 | udelay(10); | 3353 | udelay(10); |
3753 | outb(0, (brdp->iobase + BBY_ATCONFR)); | 3354 | outb(0, (brdp->iobase + BBY_ATCONFR)); |
@@ -3762,11 +3363,6 @@ static void stli_bbyreset(stlibrd_t *brdp) | |||
3762 | 3363 | ||
3763 | static void stli_stalinit(stlibrd_t *brdp) | 3364 | static void stli_stalinit(stlibrd_t *brdp) |
3764 | { | 3365 | { |
3765 | |||
3766 | #ifdef DEBUG | ||
3767 | printk(KERN_DEBUG "stli_stalinit(brdp=%d)\n", (int) brdp); | ||
3768 | #endif | ||
3769 | |||
3770 | outb(0x1, brdp->iobase); | 3366 | outb(0x1, brdp->iobase); |
3771 | mdelay(1000); | 3367 | mdelay(1000); |
3772 | } | 3368 | } |
@@ -3775,36 +3371,18 @@ static void stli_stalinit(stlibrd_t *brdp) | |||
3775 | 3371 | ||
3776 | static char *stli_stalgetmemptr(stlibrd_t *brdp, unsigned long offset, int line) | 3372 | static char *stli_stalgetmemptr(stlibrd_t *brdp, unsigned long offset, int line) |
3777 | { | 3373 | { |
3778 | void *ptr; | 3374 | BUG_ON(offset > brdp->memsize); |
3779 | 3375 | return brdp->membase + (offset % STAL_PAGESIZE); | |
3780 | #ifdef DEBUG | ||
3781 | printk(KERN_DEBUG "stli_stalgetmemptr(brdp=%x,offset=%x)\n", (int) brdp, | ||
3782 | (int) offset); | ||
3783 | #endif | ||
3784 | |||
3785 | if (offset > brdp->memsize) { | ||
3786 | printk(KERN_ERR "STALLION: shared memory pointer=%x out of " | ||
3787 | "range at line=%d(%d), brd=%d\n", | ||
3788 | (int) offset, line, __LINE__, brdp->brdnr); | ||
3789 | ptr = NULL; | ||
3790 | } else { | ||
3791 | ptr = brdp->membase + (offset % STAL_PAGESIZE); | ||
3792 | } | ||
3793 | return(ptr); | ||
3794 | } | 3376 | } |
3795 | 3377 | ||
3796 | /*****************************************************************************/ | 3378 | /*****************************************************************************/ |
3797 | 3379 | ||
3798 | static void stli_stalreset(stlibrd_t *brdp) | 3380 | static void stli_stalreset(stlibrd_t *brdp) |
3799 | { | 3381 | { |
3800 | volatile unsigned long *vecp; | 3382 | u32 __iomem *vecp; |
3801 | 3383 | ||
3802 | #ifdef DEBUG | 3384 | vecp = (u32 __iomem *) (brdp->membase + 0x30); |
3803 | printk(KERN_DEBUG "stli_stalreset(brdp=%x)\n", (int) brdp); | 3385 | writel(0xffff0000, vecp); |
3804 | #endif | ||
3805 | |||
3806 | vecp = (volatile unsigned long *) (brdp->membase + 0x30); | ||
3807 | *vecp = 0xffff0000; | ||
3808 | outb(0, brdp->iobase); | 3386 | outb(0, brdp->iobase); |
3809 | mdelay(1000); | 3387 | mdelay(1000); |
3810 | } | 3388 | } |
@@ -3818,15 +3396,11 @@ static void stli_stalreset(stlibrd_t *brdp) | |||
3818 | 3396 | ||
3819 | static int stli_initecp(stlibrd_t *brdp) | 3397 | static int stli_initecp(stlibrd_t *brdp) |
3820 | { | 3398 | { |
3821 | cdkecpsig_t sig; | 3399 | cdkecpsig_t sig; |
3822 | cdkecpsig_t *sigsp; | 3400 | cdkecpsig_t __iomem *sigsp; |
3823 | unsigned int status, nxtid; | 3401 | unsigned int status, nxtid; |
3824 | char *name; | 3402 | char *name; |
3825 | int panelnr, nrports; | 3403 | int panelnr, nrports; |
3826 | |||
3827 | #ifdef DEBUG | ||
3828 | printk(KERN_DEBUG "stli_initecp(brdp=%x)\n", (int) brdp); | ||
3829 | #endif | ||
3830 | 3404 | ||
3831 | if (!request_region(brdp->iobase, brdp->iosize, "istallion")) | 3405 | if (!request_region(brdp->iobase, brdp->iosize, "istallion")) |
3832 | return -EIO; | 3406 | return -EIO; |
@@ -3834,7 +3408,7 @@ static int stli_initecp(stlibrd_t *brdp) | |||
3834 | if ((brdp->iobase == 0) || (brdp->memaddr == 0)) | 3408 | if ((brdp->iobase == 0) || (brdp->memaddr == 0)) |
3835 | { | 3409 | { |
3836 | release_region(brdp->iobase, brdp->iosize); | 3410 | release_region(brdp->iobase, brdp->iosize); |
3837 | return(-ENODEV); | 3411 | return -ENODEV; |
3838 | } | 3412 | } |
3839 | 3413 | ||
3840 | brdp->iosize = ECP_IOSIZE; | 3414 | brdp->iosize = ECP_IOSIZE; |
@@ -3903,7 +3477,7 @@ static int stli_initecp(stlibrd_t *brdp) | |||
3903 | 3477 | ||
3904 | default: | 3478 | default: |
3905 | release_region(brdp->iobase, brdp->iosize); | 3479 | release_region(brdp->iobase, brdp->iosize); |
3906 | return(-EINVAL); | 3480 | return -EINVAL; |
3907 | } | 3481 | } |
3908 | 3482 | ||
3909 | /* | 3483 | /* |
@@ -3915,10 +3489,10 @@ static int stli_initecp(stlibrd_t *brdp) | |||
3915 | EBRDINIT(brdp); | 3489 | EBRDINIT(brdp); |
3916 | 3490 | ||
3917 | brdp->membase = ioremap(brdp->memaddr, brdp->memsize); | 3491 | brdp->membase = ioremap(brdp->memaddr, brdp->memsize); |
3918 | if (brdp->membase == (void *) NULL) | 3492 | if (brdp->membase == NULL) |
3919 | { | 3493 | { |
3920 | release_region(brdp->iobase, brdp->iosize); | 3494 | release_region(brdp->iobase, brdp->iosize); |
3921 | return(-ENOMEM); | 3495 | return -ENOMEM; |
3922 | } | 3496 | } |
3923 | 3497 | ||
3924 | /* | 3498 | /* |
@@ -3927,23 +3501,14 @@ static int stli_initecp(stlibrd_t *brdp) | |||
3927 | * this is, and what it is connected to it. | 3501 | * this is, and what it is connected to it. |
3928 | */ | 3502 | */ |
3929 | EBRDENABLE(brdp); | 3503 | EBRDENABLE(brdp); |
3930 | sigsp = (cdkecpsig_t *) EBRDGETMEMPTR(brdp, CDK_SIGADDR); | 3504 | sigsp = (cdkecpsig_t __iomem *) EBRDGETMEMPTR(brdp, CDK_SIGADDR); |
3931 | memcpy(&sig, sigsp, sizeof(cdkecpsig_t)); | 3505 | memcpy(&sig, sigsp, sizeof(cdkecpsig_t)); |
3932 | EBRDDISABLE(brdp); | 3506 | EBRDDISABLE(brdp); |
3933 | 3507 | ||
3934 | #if 0 | 3508 | if (sig.magic != cpu_to_le32(ECP_MAGIC)) |
3935 | printk("%s(%d): sig-> magic=%x rom=%x panel=%x,%x,%x,%x,%x,%x,%x,%x\n", | ||
3936 | __FILE__, __LINE__, (int) sig.magic, sig.romver, sig.panelid[0], | ||
3937 | (int) sig.panelid[1], (int) sig.panelid[2], | ||
3938 | (int) sig.panelid[3], (int) sig.panelid[4], | ||
3939 | (int) sig.panelid[5], (int) sig.panelid[6], | ||
3940 | (int) sig.panelid[7]); | ||
3941 | #endif | ||
3942 | |||
3943 | if (sig.magic != ECP_MAGIC) | ||
3944 | { | 3509 | { |
3945 | release_region(brdp->iobase, brdp->iosize); | 3510 | release_region(brdp->iobase, brdp->iosize); |
3946 | return(-ENODEV); | 3511 | return -ENODEV; |
3947 | } | 3512 | } |
3948 | 3513 | ||
3949 | /* | 3514 | /* |
@@ -3967,7 +3532,7 @@ static int stli_initecp(stlibrd_t *brdp) | |||
3967 | 3532 | ||
3968 | 3533 | ||
3969 | brdp->state |= BST_FOUND; | 3534 | brdp->state |= BST_FOUND; |
3970 | return(0); | 3535 | return 0; |
3971 | } | 3536 | } |
3972 | 3537 | ||
3973 | /*****************************************************************************/ | 3538 | /*****************************************************************************/ |
@@ -3979,20 +3544,16 @@ static int stli_initecp(stlibrd_t *brdp) | |||
3979 | 3544 | ||
3980 | static int stli_initonb(stlibrd_t *brdp) | 3545 | static int stli_initonb(stlibrd_t *brdp) |
3981 | { | 3546 | { |
3982 | cdkonbsig_t sig; | 3547 | cdkonbsig_t sig; |
3983 | cdkonbsig_t *sigsp; | 3548 | cdkonbsig_t __iomem *sigsp; |
3984 | char *name; | 3549 | char *name; |
3985 | int i; | 3550 | int i; |
3986 | |||
3987 | #ifdef DEBUG | ||
3988 | printk(KERN_DEBUG "stli_initonb(brdp=%x)\n", (int) brdp); | ||
3989 | #endif | ||
3990 | 3551 | ||
3991 | /* | 3552 | /* |
3992 | * Do a basic sanity check on the IO and memory addresses. | 3553 | * Do a basic sanity check on the IO and memory addresses. |
3993 | */ | 3554 | */ |
3994 | if ((brdp->iobase == 0) || (brdp->memaddr == 0)) | 3555 | if (brdp->iobase == 0 || brdp->memaddr == 0) |
3995 | return(-ENODEV); | 3556 | return -ENODEV; |
3996 | 3557 | ||
3997 | brdp->iosize = ONB_IOSIZE; | 3558 | brdp->iosize = ONB_IOSIZE; |
3998 | 3559 | ||
@@ -4010,7 +3571,6 @@ static int stli_initonb(stlibrd_t *brdp) | |||
4010 | case BRD_ONBOARD2: | 3571 | case BRD_ONBOARD2: |
4011 | case BRD_ONBOARD2_32: | 3572 | case BRD_ONBOARD2_32: |
4012 | case BRD_ONBOARDRS: | 3573 | case BRD_ONBOARDRS: |
4013 | brdp->membase = (void *) brdp->memaddr; | ||
4014 | brdp->memsize = ONB_MEMSIZE; | 3574 | brdp->memsize = ONB_MEMSIZE; |
4015 | brdp->pagesize = ONB_ATPAGESIZE; | 3575 | brdp->pagesize = ONB_ATPAGESIZE; |
4016 | brdp->init = stli_onbinit; | 3576 | brdp->init = stli_onbinit; |
@@ -4028,7 +3588,6 @@ static int stli_initonb(stlibrd_t *brdp) | |||
4028 | break; | 3588 | break; |
4029 | 3589 | ||
4030 | case BRD_ONBOARDE: | 3590 | case BRD_ONBOARDE: |
4031 | brdp->membase = (void *) brdp->memaddr; | ||
4032 | brdp->memsize = ONB_EIMEMSIZE; | 3591 | brdp->memsize = ONB_EIMEMSIZE; |
4033 | brdp->pagesize = ONB_EIPAGESIZE; | 3592 | brdp->pagesize = ONB_EIPAGESIZE; |
4034 | brdp->init = stli_onbeinit; | 3593 | brdp->init = stli_onbeinit; |
@@ -4044,7 +3603,6 @@ static int stli_initonb(stlibrd_t *brdp) | |||
4044 | case BRD_BRUMBY4: | 3603 | case BRD_BRUMBY4: |
4045 | case BRD_BRUMBY8: | 3604 | case BRD_BRUMBY8: |
4046 | case BRD_BRUMBY16: | 3605 | case BRD_BRUMBY16: |
4047 | brdp->membase = (void *) brdp->memaddr; | ||
4048 | brdp->memsize = BBY_MEMSIZE; | 3606 | brdp->memsize = BBY_MEMSIZE; |
4049 | brdp->pagesize = BBY_PAGESIZE; | 3607 | brdp->pagesize = BBY_PAGESIZE; |
4050 | brdp->init = stli_bbyinit; | 3608 | brdp->init = stli_bbyinit; |
@@ -4058,7 +3616,6 @@ static int stli_initonb(stlibrd_t *brdp) | |||
4058 | break; | 3616 | break; |
4059 | 3617 | ||
4060 | case BRD_STALLION: | 3618 | case BRD_STALLION: |
4061 | brdp->membase = (void *) brdp->memaddr; | ||
4062 | brdp->memsize = STAL_MEMSIZE; | 3619 | brdp->memsize = STAL_MEMSIZE; |
4063 | brdp->pagesize = STAL_PAGESIZE; | 3620 | brdp->pagesize = STAL_PAGESIZE; |
4064 | brdp->init = stli_stalinit; | 3621 | brdp->init = stli_stalinit; |
@@ -4073,7 +3630,7 @@ static int stli_initonb(stlibrd_t *brdp) | |||
4073 | 3630 | ||
4074 | default: | 3631 | default: |
4075 | release_region(brdp->iobase, brdp->iosize); | 3632 | release_region(brdp->iobase, brdp->iosize); |
4076 | return(-EINVAL); | 3633 | return -EINVAL; |
4077 | } | 3634 | } |
4078 | 3635 | ||
4079 | /* | 3636 | /* |
@@ -4085,10 +3642,10 @@ static int stli_initonb(stlibrd_t *brdp) | |||
4085 | EBRDINIT(brdp); | 3642 | EBRDINIT(brdp); |
4086 | 3643 | ||
4087 | brdp->membase = ioremap(brdp->memaddr, brdp->memsize); | 3644 | brdp->membase = ioremap(brdp->memaddr, brdp->memsize); |
4088 | if (brdp->membase == (void *) NULL) | 3645 | if (brdp->membase == NULL) |
4089 | { | 3646 | { |
4090 | release_region(brdp->iobase, brdp->iosize); | 3647 | release_region(brdp->iobase, brdp->iosize); |
4091 | return(-ENOMEM); | 3648 | return -ENOMEM; |
4092 | } | 3649 | } |
4093 | 3650 | ||
4094 | /* | 3651 | /* |
@@ -4097,21 +3654,17 @@ static int stli_initonb(stlibrd_t *brdp) | |||
4097 | * this is, and how many ports. | 3654 | * this is, and how many ports. |
4098 | */ | 3655 | */ |
4099 | EBRDENABLE(brdp); | 3656 | EBRDENABLE(brdp); |
4100 | sigsp = (cdkonbsig_t *) EBRDGETMEMPTR(brdp, CDK_SIGADDR); | 3657 | sigsp = (cdkonbsig_t __iomem *) EBRDGETMEMPTR(brdp, CDK_SIGADDR); |
4101 | memcpy(&sig, sigsp, sizeof(cdkonbsig_t)); | 3658 | memcpy_fromio(&sig, sigsp, sizeof(cdkonbsig_t)); |
4102 | EBRDDISABLE(brdp); | 3659 | EBRDDISABLE(brdp); |
4103 | 3660 | ||
4104 | #if 0 | 3661 | if (sig.magic0 != cpu_to_le16(ONB_MAGIC0) || |
4105 | printk("%s(%d): sig-> magic=%x:%x:%x:%x romver=%x amask=%x:%x:%x\n", | 3662 | sig.magic1 != cpu_to_le16(ONB_MAGIC1) || |
4106 | __FILE__, __LINE__, sig.magic0, sig.magic1, sig.magic2, | 3663 | sig.magic2 != cpu_to_le16(ONB_MAGIC2) || |
4107 | sig.magic3, sig.romver, sig.amask0, sig.amask1, sig.amask2); | 3664 | sig.magic3 != cpu_to_le16(ONB_MAGIC3)) |
4108 | #endif | ||
4109 | |||
4110 | if ((sig.magic0 != ONB_MAGIC0) || (sig.magic1 != ONB_MAGIC1) || | ||
4111 | (sig.magic2 != ONB_MAGIC2) || (sig.magic3 != ONB_MAGIC3)) | ||
4112 | { | 3665 | { |
4113 | release_region(brdp->iobase, brdp->iosize); | 3666 | release_region(brdp->iobase, brdp->iosize); |
4114 | return(-ENODEV); | 3667 | return -ENODEV; |
4115 | } | 3668 | } |
4116 | 3669 | ||
4117 | /* | 3670 | /* |
@@ -4132,7 +3685,7 @@ static int stli_initonb(stlibrd_t *brdp) | |||
4132 | 3685 | ||
4133 | 3686 | ||
4134 | brdp->state |= BST_FOUND; | 3687 | brdp->state |= BST_FOUND; |
4135 | return(0); | 3688 | return 0; |
4136 | } | 3689 | } |
4137 | 3690 | ||
4138 | /*****************************************************************************/ | 3691 | /*****************************************************************************/ |
@@ -4145,31 +3698,25 @@ static int stli_initonb(stlibrd_t *brdp) | |||
4145 | 3698 | ||
4146 | static int stli_startbrd(stlibrd_t *brdp) | 3699 | static int stli_startbrd(stlibrd_t *brdp) |
4147 | { | 3700 | { |
4148 | volatile cdkhdr_t *hdrp; | 3701 | cdkhdr_t __iomem *hdrp; |
4149 | volatile cdkmem_t *memp; | 3702 | cdkmem_t __iomem *memp; |
4150 | volatile cdkasy_t *ap; | 3703 | cdkasy_t __iomem *ap; |
4151 | unsigned long flags; | 3704 | unsigned long flags; |
4152 | stliport_t *portp; | 3705 | stliport_t *portp; |
4153 | int portnr, nrdevs, i, rc; | 3706 | int portnr, nrdevs, i, rc = 0; |
4154 | 3707 | u32 memoff; | |
4155 | #ifdef DEBUG | 3708 | |
4156 | printk(KERN_DEBUG "stli_startbrd(brdp=%x)\n", (int) brdp); | 3709 | spin_lock_irqsave(&brd_lock, flags); |
4157 | #endif | ||
4158 | |||
4159 | rc = 0; | ||
4160 | |||
4161 | save_flags(flags); | ||
4162 | cli(); | ||
4163 | EBRDENABLE(brdp); | 3710 | EBRDENABLE(brdp); |
4164 | hdrp = (volatile cdkhdr_t *) EBRDGETMEMPTR(brdp, CDK_CDKADDR); | 3711 | hdrp = (cdkhdr_t __iomem *) EBRDGETMEMPTR(brdp, CDK_CDKADDR); |
4165 | nrdevs = hdrp->nrdevs; | 3712 | nrdevs = hdrp->nrdevs; |
4166 | 3713 | ||
4167 | #if 0 | 3714 | #if 0 |
4168 | printk("%s(%d): CDK version %d.%d.%d --> " | 3715 | printk("%s(%d): CDK version %d.%d.%d --> " |
4169 | "nrdevs=%d memp=%x hostp=%x slavep=%x\n", | 3716 | "nrdevs=%d memp=%x hostp=%x slavep=%x\n", |
4170 | __FILE__, __LINE__, hdrp->ver_release, hdrp->ver_modification, | 3717 | __FILE__, __LINE__, readb(&hdrp->ver_release), readb(&hdrp->ver_modification), |
4171 | hdrp->ver_fix, nrdevs, (int) hdrp->memp, (int) hdrp->hostp, | 3718 | readb(&hdrp->ver_fix), nrdevs, (int) readl(&hdrp->memp), readl(&hdrp->hostp), |
4172 | (int) hdrp->slavep); | 3719 | readl(&hdrp->slavep)); |
4173 | #endif | 3720 | #endif |
4174 | 3721 | ||
4175 | if (nrdevs < (brdp->nrports + 1)) { | 3722 | if (nrdevs < (brdp->nrports + 1)) { |
@@ -4181,14 +3728,14 @@ static int stli_startbrd(stlibrd_t *brdp) | |||
4181 | brdp->hostoffset = hdrp->hostp - CDK_CDKADDR; | 3728 | brdp->hostoffset = hdrp->hostp - CDK_CDKADDR; |
4182 | brdp->slaveoffset = hdrp->slavep - CDK_CDKADDR; | 3729 | brdp->slaveoffset = hdrp->slavep - CDK_CDKADDR; |
4183 | brdp->bitsize = (nrdevs + 7) / 8; | 3730 | brdp->bitsize = (nrdevs + 7) / 8; |
4184 | memp = (volatile cdkmem_t *) hdrp->memp; | 3731 | memoff = readl(&hdrp->memp); |
4185 | if (((unsigned long) memp) > brdp->memsize) { | 3732 | if (memoff > brdp->memsize) { |
4186 | printk(KERN_ERR "STALLION: corrupted shared memory region?\n"); | 3733 | printk(KERN_ERR "STALLION: corrupted shared memory region?\n"); |
4187 | rc = -EIO; | 3734 | rc = -EIO; |
4188 | goto stli_donestartup; | 3735 | goto stli_donestartup; |
4189 | } | 3736 | } |
4190 | memp = (volatile cdkmem_t *) EBRDGETMEMPTR(brdp, (unsigned long) memp); | 3737 | memp = (cdkmem_t __iomem *) EBRDGETMEMPTR(brdp, memoff); |
4191 | if (memp->dtype != TYP_ASYNCTRL) { | 3738 | if (readw(&memp->dtype) != TYP_ASYNCTRL) { |
4192 | printk(KERN_ERR "STALLION: no slave control device found\n"); | 3739 | printk(KERN_ERR "STALLION: no slave control device found\n"); |
4193 | goto stli_donestartup; | 3740 | goto stli_donestartup; |
4194 | } | 3741 | } |
@@ -4200,19 +3747,19 @@ static int stli_startbrd(stlibrd_t *brdp) | |||
4200 | * change pages while reading memory map. | 3747 | * change pages while reading memory map. |
4201 | */ | 3748 | */ |
4202 | for (i = 1, portnr = 0; (i < nrdevs); i++, portnr++, memp++) { | 3749 | for (i = 1, portnr = 0; (i < nrdevs); i++, portnr++, memp++) { |
4203 | if (memp->dtype != TYP_ASYNC) | 3750 | if (readw(&memp->dtype) != TYP_ASYNC) |
4204 | break; | 3751 | break; |
4205 | portp = brdp->ports[portnr]; | 3752 | portp = brdp->ports[portnr]; |
4206 | if (portp == (stliport_t *) NULL) | 3753 | if (portp == NULL) |
4207 | break; | 3754 | break; |
4208 | portp->devnr = i; | 3755 | portp->devnr = i; |
4209 | portp->addr = memp->offset; | 3756 | portp->addr = readl(&memp->offset); |
4210 | portp->reqbit = (unsigned char) (0x1 << (i * 8 / nrdevs)); | 3757 | portp->reqbit = (unsigned char) (0x1 << (i * 8 / nrdevs)); |
4211 | portp->portidx = (unsigned char) (i / 8); | 3758 | portp->portidx = (unsigned char) (i / 8); |
4212 | portp->portbit = (unsigned char) (0x1 << (i % 8)); | 3759 | portp->portbit = (unsigned char) (0x1 << (i % 8)); |
4213 | } | 3760 | } |
4214 | 3761 | ||
4215 | hdrp->slavereq = 0xff; | 3762 | writeb(0xff, &hdrp->slavereq); |
4216 | 3763 | ||
4217 | /* | 3764 | /* |
4218 | * For each port setup a local copy of the RX and TX buffer offsets | 3765 | * For each port setup a local copy of the RX and TX buffer offsets |
@@ -4221,22 +3768,22 @@ static int stli_startbrd(stlibrd_t *brdp) | |||
4221 | */ | 3768 | */ |
4222 | for (i = 1, portnr = 0; (i < nrdevs); i++, portnr++) { | 3769 | for (i = 1, portnr = 0; (i < nrdevs); i++, portnr++) { |
4223 | portp = brdp->ports[portnr]; | 3770 | portp = brdp->ports[portnr]; |
4224 | if (portp == (stliport_t *) NULL) | 3771 | if (portp == NULL) |
4225 | break; | 3772 | break; |
4226 | if (portp->addr == 0) | 3773 | if (portp->addr == 0) |
4227 | break; | 3774 | break; |
4228 | ap = (volatile cdkasy_t *) EBRDGETMEMPTR(brdp, portp->addr); | 3775 | ap = (cdkasy_t __iomem *) EBRDGETMEMPTR(brdp, portp->addr); |
4229 | if (ap != (volatile cdkasy_t *) NULL) { | 3776 | if (ap != NULL) { |
4230 | portp->rxsize = ap->rxq.size; | 3777 | portp->rxsize = readw(&ap->rxq.size); |
4231 | portp->txsize = ap->txq.size; | 3778 | portp->txsize = readw(&ap->txq.size); |
4232 | portp->rxoffset = ap->rxq.offset; | 3779 | portp->rxoffset = readl(&ap->rxq.offset); |
4233 | portp->txoffset = ap->txq.offset; | 3780 | portp->txoffset = readl(&ap->txq.offset); |
4234 | } | 3781 | } |
4235 | } | 3782 | } |
4236 | 3783 | ||
4237 | stli_donestartup: | 3784 | stli_donestartup: |
4238 | EBRDDISABLE(brdp); | 3785 | EBRDDISABLE(brdp); |
4239 | restore_flags(flags); | 3786 | spin_unlock_irqrestore(&brd_lock, flags); |
4240 | 3787 | ||
4241 | if (rc == 0) | 3788 | if (rc == 0) |
4242 | brdp->state |= BST_STARTED; | 3789 | brdp->state |= BST_STARTED; |
@@ -4247,7 +3794,7 @@ stli_donestartup: | |||
4247 | add_timer(&stli_timerlist); | 3794 | add_timer(&stli_timerlist); |
4248 | } | 3795 | } |
4249 | 3796 | ||
4250 | return(rc); | 3797 | return rc; |
4251 | } | 3798 | } |
4252 | 3799 | ||
4253 | /*****************************************************************************/ | 3800 | /*****************************************************************************/ |
@@ -4258,10 +3805,6 @@ stli_donestartup: | |||
4258 | 3805 | ||
4259 | static int __init stli_brdinit(stlibrd_t *brdp) | 3806 | static int __init stli_brdinit(stlibrd_t *brdp) |
4260 | { | 3807 | { |
4261 | #ifdef DEBUG | ||
4262 | printk(KERN_DEBUG "stli_brdinit(brdp=%x)\n", (int) brdp); | ||
4263 | #endif | ||
4264 | |||
4265 | stli_brds[brdp->brdnr] = brdp; | 3808 | stli_brds[brdp->brdnr] = brdp; |
4266 | 3809 | ||
4267 | switch (brdp->brdtype) { | 3810 | switch (brdp->brdtype) { |
@@ -4289,11 +3832,11 @@ static int __init stli_brdinit(stlibrd_t *brdp) | |||
4289 | case BRD_ECHPCI: | 3832 | case BRD_ECHPCI: |
4290 | printk(KERN_ERR "STALLION: %s board type not supported in " | 3833 | printk(KERN_ERR "STALLION: %s board type not supported in " |
4291 | "this driver\n", stli_brdnames[brdp->brdtype]); | 3834 | "this driver\n", stli_brdnames[brdp->brdtype]); |
4292 | return(ENODEV); | 3835 | return -ENODEV; |
4293 | default: | 3836 | default: |
4294 | printk(KERN_ERR "STALLION: board=%d is unknown board " | 3837 | printk(KERN_ERR "STALLION: board=%d is unknown board " |
4295 | "type=%d\n", brdp->brdnr, brdp->brdtype); | 3838 | "type=%d\n", brdp->brdnr, brdp->brdtype); |
4296 | return(ENODEV); | 3839 | return -ENODEV; |
4297 | } | 3840 | } |
4298 | 3841 | ||
4299 | if ((brdp->state & BST_FOUND) == 0) { | 3842 | if ((brdp->state & BST_FOUND) == 0) { |
@@ -4301,7 +3844,7 @@ static int __init stli_brdinit(stlibrd_t *brdp) | |||
4301 | "io=%x mem=%x\n", | 3844 | "io=%x mem=%x\n", |
4302 | stli_brdnames[brdp->brdtype], brdp->brdnr, | 3845 | stli_brdnames[brdp->brdtype], brdp->brdnr, |
4303 | brdp->iobase, (int) brdp->memaddr); | 3846 | brdp->iobase, (int) brdp->memaddr); |
4304 | return(ENODEV); | 3847 | return -ENODEV; |
4305 | } | 3848 | } |
4306 | 3849 | ||
4307 | stli_initports(brdp); | 3850 | stli_initports(brdp); |
@@ -4309,7 +3852,7 @@ static int __init stli_brdinit(stlibrd_t *brdp) | |||
4309 | "nrpanels=%d nrports=%d\n", stli_brdnames[brdp->brdtype], | 3852 | "nrpanels=%d nrports=%d\n", stli_brdnames[brdp->brdtype], |
4310 | brdp->brdnr, brdp->iobase, (int) brdp->memaddr, | 3853 | brdp->brdnr, brdp->iobase, (int) brdp->memaddr, |
4311 | brdp->nrpanels, brdp->nrports); | 3854 | brdp->nrpanels, brdp->nrports); |
4312 | return(0); | 3855 | return 0; |
4313 | } | 3856 | } |
4314 | 3857 | ||
4315 | /*****************************************************************************/ | 3858 | /*****************************************************************************/ |
@@ -4321,14 +3864,10 @@ static int __init stli_brdinit(stlibrd_t *brdp) | |||
4321 | 3864 | ||
4322 | static int stli_eisamemprobe(stlibrd_t *brdp) | 3865 | static int stli_eisamemprobe(stlibrd_t *brdp) |
4323 | { | 3866 | { |
4324 | cdkecpsig_t ecpsig, *ecpsigp; | 3867 | cdkecpsig_t ecpsig, __iomem *ecpsigp; |
4325 | cdkonbsig_t onbsig, *onbsigp; | 3868 | cdkonbsig_t onbsig, __iomem *onbsigp; |
4326 | int i, foundit; | 3869 | int i, foundit; |
4327 | 3870 | ||
4328 | #ifdef DEBUG | ||
4329 | printk(KERN_DEBUG "stli_eisamemprobe(brdp=%x)\n", (int) brdp); | ||
4330 | #endif | ||
4331 | |||
4332 | /* | 3871 | /* |
4333 | * First up we reset the board, to get it into a known state. There | 3872 | * First up we reset the board, to get it into a known state. There |
4334 | * is only 2 board types here we need to worry about. Don;t use the | 3873 | * is only 2 board types here we need to worry about. Don;t use the |
@@ -4352,7 +3891,7 @@ static int stli_eisamemprobe(stlibrd_t *brdp) | |||
4352 | mdelay(1); | 3891 | mdelay(1); |
4353 | stli_onbeenable(brdp); | 3892 | stli_onbeenable(brdp); |
4354 | } else { | 3893 | } else { |
4355 | return(-ENODEV); | 3894 | return -ENODEV; |
4356 | } | 3895 | } |
4357 | 3896 | ||
4358 | foundit = 0; | 3897 | foundit = 0; |
@@ -4364,25 +3903,24 @@ static int stli_eisamemprobe(stlibrd_t *brdp) | |||
4364 | */ | 3903 | */ |
4365 | for (i = 0; (i < stli_eisamempsize); i++) { | 3904 | for (i = 0; (i < stli_eisamempsize); i++) { |
4366 | brdp->memaddr = stli_eisamemprobeaddrs[i]; | 3905 | brdp->memaddr = stli_eisamemprobeaddrs[i]; |
4367 | brdp->membase = (void *) brdp->memaddr; | ||
4368 | brdp->membase = ioremap(brdp->memaddr, brdp->memsize); | 3906 | brdp->membase = ioremap(brdp->memaddr, brdp->memsize); |
4369 | if (brdp->membase == (void *) NULL) | 3907 | if (brdp->membase == NULL) |
4370 | continue; | 3908 | continue; |
4371 | 3909 | ||
4372 | if (brdp->brdtype == BRD_ECPE) { | 3910 | if (brdp->brdtype == BRD_ECPE) { |
4373 | ecpsigp = (cdkecpsig_t *) stli_ecpeigetmemptr(brdp, | 3911 | ecpsigp = (cdkecpsig_t __iomem *) stli_ecpeigetmemptr(brdp, |
4374 | CDK_SIGADDR, __LINE__); | 3912 | CDK_SIGADDR, __LINE__); |
4375 | memcpy(&ecpsig, ecpsigp, sizeof(cdkecpsig_t)); | 3913 | memcpy_fromio(&ecpsig, ecpsigp, sizeof(cdkecpsig_t)); |
4376 | if (ecpsig.magic == ECP_MAGIC) | 3914 | if (ecpsig.magic == cpu_to_le32(ECP_MAGIC)) |
4377 | foundit = 1; | 3915 | foundit = 1; |
4378 | } else { | 3916 | } else { |
4379 | onbsigp = (cdkonbsig_t *) stli_onbegetmemptr(brdp, | 3917 | onbsigp = (cdkonbsig_t __iomem *) stli_onbegetmemptr(brdp, |
4380 | CDK_SIGADDR, __LINE__); | 3918 | CDK_SIGADDR, __LINE__); |
4381 | memcpy(&onbsig, onbsigp, sizeof(cdkonbsig_t)); | 3919 | memcpy_fromio(&onbsig, onbsigp, sizeof(cdkonbsig_t)); |
4382 | if ((onbsig.magic0 == ONB_MAGIC0) && | 3920 | if ((onbsig.magic0 == cpu_to_le16(ONB_MAGIC0)) && |
4383 | (onbsig.magic1 == ONB_MAGIC1) && | 3921 | (onbsig.magic1 == cpu_to_le16(ONB_MAGIC1)) && |
4384 | (onbsig.magic2 == ONB_MAGIC2) && | 3922 | (onbsig.magic2 == cpu_to_le16(ONB_MAGIC2)) && |
4385 | (onbsig.magic3 == ONB_MAGIC3)) | 3923 | (onbsig.magic3 == cpu_to_le16(ONB_MAGIC3))) |
4386 | foundit = 1; | 3924 | foundit = 1; |
4387 | } | 3925 | } |
4388 | 3926 | ||
@@ -4406,9 +3944,9 @@ static int stli_eisamemprobe(stlibrd_t *brdp) | |||
4406 | printk(KERN_ERR "STALLION: failed to probe shared memory " | 3944 | printk(KERN_ERR "STALLION: failed to probe shared memory " |
4407 | "region for %s in EISA slot=%d\n", | 3945 | "region for %s in EISA slot=%d\n", |
4408 | stli_brdnames[brdp->brdtype], (brdp->iobase >> 12)); | 3946 | stli_brdnames[brdp->brdtype], (brdp->iobase >> 12)); |
4409 | return(-ENODEV); | 3947 | return -ENODEV; |
4410 | } | 3948 | } |
4411 | return(0); | 3949 | return 0; |
4412 | } | 3950 | } |
4413 | 3951 | ||
4414 | static int stli_getbrdnr(void) | 3952 | static int stli_getbrdnr(void) |
@@ -4439,22 +3977,16 @@ static int stli_getbrdnr(void) | |||
4439 | 3977 | ||
4440 | static int stli_findeisabrds(void) | 3978 | static int stli_findeisabrds(void) |
4441 | { | 3979 | { |
4442 | stlibrd_t *brdp; | 3980 | stlibrd_t *brdp; |
4443 | unsigned int iobase, eid; | 3981 | unsigned int iobase, eid; |
4444 | int i; | 3982 | int i; |
4445 | |||
4446 | #ifdef DEBUG | ||
4447 | printk(KERN_DEBUG "stli_findeisabrds()\n"); | ||
4448 | #endif | ||
4449 | 3983 | ||
4450 | /* | 3984 | /* |
4451 | * Firstly check if this is an EISA system. Do this by probing for | 3985 | * Firstly check if this is an EISA system. If this is not an EISA system then |
4452 | * the system board EISA ID. If this is not an EISA system then | ||
4453 | * don't bother going any further! | 3986 | * don't bother going any further! |
4454 | */ | 3987 | */ |
4455 | outb(0xff, 0xc80); | 3988 | if (EISA_bus) |
4456 | if (inb(0xc80) == 0xff) | 3989 | return 0; |
4457 | return(0); | ||
4458 | 3990 | ||
4459 | /* | 3991 | /* |
4460 | * Looks like an EISA system, so go searching for EISA boards. | 3992 | * Looks like an EISA system, so go searching for EISA boards. |
@@ -4472,7 +4004,7 @@ static int stli_findeisabrds(void) | |||
4472 | */ | 4004 | */ |
4473 | for (i = 0; (i < STL_MAXBRDS); i++) { | 4005 | for (i = 0; (i < STL_MAXBRDS); i++) { |
4474 | brdp = stli_brds[i]; | 4006 | brdp = stli_brds[i]; |
4475 | if (brdp == (stlibrd_t *) NULL) | 4007 | if (brdp == NULL) |
4476 | continue; | 4008 | continue; |
4477 | if (brdp->iobase == iobase) | 4009 | if (brdp->iobase == iobase) |
4478 | break; | 4010 | break; |
@@ -4484,10 +4016,10 @@ static int stli_findeisabrds(void) | |||
4484 | * We have found a Stallion board and it is not configured already. | 4016 | * We have found a Stallion board and it is not configured already. |
4485 | * Allocate a board structure and initialize it. | 4017 | * Allocate a board structure and initialize it. |
4486 | */ | 4018 | */ |
4487 | if ((brdp = stli_allocbrd()) == (stlibrd_t *) NULL) | 4019 | if ((brdp = stli_allocbrd()) == NULL) |
4488 | return(-ENOMEM); | 4020 | return -ENOMEM; |
4489 | if ((brdp->brdnr = stli_getbrdnr()) < 0) | 4021 | if ((brdp->brdnr = stli_getbrdnr()) < 0) |
4490 | return(-ENOMEM); | 4022 | return -ENOMEM; |
4491 | eid = inb(iobase + 0xc82); | 4023 | eid = inb(iobase + 0xc82); |
4492 | if (eid == ECP_EISAID) | 4024 | if (eid == ECP_EISAID) |
4493 | brdp->brdtype = BRD_ECPE; | 4025 | brdp->brdtype = BRD_ECPE; |
@@ -4502,7 +4034,7 @@ static int stli_findeisabrds(void) | |||
4502 | stli_brdinit(brdp); | 4034 | stli_brdinit(brdp); |
4503 | } | 4035 | } |
4504 | 4036 | ||
4505 | return(0); | 4037 | return 0; |
4506 | } | 4038 | } |
4507 | 4039 | ||
4508 | /*****************************************************************************/ | 4040 | /*****************************************************************************/ |
@@ -4523,32 +4055,18 @@ static int stli_findeisabrds(void) | |||
4523 | 4055 | ||
4524 | static int stli_initpcibrd(int brdtype, struct pci_dev *devp) | 4056 | static int stli_initpcibrd(int brdtype, struct pci_dev *devp) |
4525 | { | 4057 | { |
4526 | stlibrd_t *brdp; | 4058 | stlibrd_t *brdp; |
4527 | |||
4528 | #ifdef DEBUG | ||
4529 | printk(KERN_DEBUG "stli_initpcibrd(brdtype=%d,busnr=%x,devnr=%x)\n", | ||
4530 | brdtype, dev->bus->number, dev->devfn); | ||
4531 | #endif | ||
4532 | 4059 | ||
4533 | if (pci_enable_device(devp)) | 4060 | if (pci_enable_device(devp)) |
4534 | return(-EIO); | 4061 | return -EIO; |
4535 | if ((brdp = stli_allocbrd()) == (stlibrd_t *) NULL) | 4062 | if ((brdp = stli_allocbrd()) == NULL) |
4536 | return(-ENOMEM); | 4063 | return -ENOMEM; |
4537 | if ((brdp->brdnr = stli_getbrdnr()) < 0) { | 4064 | if ((brdp->brdnr = stli_getbrdnr()) < 0) { |
4538 | printk(KERN_INFO "STALLION: too many boards found, " | 4065 | printk(KERN_INFO "STALLION: too many boards found, " |
4539 | "maximum supported %d\n", STL_MAXBRDS); | 4066 | "maximum supported %d\n", STL_MAXBRDS); |
4540 | return(0); | 4067 | return 0; |
4541 | } | 4068 | } |
4542 | brdp->brdtype = brdtype; | 4069 | brdp->brdtype = brdtype; |
4543 | |||
4544 | #ifdef DEBUG | ||
4545 | printk(KERN_DEBUG "%s(%d): BAR[]=%lx,%lx,%lx,%lx\n", __FILE__, __LINE__, | ||
4546 | pci_resource_start(devp, 0), | ||
4547 | pci_resource_start(devp, 1), | ||
4548 | pci_resource_start(devp, 2), | ||
4549 | pci_resource_start(devp, 3)); | ||
4550 | #endif | ||
4551 | |||
4552 | /* | 4070 | /* |
4553 | * We have all resources from the board, so lets setup the actual | 4071 | * We have all resources from the board, so lets setup the actual |
4554 | * board structure now. | 4072 | * board structure now. |
@@ -4557,7 +4075,7 @@ static int stli_initpcibrd(int brdtype, struct pci_dev *devp) | |||
4557 | brdp->memaddr = pci_resource_start(devp, 2); | 4075 | brdp->memaddr = pci_resource_start(devp, 2); |
4558 | stli_brdinit(brdp); | 4076 | stli_brdinit(brdp); |
4559 | 4077 | ||
4560 | return(0); | 4078 | return 0; |
4561 | } | 4079 | } |
4562 | 4080 | ||
4563 | /*****************************************************************************/ | 4081 | /*****************************************************************************/ |
@@ -4569,20 +4087,12 @@ static int stli_initpcibrd(int brdtype, struct pci_dev *devp) | |||
4569 | 4087 | ||
4570 | static int stli_findpcibrds(void) | 4088 | static int stli_findpcibrds(void) |
4571 | { | 4089 | { |
4572 | struct pci_dev *dev = NULL; | 4090 | struct pci_dev *dev = NULL; |
4573 | int rc; | ||
4574 | 4091 | ||
4575 | #ifdef DEBUG | 4092 | while ((dev = pci_get_device(PCI_VENDOR_ID_STALLION, PCI_DEVICE_ID_ECRA, dev))) { |
4576 | printk("stli_findpcibrds()\n"); | 4093 | stli_initpcibrd(BRD_ECPPCI, dev); |
4577 | #endif | ||
4578 | |||
4579 | while ((dev = pci_find_device(PCI_VENDOR_ID_STALLION, | ||
4580 | PCI_DEVICE_ID_ECRA, dev))) { | ||
4581 | if ((rc = stli_initpcibrd(BRD_ECPPCI, dev))) | ||
4582 | return(rc); | ||
4583 | } | 4094 | } |
4584 | 4095 | return 0; | |
4585 | return(0); | ||
4586 | } | 4096 | } |
4587 | 4097 | ||
4588 | #endif | 4098 | #endif |
@@ -4595,17 +4105,16 @@ static int stli_findpcibrds(void) | |||
4595 | 4105 | ||
4596 | static stlibrd_t *stli_allocbrd(void) | 4106 | static stlibrd_t *stli_allocbrd(void) |
4597 | { | 4107 | { |
4598 | stlibrd_t *brdp; | 4108 | stlibrd_t *brdp; |
4599 | 4109 | ||
4600 | brdp = kzalloc(sizeof(stlibrd_t), GFP_KERNEL); | 4110 | brdp = kzalloc(sizeof(stlibrd_t), GFP_KERNEL); |
4601 | if (!brdp) { | 4111 | if (!brdp) { |
4602 | printk(KERN_ERR "STALLION: failed to allocate memory " | 4112 | printk(KERN_ERR "STALLION: failed to allocate memory " |
4603 | "(size=%d)\n", sizeof(stlibrd_t)); | 4113 | "(size=%Zd)\n", sizeof(stlibrd_t)); |
4604 | return NULL; | 4114 | return NULL; |
4605 | } | 4115 | } |
4606 | |||
4607 | brdp->magic = STLI_BOARDMAGIC; | 4116 | brdp->magic = STLI_BOARDMAGIC; |
4608 | return(brdp); | 4117 | return brdp; |
4609 | } | 4118 | } |
4610 | 4119 | ||
4611 | /*****************************************************************************/ | 4120 | /*****************************************************************************/ |
@@ -4617,13 +4126,9 @@ static stlibrd_t *stli_allocbrd(void) | |||
4617 | 4126 | ||
4618 | static int stli_initbrds(void) | 4127 | static int stli_initbrds(void) |
4619 | { | 4128 | { |
4620 | stlibrd_t *brdp, *nxtbrdp; | 4129 | stlibrd_t *brdp, *nxtbrdp; |
4621 | stlconf_t *confp; | 4130 | stlconf_t *confp; |
4622 | int i, j; | 4131 | int i, j; |
4623 | |||
4624 | #ifdef DEBUG | ||
4625 | printk(KERN_DEBUG "stli_initbrds()\n"); | ||
4626 | #endif | ||
4627 | 4132 | ||
4628 | if (stli_nrbrds > STL_MAXBRDS) { | 4133 | if (stli_nrbrds > STL_MAXBRDS) { |
4629 | printk(KERN_INFO "STALLION: too many boards in configuration " | 4134 | printk(KERN_INFO "STALLION: too many boards in configuration " |
@@ -4638,11 +4143,9 @@ static int stli_initbrds(void) | |||
4638 | */ | 4143 | */ |
4639 | for (i = 0; (i < stli_nrbrds); i++) { | 4144 | for (i = 0; (i < stli_nrbrds); i++) { |
4640 | confp = &stli_brdconf[i]; | 4145 | confp = &stli_brdconf[i]; |
4641 | #ifdef MODULE | ||
4642 | stli_parsebrd(confp, stli_brdsp[i]); | 4146 | stli_parsebrd(confp, stli_brdsp[i]); |
4643 | #endif | 4147 | if ((brdp = stli_allocbrd()) == NULL) |
4644 | if ((brdp = stli_allocbrd()) == (stlibrd_t *) NULL) | 4148 | return -ENOMEM; |
4645 | return(-ENOMEM); | ||
4646 | brdp->brdnr = i; | 4149 | brdp->brdnr = i; |
4647 | brdp->brdtype = confp->brdtype; | 4150 | brdp->brdtype = confp->brdtype; |
4648 | brdp->iobase = confp->ioaddr1; | 4151 | brdp->iobase = confp->ioaddr1; |
@@ -4654,9 +4157,7 @@ static int stli_initbrds(void) | |||
4654 | * Static configuration table done, so now use dynamic methods to | 4157 | * Static configuration table done, so now use dynamic methods to |
4655 | * see if any more boards should be configured. | 4158 | * see if any more boards should be configured. |
4656 | */ | 4159 | */ |
4657 | #ifdef MODULE | ||
4658 | stli_argbrds(); | 4160 | stli_argbrds(); |
4659 | #endif | ||
4660 | if (STLI_EISAPROBE) | 4161 | if (STLI_EISAPROBE) |
4661 | stli_findeisabrds(); | 4162 | stli_findeisabrds(); |
4662 | #ifdef CONFIG_PCI | 4163 | #ifdef CONFIG_PCI |
@@ -4672,11 +4173,11 @@ static int stli_initbrds(void) | |||
4672 | if (stli_nrbrds > 1) { | 4173 | if (stli_nrbrds > 1) { |
4673 | for (i = 0; (i < stli_nrbrds); i++) { | 4174 | for (i = 0; (i < stli_nrbrds); i++) { |
4674 | brdp = stli_brds[i]; | 4175 | brdp = stli_brds[i]; |
4675 | if (brdp == (stlibrd_t *) NULL) | 4176 | if (brdp == NULL) |
4676 | continue; | 4177 | continue; |
4677 | for (j = i + 1; (j < stli_nrbrds); j++) { | 4178 | for (j = i + 1; (j < stli_nrbrds); j++) { |
4678 | nxtbrdp = stli_brds[j]; | 4179 | nxtbrdp = stli_brds[j]; |
4679 | if (nxtbrdp == (stlibrd_t *) NULL) | 4180 | if (nxtbrdp == NULL) |
4680 | continue; | 4181 | continue; |
4681 | if ((brdp->membase >= nxtbrdp->membase) && | 4182 | if ((brdp->membase >= nxtbrdp->membase) && |
4682 | (brdp->membase <= (nxtbrdp->membase + | 4183 | (brdp->membase <= (nxtbrdp->membase + |
@@ -4691,7 +4192,7 @@ static int stli_initbrds(void) | |||
4691 | if (stli_shared == 0) { | 4192 | if (stli_shared == 0) { |
4692 | for (i = 0; (i < stli_nrbrds); i++) { | 4193 | for (i = 0; (i < stli_nrbrds); i++) { |
4693 | brdp = stli_brds[i]; | 4194 | brdp = stli_brds[i]; |
4694 | if (brdp == (stlibrd_t *) NULL) | 4195 | if (brdp == NULL) |
4695 | continue; | 4196 | continue; |
4696 | if (brdp->state & BST_FOUND) { | 4197 | if (brdp->state & BST_FOUND) { |
4697 | EBRDENABLE(brdp); | 4198 | EBRDENABLE(brdp); |
@@ -4701,7 +4202,7 @@ static int stli_initbrds(void) | |||
4701 | } | 4202 | } |
4702 | } | 4203 | } |
4703 | 4204 | ||
4704 | return(0); | 4205 | return 0; |
4705 | } | 4206 | } |
4706 | 4207 | ||
4707 | /*****************************************************************************/ | 4208 | /*****************************************************************************/ |
@@ -4714,48 +4215,55 @@ static int stli_initbrds(void) | |||
4714 | 4215 | ||
4715 | static ssize_t stli_memread(struct file *fp, char __user *buf, size_t count, loff_t *offp) | 4216 | static ssize_t stli_memread(struct file *fp, char __user *buf, size_t count, loff_t *offp) |
4716 | { | 4217 | { |
4717 | unsigned long flags; | 4218 | unsigned long flags; |
4718 | void *memptr; | 4219 | void *memptr; |
4719 | stlibrd_t *brdp; | 4220 | stlibrd_t *brdp; |
4720 | int brdnr, size, n; | 4221 | int brdnr, size, n; |
4721 | 4222 | void *p; | |
4722 | #ifdef DEBUG | 4223 | loff_t off = *offp; |
4723 | printk(KERN_DEBUG "stli_memread(fp=%x,buf=%x,count=%x,offp=%x)\n", | ||
4724 | (int) fp, (int) buf, count, (int) offp); | ||
4725 | #endif | ||
4726 | 4224 | ||
4727 | brdnr = iminor(fp->f_dentry->d_inode); | 4225 | brdnr = iminor(fp->f_dentry->d_inode); |
4728 | if (brdnr >= stli_nrbrds) | 4226 | if (brdnr >= stli_nrbrds) |
4729 | return(-ENODEV); | 4227 | return -ENODEV; |
4730 | brdp = stli_brds[brdnr]; | 4228 | brdp = stli_brds[brdnr]; |
4731 | if (brdp == (stlibrd_t *) NULL) | 4229 | if (brdp == NULL) |
4732 | return(-ENODEV); | 4230 | return -ENODEV; |
4733 | if (brdp->state == 0) | 4231 | if (brdp->state == 0) |
4734 | return(-ENODEV); | 4232 | return -ENODEV; |
4735 | if (fp->f_pos >= brdp->memsize) | 4233 | if (off >= brdp->memsize || off + count < off) |
4736 | return(0); | 4234 | return 0; |
4737 | 4235 | ||
4738 | size = MIN(count, (brdp->memsize - fp->f_pos)); | 4236 | size = MIN(count, (brdp->memsize - off)); |
4237 | |||
4238 | /* | ||
4239 | * Copy the data a page at a time | ||
4240 | */ | ||
4241 | |||
4242 | p = (void *)__get_free_page(GFP_KERNEL); | ||
4243 | if(p == NULL) | ||
4244 | return -ENOMEM; | ||
4739 | 4245 | ||
4740 | save_flags(flags); | ||
4741 | cli(); | ||
4742 | EBRDENABLE(brdp); | ||
4743 | while (size > 0) { | 4246 | while (size > 0) { |
4744 | memptr = (void *) EBRDGETMEMPTR(brdp, fp->f_pos); | 4247 | spin_lock_irqsave(&brd_lock, flags); |
4745 | n = MIN(size, (brdp->pagesize - (((unsigned long) fp->f_pos) % brdp->pagesize))); | 4248 | EBRDENABLE(brdp); |
4746 | if (copy_to_user(buf, memptr, n)) { | 4249 | memptr = (void *) EBRDGETMEMPTR(brdp, off); |
4250 | n = MIN(size, (brdp->pagesize - (((unsigned long) off) % brdp->pagesize))); | ||
4251 | n = MIN(n, PAGE_SIZE); | ||
4252 | memcpy_fromio(p, memptr, n); | ||
4253 | EBRDDISABLE(brdp); | ||
4254 | spin_unlock_irqrestore(&brd_lock, flags); | ||
4255 | if (copy_to_user(buf, p, n)) { | ||
4747 | count = -EFAULT; | 4256 | count = -EFAULT; |
4748 | goto out; | 4257 | goto out; |
4749 | } | 4258 | } |
4750 | fp->f_pos += n; | 4259 | off += n; |
4751 | buf += n; | 4260 | buf += n; |
4752 | size -= n; | 4261 | size -= n; |
4753 | } | 4262 | } |
4754 | out: | 4263 | out: |
4755 | EBRDDISABLE(brdp); | 4264 | *offp = off; |
4756 | restore_flags(flags); | 4265 | free_page((unsigned long)p); |
4757 | 4266 | return count; | |
4758 | return(count); | ||
4759 | } | 4267 | } |
4760 | 4268 | ||
4761 | /*****************************************************************************/ | 4269 | /*****************************************************************************/ |
@@ -4764,54 +4272,65 @@ out: | |||
4764 | * Code to handle an "staliomem" write operation. This device is the | 4272 | * Code to handle an "staliomem" write operation. This device is the |
4765 | * contents of the board shared memory. It is used for down loading | 4273 | * contents of the board shared memory. It is used for down loading |
4766 | * the slave image (and debugging :-) | 4274 | * the slave image (and debugging :-) |
4275 | * | ||
4276 | * FIXME: copy under lock | ||
4767 | */ | 4277 | */ |
4768 | 4278 | ||
4769 | static ssize_t stli_memwrite(struct file *fp, const char __user *buf, size_t count, loff_t *offp) | 4279 | static ssize_t stli_memwrite(struct file *fp, const char __user *buf, size_t count, loff_t *offp) |
4770 | { | 4280 | { |
4771 | unsigned long flags; | 4281 | unsigned long flags; |
4772 | void *memptr; | 4282 | void *memptr; |
4773 | stlibrd_t *brdp; | 4283 | stlibrd_t *brdp; |
4774 | char __user *chbuf; | 4284 | char __user *chbuf; |
4775 | int brdnr, size, n; | 4285 | int brdnr, size, n; |
4776 | 4286 | void *p; | |
4777 | #ifdef DEBUG | 4287 | loff_t off = *offp; |
4778 | printk(KERN_DEBUG "stli_memwrite(fp=%x,buf=%x,count=%x,offp=%x)\n", | ||
4779 | (int) fp, (int) buf, count, (int) offp); | ||
4780 | #endif | ||
4781 | 4288 | ||
4782 | brdnr = iminor(fp->f_dentry->d_inode); | 4289 | brdnr = iminor(fp->f_dentry->d_inode); |
4290 | |||
4783 | if (brdnr >= stli_nrbrds) | 4291 | if (brdnr >= stli_nrbrds) |
4784 | return(-ENODEV); | 4292 | return -ENODEV; |
4785 | brdp = stli_brds[brdnr]; | 4293 | brdp = stli_brds[brdnr]; |
4786 | if (brdp == (stlibrd_t *) NULL) | 4294 | if (brdp == NULL) |
4787 | return(-ENODEV); | 4295 | return -ENODEV; |
4788 | if (brdp->state == 0) | 4296 | if (brdp->state == 0) |
4789 | return(-ENODEV); | 4297 | return -ENODEV; |
4790 | if (fp->f_pos >= brdp->memsize) | 4298 | if (off >= brdp->memsize || off + count < off) |
4791 | return(0); | 4299 | return 0; |
4792 | 4300 | ||
4793 | chbuf = (char __user *) buf; | 4301 | chbuf = (char __user *) buf; |
4794 | size = MIN(count, (brdp->memsize - fp->f_pos)); | 4302 | size = MIN(count, (brdp->memsize - off)); |
4303 | |||
4304 | /* | ||
4305 | * Copy the data a page at a time | ||
4306 | */ | ||
4307 | |||
4308 | p = (void *)__get_free_page(GFP_KERNEL); | ||
4309 | if(p == NULL) | ||
4310 | return -ENOMEM; | ||
4795 | 4311 | ||
4796 | save_flags(flags); | ||
4797 | cli(); | ||
4798 | EBRDENABLE(brdp); | ||
4799 | while (size > 0) { | 4312 | while (size > 0) { |
4800 | memptr = (void *) EBRDGETMEMPTR(brdp, fp->f_pos); | 4313 | n = MIN(size, (brdp->pagesize - (((unsigned long) off) % brdp->pagesize))); |
4801 | n = MIN(size, (brdp->pagesize - (((unsigned long) fp->f_pos) % brdp->pagesize))); | 4314 | n = MIN(n, PAGE_SIZE); |
4802 | if (copy_from_user(memptr, chbuf, n)) { | 4315 | if (copy_from_user(p, chbuf, n)) { |
4803 | count = -EFAULT; | 4316 | if (count == 0) |
4317 | count = -EFAULT; | ||
4804 | goto out; | 4318 | goto out; |
4805 | } | 4319 | } |
4806 | fp->f_pos += n; | 4320 | spin_lock_irqsave(&brd_lock, flags); |
4321 | EBRDENABLE(brdp); | ||
4322 | memptr = (void *) EBRDGETMEMPTR(brdp, off); | ||
4323 | memcpy_toio(memptr, p, n); | ||
4324 | EBRDDISABLE(brdp); | ||
4325 | spin_unlock_irqrestore(&brd_lock, flags); | ||
4326 | off += n; | ||
4807 | chbuf += n; | 4327 | chbuf += n; |
4808 | size -= n; | 4328 | size -= n; |
4809 | } | 4329 | } |
4810 | out: | 4330 | out: |
4811 | EBRDDISABLE(brdp); | 4331 | free_page((unsigned long) p); |
4812 | restore_flags(flags); | 4332 | *offp = off; |
4813 | 4333 | return count; | |
4814 | return(count); | ||
4815 | } | 4334 | } |
4816 | 4335 | ||
4817 | /*****************************************************************************/ | 4336 | /*****************************************************************************/ |
@@ -4822,16 +4341,16 @@ out: | |||
4822 | 4341 | ||
4823 | static int stli_getbrdstats(combrd_t __user *bp) | 4342 | static int stli_getbrdstats(combrd_t __user *bp) |
4824 | { | 4343 | { |
4825 | stlibrd_t *brdp; | 4344 | stlibrd_t *brdp; |
4826 | int i; | 4345 | int i; |
4827 | 4346 | ||
4828 | if (copy_from_user(&stli_brdstats, bp, sizeof(combrd_t))) | 4347 | if (copy_from_user(&stli_brdstats, bp, sizeof(combrd_t))) |
4829 | return -EFAULT; | 4348 | return -EFAULT; |
4830 | if (stli_brdstats.brd >= STL_MAXBRDS) | 4349 | if (stli_brdstats.brd >= STL_MAXBRDS) |
4831 | return(-ENODEV); | 4350 | return -ENODEV; |
4832 | brdp = stli_brds[stli_brdstats.brd]; | 4351 | brdp = stli_brds[stli_brdstats.brd]; |
4833 | if (brdp == (stlibrd_t *) NULL) | 4352 | if (brdp == NULL) |
4834 | return(-ENODEV); | 4353 | return -ENODEV; |
4835 | 4354 | ||
4836 | memset(&stli_brdstats, 0, sizeof(combrd_t)); | 4355 | memset(&stli_brdstats, 0, sizeof(combrd_t)); |
4837 | stli_brdstats.brd = brdp->brdnr; | 4356 | stli_brdstats.brd = brdp->brdnr; |
@@ -4850,7 +4369,7 @@ static int stli_getbrdstats(combrd_t __user *bp) | |||
4850 | 4369 | ||
4851 | if (copy_to_user(bp, &stli_brdstats, sizeof(combrd_t))) | 4370 | if (copy_to_user(bp, &stli_brdstats, sizeof(combrd_t))) |
4852 | return -EFAULT; | 4371 | return -EFAULT; |
4853 | return(0); | 4372 | return 0; |
4854 | } | 4373 | } |
4855 | 4374 | ||
4856 | /*****************************************************************************/ | 4375 | /*****************************************************************************/ |
@@ -4861,19 +4380,19 @@ static int stli_getbrdstats(combrd_t __user *bp) | |||
4861 | 4380 | ||
4862 | static stliport_t *stli_getport(int brdnr, int panelnr, int portnr) | 4381 | static stliport_t *stli_getport(int brdnr, int panelnr, int portnr) |
4863 | { | 4382 | { |
4864 | stlibrd_t *brdp; | 4383 | stlibrd_t *brdp; |
4865 | int i; | 4384 | int i; |
4866 | 4385 | ||
4867 | if ((brdnr < 0) || (brdnr >= STL_MAXBRDS)) | 4386 | if (brdnr < 0 || brdnr >= STL_MAXBRDS) |
4868 | return((stliport_t *) NULL); | 4387 | return NULL; |
4869 | brdp = stli_brds[brdnr]; | 4388 | brdp = stli_brds[brdnr]; |
4870 | if (brdp == (stlibrd_t *) NULL) | 4389 | if (brdp == NULL) |
4871 | return((stliport_t *) NULL); | 4390 | return NULL; |
4872 | for (i = 0; (i < panelnr); i++) | 4391 | for (i = 0; (i < panelnr); i++) |
4873 | portnr += brdp->panels[i]; | 4392 | portnr += brdp->panels[i]; |
4874 | if ((portnr < 0) || (portnr >= brdp->nrports)) | 4393 | if ((portnr < 0) || (portnr >= brdp->nrports)) |
4875 | return((stliport_t *) NULL); | 4394 | return NULL; |
4876 | return(brdp->ports[portnr]); | 4395 | return brdp->ports[portnr]; |
4877 | } | 4396 | } |
4878 | 4397 | ||
4879 | /*****************************************************************************/ | 4398 | /*****************************************************************************/ |
@@ -4892,16 +4411,16 @@ static int stli_portcmdstats(stliport_t *portp) | |||
4892 | 4411 | ||
4893 | memset(&stli_comstats, 0, sizeof(comstats_t)); | 4412 | memset(&stli_comstats, 0, sizeof(comstats_t)); |
4894 | 4413 | ||
4895 | if (portp == (stliport_t *) NULL) | 4414 | if (portp == NULL) |
4896 | return(-ENODEV); | 4415 | return -ENODEV; |
4897 | brdp = stli_brds[portp->brdnr]; | 4416 | brdp = stli_brds[portp->brdnr]; |
4898 | if (brdp == (stlibrd_t *) NULL) | 4417 | if (brdp == NULL) |
4899 | return(-ENODEV); | 4418 | return -ENODEV; |
4900 | 4419 | ||
4901 | if (brdp->state & BST_STARTED) { | 4420 | if (brdp->state & BST_STARTED) { |
4902 | if ((rc = stli_cmdwait(brdp, portp, A_GETSTATS, | 4421 | if ((rc = stli_cmdwait(brdp, portp, A_GETSTATS, |
4903 | &stli_cdkstats, sizeof(asystats_t), 1)) < 0) | 4422 | &stli_cdkstats, sizeof(asystats_t), 1)) < 0) |
4904 | return(rc); | 4423 | return rc; |
4905 | } else { | 4424 | } else { |
4906 | memset(&stli_cdkstats, 0, sizeof(asystats_t)); | 4425 | memset(&stli_cdkstats, 0, sizeof(asystats_t)); |
4907 | } | 4426 | } |
@@ -4912,13 +4431,12 @@ static int stli_portcmdstats(stliport_t *portp) | |||
4912 | stli_comstats.state = portp->state; | 4431 | stli_comstats.state = portp->state; |
4913 | stli_comstats.flags = portp->flags; | 4432 | stli_comstats.flags = portp->flags; |
4914 | 4433 | ||
4915 | save_flags(flags); | 4434 | spin_lock_irqsave(&brd_lock, flags); |
4916 | cli(); | 4435 | if (portp->tty != NULL) { |
4917 | if (portp->tty != (struct tty_struct *) NULL) { | ||
4918 | if (portp->tty->driver_data == portp) { | 4436 | if (portp->tty->driver_data == portp) { |
4919 | stli_comstats.ttystate = portp->tty->flags; | 4437 | stli_comstats.ttystate = portp->tty->flags; |
4920 | stli_comstats.rxbuffered = -1 /*portp->tty->flip.count*/; | 4438 | stli_comstats.rxbuffered = -1; |
4921 | if (portp->tty->termios != (struct termios *) NULL) { | 4439 | if (portp->tty->termios != NULL) { |
4922 | stli_comstats.cflags = portp->tty->termios->c_cflag; | 4440 | stli_comstats.cflags = portp->tty->termios->c_cflag; |
4923 | stli_comstats.iflags = portp->tty->termios->c_iflag; | 4441 | stli_comstats.iflags = portp->tty->termios->c_iflag; |
4924 | stli_comstats.oflags = portp->tty->termios->c_oflag; | 4442 | stli_comstats.oflags = portp->tty->termios->c_oflag; |
@@ -4926,7 +4444,7 @@ static int stli_portcmdstats(stliport_t *portp) | |||
4926 | } | 4444 | } |
4927 | } | 4445 | } |
4928 | } | 4446 | } |
4929 | restore_flags(flags); | 4447 | spin_unlock_irqrestore(&brd_lock, flags); |
4930 | 4448 | ||
4931 | stli_comstats.txtotal = stli_cdkstats.txchars; | 4449 | stli_comstats.txtotal = stli_cdkstats.txchars; |
4932 | stli_comstats.rxtotal = stli_cdkstats.rxchars + stli_cdkstats.ringover; | 4450 | stli_comstats.rxtotal = stli_cdkstats.rxchars + stli_cdkstats.ringover; |
@@ -4948,7 +4466,7 @@ static int stli_portcmdstats(stliport_t *portp) | |||
4948 | stli_comstats.hwid = stli_cdkstats.hwid; | 4466 | stli_comstats.hwid = stli_cdkstats.hwid; |
4949 | stli_comstats.signals = stli_mktiocm(stli_cdkstats.signals); | 4467 | stli_comstats.signals = stli_mktiocm(stli_cdkstats.signals); |
4950 | 4468 | ||
4951 | return(0); | 4469 | return 0; |
4952 | } | 4470 | } |
4953 | 4471 | ||
4954 | /*****************************************************************************/ | 4472 | /*****************************************************************************/ |
@@ -4961,8 +4479,8 @@ static int stli_portcmdstats(stliport_t *portp) | |||
4961 | 4479 | ||
4962 | static int stli_getportstats(stliport_t *portp, comstats_t __user *cp) | 4480 | static int stli_getportstats(stliport_t *portp, comstats_t __user *cp) |
4963 | { | 4481 | { |
4964 | stlibrd_t *brdp; | 4482 | stlibrd_t *brdp; |
4965 | int rc; | 4483 | int rc; |
4966 | 4484 | ||
4967 | if (!portp) { | 4485 | if (!portp) { |
4968 | if (copy_from_user(&stli_comstats, cp, sizeof(comstats_t))) | 4486 | if (copy_from_user(&stli_comstats, cp, sizeof(comstats_t))) |
@@ -4992,8 +4510,8 @@ static int stli_getportstats(stliport_t *portp, comstats_t __user *cp) | |||
4992 | 4510 | ||
4993 | static int stli_clrportstats(stliport_t *portp, comstats_t __user *cp) | 4511 | static int stli_clrportstats(stliport_t *portp, comstats_t __user *cp) |
4994 | { | 4512 | { |
4995 | stlibrd_t *brdp; | 4513 | stlibrd_t *brdp; |
4996 | int rc; | 4514 | int rc; |
4997 | 4515 | ||
4998 | if (!portp) { | 4516 | if (!portp) { |
4999 | if (copy_from_user(&stli_comstats, cp, sizeof(comstats_t))) | 4517 | if (copy_from_user(&stli_comstats, cp, sizeof(comstats_t))) |
@@ -5031,7 +4549,7 @@ static int stli_clrportstats(stliport_t *portp, comstats_t __user *cp) | |||
5031 | 4549 | ||
5032 | static int stli_getportstruct(stliport_t __user *arg) | 4550 | static int stli_getportstruct(stliport_t __user *arg) |
5033 | { | 4551 | { |
5034 | stliport_t *portp; | 4552 | stliport_t *portp; |
5035 | 4553 | ||
5036 | if (copy_from_user(&stli_dummyport, arg, sizeof(stliport_t))) | 4554 | if (copy_from_user(&stli_dummyport, arg, sizeof(stliport_t))) |
5037 | return -EFAULT; | 4555 | return -EFAULT; |
@@ -5052,7 +4570,7 @@ static int stli_getportstruct(stliport_t __user *arg) | |||
5052 | 4570 | ||
5053 | static int stli_getbrdstruct(stlibrd_t __user *arg) | 4571 | static int stli_getbrdstruct(stlibrd_t __user *arg) |
5054 | { | 4572 | { |
5055 | stlibrd_t *brdp; | 4573 | stlibrd_t *brdp; |
5056 | 4574 | ||
5057 | if (copy_from_user(&stli_dummybrd, arg, sizeof(stlibrd_t))) | 4575 | if (copy_from_user(&stli_dummybrd, arg, sizeof(stlibrd_t))) |
5058 | return -EFAULT; | 4576 | return -EFAULT; |
@@ -5076,15 +4594,10 @@ static int stli_getbrdstruct(stlibrd_t __user *arg) | |||
5076 | 4594 | ||
5077 | static int stli_memioctl(struct inode *ip, struct file *fp, unsigned int cmd, unsigned long arg) | 4595 | static int stli_memioctl(struct inode *ip, struct file *fp, unsigned int cmd, unsigned long arg) |
5078 | { | 4596 | { |
5079 | stlibrd_t *brdp; | 4597 | stlibrd_t *brdp; |
5080 | int brdnr, rc, done; | 4598 | int brdnr, rc, done; |
5081 | void __user *argp = (void __user *)arg; | 4599 | void __user *argp = (void __user *)arg; |
5082 | 4600 | ||
5083 | #ifdef DEBUG | ||
5084 | printk(KERN_DEBUG "stli_memioctl(ip=%x,fp=%x,cmd=%x,arg=%x)\n", | ||
5085 | (int) ip, (int) fp, cmd, (int) arg); | ||
5086 | #endif | ||
5087 | |||
5088 | /* | 4601 | /* |
5089 | * First up handle the board independent ioctls. | 4602 | * First up handle the board independent ioctls. |
5090 | */ | 4603 | */ |
@@ -5115,7 +4628,7 @@ static int stli_memioctl(struct inode *ip, struct file *fp, unsigned int cmd, un | |||
5115 | } | 4628 | } |
5116 | 4629 | ||
5117 | if (done) | 4630 | if (done) |
5118 | return(rc); | 4631 | return rc; |
5119 | 4632 | ||
5120 | /* | 4633 | /* |
5121 | * Now handle the board specific ioctls. These all depend on the | 4634 | * Now handle the board specific ioctls. These all depend on the |
@@ -5123,12 +4636,12 @@ static int stli_memioctl(struct inode *ip, struct file *fp, unsigned int cmd, un | |||
5123 | */ | 4636 | */ |
5124 | brdnr = iminor(ip); | 4637 | brdnr = iminor(ip); |
5125 | if (brdnr >= STL_MAXBRDS) | 4638 | if (brdnr >= STL_MAXBRDS) |
5126 | return(-ENODEV); | 4639 | return -ENODEV; |
5127 | brdp = stli_brds[brdnr]; | 4640 | brdp = stli_brds[brdnr]; |
5128 | if (!brdp) | 4641 | if (!brdp) |
5129 | return(-ENODEV); | 4642 | return -ENODEV; |
5130 | if (brdp->state == 0) | 4643 | if (brdp->state == 0) |
5131 | return(-ENODEV); | 4644 | return -ENODEV; |
5132 | 4645 | ||
5133 | switch (cmd) { | 4646 | switch (cmd) { |
5134 | case STL_BINTR: | 4647 | case STL_BINTR: |
@@ -5152,8 +4665,7 @@ static int stli_memioctl(struct inode *ip, struct file *fp, unsigned int cmd, un | |||
5152 | rc = -ENOIOCTLCMD; | 4665 | rc = -ENOIOCTLCMD; |
5153 | break; | 4666 | break; |
5154 | } | 4667 | } |
5155 | 4668 | return rc; | |
5156 | return(rc); | ||
5157 | } | 4669 | } |
5158 | 4670 | ||
5159 | static struct tty_operations stli_ops = { | 4671 | static struct tty_operations stli_ops = { |
@@ -5187,6 +4699,9 @@ int __init stli_init(void) | |||
5187 | int i; | 4699 | int i; |
5188 | printk(KERN_INFO "%s: version %s\n", stli_drvtitle, stli_drvversion); | 4700 | printk(KERN_INFO "%s: version %s\n", stli_drvtitle, stli_drvversion); |
5189 | 4701 | ||
4702 | spin_lock_init(&stli_lock); | ||
4703 | spin_lock_init(&brd_lock); | ||
4704 | |||
5190 | stli_initbrds(); | 4705 | stli_initbrds(); |
5191 | 4706 | ||
5192 | stli_serial = alloc_tty_driver(STL_MAXBRDS * STL_MAXPORTS); | 4707 | stli_serial = alloc_tty_driver(STL_MAXBRDS * STL_MAXPORTS); |
@@ -5196,10 +4711,6 @@ int __init stli_init(void) | |||
5196 | /* | 4711 | /* |
5197 | * Allocate a temporary write buffer. | 4712 | * Allocate a temporary write buffer. |
5198 | */ | 4713 | */ |
5199 | stli_tmpwritebuf = kmalloc(STLI_TXBUFSIZE, GFP_KERNEL); | ||
5200 | if (!stli_tmpwritebuf) | ||
5201 | printk(KERN_ERR "STALLION: failed to allocate memory " | ||
5202 | "(size=%d)\n", STLI_TXBUFSIZE); | ||
5203 | stli_txcookbuf = kmalloc(STLI_TXBUFSIZE, GFP_KERNEL); | 4714 | stli_txcookbuf = kmalloc(STLI_TXBUFSIZE, GFP_KERNEL); |
5204 | if (!stli_txcookbuf) | 4715 | if (!stli_txcookbuf) |
5205 | printk(KERN_ERR "STALLION: failed to allocate memory " | 4716 | printk(KERN_ERR "STALLION: failed to allocate memory " |
@@ -5213,16 +4724,11 @@ int __init stli_init(void) | |||
5213 | printk(KERN_ERR "STALLION: failed to register serial memory " | 4724 | printk(KERN_ERR "STALLION: failed to register serial memory " |
5214 | "device\n"); | 4725 | "device\n"); |
5215 | 4726 | ||
5216 | devfs_mk_dir("staliomem"); | ||
5217 | istallion_class = class_create(THIS_MODULE, "staliomem"); | 4727 | istallion_class = class_create(THIS_MODULE, "staliomem"); |
5218 | for (i = 0; i < 4; i++) { | 4728 | for (i = 0; i < 4; i++) |
5219 | devfs_mk_cdev(MKDEV(STL_SIOMEMMAJOR, i), | ||
5220 | S_IFCHR | S_IRUSR | S_IWUSR, | ||
5221 | "staliomem/%d", i); | ||
5222 | class_device_create(istallion_class, NULL, | 4729 | class_device_create(istallion_class, NULL, |
5223 | MKDEV(STL_SIOMEMMAJOR, i), | 4730 | MKDEV(STL_SIOMEMMAJOR, i), |
5224 | NULL, "staliomem%d", i); | 4731 | NULL, "staliomem%d", i); |
5225 | } | ||
5226 | 4732 | ||
5227 | /* | 4733 | /* |
5228 | * Set up the tty driver structure and register us as a driver. | 4734 | * Set up the tty driver structure and register us as a driver. |
@@ -5243,7 +4749,7 @@ int __init stli_init(void) | |||
5243 | printk(KERN_ERR "STALLION: failed to register serial driver\n"); | 4749 | printk(KERN_ERR "STALLION: failed to register serial driver\n"); |
5244 | return -EBUSY; | 4750 | return -EBUSY; |
5245 | } | 4751 | } |
5246 | return(0); | 4752 | return 0; |
5247 | } | 4753 | } |
5248 | 4754 | ||
5249 | /*****************************************************************************/ | 4755 | /*****************************************************************************/ |
diff --git a/drivers/char/lp.c b/drivers/char/lp.c index e57260525293..b11a390581ba 100644 --- a/drivers/char/lp.c +++ b/drivers/char/lp.c | |||
@@ -120,7 +120,6 @@ | |||
120 | #include <linux/major.h> | 120 | #include <linux/major.h> |
121 | #include <linux/sched.h> | 121 | #include <linux/sched.h> |
122 | #include <linux/smp_lock.h> | 122 | #include <linux/smp_lock.h> |
123 | #include <linux/devfs_fs_kernel.h> | ||
124 | #include <linux/slab.h> | 123 | #include <linux/slab.h> |
125 | #include <linux/fcntl.h> | 124 | #include <linux/fcntl.h> |
126 | #include <linux/delay.h> | 125 | #include <linux/delay.h> |
@@ -807,8 +806,6 @@ static int lp_register(int nr, struct parport *port) | |||
807 | 806 | ||
808 | class_device_create(lp_class, NULL, MKDEV(LP_MAJOR, nr), NULL, | 807 | class_device_create(lp_class, NULL, MKDEV(LP_MAJOR, nr), NULL, |
809 | "lp%d", nr); | 808 | "lp%d", nr); |
810 | devfs_mk_cdev(MKDEV(LP_MAJOR, nr), S_IFCHR | S_IRUGO | S_IWUGO, | ||
811 | "printers/%d", nr); | ||
812 | 809 | ||
813 | printk(KERN_INFO "lp%d: using %s (%s).\n", nr, port->name, | 810 | printk(KERN_INFO "lp%d: using %s (%s).\n", nr, port->name, |
814 | (port->irq == PARPORT_IRQ_NONE)?"polling":"interrupt-driven"); | 811 | (port->irq == PARPORT_IRQ_NONE)?"polling":"interrupt-driven"); |
@@ -907,7 +904,6 @@ static int __init lp_init (void) | |||
907 | return -EIO; | 904 | return -EIO; |
908 | } | 905 | } |
909 | 906 | ||
910 | devfs_mk_dir("printers"); | ||
911 | lp_class = class_create(THIS_MODULE, "printer"); | 907 | lp_class = class_create(THIS_MODULE, "printer"); |
912 | if (IS_ERR(lp_class)) { | 908 | if (IS_ERR(lp_class)) { |
913 | err = PTR_ERR(lp_class); | 909 | err = PTR_ERR(lp_class); |
@@ -933,7 +929,6 @@ static int __init lp_init (void) | |||
933 | out_class: | 929 | out_class: |
934 | class_destroy(lp_class); | 930 | class_destroy(lp_class); |
935 | out_devfs: | 931 | out_devfs: |
936 | devfs_remove("printers"); | ||
937 | unregister_chrdev(LP_MAJOR, "lp"); | 932 | unregister_chrdev(LP_MAJOR, "lp"); |
938 | return err; | 933 | return err; |
939 | } | 934 | } |
@@ -981,10 +976,8 @@ static void lp_cleanup_module (void) | |||
981 | if (lp_table[offset].dev == NULL) | 976 | if (lp_table[offset].dev == NULL) |
982 | continue; | 977 | continue; |
983 | parport_unregister_device(lp_table[offset].dev); | 978 | parport_unregister_device(lp_table[offset].dev); |
984 | devfs_remove("printers/%d", offset); | ||
985 | class_device_destroy(lp_class, MKDEV(LP_MAJOR, offset)); | 979 | class_device_destroy(lp_class, MKDEV(LP_MAJOR, offset)); |
986 | } | 980 | } |
987 | devfs_remove("printers"); | ||
988 | class_destroy(lp_class); | 981 | class_destroy(lp_class); |
989 | } | 982 | } |
990 | 983 | ||
diff --git a/drivers/char/mem.c b/drivers/char/mem.c index 1fa9fa157c12..6fe7b6c6c462 100644 --- a/drivers/char/mem.c +++ b/drivers/char/mem.c | |||
@@ -20,7 +20,6 @@ | |||
20 | #include <linux/tty.h> | 20 | #include <linux/tty.h> |
21 | #include <linux/capability.h> | 21 | #include <linux/capability.h> |
22 | #include <linux/smp_lock.h> | 22 | #include <linux/smp_lock.h> |
23 | #include <linux/devfs_fs_kernel.h> | ||
24 | #include <linux/ptrace.h> | 23 | #include <linux/ptrace.h> |
25 | #include <linux/device.h> | 24 | #include <linux/device.h> |
26 | #include <linux/highmem.h> | 25 | #include <linux/highmem.h> |
@@ -941,13 +940,10 @@ static int __init chr_dev_init(void) | |||
941 | printk("unable to get major %d for memory devs\n", MEM_MAJOR); | 940 | printk("unable to get major %d for memory devs\n", MEM_MAJOR); |
942 | 941 | ||
943 | mem_class = class_create(THIS_MODULE, "mem"); | 942 | mem_class = class_create(THIS_MODULE, "mem"); |
944 | for (i = 0; i < ARRAY_SIZE(devlist); i++) { | 943 | for (i = 0; i < ARRAY_SIZE(devlist); i++) |
945 | class_device_create(mem_class, NULL, | 944 | class_device_create(mem_class, NULL, |
946 | MKDEV(MEM_MAJOR, devlist[i].minor), | 945 | MKDEV(MEM_MAJOR, devlist[i].minor), |
947 | NULL, devlist[i].name); | 946 | NULL, devlist[i].name); |
948 | devfs_mk_cdev(MKDEV(MEM_MAJOR, devlist[i].minor), | ||
949 | S_IFCHR | devlist[i].mode, devlist[i].name); | ||
950 | } | ||
951 | 947 | ||
952 | return 0; | 948 | return 0; |
953 | } | 949 | } |
diff --git a/drivers/char/misc.c b/drivers/char/misc.c index 96eb2a709e21..dfe1cede3916 100644 --- a/drivers/char/misc.c +++ b/drivers/char/misc.c | |||
@@ -44,7 +44,6 @@ | |||
44 | #include <linux/slab.h> | 44 | #include <linux/slab.h> |
45 | #include <linux/proc_fs.h> | 45 | #include <linux/proc_fs.h> |
46 | #include <linux/seq_file.h> | 46 | #include <linux/seq_file.h> |
47 | #include <linux/devfs_fs_kernel.h> | ||
48 | #include <linux/stat.h> | 47 | #include <linux/stat.h> |
49 | #include <linux/init.h> | 48 | #include <linux/init.h> |
50 | #include <linux/device.h> | 49 | #include <linux/device.h> |
@@ -204,7 +203,7 @@ int misc_register(struct miscdevice * misc) | |||
204 | { | 203 | { |
205 | struct miscdevice *c; | 204 | struct miscdevice *c; |
206 | dev_t dev; | 205 | dev_t dev; |
207 | int err; | 206 | int err = 0; |
208 | 207 | ||
209 | down(&misc_sem); | 208 | down(&misc_sem); |
210 | list_for_each_entry(c, &misc_list, list) { | 209 | list_for_each_entry(c, &misc_list, list) { |
@@ -228,10 +227,6 @@ int misc_register(struct miscdevice * misc) | |||
228 | 227 | ||
229 | if (misc->minor < DYNAMIC_MINORS) | 228 | if (misc->minor < DYNAMIC_MINORS) |
230 | misc_minors[misc->minor >> 3] |= 1 << (misc->minor & 7); | 229 | misc_minors[misc->minor >> 3] |= 1 << (misc->minor & 7); |
231 | if (misc->devfs_name[0] == '\0') { | ||
232 | snprintf(misc->devfs_name, sizeof(misc->devfs_name), | ||
233 | "misc/%s", misc->name); | ||
234 | } | ||
235 | dev = MKDEV(MISC_MAJOR, misc->minor); | 230 | dev = MKDEV(MISC_MAJOR, misc->minor); |
236 | 231 | ||
237 | misc->class = class_device_create(misc_class, NULL, dev, misc->dev, | 232 | misc->class = class_device_create(misc_class, NULL, dev, misc->dev, |
@@ -241,13 +236,6 @@ int misc_register(struct miscdevice * misc) | |||
241 | goto out; | 236 | goto out; |
242 | } | 237 | } |
243 | 238 | ||
244 | err = devfs_mk_cdev(dev, S_IFCHR|S_IRUSR|S_IWUSR|S_IRGRP, | ||
245 | misc->devfs_name); | ||
246 | if (err) { | ||
247 | class_device_destroy(misc_class, dev); | ||
248 | goto out; | ||
249 | } | ||
250 | |||
251 | /* | 239 | /* |
252 | * Add it to the front, so that later devices can "override" | 240 | * Add it to the front, so that later devices can "override" |
253 | * earlier defaults | 241 | * earlier defaults |
@@ -278,7 +266,6 @@ int misc_deregister(struct miscdevice * misc) | |||
278 | down(&misc_sem); | 266 | down(&misc_sem); |
279 | list_del(&misc->list); | 267 | list_del(&misc->list); |
280 | class_device_destroy(misc_class, MKDEV(MISC_MAJOR, misc->minor)); | 268 | class_device_destroy(misc_class, MKDEV(MISC_MAJOR, misc->minor)); |
281 | devfs_remove(misc->devfs_name); | ||
282 | if (i < DYNAMIC_MINORS && i>0) { | 269 | if (i < DYNAMIC_MINORS && i>0) { |
283 | misc_minors[i>>3] &= ~(1 << (misc->minor & 7)); | 270 | misc_minors[i>>3] &= ~(1 << (misc->minor & 7)); |
284 | } | 271 | } |
diff --git a/drivers/char/mmtimer.c b/drivers/char/mmtimer.c index d65b3109318a..95e8122b8068 100644 --- a/drivers/char/mmtimer.c +++ b/drivers/char/mmtimer.c | |||
@@ -25,7 +25,6 @@ | |||
25 | #include <linux/init.h> | 25 | #include <linux/init.h> |
26 | #include <linux/errno.h> | 26 | #include <linux/errno.h> |
27 | #include <linux/mm.h> | 27 | #include <linux/mm.h> |
28 | #include <linux/devfs_fs_kernel.h> | ||
29 | #include <linux/mmtimer.h> | 28 | #include <linux/mmtimer.h> |
30 | #include <linux/miscdevice.h> | 29 | #include <linux/miscdevice.h> |
31 | #include <linux/posix-timers.h> | 30 | #include <linux/posix-timers.h> |
@@ -694,7 +693,6 @@ static int __init mmtimer_init(void) | |||
694 | return -1; | 693 | return -1; |
695 | } | 694 | } |
696 | 695 | ||
697 | strcpy(mmtimer_miscdev.devfs_name, MMTIMER_NAME); | ||
698 | if (misc_register(&mmtimer_miscdev)) { | 696 | if (misc_register(&mmtimer_miscdev)) { |
699 | printk(KERN_ERR "%s: failed to register device\n", | 697 | printk(KERN_ERR "%s: failed to register device\n", |
700 | MMTIMER_NAME); | 698 | MMTIMER_NAME); |
diff --git a/drivers/char/moxa.c b/drivers/char/moxa.c index f43c2e04eadd..52ef61f54ba0 100644 --- a/drivers/char/moxa.c +++ b/drivers/char/moxa.c | |||
@@ -301,7 +301,7 @@ static struct tty_operations moxa_ops = { | |||
301 | .tiocmset = moxa_tiocmset, | 301 | .tiocmset = moxa_tiocmset, |
302 | }; | 302 | }; |
303 | 303 | ||
304 | static spinlock_t moxa_lock = SPIN_LOCK_UNLOCKED; | 304 | static DEFINE_SPINLOCK(moxa_lock); |
305 | 305 | ||
306 | #ifdef CONFIG_PCI | 306 | #ifdef CONFIG_PCI |
307 | static int moxa_get_PCI_conf(struct pci_dev *p, int board_type, moxa_board_conf * board) | 307 | static int moxa_get_PCI_conf(struct pci_dev *p, int board_type, moxa_board_conf * board) |
@@ -342,7 +342,6 @@ static int __init moxa_init(void) | |||
342 | init_MUTEX(&moxaBuffSem); | 342 | init_MUTEX(&moxaBuffSem); |
343 | moxaDriver->owner = THIS_MODULE; | 343 | moxaDriver->owner = THIS_MODULE; |
344 | moxaDriver->name = "ttyMX"; | 344 | moxaDriver->name = "ttyMX"; |
345 | moxaDriver->devfs_name = "tts/a"; | ||
346 | moxaDriver->major = ttymajor; | 345 | moxaDriver->major = ttymajor; |
347 | moxaDriver->minor_start = 0; | 346 | moxaDriver->minor_start = 0; |
348 | moxaDriver->type = TTY_DRIVER_TYPE_SERIAL; | 347 | moxaDriver->type = TTY_DRIVER_TYPE_SERIAL; |
diff --git a/drivers/char/mxser.c b/drivers/char/mxser.c index 645d9d713aec..72cfd09091e0 100644 --- a/drivers/char/mxser.c +++ b/drivers/char/mxser.c | |||
@@ -996,7 +996,6 @@ static int mxser_open(struct tty_struct *tty, struct file *filp) | |||
996 | 996 | ||
997 | info->session = current->signal->session; | 997 | info->session = current->signal->session; |
998 | info->pgrp = process_group(current); | 998 | info->pgrp = process_group(current); |
999 | clear_bit(TTY_DONT_FLIP, &tty->flags); | ||
1000 | 999 | ||
1001 | /* | 1000 | /* |
1002 | status = mxser_get_msr(info->base, 0, info->port); | 1001 | status = mxser_get_msr(info->base, 0, info->port); |
diff --git a/drivers/char/n_tty.c b/drivers/char/n_tty.c index b9371d5bf790..603b9ade5eb0 100644 --- a/drivers/char/n_tty.c +++ b/drivers/char/n_tty.c | |||
@@ -1132,7 +1132,7 @@ static inline int input_available_p(struct tty_struct *tty, int amt) | |||
1132 | * buffer, and once to drain the space from the (physical) beginning of | 1132 | * buffer, and once to drain the space from the (physical) beginning of |
1133 | * the buffer to head pointer. | 1133 | * the buffer to head pointer. |
1134 | * | 1134 | * |
1135 | * Called under the tty->atomic_read_lock sem and with TTY_DONT_FLIP set | 1135 | * Called under the tty->atomic_read_lock sem |
1136 | * | 1136 | * |
1137 | */ | 1137 | */ |
1138 | 1138 | ||
@@ -1271,7 +1271,6 @@ do_it_again: | |||
1271 | } | 1271 | } |
1272 | 1272 | ||
1273 | add_wait_queue(&tty->read_wait, &wait); | 1273 | add_wait_queue(&tty->read_wait, &wait); |
1274 | set_bit(TTY_DONT_FLIP, &tty->flags); | ||
1275 | while (nr) { | 1274 | while (nr) { |
1276 | /* First test for status change. */ | 1275 | /* First test for status change. */ |
1277 | if (tty->packet && tty->link->ctrl_status) { | 1276 | if (tty->packet && tty->link->ctrl_status) { |
@@ -1315,9 +1314,7 @@ do_it_again: | |||
1315 | break; | 1314 | break; |
1316 | } | 1315 | } |
1317 | n_tty_set_room(tty); | 1316 | n_tty_set_room(tty); |
1318 | clear_bit(TTY_DONT_FLIP, &tty->flags); | ||
1319 | timeout = schedule_timeout(timeout); | 1317 | timeout = schedule_timeout(timeout); |
1320 | set_bit(TTY_DONT_FLIP, &tty->flags); | ||
1321 | continue; | 1318 | continue; |
1322 | } | 1319 | } |
1323 | __set_current_state(TASK_RUNNING); | 1320 | __set_current_state(TASK_RUNNING); |
@@ -1394,7 +1391,6 @@ do_it_again: | |||
1394 | if (time) | 1391 | if (time) |
1395 | timeout = time; | 1392 | timeout = time; |
1396 | } | 1393 | } |
1397 | clear_bit(TTY_DONT_FLIP, &tty->flags); | ||
1398 | mutex_unlock(&tty->atomic_read_lock); | 1394 | mutex_unlock(&tty->atomic_read_lock); |
1399 | remove_wait_queue(&tty->read_wait, &wait); | 1395 | remove_wait_queue(&tty->read_wait, &wait); |
1400 | 1396 | ||
diff --git a/drivers/char/nsc_gpio.c b/drivers/char/nsc_gpio.c new file mode 100644 index 000000000000..5b91e4e25641 --- /dev/null +++ b/drivers/char/nsc_gpio.c | |||
@@ -0,0 +1,142 @@ | |||
1 | /* linux/drivers/char/nsc_gpio.c | ||
2 | |||
3 | National Semiconductor common GPIO device-file/VFS methods. | ||
4 | Allows a user space process to control the GPIO pins. | ||
5 | |||
6 | Copyright (c) 2001,2002 Christer Weinigel <wingel@nano-system.com> | ||
7 | Copyright (c) 2005 Jim Cromie <jim.cromie@gmail.com> | ||
8 | */ | ||
9 | |||
10 | #include <linux/config.h> | ||
11 | #include <linux/fs.h> | ||
12 | #include <linux/module.h> | ||
13 | #include <linux/errno.h> | ||
14 | #include <linux/kernel.h> | ||
15 | #include <linux/init.h> | ||
16 | #include <linux/nsc_gpio.h> | ||
17 | #include <linux/platform_device.h> | ||
18 | #include <asm/uaccess.h> | ||
19 | #include <asm/io.h> | ||
20 | |||
21 | #define NAME "nsc_gpio" | ||
22 | |||
23 | void nsc_gpio_dump(struct nsc_gpio_ops *amp, unsigned index) | ||
24 | { | ||
25 | /* retrieve current config w/o changing it */ | ||
26 | u32 config = amp->gpio_config(index, ~0, 0); | ||
27 | |||
28 | /* user requested via 'v' command, so its INFO */ | ||
29 | dev_info(amp->dev, "io%02u: 0x%04x %s %s %s %s %s %s %s\tio:%d/%d\n", | ||
30 | index, config, | ||
31 | (config & 1) ? "OE" : "TS", /* output-enabled/tristate */ | ||
32 | (config & 2) ? "PP" : "OD", /* push pull / open drain */ | ||
33 | (config & 4) ? "PUE" : "PUD", /* pull up enabled/disabled */ | ||
34 | (config & 8) ? "LOCKED" : "", /* locked / unlocked */ | ||
35 | (config & 16) ? "LEVEL" : "EDGE",/* level/edge input */ | ||
36 | (config & 32) ? "HI" : "LO", /* trigger on rise/fall edge */ | ||
37 | (config & 64) ? "DEBOUNCE" : "", /* debounce */ | ||
38 | |||
39 | amp->gpio_get(index), amp->gpio_current(index)); | ||
40 | } | ||
41 | |||
42 | ssize_t nsc_gpio_write(struct file *file, const char __user *data, | ||
43 | size_t len, loff_t *ppos) | ||
44 | { | ||
45 | unsigned m = iminor(file->f_dentry->d_inode); | ||
46 | struct nsc_gpio_ops *amp = file->private_data; | ||
47 | struct device *dev = amp->dev; | ||
48 | size_t i; | ||
49 | int err = 0; | ||
50 | |||
51 | for (i = 0; i < len; ++i) { | ||
52 | char c; | ||
53 | if (get_user(c, data + i)) | ||
54 | return -EFAULT; | ||
55 | switch (c) { | ||
56 | case '0': | ||
57 | amp->gpio_set(m, 0); | ||
58 | break; | ||
59 | case '1': | ||
60 | amp->gpio_set(m, 1); | ||
61 | break; | ||
62 | case 'O': | ||
63 | dev_dbg(dev, "GPIO%d output enabled\n", m); | ||
64 | amp->gpio_config(m, ~1, 1); | ||
65 | break; | ||
66 | case 'o': | ||
67 | dev_dbg(dev, "GPIO%d output disabled\n", m); | ||
68 | amp->gpio_config(m, ~1, 0); | ||
69 | break; | ||
70 | case 'T': | ||
71 | dev_dbg(dev, "GPIO%d output is push pull\n", | ||
72 | m); | ||
73 | amp->gpio_config(m, ~2, 2); | ||
74 | break; | ||
75 | case 't': | ||
76 | dev_dbg(dev, "GPIO%d output is open drain\n", | ||
77 | m); | ||
78 | amp->gpio_config(m, ~2, 0); | ||
79 | break; | ||
80 | case 'P': | ||
81 | dev_dbg(dev, "GPIO%d pull up enabled\n", m); | ||
82 | amp->gpio_config(m, ~4, 4); | ||
83 | break; | ||
84 | case 'p': | ||
85 | dev_dbg(dev, "GPIO%d pull up disabled\n", m); | ||
86 | amp->gpio_config(m, ~4, 0); | ||
87 | break; | ||
88 | case 'v': | ||
89 | /* View Current pin settings */ | ||
90 | amp->gpio_dump(amp, m); | ||
91 | break; | ||
92 | case '\n': | ||
93 | /* end of settings string, do nothing */ | ||
94 | break; | ||
95 | default: | ||
96 | dev_err(dev, "io%2d bad setting: chr<0x%2x>\n", | ||
97 | m, (int)c); | ||
98 | err++; | ||
99 | } | ||
100 | } | ||
101 | if (err) | ||
102 | return -EINVAL; /* full string handled, report error */ | ||
103 | |||
104 | return len; | ||
105 | } | ||
106 | |||
107 | ssize_t nsc_gpio_read(struct file *file, char __user * buf, | ||
108 | size_t len, loff_t * ppos) | ||
109 | { | ||
110 | unsigned m = iminor(file->f_dentry->d_inode); | ||
111 | int value; | ||
112 | struct nsc_gpio_ops *amp = file->private_data; | ||
113 | |||
114 | value = amp->gpio_get(m); | ||
115 | if (put_user(value ? '1' : '0', buf)) | ||
116 | return -EFAULT; | ||
117 | |||
118 | return 1; | ||
119 | } | ||
120 | |||
121 | /* common file-ops routines for both scx200_gpio and pc87360_gpio */ | ||
122 | EXPORT_SYMBOL(nsc_gpio_write); | ||
123 | EXPORT_SYMBOL(nsc_gpio_read); | ||
124 | EXPORT_SYMBOL(nsc_gpio_dump); | ||
125 | |||
126 | static int __init nsc_gpio_init(void) | ||
127 | { | ||
128 | printk(KERN_DEBUG NAME " initializing\n"); | ||
129 | return 0; | ||
130 | } | ||
131 | |||
132 | static void __exit nsc_gpio_cleanup(void) | ||
133 | { | ||
134 | printk(KERN_DEBUG NAME " cleanup\n"); | ||
135 | } | ||
136 | |||
137 | module_init(nsc_gpio_init); | ||
138 | module_exit(nsc_gpio_cleanup); | ||
139 | |||
140 | MODULE_AUTHOR("Jim Cromie <jim.cromie@gmail.com>"); | ||
141 | MODULE_DESCRIPTION("NatSemi GPIO Common Methods"); | ||
142 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/char/pc8736x_gpio.c b/drivers/char/pc8736x_gpio.c new file mode 100644 index 000000000000..1c706ccfdbb3 --- /dev/null +++ b/drivers/char/pc8736x_gpio.c | |||
@@ -0,0 +1,340 @@ | |||
1 | /* linux/drivers/char/pc8736x_gpio.c | ||
2 | |||
3 | National Semiconductor PC8736x GPIO driver. Allows a user space | ||
4 | process to play with the GPIO pins. | ||
5 | |||
6 | Copyright (c) 2005 Jim Cromie <jim.cromie@gmail.com> | ||
7 | |||
8 | adapted from linux/drivers/char/scx200_gpio.c | ||
9 | Copyright (c) 2001,2002 Christer Weinigel <wingel@nano-system.com>, | ||
10 | */ | ||
11 | |||
12 | #include <linux/config.h> | ||
13 | #include <linux/fs.h> | ||
14 | #include <linux/module.h> | ||
15 | #include <linux/errno.h> | ||
16 | #include <linux/kernel.h> | ||
17 | #include <linux/init.h> | ||
18 | #include <linux/io.h> | ||
19 | #include <linux/ioport.h> | ||
20 | #include <linux/mutex.h> | ||
21 | #include <linux/nsc_gpio.h> | ||
22 | #include <linux/platform_device.h> | ||
23 | #include <asm/uaccess.h> | ||
24 | |||
25 | #define DEVNAME "pc8736x_gpio" | ||
26 | |||
27 | MODULE_AUTHOR("Jim Cromie <jim.cromie@gmail.com>"); | ||
28 | MODULE_DESCRIPTION("NatSemi PC-8736x GPIO Pin Driver"); | ||
29 | MODULE_LICENSE("GPL"); | ||
30 | |||
31 | static int major; /* default to dynamic major */ | ||
32 | module_param(major, int, 0); | ||
33 | MODULE_PARM_DESC(major, "Major device number"); | ||
34 | |||
35 | static DEFINE_MUTEX(pc8736x_gpio_config_lock); | ||
36 | static unsigned pc8736x_gpio_base; | ||
37 | static u8 pc8736x_gpio_shadow[4]; | ||
38 | |||
39 | #define SIO_BASE1 0x2E /* 1st command-reg to check */ | ||
40 | #define SIO_BASE2 0x4E /* alt command-reg to check */ | ||
41 | #define SIO_BASE_OFFSET 0x20 | ||
42 | |||
43 | #define SIO_SID 0x20 /* SuperI/O ID Register */ | ||
44 | #define SIO_SID_VALUE 0xe9 /* Expected value in SuperI/O ID Register */ | ||
45 | |||
46 | #define SIO_CF1 0x21 /* chip config, bit0 is chip enable */ | ||
47 | |||
48 | #define PC8736X_GPIO_SIZE 16 | ||
49 | |||
50 | #define SIO_UNIT_SEL 0x7 /* unit select reg */ | ||
51 | #define SIO_UNIT_ACT 0x30 /* unit enable */ | ||
52 | #define SIO_GPIO_UNIT 0x7 /* unit number of GPIO */ | ||
53 | #define SIO_VLM_UNIT 0x0D | ||
54 | #define SIO_TMS_UNIT 0x0E | ||
55 | |||
56 | /* config-space addrs to read/write each unit's runtime addr */ | ||
57 | #define SIO_BASE_HADDR 0x60 | ||
58 | #define SIO_BASE_LADDR 0x61 | ||
59 | |||
60 | /* GPIO config-space pin-control addresses */ | ||
61 | #define SIO_GPIO_PIN_SELECT 0xF0 | ||
62 | #define SIO_GPIO_PIN_CONFIG 0xF1 | ||
63 | #define SIO_GPIO_PIN_EVENT 0xF2 | ||
64 | |||
65 | static unsigned char superio_cmd = 0; | ||
66 | static unsigned char selected_device = 0xFF; /* bogus start val */ | ||
67 | |||
68 | /* GPIO port runtime access, functionality */ | ||
69 | static int port_offset[] = { 0, 4, 8, 10 }; /* non-uniform offsets ! */ | ||
70 | /* static int event_capable[] = { 1, 1, 0, 0 }; ports 2,3 are hobbled */ | ||
71 | |||
72 | #define PORT_OUT 0 | ||
73 | #define PORT_IN 1 | ||
74 | #define PORT_EVT_EN 2 | ||
75 | #define PORT_EVT_STST 3 | ||
76 | |||
77 | static struct platform_device *pdev; /* use in dev_*() */ | ||
78 | |||
79 | static inline void superio_outb(int addr, int val) | ||
80 | { | ||
81 | outb_p(addr, superio_cmd); | ||
82 | outb_p(val, superio_cmd + 1); | ||
83 | } | ||
84 | |||
85 | static inline int superio_inb(int addr) | ||
86 | { | ||
87 | outb_p(addr, superio_cmd); | ||
88 | return inb_p(superio_cmd + 1); | ||
89 | } | ||
90 | |||
91 | static int pc8736x_superio_present(void) | ||
92 | { | ||
93 | /* try the 2 possible values, read a hardware reg to verify */ | ||
94 | superio_cmd = SIO_BASE1; | ||
95 | if (superio_inb(SIO_SID) == SIO_SID_VALUE) | ||
96 | return superio_cmd; | ||
97 | |||
98 | superio_cmd = SIO_BASE2; | ||
99 | if (superio_inb(SIO_SID) == SIO_SID_VALUE) | ||
100 | return superio_cmd; | ||
101 | |||
102 | return 0; | ||
103 | } | ||
104 | |||
105 | static void device_select(unsigned devldn) | ||
106 | { | ||
107 | superio_outb(SIO_UNIT_SEL, devldn); | ||
108 | selected_device = devldn; | ||
109 | } | ||
110 | |||
111 | static void select_pin(unsigned iminor) | ||
112 | { | ||
113 | /* select GPIO port/pin from device minor number */ | ||
114 | device_select(SIO_GPIO_UNIT); | ||
115 | superio_outb(SIO_GPIO_PIN_SELECT, | ||
116 | ((iminor << 1) & 0xF0) | (iminor & 0x7)); | ||
117 | } | ||
118 | |||
119 | static inline u32 pc8736x_gpio_configure_fn(unsigned index, u32 mask, u32 bits, | ||
120 | u32 func_slct) | ||
121 | { | ||
122 | u32 config, new_config; | ||
123 | |||
124 | mutex_lock(&pc8736x_gpio_config_lock); | ||
125 | |||
126 | device_select(SIO_GPIO_UNIT); | ||
127 | select_pin(index); | ||
128 | |||
129 | /* read current config value */ | ||
130 | config = superio_inb(func_slct); | ||
131 | |||
132 | /* set new config */ | ||
133 | new_config = (config & mask) | bits; | ||
134 | superio_outb(func_slct, new_config); | ||
135 | |||
136 | mutex_unlock(&pc8736x_gpio_config_lock); | ||
137 | |||
138 | return config; | ||
139 | } | ||
140 | |||
141 | static u32 pc8736x_gpio_configure(unsigned index, u32 mask, u32 bits) | ||
142 | { | ||
143 | return pc8736x_gpio_configure_fn(index, mask, bits, | ||
144 | SIO_GPIO_PIN_CONFIG); | ||
145 | } | ||
146 | |||
147 | static int pc8736x_gpio_get(unsigned minor) | ||
148 | { | ||
149 | int port, bit, val; | ||
150 | |||
151 | port = minor >> 3; | ||
152 | bit = minor & 7; | ||
153 | val = inb_p(pc8736x_gpio_base + port_offset[port] + PORT_IN); | ||
154 | val >>= bit; | ||
155 | val &= 1; | ||
156 | |||
157 | dev_dbg(&pdev->dev, "_gpio_get(%d from %x bit %d) == val %d\n", | ||
158 | minor, pc8736x_gpio_base + port_offset[port] + PORT_IN, bit, | ||
159 | val); | ||
160 | |||
161 | return val; | ||
162 | } | ||
163 | |||
164 | static void pc8736x_gpio_set(unsigned minor, int val) | ||
165 | { | ||
166 | int port, bit, curval; | ||
167 | |||
168 | minor &= 0x1f; | ||
169 | port = minor >> 3; | ||
170 | bit = minor & 7; | ||
171 | curval = inb_p(pc8736x_gpio_base + port_offset[port] + PORT_OUT); | ||
172 | |||
173 | dev_dbg(&pdev->dev, "addr:%x cur:%x bit-pos:%d cur-bit:%x + new:%d -> bit-new:%d\n", | ||
174 | pc8736x_gpio_base + port_offset[port] + PORT_OUT, | ||
175 | curval, bit, (curval & ~(1 << bit)), val, (val << bit)); | ||
176 | |||
177 | val = (curval & ~(1 << bit)) | (val << bit); | ||
178 | |||
179 | dev_dbg(&pdev->dev, "gpio_set(minor:%d port:%d bit:%d)" | ||
180 | " %2x -> %2x\n", minor, port, bit, curval, val); | ||
181 | |||
182 | outb_p(val, pc8736x_gpio_base + port_offset[port] + PORT_OUT); | ||
183 | |||
184 | curval = inb_p(pc8736x_gpio_base + port_offset[port] + PORT_OUT); | ||
185 | val = inb_p(pc8736x_gpio_base + port_offset[port] + PORT_IN); | ||
186 | |||
187 | dev_dbg(&pdev->dev, "wrote %x, read: %x\n", curval, val); | ||
188 | pc8736x_gpio_shadow[port] = val; | ||
189 | } | ||
190 | |||
191 | static void pc8736x_gpio_set_high(unsigned index) | ||
192 | { | ||
193 | pc8736x_gpio_set(index, 1); | ||
194 | } | ||
195 | |||
196 | static void pc8736x_gpio_set_low(unsigned index) | ||
197 | { | ||
198 | pc8736x_gpio_set(index, 0); | ||
199 | } | ||
200 | |||
201 | static int pc8736x_gpio_current(unsigned minor) | ||
202 | { | ||
203 | int port, bit; | ||
204 | minor &= 0x1f; | ||
205 | port = minor >> 3; | ||
206 | bit = minor & 7; | ||
207 | return ((pc8736x_gpio_shadow[port] >> bit) & 0x01); | ||
208 | } | ||
209 | |||
210 | static void pc8736x_gpio_change(unsigned index) | ||
211 | { | ||
212 | pc8736x_gpio_set(index, !pc8736x_gpio_current(index)); | ||
213 | } | ||
214 | |||
215 | static struct nsc_gpio_ops pc8736x_access = { | ||
216 | .owner = THIS_MODULE, | ||
217 | .gpio_config = pc8736x_gpio_configure, | ||
218 | .gpio_dump = nsc_gpio_dump, | ||
219 | .gpio_get = pc8736x_gpio_get, | ||
220 | .gpio_set = pc8736x_gpio_set, | ||
221 | .gpio_set_high = pc8736x_gpio_set_high, | ||
222 | .gpio_set_low = pc8736x_gpio_set_low, | ||
223 | .gpio_change = pc8736x_gpio_change, | ||
224 | .gpio_current = pc8736x_gpio_current | ||
225 | }; | ||
226 | |||
227 | static int pc8736x_gpio_open(struct inode *inode, struct file *file) | ||
228 | { | ||
229 | unsigned m = iminor(inode); | ||
230 | file->private_data = &pc8736x_access; | ||
231 | |||
232 | dev_dbg(&pdev->dev, "open %d\n", m); | ||
233 | |||
234 | if (m > 63) | ||
235 | return -EINVAL; | ||
236 | return nonseekable_open(inode, file); | ||
237 | } | ||
238 | |||
239 | static struct file_operations pc8736x_gpio_fops = { | ||
240 | .owner = THIS_MODULE, | ||
241 | .open = pc8736x_gpio_open, | ||
242 | .write = nsc_gpio_write, | ||
243 | .read = nsc_gpio_read, | ||
244 | }; | ||
245 | |||
246 | static void __init pc8736x_init_shadow(void) | ||
247 | { | ||
248 | int port; | ||
249 | |||
250 | /* read the current values driven on the GPIO signals */ | ||
251 | for (port = 0; port < 4; ++port) | ||
252 | pc8736x_gpio_shadow[port] | ||
253 | = inb_p(pc8736x_gpio_base + port_offset[port] | ||
254 | + PORT_OUT); | ||
255 | |||
256 | } | ||
257 | |||
258 | static int __init pc8736x_gpio_init(void) | ||
259 | { | ||
260 | int rc = 0; | ||
261 | |||
262 | pdev = platform_device_alloc(DEVNAME, 0); | ||
263 | if (!pdev) | ||
264 | return -ENOMEM; | ||
265 | |||
266 | rc = platform_device_add(pdev); | ||
267 | if (rc) { | ||
268 | rc = -ENODEV; | ||
269 | goto undo_platform_dev_alloc; | ||
270 | } | ||
271 | dev_info(&pdev->dev, "NatSemi pc8736x GPIO Driver Initializing\n"); | ||
272 | |||
273 | if (!pc8736x_superio_present()) { | ||
274 | rc = -ENODEV; | ||
275 | dev_err(&pdev->dev, "no device found\n"); | ||
276 | goto undo_platform_dev_add; | ||
277 | } | ||
278 | pc8736x_access.dev = &pdev->dev; | ||
279 | |||
280 | /* Verify that chip and it's GPIO unit are both enabled. | ||
281 | My BIOS does this, so I take minimum action here | ||
282 | */ | ||
283 | rc = superio_inb(SIO_CF1); | ||
284 | if (!(rc & 0x01)) { | ||
285 | rc = -ENODEV; | ||
286 | dev_err(&pdev->dev, "device not enabled\n"); | ||
287 | goto undo_platform_dev_add; | ||
288 | } | ||
289 | device_select(SIO_GPIO_UNIT); | ||
290 | if (!superio_inb(SIO_UNIT_ACT)) { | ||
291 | rc = -ENODEV; | ||
292 | dev_err(&pdev->dev, "GPIO unit not enabled\n"); | ||
293 | goto undo_platform_dev_add; | ||
294 | } | ||
295 | |||
296 | /* read the GPIO unit base addr that chip responds to */ | ||
297 | pc8736x_gpio_base = (superio_inb(SIO_BASE_HADDR) << 8 | ||
298 | | superio_inb(SIO_BASE_LADDR)); | ||
299 | |||
300 | if (!request_region(pc8736x_gpio_base, 16, DEVNAME)) { | ||
301 | rc = -ENODEV; | ||
302 | dev_err(&pdev->dev, "GPIO ioport %x busy\n", | ||
303 | pc8736x_gpio_base); | ||
304 | goto undo_platform_dev_add; | ||
305 | } | ||
306 | dev_info(&pdev->dev, "GPIO ioport %x reserved\n", pc8736x_gpio_base); | ||
307 | |||
308 | rc = register_chrdev(major, DEVNAME, &pc8736x_gpio_fops); | ||
309 | if (rc < 0) { | ||
310 | dev_err(&pdev->dev, "register-chrdev failed: %d\n", rc); | ||
311 | goto undo_platform_dev_add; | ||
312 | } | ||
313 | if (!major) { | ||
314 | major = rc; | ||
315 | dev_dbg(&pdev->dev, "got dynamic major %d\n", major); | ||
316 | } | ||
317 | |||
318 | pc8736x_init_shadow(); | ||
319 | return 0; | ||
320 | |||
321 | undo_platform_dev_add: | ||
322 | platform_device_put(pdev); | ||
323 | undo_platform_dev_alloc: | ||
324 | kfree(pdev); | ||
325 | return rc; | ||
326 | } | ||
327 | |||
328 | static void __exit pc8736x_gpio_cleanup(void) | ||
329 | { | ||
330 | dev_dbg(&pdev->dev, " cleanup\n"); | ||
331 | |||
332 | release_region(pc8736x_gpio_base, 16); | ||
333 | |||
334 | unregister_chrdev(major, DEVNAME); | ||
335 | } | ||
336 | |||
337 | EXPORT_SYMBOL(pc8736x_access); | ||
338 | |||
339 | module_init(pc8736x_gpio_init); | ||
340 | module_exit(pc8736x_gpio_cleanup); | ||
diff --git a/drivers/char/ppdev.c b/drivers/char/ppdev.c index bee6c47b45bd..24231d9743dc 100644 --- a/drivers/char/ppdev.c +++ b/drivers/char/ppdev.c | |||
@@ -60,7 +60,6 @@ | |||
60 | #include <linux/init.h> | 60 | #include <linux/init.h> |
61 | #include <linux/sched.h> | 61 | #include <linux/sched.h> |
62 | #include <linux/device.h> | 62 | #include <linux/device.h> |
63 | #include <linux/devfs_fs_kernel.h> | ||
64 | #include <linux/ioctl.h> | 63 | #include <linux/ioctl.h> |
65 | #include <linux/parport.h> | 64 | #include <linux/parport.h> |
66 | #include <linux/ctype.h> | 65 | #include <linux/ctype.h> |
@@ -770,7 +769,7 @@ static struct parport_driver pp_driver = { | |||
770 | 769 | ||
771 | static int __init ppdev_init (void) | 770 | static int __init ppdev_init (void) |
772 | { | 771 | { |
773 | int i, err = 0; | 772 | int err = 0; |
774 | 773 | ||
775 | if (register_chrdev (PP_MAJOR, CHRDEV, &pp_fops)) { | 774 | if (register_chrdev (PP_MAJOR, CHRDEV, &pp_fops)) { |
776 | printk (KERN_WARNING CHRDEV ": unable to get major %d\n", | 775 | printk (KERN_WARNING CHRDEV ": unable to get major %d\n", |
@@ -782,11 +781,6 @@ static int __init ppdev_init (void) | |||
782 | err = PTR_ERR(ppdev_class); | 781 | err = PTR_ERR(ppdev_class); |
783 | goto out_chrdev; | 782 | goto out_chrdev; |
784 | } | 783 | } |
785 | devfs_mk_dir("parports"); | ||
786 | for (i = 0; i < PARPORT_MAX; i++) { | ||
787 | devfs_mk_cdev(MKDEV(PP_MAJOR, i), | ||
788 | S_IFCHR | S_IRUGO | S_IWUGO, "parports/%d", i); | ||
789 | } | ||
790 | if (parport_register_driver(&pp_driver)) { | 784 | if (parport_register_driver(&pp_driver)) { |
791 | printk (KERN_WARNING CHRDEV ": unable to register with parport\n"); | 785 | printk (KERN_WARNING CHRDEV ": unable to register with parport\n"); |
792 | goto out_class; | 786 | goto out_class; |
@@ -796,9 +790,6 @@ static int __init ppdev_init (void) | |||
796 | goto out; | 790 | goto out; |
797 | 791 | ||
798 | out_class: | 792 | out_class: |
799 | for (i = 0; i < PARPORT_MAX; i++) | ||
800 | devfs_remove("parports/%d", i); | ||
801 | devfs_remove("parports"); | ||
802 | class_destroy(ppdev_class); | 793 | class_destroy(ppdev_class); |
803 | out_chrdev: | 794 | out_chrdev: |
804 | unregister_chrdev(PP_MAJOR, CHRDEV); | 795 | unregister_chrdev(PP_MAJOR, CHRDEV); |
@@ -808,12 +799,8 @@ out: | |||
808 | 799 | ||
809 | static void __exit ppdev_cleanup (void) | 800 | static void __exit ppdev_cleanup (void) |
810 | { | 801 | { |
811 | int i; | ||
812 | /* Clean up all parport stuff */ | 802 | /* Clean up all parport stuff */ |
813 | for (i = 0; i < PARPORT_MAX; i++) | ||
814 | devfs_remove("parports/%d", i); | ||
815 | parport_unregister_driver(&pp_driver); | 803 | parport_unregister_driver(&pp_driver); |
816 | devfs_remove("parports"); | ||
817 | class_destroy(ppdev_class); | 804 | class_destroy(ppdev_class); |
818 | unregister_chrdev (PP_MAJOR, CHRDEV); | 805 | unregister_chrdev (PP_MAJOR, CHRDEV); |
819 | } | 806 | } |
diff --git a/drivers/char/pty.c b/drivers/char/pty.c index 9b5a2c0e7008..9491e4307566 100644 --- a/drivers/char/pty.c +++ b/drivers/char/pty.c | |||
@@ -24,7 +24,6 @@ | |||
24 | #include <linux/major.h> | 24 | #include <linux/major.h> |
25 | #include <linux/mm.h> | 25 | #include <linux/mm.h> |
26 | #include <linux/init.h> | 26 | #include <linux/init.h> |
27 | #include <linux/devfs_fs_kernel.h> | ||
28 | #include <linux/sysctl.h> | 27 | #include <linux/sysctl.h> |
29 | 28 | ||
30 | #include <asm/uaccess.h> | 29 | #include <asm/uaccess.h> |
@@ -101,7 +100,7 @@ static void pty_unthrottle(struct tty_struct * tty) | |||
101 | * | 100 | * |
102 | * FIXME: Our pty_write method is called with our ldisc lock held but | 101 | * FIXME: Our pty_write method is called with our ldisc lock held but |
103 | * not our partners. We can't just take the other one blindly without | 102 | * not our partners. We can't just take the other one blindly without |
104 | * risking deadlocks. There is also the small matter of TTY_DONT_FLIP | 103 | * risking deadlocks. |
105 | */ | 104 | */ |
106 | static int pty_write(struct tty_struct * tty, const unsigned char *buf, int count) | 105 | static int pty_write(struct tty_struct * tty, const unsigned char *buf, int count) |
107 | { | 106 | { |
@@ -265,7 +264,6 @@ static void __init legacy_pty_init(void) | |||
265 | pty_driver->owner = THIS_MODULE; | 264 | pty_driver->owner = THIS_MODULE; |
266 | pty_driver->driver_name = "pty_master"; | 265 | pty_driver->driver_name = "pty_master"; |
267 | pty_driver->name = "pty"; | 266 | pty_driver->name = "pty"; |
268 | pty_driver->devfs_name = "pty/m"; | ||
269 | pty_driver->major = PTY_MASTER_MAJOR; | 267 | pty_driver->major = PTY_MASTER_MAJOR; |
270 | pty_driver->minor_start = 0; | 268 | pty_driver->minor_start = 0; |
271 | pty_driver->type = TTY_DRIVER_TYPE_PTY; | 269 | pty_driver->type = TTY_DRIVER_TYPE_PTY; |
@@ -283,7 +281,6 @@ static void __init legacy_pty_init(void) | |||
283 | pty_slave_driver->owner = THIS_MODULE; | 281 | pty_slave_driver->owner = THIS_MODULE; |
284 | pty_slave_driver->driver_name = "pty_slave"; | 282 | pty_slave_driver->driver_name = "pty_slave"; |
285 | pty_slave_driver->name = "ttyp"; | 283 | pty_slave_driver->name = "ttyp"; |
286 | pty_slave_driver->devfs_name = "pty/s"; | ||
287 | pty_slave_driver->major = PTY_SLAVE_MAJOR; | 284 | pty_slave_driver->major = PTY_SLAVE_MAJOR; |
288 | pty_slave_driver->minor_start = 0; | 285 | pty_slave_driver->minor_start = 0; |
289 | pty_slave_driver->type = TTY_DRIVER_TYPE_PTY; | 286 | pty_slave_driver->type = TTY_DRIVER_TYPE_PTY; |
@@ -351,7 +348,6 @@ static int pty_unix98_ioctl(struct tty_struct *tty, struct file *file, | |||
351 | 348 | ||
352 | static void __init unix98_pty_init(void) | 349 | static void __init unix98_pty_init(void) |
353 | { | 350 | { |
354 | devfs_mk_dir("pts"); | ||
355 | ptm_driver = alloc_tty_driver(NR_UNIX98_PTY_MAX); | 351 | ptm_driver = alloc_tty_driver(NR_UNIX98_PTY_MAX); |
356 | if (!ptm_driver) | 352 | if (!ptm_driver) |
357 | panic("Couldn't allocate Unix98 ptm driver"); | 353 | panic("Couldn't allocate Unix98 ptm driver"); |
@@ -372,7 +368,7 @@ static void __init unix98_pty_init(void) | |||
372 | ptm_driver->init_termios.c_cflag = B38400 | CS8 | CREAD; | 368 | ptm_driver->init_termios.c_cflag = B38400 | CS8 | CREAD; |
373 | ptm_driver->init_termios.c_lflag = 0; | 369 | ptm_driver->init_termios.c_lflag = 0; |
374 | ptm_driver->flags = TTY_DRIVER_RESET_TERMIOS | TTY_DRIVER_REAL_RAW | | 370 | ptm_driver->flags = TTY_DRIVER_RESET_TERMIOS | TTY_DRIVER_REAL_RAW | |
375 | TTY_DRIVER_NO_DEVFS | TTY_DRIVER_DEVPTS_MEM; | 371 | TTY_DRIVER_DYNAMIC_DEV | TTY_DRIVER_DEVPTS_MEM; |
376 | ptm_driver->other = pts_driver; | 372 | ptm_driver->other = pts_driver; |
377 | tty_set_operations(ptm_driver, &pty_ops); | 373 | tty_set_operations(ptm_driver, &pty_ops); |
378 | ptm_driver->ioctl = pty_unix98_ioctl; | 374 | ptm_driver->ioctl = pty_unix98_ioctl; |
@@ -387,7 +383,7 @@ static void __init unix98_pty_init(void) | |||
387 | pts_driver->init_termios = tty_std_termios; | 383 | pts_driver->init_termios = tty_std_termios; |
388 | pts_driver->init_termios.c_cflag = B38400 | CS8 | CREAD; | 384 | pts_driver->init_termios.c_cflag = B38400 | CS8 | CREAD; |
389 | pts_driver->flags = TTY_DRIVER_RESET_TERMIOS | TTY_DRIVER_REAL_RAW | | 385 | pts_driver->flags = TTY_DRIVER_RESET_TERMIOS | TTY_DRIVER_REAL_RAW | |
390 | TTY_DRIVER_NO_DEVFS | TTY_DRIVER_DEVPTS_MEM; | 386 | TTY_DRIVER_DYNAMIC_DEV | TTY_DRIVER_DEVPTS_MEM; |
391 | pts_driver->other = ptm_driver; | 387 | pts_driver->other = ptm_driver; |
392 | tty_set_operations(pts_driver, &pty_ops); | 388 | tty_set_operations(pts_driver, &pty_ops); |
393 | 389 | ||
diff --git a/drivers/char/raw.c b/drivers/char/raw.c index 15a7b4086524..9bf97c5e38c0 100644 --- a/drivers/char/raw.c +++ b/drivers/char/raw.c | |||
@@ -10,7 +10,6 @@ | |||
10 | 10 | ||
11 | #include <linux/init.h> | 11 | #include <linux/init.h> |
12 | #include <linux/fs.h> | 12 | #include <linux/fs.h> |
13 | #include <linux/devfs_fs_kernel.h> | ||
14 | #include <linux/major.h> | 13 | #include <linux/major.h> |
15 | #include <linux/blkdev.h> | 14 | #include <linux/blkdev.h> |
16 | #include <linux/module.h> | 15 | #include <linux/module.h> |
@@ -288,7 +287,6 @@ static struct cdev raw_cdev = { | |||
288 | 287 | ||
289 | static int __init raw_init(void) | 288 | static int __init raw_init(void) |
290 | { | 289 | { |
291 | int i; | ||
292 | dev_t dev = MKDEV(RAW_MAJOR, 0); | 290 | dev_t dev = MKDEV(RAW_MAJOR, 0); |
293 | 291 | ||
294 | if (register_chrdev_region(dev, MAX_RAW_MINORS, "raw")) | 292 | if (register_chrdev_region(dev, MAX_RAW_MINORS, "raw")) |
@@ -310,13 +308,6 @@ static int __init raw_init(void) | |||
310 | } | 308 | } |
311 | class_device_create(raw_class, NULL, MKDEV(RAW_MAJOR, 0), NULL, "rawctl"); | 309 | class_device_create(raw_class, NULL, MKDEV(RAW_MAJOR, 0), NULL, "rawctl"); |
312 | 310 | ||
313 | devfs_mk_cdev(MKDEV(RAW_MAJOR, 0), | ||
314 | S_IFCHR | S_IRUGO | S_IWUGO, | ||
315 | "raw/rawctl"); | ||
316 | for (i = 1; i < MAX_RAW_MINORS; i++) | ||
317 | devfs_mk_cdev(MKDEV(RAW_MAJOR, i), | ||
318 | S_IFCHR | S_IRUGO | S_IWUGO, | ||
319 | "raw/raw%d", i); | ||
320 | return 0; | 311 | return 0; |
321 | 312 | ||
322 | error: | 313 | error: |
@@ -326,12 +317,6 @@ error: | |||
326 | 317 | ||
327 | static void __exit raw_exit(void) | 318 | static void __exit raw_exit(void) |
328 | { | 319 | { |
329 | int i; | ||
330 | |||
331 | for (i = 1; i < MAX_RAW_MINORS; i++) | ||
332 | devfs_remove("raw/raw%d", i); | ||
333 | devfs_remove("raw/rawctl"); | ||
334 | devfs_remove("raw"); | ||
335 | class_device_destroy(raw_class, MKDEV(RAW_MAJOR, 0)); | 320 | class_device_destroy(raw_class, MKDEV(RAW_MAJOR, 0)); |
336 | class_destroy(raw_class); | 321 | class_destroy(raw_class); |
337 | cdev_del(&raw_cdev); | 322 | cdev_del(&raw_cdev); |
diff --git a/drivers/char/riscom8.c b/drivers/char/riscom8.c index 657c0d88f48c..c84c3c3f10c3 100644 --- a/drivers/char/riscom8.c +++ b/drivers/char/riscom8.c | |||
@@ -1634,7 +1634,6 @@ static inline int rc_init_drivers(void) | |||
1634 | memset(IRQ_to_board, 0, sizeof(IRQ_to_board)); | 1634 | memset(IRQ_to_board, 0, sizeof(IRQ_to_board)); |
1635 | riscom_driver->owner = THIS_MODULE; | 1635 | riscom_driver->owner = THIS_MODULE; |
1636 | riscom_driver->name = "ttyL"; | 1636 | riscom_driver->name = "ttyL"; |
1637 | riscom_driver->devfs_name = "tts/L"; | ||
1638 | riscom_driver->major = RISCOM8_NORMAL_MAJOR; | 1637 | riscom_driver->major = RISCOM8_NORMAL_MAJOR; |
1639 | riscom_driver->type = TTY_DRIVER_TYPE_SERIAL; | 1638 | riscom_driver->type = TTY_DRIVER_TYPE_SERIAL; |
1640 | riscom_driver->subtype = SERIAL_TYPE_NORMAL; | 1639 | riscom_driver->subtype = SERIAL_TYPE_NORMAL; |
diff --git a/drivers/char/rocket.c b/drivers/char/rocket.c index 0708c5164c83..0ac131881322 100644 --- a/drivers/char/rocket.c +++ b/drivers/char/rocket.c | |||
@@ -2426,8 +2426,7 @@ static int __init rp_init(void) | |||
2426 | */ | 2426 | */ |
2427 | 2427 | ||
2428 | rocket_driver->owner = THIS_MODULE; | 2428 | rocket_driver->owner = THIS_MODULE; |
2429 | rocket_driver->flags = TTY_DRIVER_NO_DEVFS; | 2429 | rocket_driver->flags = TTY_DRIVER_DYNAMIC_DEV; |
2430 | rocket_driver->devfs_name = "tts/R"; | ||
2431 | rocket_driver->name = "ttyR"; | 2430 | rocket_driver->name = "ttyR"; |
2432 | rocket_driver->driver_name = "Comtrol RocketPort"; | 2431 | rocket_driver->driver_name = "Comtrol RocketPort"; |
2433 | rocket_driver->major = TTY_ROCKET_MAJOR; | 2432 | rocket_driver->major = TTY_ROCKET_MAJOR; |
@@ -2438,7 +2437,7 @@ static int __init rp_init(void) | |||
2438 | rocket_driver->init_termios.c_cflag = | 2437 | rocket_driver->init_termios.c_cflag = |
2439 | B9600 | CS8 | CREAD | HUPCL | CLOCAL; | 2438 | B9600 | CS8 | CREAD | HUPCL | CLOCAL; |
2440 | #ifdef ROCKET_SOFT_FLOW | 2439 | #ifdef ROCKET_SOFT_FLOW |
2441 | rocket_driver->flags |= TTY_DRIVER_REAL_RAW | TTY_DRIVER_NO_DEVFS; | 2440 | rocket_driver->flags |= TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV; |
2442 | #endif | 2441 | #endif |
2443 | tty_set_operations(rocket_driver, &rocket_ops); | 2442 | tty_set_operations(rocket_driver, &rocket_ops); |
2444 | 2443 | ||
diff --git a/drivers/char/scx200_gpio.c b/drivers/char/scx200_gpio.c index 664a6e97eb1a..5a280a330401 100644 --- a/drivers/char/scx200_gpio.c +++ b/drivers/char/scx200_gpio.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* linux/drivers/char/scx200_gpio.c | 1 | /* linux/drivers/char/scx200_gpio.c |
2 | 2 | ||
3 | National Semiconductor SCx200 GPIO driver. Allows a user space | 3 | National Semiconductor SCx200 GPIO driver. Allows a user space |
4 | process to play with the GPIO pins. | 4 | process to play with the GPIO pins. |
@@ -6,17 +6,26 @@ | |||
6 | Copyright (c) 2001,2002 Christer Weinigel <wingel@nano-system.com> */ | 6 | Copyright (c) 2001,2002 Christer Weinigel <wingel@nano-system.com> */ |
7 | 7 | ||
8 | #include <linux/config.h> | 8 | #include <linux/config.h> |
9 | #include <linux/device.h> | ||
9 | #include <linux/fs.h> | 10 | #include <linux/fs.h> |
10 | #include <linux/module.h> | 11 | #include <linux/module.h> |
11 | #include <linux/errno.h> | 12 | #include <linux/errno.h> |
12 | #include <linux/kernel.h> | 13 | #include <linux/kernel.h> |
13 | #include <linux/init.h> | 14 | #include <linux/init.h> |
15 | #include <linux/platform_device.h> | ||
14 | #include <asm/uaccess.h> | 16 | #include <asm/uaccess.h> |
15 | #include <asm/io.h> | 17 | #include <asm/io.h> |
16 | 18 | ||
19 | #include <linux/types.h> | ||
20 | #include <linux/cdev.h> | ||
21 | |||
17 | #include <linux/scx200_gpio.h> | 22 | #include <linux/scx200_gpio.h> |
23 | #include <linux/nsc_gpio.h> | ||
18 | 24 | ||
19 | #define NAME "scx200_gpio" | 25 | #define NAME "scx200_gpio" |
26 | #define DEVNAME NAME | ||
27 | |||
28 | static struct platform_device *pdev; | ||
20 | 29 | ||
21 | MODULE_AUTHOR("Christer Weinigel <wingel@nano-system.com>"); | 30 | MODULE_AUTHOR("Christer Weinigel <wingel@nano-system.com>"); |
22 | MODULE_DESCRIPTION("NatSemi SCx200 GPIO Pin Driver"); | 31 | MODULE_DESCRIPTION("NatSemi SCx200 GPIO Pin Driver"); |
@@ -26,70 +35,23 @@ static int major = 0; /* default to dynamic major */ | |||
26 | module_param(major, int, 0); | 35 | module_param(major, int, 0); |
27 | MODULE_PARM_DESC(major, "Major device number"); | 36 | MODULE_PARM_DESC(major, "Major device number"); |
28 | 37 | ||
29 | static ssize_t scx200_gpio_write(struct file *file, const char __user *data, | 38 | struct nsc_gpio_ops scx200_access = { |
30 | size_t len, loff_t *ppos) | 39 | .owner = THIS_MODULE, |
31 | { | 40 | .gpio_config = scx200_gpio_configure, |
32 | unsigned m = iminor(file->f_dentry->d_inode); | 41 | .gpio_dump = nsc_gpio_dump, |
33 | size_t i; | 42 | .gpio_get = scx200_gpio_get, |
34 | 43 | .gpio_set = scx200_gpio_set, | |
35 | for (i = 0; i < len; ++i) { | 44 | .gpio_set_high = scx200_gpio_set_high, |
36 | char c; | 45 | .gpio_set_low = scx200_gpio_set_low, |
37 | if (get_user(c, data+i)) | 46 | .gpio_change = scx200_gpio_change, |
38 | return -EFAULT; | 47 | .gpio_current = scx200_gpio_current |
39 | switch (c) | 48 | }; |
40 | { | ||
41 | case '0': | ||
42 | scx200_gpio_set(m, 0); | ||
43 | break; | ||
44 | case '1': | ||
45 | scx200_gpio_set(m, 1); | ||
46 | break; | ||
47 | case 'O': | ||
48 | printk(KERN_INFO NAME ": GPIO%d output enabled\n", m); | ||
49 | scx200_gpio_configure(m, ~1, 1); | ||
50 | break; | ||
51 | case 'o': | ||
52 | printk(KERN_INFO NAME ": GPIO%d output disabled\n", m); | ||
53 | scx200_gpio_configure(m, ~1, 0); | ||
54 | break; | ||
55 | case 'T': | ||
56 | printk(KERN_INFO NAME ": GPIO%d output is push pull\n", m); | ||
57 | scx200_gpio_configure(m, ~2, 2); | ||
58 | break; | ||
59 | case 't': | ||
60 | printk(KERN_INFO NAME ": GPIO%d output is open drain\n", m); | ||
61 | scx200_gpio_configure(m, ~2, 0); | ||
62 | break; | ||
63 | case 'P': | ||
64 | printk(KERN_INFO NAME ": GPIO%d pull up enabled\n", m); | ||
65 | scx200_gpio_configure(m, ~4, 4); | ||
66 | break; | ||
67 | case 'p': | ||
68 | printk(KERN_INFO NAME ": GPIO%d pull up disabled\n", m); | ||
69 | scx200_gpio_configure(m, ~4, 0); | ||
70 | break; | ||
71 | } | ||
72 | } | ||
73 | |||
74 | return len; | ||
75 | } | ||
76 | |||
77 | static ssize_t scx200_gpio_read(struct file *file, char __user *buf, | ||
78 | size_t len, loff_t *ppos) | ||
79 | { | ||
80 | unsigned m = iminor(file->f_dentry->d_inode); | ||
81 | int value; | ||
82 | |||
83 | value = scx200_gpio_get(m); | ||
84 | if (put_user(value ? '1' : '0', buf)) | ||
85 | return -EFAULT; | ||
86 | |||
87 | return 1; | ||
88 | } | ||
89 | 49 | ||
90 | static int scx200_gpio_open(struct inode *inode, struct file *file) | 50 | static int scx200_gpio_open(struct inode *inode, struct file *file) |
91 | { | 51 | { |
92 | unsigned m = iminor(inode); | 52 | unsigned m = iminor(inode); |
53 | file->private_data = &scx200_access; | ||
54 | |||
93 | if (m > 63) | 55 | if (m > 63) |
94 | return -EINVAL; | 56 | return -EINVAL; |
95 | return nonseekable_open(inode, file); | 57 | return nonseekable_open(inode, file); |
@@ -103,47 +65,81 @@ static int scx200_gpio_release(struct inode *inode, struct file *file) | |||
103 | 65 | ||
104 | static struct file_operations scx200_gpio_fops = { | 66 | static struct file_operations scx200_gpio_fops = { |
105 | .owner = THIS_MODULE, | 67 | .owner = THIS_MODULE, |
106 | .write = scx200_gpio_write, | 68 | .write = nsc_gpio_write, |
107 | .read = scx200_gpio_read, | 69 | .read = nsc_gpio_read, |
108 | .open = scx200_gpio_open, | 70 | .open = scx200_gpio_open, |
109 | .release = scx200_gpio_release, | 71 | .release = scx200_gpio_release, |
110 | }; | 72 | }; |
111 | 73 | ||
74 | struct cdev *scx200_devices; | ||
75 | static int num_pins = 32; | ||
76 | |||
112 | static int __init scx200_gpio_init(void) | 77 | static int __init scx200_gpio_init(void) |
113 | { | 78 | { |
114 | int r; | 79 | int rc, i; |
115 | 80 | dev_t dev = MKDEV(major, 0); | |
116 | printk(KERN_DEBUG NAME ": NatSemi SCx200 GPIO Driver\n"); | ||
117 | 81 | ||
118 | if (!scx200_gpio_present()) { | 82 | if (!scx200_gpio_present()) { |
119 | printk(KERN_ERR NAME ": no SCx200 gpio pins available\n"); | 83 | printk(KERN_ERR NAME ": no SCx200 gpio present\n"); |
120 | return -ENODEV; | 84 | return -ENODEV; |
121 | } | 85 | } |
122 | 86 | ||
123 | r = register_chrdev(major, NAME, &scx200_gpio_fops); | 87 | /* support dev_dbg() with pdev->dev */ |
124 | if (r < 0) { | 88 | pdev = platform_device_alloc(DEVNAME, 0); |
125 | printk(KERN_ERR NAME ": unable to register character device\n"); | 89 | if (!pdev) |
126 | return r; | 90 | return -ENOMEM; |
91 | |||
92 | rc = platform_device_add(pdev); | ||
93 | if (rc) | ||
94 | goto undo_malloc; | ||
95 | |||
96 | /* nsc_gpio uses dev_dbg(), so needs this */ | ||
97 | scx200_access.dev = &pdev->dev; | ||
98 | |||
99 | if (major) | ||
100 | rc = register_chrdev_region(dev, num_pins, "scx200_gpio"); | ||
101 | else { | ||
102 | rc = alloc_chrdev_region(&dev, 0, num_pins, "scx200_gpio"); | ||
103 | major = MAJOR(dev); | ||
127 | } | 104 | } |
128 | if (!major) { | 105 | if (rc < 0) { |
129 | major = r; | 106 | dev_err(&pdev->dev, "SCx200 chrdev_region err: %d\n", rc); |
130 | printk(KERN_DEBUG NAME ": got dynamic major %d\n", major); | 107 | goto undo_platform_device_add; |
108 | } | ||
109 | scx200_devices = kzalloc(num_pins * sizeof(struct cdev), GFP_KERNEL); | ||
110 | if (!scx200_devices) { | ||
111 | rc = -ENOMEM; | ||
112 | goto undo_chrdev_region; | ||
113 | } | ||
114 | for (i = 0; i < num_pins; i++) { | ||
115 | struct cdev *cdev = &scx200_devices[i]; | ||
116 | cdev_init(cdev, &scx200_gpio_fops); | ||
117 | cdev->owner = THIS_MODULE; | ||
118 | rc = cdev_add(cdev, MKDEV(major, i), 1); | ||
119 | /* tolerate 'minor' errors */ | ||
120 | if (rc) | ||
121 | dev_err(&pdev->dev, "Error %d on minor %d", rc, i); | ||
131 | } | 122 | } |
132 | 123 | ||
133 | return 0; | 124 | return 0; /* succeed */ |
125 | |||
126 | undo_chrdev_region: | ||
127 | unregister_chrdev_region(dev, num_pins); | ||
128 | undo_platform_device_add: | ||
129 | platform_device_put(pdev); | ||
130 | undo_malloc: | ||
131 | kfree(pdev); | ||
132 | return rc; | ||
134 | } | 133 | } |
135 | 134 | ||
136 | static void __exit scx200_gpio_cleanup(void) | 135 | static void __exit scx200_gpio_cleanup(void) |
137 | { | 136 | { |
138 | unregister_chrdev(major, NAME); | 137 | kfree(scx200_devices); |
138 | unregister_chrdev_region(MKDEV(major, 0), num_pins); | ||
139 | platform_device_put(pdev); | ||
140 | platform_device_unregister(pdev); | ||
141 | /* kfree(pdev); */ | ||
139 | } | 142 | } |
140 | 143 | ||
141 | module_init(scx200_gpio_init); | 144 | module_init(scx200_gpio_init); |
142 | module_exit(scx200_gpio_cleanup); | 145 | module_exit(scx200_gpio_cleanup); |
143 | |||
144 | /* | ||
145 | Local variables: | ||
146 | compile-command: "make -k -C ../.. SUBDIRS=drivers/char modules" | ||
147 | c-basic-offset: 8 | ||
148 | End: | ||
149 | */ | ||
diff --git a/drivers/char/serial167.c b/drivers/char/serial167.c index 037c940ac71b..c851eeaa4069 100644 --- a/drivers/char/serial167.c +++ b/drivers/char/serial167.c | |||
@@ -2235,7 +2235,6 @@ scrn[1] = '\0'; | |||
2235 | /* Initialize the tty_driver structure */ | 2235 | /* Initialize the tty_driver structure */ |
2236 | 2236 | ||
2237 | cy_serial_driver->owner = THIS_MODULE; | 2237 | cy_serial_driver->owner = THIS_MODULE; |
2238 | cy_serial_driver->devfs_name = "tts/"; | ||
2239 | cy_serial_driver->name = "ttyS"; | 2238 | cy_serial_driver->name = "ttyS"; |
2240 | cy_serial_driver->major = TTY_MAJOR; | 2239 | cy_serial_driver->major = TTY_MAJOR; |
2241 | cy_serial_driver->minor_start = 64; | 2240 | cy_serial_driver->minor_start = 64; |
diff --git a/drivers/char/specialix.c b/drivers/char/specialix.c index 1b5330299e30..d2d6b01dcd05 100644 --- a/drivers/char/specialix.c +++ b/drivers/char/specialix.c | |||
@@ -2477,7 +2477,7 @@ static int __init specialix_init(void) | |||
2477 | #endif | 2477 | #endif |
2478 | 2478 | ||
2479 | for (i = 0; i < SX_NBOARD; i++) | 2479 | for (i = 0; i < SX_NBOARD; i++) |
2480 | sx_board[i].lock = SPIN_LOCK_UNLOCKED; | 2480 | spin_lock_init(&sx_board[i].lock); |
2481 | 2481 | ||
2482 | if (sx_init_drivers()) { | 2482 | if (sx_init_drivers()) { |
2483 | func_exit(); | 2483 | func_exit(); |
diff --git a/drivers/char/stallion.c b/drivers/char/stallion.c index a9c5a7230f89..0f7a542d9041 100644 --- a/drivers/char/stallion.c +++ b/drivers/char/stallion.c | |||
@@ -40,7 +40,6 @@ | |||
40 | #include <linux/ioport.h> | 40 | #include <linux/ioport.h> |
41 | #include <linux/init.h> | 41 | #include <linux/init.h> |
42 | #include <linux/smp_lock.h> | 42 | #include <linux/smp_lock.h> |
43 | #include <linux/devfs_fs_kernel.h> | ||
44 | #include <linux/device.h> | 43 | #include <linux/device.h> |
45 | #include <linux/delay.h> | 44 | #include <linux/delay.h> |
46 | 45 | ||
@@ -141,15 +140,6 @@ static char *stl_drvversion = "5.6.0"; | |||
141 | static struct tty_driver *stl_serial; | 140 | static struct tty_driver *stl_serial; |
142 | 141 | ||
143 | /* | 142 | /* |
144 | * We will need to allocate a temporary write buffer for chars that | ||
145 | * come direct from user space. The problem is that a copy from user | ||
146 | * space might cause a page fault (typically on a system that is | ||
147 | * swapping!). All ports will share one buffer - since if the system | ||
148 | * is already swapping a shared buffer won't make things any worse. | ||
149 | */ | ||
150 | static char *stl_tmpwritebuf; | ||
151 | |||
152 | /* | ||
153 | * Define a local default termios struct. All ports will be created | 143 | * Define a local default termios struct. All ports will be created |
154 | * with this termios initially. Basically all it defines is a raw port | 144 | * with this termios initially. Basically all it defines is a raw port |
155 | * at 9600, 8 data bits, 1 stop bit. | 145 | * at 9600, 8 data bits, 1 stop bit. |
@@ -363,6 +353,14 @@ static unsigned char stl_vecmap[] = { | |||
363 | }; | 353 | }; |
364 | 354 | ||
365 | /* | 355 | /* |
356 | * Lock ordering is that you may not take stallion_lock holding | ||
357 | * brd_lock. | ||
358 | */ | ||
359 | |||
360 | static spinlock_t brd_lock; /* Guard the board mapping */ | ||
361 | static spinlock_t stallion_lock; /* Guard the tty driver */ | ||
362 | |||
363 | /* | ||
366 | * Set up enable and disable macros for the ECH boards. They require | 364 | * Set up enable and disable macros for the ECH boards. They require |
367 | * the secondary io address space to be activated and deactivated. | 365 | * the secondary io address space to be activated and deactivated. |
368 | * This way all ECH boards can share their secondary io region. | 366 | * This way all ECH boards can share their secondary io region. |
@@ -725,17 +723,7 @@ static struct class *stallion_class; | |||
725 | 723 | ||
726 | static int __init stallion_module_init(void) | 724 | static int __init stallion_module_init(void) |
727 | { | 725 | { |
728 | unsigned long flags; | ||
729 | |||
730 | #ifdef DEBUG | ||
731 | printk("init_module()\n"); | ||
732 | #endif | ||
733 | |||
734 | save_flags(flags); | ||
735 | cli(); | ||
736 | stl_init(); | 726 | stl_init(); |
737 | restore_flags(flags); | ||
738 | |||
739 | return 0; | 727 | return 0; |
740 | } | 728 | } |
741 | 729 | ||
@@ -746,7 +734,6 @@ static void __exit stallion_module_exit(void) | |||
746 | stlbrd_t *brdp; | 734 | stlbrd_t *brdp; |
747 | stlpanel_t *panelp; | 735 | stlpanel_t *panelp; |
748 | stlport_t *portp; | 736 | stlport_t *portp; |
749 | unsigned long flags; | ||
750 | int i, j, k; | 737 | int i, j, k; |
751 | 738 | ||
752 | #ifdef DEBUG | 739 | #ifdef DEBUG |
@@ -756,9 +743,6 @@ static void __exit stallion_module_exit(void) | |||
756 | printk(KERN_INFO "Unloading %s: version %s\n", stl_drvtitle, | 743 | printk(KERN_INFO "Unloading %s: version %s\n", stl_drvtitle, |
757 | stl_drvversion); | 744 | stl_drvversion); |
758 | 745 | ||
759 | save_flags(flags); | ||
760 | cli(); | ||
761 | |||
762 | /* | 746 | /* |
763 | * Free up all allocated resources used by the ports. This includes | 747 | * Free up all allocated resources used by the ports. This includes |
764 | * memory and interrupts. As part of this process we will also do | 748 | * memory and interrupts. As part of this process we will also do |
@@ -770,21 +754,15 @@ static void __exit stallion_module_exit(void) | |||
770 | if (i) { | 754 | if (i) { |
771 | printk("STALLION: failed to un-register tty driver, " | 755 | printk("STALLION: failed to un-register tty driver, " |
772 | "errno=%d\n", -i); | 756 | "errno=%d\n", -i); |
773 | restore_flags(flags); | ||
774 | return; | 757 | return; |
775 | } | 758 | } |
776 | for (i = 0; i < 4; i++) { | 759 | for (i = 0; i < 4; i++) |
777 | devfs_remove("staliomem/%d", i); | ||
778 | class_device_destroy(stallion_class, MKDEV(STL_SIOMEMMAJOR, i)); | 760 | class_device_destroy(stallion_class, MKDEV(STL_SIOMEMMAJOR, i)); |
779 | } | ||
780 | devfs_remove("staliomem"); | ||
781 | if ((i = unregister_chrdev(STL_SIOMEMMAJOR, "staliomem"))) | 761 | if ((i = unregister_chrdev(STL_SIOMEMMAJOR, "staliomem"))) |
782 | printk("STALLION: failed to un-register serial memory device, " | 762 | printk("STALLION: failed to un-register serial memory device, " |
783 | "errno=%d\n", -i); | 763 | "errno=%d\n", -i); |
784 | class_destroy(stallion_class); | 764 | class_destroy(stallion_class); |
785 | 765 | ||
786 | kfree(stl_tmpwritebuf); | ||
787 | |||
788 | for (i = 0; (i < stl_nrbrds); i++) { | 766 | for (i = 0; (i < stl_nrbrds); i++) { |
789 | if ((brdp = stl_brds[i]) == (stlbrd_t *) NULL) | 767 | if ((brdp = stl_brds[i]) == (stlbrd_t *) NULL) |
790 | continue; | 768 | continue; |
@@ -814,8 +792,6 @@ static void __exit stallion_module_exit(void) | |||
814 | kfree(brdp); | 792 | kfree(brdp); |
815 | stl_brds[i] = (stlbrd_t *) NULL; | 793 | stl_brds[i] = (stlbrd_t *) NULL; |
816 | } | 794 | } |
817 | |||
818 | restore_flags(flags); | ||
819 | } | 795 | } |
820 | 796 | ||
821 | module_init(stallion_module_init); | 797 | module_init(stallion_module_init); |
@@ -948,7 +924,7 @@ static stlbrd_t *stl_allocbrd(void) | |||
948 | 924 | ||
949 | brdp = kzalloc(sizeof(stlbrd_t), GFP_KERNEL); | 925 | brdp = kzalloc(sizeof(stlbrd_t), GFP_KERNEL); |
950 | if (!brdp) { | 926 | if (!brdp) { |
951 | printk("STALLION: failed to allocate memory (size=%d)\n", | 927 | printk("STALLION: failed to allocate memory (size=%Zd)\n", |
952 | sizeof(stlbrd_t)); | 928 | sizeof(stlbrd_t)); |
953 | return NULL; | 929 | return NULL; |
954 | } | 930 | } |
@@ -1066,16 +1042,17 @@ static int stl_waitcarrier(stlport_t *portp, struct file *filp) | |||
1066 | rc = 0; | 1042 | rc = 0; |
1067 | doclocal = 0; | 1043 | doclocal = 0; |
1068 | 1044 | ||
1045 | spin_lock_irqsave(&stallion_lock, flags); | ||
1046 | |||
1069 | if (portp->tty->termios->c_cflag & CLOCAL) | 1047 | if (portp->tty->termios->c_cflag & CLOCAL) |
1070 | doclocal++; | 1048 | doclocal++; |
1071 | 1049 | ||
1072 | save_flags(flags); | ||
1073 | cli(); | ||
1074 | portp->openwaitcnt++; | 1050 | portp->openwaitcnt++; |
1075 | if (! tty_hung_up_p(filp)) | 1051 | if (! tty_hung_up_p(filp)) |
1076 | portp->refcount--; | 1052 | portp->refcount--; |
1077 | 1053 | ||
1078 | for (;;) { | 1054 | for (;;) { |
1055 | /* Takes brd_lock internally */ | ||
1079 | stl_setsignals(portp, 1, 1); | 1056 | stl_setsignals(portp, 1, 1); |
1080 | if (tty_hung_up_p(filp) || | 1057 | if (tty_hung_up_p(filp) || |
1081 | ((portp->flags & ASYNC_INITIALIZED) == 0)) { | 1058 | ((portp->flags & ASYNC_INITIALIZED) == 0)) { |
@@ -1093,13 +1070,14 @@ static int stl_waitcarrier(stlport_t *portp, struct file *filp) | |||
1093 | rc = -ERESTARTSYS; | 1070 | rc = -ERESTARTSYS; |
1094 | break; | 1071 | break; |
1095 | } | 1072 | } |
1073 | /* FIXME */ | ||
1096 | interruptible_sleep_on(&portp->open_wait); | 1074 | interruptible_sleep_on(&portp->open_wait); |
1097 | } | 1075 | } |
1098 | 1076 | ||
1099 | if (! tty_hung_up_p(filp)) | 1077 | if (! tty_hung_up_p(filp)) |
1100 | portp->refcount++; | 1078 | portp->refcount++; |
1101 | portp->openwaitcnt--; | 1079 | portp->openwaitcnt--; |
1102 | restore_flags(flags); | 1080 | spin_unlock_irqrestore(&stallion_lock, flags); |
1103 | 1081 | ||
1104 | return rc; | 1082 | return rc; |
1105 | } | 1083 | } |
@@ -1119,16 +1097,15 @@ static void stl_close(struct tty_struct *tty, struct file *filp) | |||
1119 | if (portp == (stlport_t *) NULL) | 1097 | if (portp == (stlport_t *) NULL) |
1120 | return; | 1098 | return; |
1121 | 1099 | ||
1122 | save_flags(flags); | 1100 | spin_lock_irqsave(&stallion_lock, flags); |
1123 | cli(); | ||
1124 | if (tty_hung_up_p(filp)) { | 1101 | if (tty_hung_up_p(filp)) { |
1125 | restore_flags(flags); | 1102 | spin_unlock_irqrestore(&stallion_lock, flags); |
1126 | return; | 1103 | return; |
1127 | } | 1104 | } |
1128 | if ((tty->count == 1) && (portp->refcount != 1)) | 1105 | if ((tty->count == 1) && (portp->refcount != 1)) |
1129 | portp->refcount = 1; | 1106 | portp->refcount = 1; |
1130 | if (portp->refcount-- > 1) { | 1107 | if (portp->refcount-- > 1) { |
1131 | restore_flags(flags); | 1108 | spin_unlock_irqrestore(&stallion_lock, flags); |
1132 | return; | 1109 | return; |
1133 | } | 1110 | } |
1134 | 1111 | ||
@@ -1142,11 +1119,18 @@ static void stl_close(struct tty_struct *tty, struct file *filp) | |||
1142 | * (The sc26198 has no "end-of-data" interrupt only empty FIFO) | 1119 | * (The sc26198 has no "end-of-data" interrupt only empty FIFO) |
1143 | */ | 1120 | */ |
1144 | tty->closing = 1; | 1121 | tty->closing = 1; |
1122 | |||
1123 | spin_unlock_irqrestore(&stallion_lock, flags); | ||
1124 | |||
1145 | if (portp->closing_wait != ASYNC_CLOSING_WAIT_NONE) | 1125 | if (portp->closing_wait != ASYNC_CLOSING_WAIT_NONE) |
1146 | tty_wait_until_sent(tty, portp->closing_wait); | 1126 | tty_wait_until_sent(tty, portp->closing_wait); |
1147 | stl_waituntilsent(tty, (HZ / 2)); | 1127 | stl_waituntilsent(tty, (HZ / 2)); |
1148 | 1128 | ||
1129 | |||
1130 | spin_lock_irqsave(&stallion_lock, flags); | ||
1149 | portp->flags &= ~ASYNC_INITIALIZED; | 1131 | portp->flags &= ~ASYNC_INITIALIZED; |
1132 | spin_unlock_irqrestore(&stallion_lock, flags); | ||
1133 | |||
1150 | stl_disableintrs(portp); | 1134 | stl_disableintrs(portp); |
1151 | if (tty->termios->c_cflag & HUPCL) | 1135 | if (tty->termios->c_cflag & HUPCL) |
1152 | stl_setsignals(portp, 0, 0); | 1136 | stl_setsignals(portp, 0, 0); |
@@ -1173,7 +1157,6 @@ static void stl_close(struct tty_struct *tty, struct file *filp) | |||
1173 | 1157 | ||
1174 | portp->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING); | 1158 | portp->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING); |
1175 | wake_up_interruptible(&portp->close_wait); | 1159 | wake_up_interruptible(&portp->close_wait); |
1176 | restore_flags(flags); | ||
1177 | } | 1160 | } |
1178 | 1161 | ||
1179 | /*****************************************************************************/ | 1162 | /*****************************************************************************/ |
@@ -1195,9 +1178,6 @@ static int stl_write(struct tty_struct *tty, const unsigned char *buf, int count | |||
1195 | (int) tty, (int) buf, count); | 1178 | (int) tty, (int) buf, count); |
1196 | #endif | 1179 | #endif |
1197 | 1180 | ||
1198 | if ((tty == (struct tty_struct *) NULL) || | ||
1199 | (stl_tmpwritebuf == (char *) NULL)) | ||
1200 | return 0; | ||
1201 | portp = tty->driver_data; | 1181 | portp = tty->driver_data; |
1202 | if (portp == (stlport_t *) NULL) | 1182 | if (portp == (stlport_t *) NULL) |
1203 | return 0; | 1183 | return 0; |
@@ -1302,11 +1282,6 @@ static void stl_flushchars(struct tty_struct *tty) | |||
1302 | if (portp->tx.buf == (char *) NULL) | 1282 | if (portp->tx.buf == (char *) NULL) |
1303 | return; | 1283 | return; |
1304 | 1284 | ||
1305 | #if 0 | ||
1306 | if (tty->stopped || tty->hw_stopped || | ||
1307 | (portp->tx.head == portp->tx.tail)) | ||
1308 | return; | ||
1309 | #endif | ||
1310 | stl_startrxtx(portp, -1, 1); | 1285 | stl_startrxtx(portp, -1, 1); |
1311 | } | 1286 | } |
1312 | 1287 | ||
@@ -1977,12 +1952,14 @@ static int stl_eiointr(stlbrd_t *brdp) | |||
1977 | unsigned int iobase; | 1952 | unsigned int iobase; |
1978 | int handled = 0; | 1953 | int handled = 0; |
1979 | 1954 | ||
1955 | spin_lock(&brd_lock); | ||
1980 | panelp = brdp->panels[0]; | 1956 | panelp = brdp->panels[0]; |
1981 | iobase = panelp->iobase; | 1957 | iobase = panelp->iobase; |
1982 | while (inb(brdp->iostatus) & EIO_INTRPEND) { | 1958 | while (inb(brdp->iostatus) & EIO_INTRPEND) { |
1983 | handled = 1; | 1959 | handled = 1; |
1984 | (* panelp->isr)(panelp, iobase); | 1960 | (* panelp->isr)(panelp, iobase); |
1985 | } | 1961 | } |
1962 | spin_unlock(&brd_lock); | ||
1986 | return handled; | 1963 | return handled; |
1987 | } | 1964 | } |
1988 | 1965 | ||
@@ -2168,7 +2145,7 @@ static int __init stl_initports(stlbrd_t *brdp, stlpanel_t *panelp) | |||
2168 | portp = kzalloc(sizeof(stlport_t), GFP_KERNEL); | 2145 | portp = kzalloc(sizeof(stlport_t), GFP_KERNEL); |
2169 | if (!portp) { | 2146 | if (!portp) { |
2170 | printk("STALLION: failed to allocate memory " | 2147 | printk("STALLION: failed to allocate memory " |
2171 | "(size=%d)\n", sizeof(stlport_t)); | 2148 | "(size=%Zd)\n", sizeof(stlport_t)); |
2172 | break; | 2149 | break; |
2173 | } | 2150 | } |
2174 | 2151 | ||
@@ -2304,7 +2281,7 @@ static inline int stl_initeio(stlbrd_t *brdp) | |||
2304 | panelp = kzalloc(sizeof(stlpanel_t), GFP_KERNEL); | 2281 | panelp = kzalloc(sizeof(stlpanel_t), GFP_KERNEL); |
2305 | if (!panelp) { | 2282 | if (!panelp) { |
2306 | printk(KERN_WARNING "STALLION: failed to allocate memory " | 2283 | printk(KERN_WARNING "STALLION: failed to allocate memory " |
2307 | "(size=%d)\n", sizeof(stlpanel_t)); | 2284 | "(size=%Zd)\n", sizeof(stlpanel_t)); |
2308 | return -ENOMEM; | 2285 | return -ENOMEM; |
2309 | } | 2286 | } |
2310 | 2287 | ||
@@ -2478,7 +2455,7 @@ static inline int stl_initech(stlbrd_t *brdp) | |||
2478 | panelp = kzalloc(sizeof(stlpanel_t), GFP_KERNEL); | 2455 | panelp = kzalloc(sizeof(stlpanel_t), GFP_KERNEL); |
2479 | if (!panelp) { | 2456 | if (!panelp) { |
2480 | printk("STALLION: failed to allocate memory " | 2457 | printk("STALLION: failed to allocate memory " |
2481 | "(size=%d)\n", sizeof(stlpanel_t)); | 2458 | "(size=%Zd)\n", sizeof(stlpanel_t)); |
2482 | break; | 2459 | break; |
2483 | } | 2460 | } |
2484 | panelp->magic = STL_PANELMAGIC; | 2461 | panelp->magic = STL_PANELMAGIC; |
@@ -2879,8 +2856,7 @@ static int stl_getportstats(stlport_t *portp, comstats_t __user *cp) | |||
2879 | portp->stats.lflags = 0; | 2856 | portp->stats.lflags = 0; |
2880 | portp->stats.rxbuffered = 0; | 2857 | portp->stats.rxbuffered = 0; |
2881 | 2858 | ||
2882 | save_flags(flags); | 2859 | spin_lock_irqsave(&stallion_lock, flags); |
2883 | cli(); | ||
2884 | if (portp->tty != (struct tty_struct *) NULL) { | 2860 | if (portp->tty != (struct tty_struct *) NULL) { |
2885 | if (portp->tty->driver_data == portp) { | 2861 | if (portp->tty->driver_data == portp) { |
2886 | portp->stats.ttystate = portp->tty->flags; | 2862 | portp->stats.ttystate = portp->tty->flags; |
@@ -2894,7 +2870,7 @@ static int stl_getportstats(stlport_t *portp, comstats_t __user *cp) | |||
2894 | } | 2870 | } |
2895 | } | 2871 | } |
2896 | } | 2872 | } |
2897 | restore_flags(flags); | 2873 | spin_unlock_irqrestore(&stallion_lock, flags); |
2898 | 2874 | ||
2899 | head = portp->tx.head; | 2875 | head = portp->tx.head; |
2900 | tail = portp->tx.tail; | 2876 | tail = portp->tx.tail; |
@@ -3049,6 +3025,9 @@ static int __init stl_init(void) | |||
3049 | int i; | 3025 | int i; |
3050 | printk(KERN_INFO "%s: version %s\n", stl_drvtitle, stl_drvversion); | 3026 | printk(KERN_INFO "%s: version %s\n", stl_drvtitle, stl_drvversion); |
3051 | 3027 | ||
3028 | spin_lock_init(&stallion_lock); | ||
3029 | spin_lock_init(&brd_lock); | ||
3030 | |||
3052 | stl_initbrds(); | 3031 | stl_initbrds(); |
3053 | 3032 | ||
3054 | stl_serial = alloc_tty_driver(STL_MAXBRDS * STL_MAXPORTS); | 3033 | stl_serial = alloc_tty_driver(STL_MAXBRDS * STL_MAXPORTS); |
@@ -3056,35 +3035,21 @@ static int __init stl_init(void) | |||
3056 | return -1; | 3035 | return -1; |
3057 | 3036 | ||
3058 | /* | 3037 | /* |
3059 | * Allocate a temporary write buffer. | ||
3060 | */ | ||
3061 | stl_tmpwritebuf = kmalloc(STL_TXBUFSIZE, GFP_KERNEL); | ||
3062 | if (!stl_tmpwritebuf) | ||
3063 | printk("STALLION: failed to allocate memory (size=%d)\n", | ||
3064 | STL_TXBUFSIZE); | ||
3065 | |||
3066 | /* | ||
3067 | * Set up a character driver for per board stuff. This is mainly used | 3038 | * Set up a character driver for per board stuff. This is mainly used |
3068 | * to do stats ioctls on the ports. | 3039 | * to do stats ioctls on the ports. |
3069 | */ | 3040 | */ |
3070 | if (register_chrdev(STL_SIOMEMMAJOR, "staliomem", &stl_fsiomem)) | 3041 | if (register_chrdev(STL_SIOMEMMAJOR, "staliomem", &stl_fsiomem)) |
3071 | printk("STALLION: failed to register serial board device\n"); | 3042 | printk("STALLION: failed to register serial board device\n"); |
3072 | devfs_mk_dir("staliomem"); | ||
3073 | 3043 | ||
3074 | stallion_class = class_create(THIS_MODULE, "staliomem"); | 3044 | stallion_class = class_create(THIS_MODULE, "staliomem"); |
3075 | for (i = 0; i < 4; i++) { | 3045 | for (i = 0; i < 4; i++) |
3076 | devfs_mk_cdev(MKDEV(STL_SIOMEMMAJOR, i), | ||
3077 | S_IFCHR|S_IRUSR|S_IWUSR, | ||
3078 | "staliomem/%d", i); | ||
3079 | class_device_create(stallion_class, NULL, | 3046 | class_device_create(stallion_class, NULL, |
3080 | MKDEV(STL_SIOMEMMAJOR, i), NULL, | 3047 | MKDEV(STL_SIOMEMMAJOR, i), NULL, |
3081 | "staliomem%d", i); | 3048 | "staliomem%d", i); |
3082 | } | ||
3083 | 3049 | ||
3084 | stl_serial->owner = THIS_MODULE; | 3050 | stl_serial->owner = THIS_MODULE; |
3085 | stl_serial->driver_name = stl_drvname; | 3051 | stl_serial->driver_name = stl_drvname; |
3086 | stl_serial->name = "ttyE"; | 3052 | stl_serial->name = "ttyE"; |
3087 | stl_serial->devfs_name = "tts/E"; | ||
3088 | stl_serial->major = STL_SERIALMAJOR; | 3053 | stl_serial->major = STL_SERIALMAJOR; |
3089 | stl_serial->minor_start = 0; | 3054 | stl_serial->minor_start = 0; |
3090 | stl_serial->type = TTY_DRIVER_TYPE_SERIAL; | 3055 | stl_serial->type = TTY_DRIVER_TYPE_SERIAL; |
@@ -3147,11 +3112,13 @@ static int stl_cd1400panelinit(stlbrd_t *brdp, stlpanel_t *panelp) | |||
3147 | unsigned int gfrcr; | 3112 | unsigned int gfrcr; |
3148 | int chipmask, i, j; | 3113 | int chipmask, i, j; |
3149 | int nrchips, uartaddr, ioaddr; | 3114 | int nrchips, uartaddr, ioaddr; |
3115 | unsigned long flags; | ||
3150 | 3116 | ||
3151 | #ifdef DEBUG | 3117 | #ifdef DEBUG |
3152 | printk("stl_panelinit(brdp=%x,panelp=%x)\n", (int) brdp, (int) panelp); | 3118 | printk("stl_panelinit(brdp=%x,panelp=%x)\n", (int) brdp, (int) panelp); |
3153 | #endif | 3119 | #endif |
3154 | 3120 | ||
3121 | spin_lock_irqsave(&brd_lock, flags); | ||
3155 | BRDENABLE(panelp->brdnr, panelp->pagenr); | 3122 | BRDENABLE(panelp->brdnr, panelp->pagenr); |
3156 | 3123 | ||
3157 | /* | 3124 | /* |
@@ -3189,6 +3156,7 @@ static int stl_cd1400panelinit(stlbrd_t *brdp, stlpanel_t *panelp) | |||
3189 | } | 3156 | } |
3190 | 3157 | ||
3191 | BRDDISABLE(panelp->brdnr); | 3158 | BRDDISABLE(panelp->brdnr); |
3159 | spin_unlock_irqrestore(&brd_lock, flags); | ||
3192 | return chipmask; | 3160 | return chipmask; |
3193 | } | 3161 | } |
3194 | 3162 | ||
@@ -3200,6 +3168,7 @@ static int stl_cd1400panelinit(stlbrd_t *brdp, stlpanel_t *panelp) | |||
3200 | 3168 | ||
3201 | static void stl_cd1400portinit(stlbrd_t *brdp, stlpanel_t *panelp, stlport_t *portp) | 3169 | static void stl_cd1400portinit(stlbrd_t *brdp, stlpanel_t *panelp, stlport_t *portp) |
3202 | { | 3170 | { |
3171 | unsigned long flags; | ||
3203 | #ifdef DEBUG | 3172 | #ifdef DEBUG |
3204 | printk("stl_cd1400portinit(brdp=%x,panelp=%x,portp=%x)\n", | 3173 | printk("stl_cd1400portinit(brdp=%x,panelp=%x,portp=%x)\n", |
3205 | (int) brdp, (int) panelp, (int) portp); | 3174 | (int) brdp, (int) panelp, (int) portp); |
@@ -3209,6 +3178,7 @@ static void stl_cd1400portinit(stlbrd_t *brdp, stlpanel_t *panelp, stlport_t *po | |||
3209 | (portp == (stlport_t *) NULL)) | 3178 | (portp == (stlport_t *) NULL)) |
3210 | return; | 3179 | return; |
3211 | 3180 | ||
3181 | spin_lock_irqsave(&brd_lock, flags); | ||
3212 | portp->ioaddr = panelp->iobase + (((brdp->brdtype == BRD_ECHPCI) || | 3182 | portp->ioaddr = panelp->iobase + (((brdp->brdtype == BRD_ECHPCI) || |
3213 | (portp->portnr < 8)) ? 0 : EREG_BANKSIZE); | 3183 | (portp->portnr < 8)) ? 0 : EREG_BANKSIZE); |
3214 | portp->uartaddr = (portp->portnr & 0x04) << 5; | 3184 | portp->uartaddr = (portp->portnr & 0x04) << 5; |
@@ -3219,6 +3189,7 @@ static void stl_cd1400portinit(stlbrd_t *brdp, stlpanel_t *panelp, stlport_t *po | |||
3219 | stl_cd1400setreg(portp, LIVR, (portp->portnr << 3)); | 3189 | stl_cd1400setreg(portp, LIVR, (portp->portnr << 3)); |
3220 | portp->hwid = stl_cd1400getreg(portp, GFRCR); | 3190 | portp->hwid = stl_cd1400getreg(portp, GFRCR); |
3221 | BRDDISABLE(portp->brdnr); | 3191 | BRDDISABLE(portp->brdnr); |
3192 | spin_unlock_irqrestore(&brd_lock, flags); | ||
3222 | } | 3193 | } |
3223 | 3194 | ||
3224 | /*****************************************************************************/ | 3195 | /*****************************************************************************/ |
@@ -3428,8 +3399,7 @@ static void stl_cd1400setport(stlport_t *portp, struct termios *tiosp) | |||
3428 | tiosp->c_cc[VSTART], tiosp->c_cc[VSTOP]); | 3399 | tiosp->c_cc[VSTART], tiosp->c_cc[VSTOP]); |
3429 | #endif | 3400 | #endif |
3430 | 3401 | ||
3431 | save_flags(flags); | 3402 | spin_lock_irqsave(&brd_lock, flags); |
3432 | cli(); | ||
3433 | BRDENABLE(portp->brdnr, portp->pagenr); | 3403 | BRDENABLE(portp->brdnr, portp->pagenr); |
3434 | stl_cd1400setreg(portp, CAR, (portp->portnr & 0x3)); | 3404 | stl_cd1400setreg(portp, CAR, (portp->portnr & 0x3)); |
3435 | srer = stl_cd1400getreg(portp, SRER); | 3405 | srer = stl_cd1400getreg(portp, SRER); |
@@ -3466,7 +3436,7 @@ static void stl_cd1400setport(stlport_t *portp, struct termios *tiosp) | |||
3466 | portp->sigs &= ~TIOCM_CD; | 3436 | portp->sigs &= ~TIOCM_CD; |
3467 | stl_cd1400setreg(portp, SRER, ((srer & ~sreroff) | sreron)); | 3437 | stl_cd1400setreg(portp, SRER, ((srer & ~sreroff) | sreron)); |
3468 | BRDDISABLE(portp->brdnr); | 3438 | BRDDISABLE(portp->brdnr); |
3469 | restore_flags(flags); | 3439 | spin_unlock_irqrestore(&brd_lock, flags); |
3470 | } | 3440 | } |
3471 | 3441 | ||
3472 | /*****************************************************************************/ | 3442 | /*****************************************************************************/ |
@@ -3492,8 +3462,7 @@ static void stl_cd1400setsignals(stlport_t *portp, int dtr, int rts) | |||
3492 | if (rts > 0) | 3462 | if (rts > 0) |
3493 | msvr2 = MSVR2_RTS; | 3463 | msvr2 = MSVR2_RTS; |
3494 | 3464 | ||
3495 | save_flags(flags); | 3465 | spin_lock_irqsave(&brd_lock, flags); |
3496 | cli(); | ||
3497 | BRDENABLE(portp->brdnr, portp->pagenr); | 3466 | BRDENABLE(portp->brdnr, portp->pagenr); |
3498 | stl_cd1400setreg(portp, CAR, (portp->portnr & 0x03)); | 3467 | stl_cd1400setreg(portp, CAR, (portp->portnr & 0x03)); |
3499 | if (rts >= 0) | 3468 | if (rts >= 0) |
@@ -3501,7 +3470,7 @@ static void stl_cd1400setsignals(stlport_t *portp, int dtr, int rts) | |||
3501 | if (dtr >= 0) | 3470 | if (dtr >= 0) |
3502 | stl_cd1400setreg(portp, MSVR1, msvr1); | 3471 | stl_cd1400setreg(portp, MSVR1, msvr1); |
3503 | BRDDISABLE(portp->brdnr); | 3472 | BRDDISABLE(portp->brdnr); |
3504 | restore_flags(flags); | 3473 | spin_unlock_irqrestore(&brd_lock, flags); |
3505 | } | 3474 | } |
3506 | 3475 | ||
3507 | /*****************************************************************************/ | 3476 | /*****************************************************************************/ |
@@ -3520,14 +3489,13 @@ static int stl_cd1400getsignals(stlport_t *portp) | |||
3520 | printk("stl_cd1400getsignals(portp=%x)\n", (int) portp); | 3489 | printk("stl_cd1400getsignals(portp=%x)\n", (int) portp); |
3521 | #endif | 3490 | #endif |
3522 | 3491 | ||
3523 | save_flags(flags); | 3492 | spin_lock_irqsave(&brd_lock, flags); |
3524 | cli(); | ||
3525 | BRDENABLE(portp->brdnr, portp->pagenr); | 3493 | BRDENABLE(portp->brdnr, portp->pagenr); |
3526 | stl_cd1400setreg(portp, CAR, (portp->portnr & 0x03)); | 3494 | stl_cd1400setreg(portp, CAR, (portp->portnr & 0x03)); |
3527 | msvr1 = stl_cd1400getreg(portp, MSVR1); | 3495 | msvr1 = stl_cd1400getreg(portp, MSVR1); |
3528 | msvr2 = stl_cd1400getreg(portp, MSVR2); | 3496 | msvr2 = stl_cd1400getreg(portp, MSVR2); |
3529 | BRDDISABLE(portp->brdnr); | 3497 | BRDDISABLE(portp->brdnr); |
3530 | restore_flags(flags); | 3498 | spin_unlock_irqrestore(&brd_lock, flags); |
3531 | 3499 | ||
3532 | sigs = 0; | 3500 | sigs = 0; |
3533 | sigs |= (msvr1 & MSVR1_DCD) ? TIOCM_CD : 0; | 3501 | sigs |= (msvr1 & MSVR1_DCD) ? TIOCM_CD : 0; |
@@ -3569,15 +3537,14 @@ static void stl_cd1400enablerxtx(stlport_t *portp, int rx, int tx) | |||
3569 | else if (rx > 0) | 3537 | else if (rx > 0) |
3570 | ccr |= CCR_RXENABLE; | 3538 | ccr |= CCR_RXENABLE; |
3571 | 3539 | ||
3572 | save_flags(flags); | 3540 | spin_lock_irqsave(&brd_lock, flags); |
3573 | cli(); | ||
3574 | BRDENABLE(portp->brdnr, portp->pagenr); | 3541 | BRDENABLE(portp->brdnr, portp->pagenr); |
3575 | stl_cd1400setreg(portp, CAR, (portp->portnr & 0x03)); | 3542 | stl_cd1400setreg(portp, CAR, (portp->portnr & 0x03)); |
3576 | stl_cd1400ccrwait(portp); | 3543 | stl_cd1400ccrwait(portp); |
3577 | stl_cd1400setreg(portp, CCR, ccr); | 3544 | stl_cd1400setreg(portp, CCR, ccr); |
3578 | stl_cd1400ccrwait(portp); | 3545 | stl_cd1400ccrwait(portp); |
3579 | BRDDISABLE(portp->brdnr); | 3546 | BRDDISABLE(portp->brdnr); |
3580 | restore_flags(flags); | 3547 | spin_unlock_irqrestore(&brd_lock, flags); |
3581 | } | 3548 | } |
3582 | 3549 | ||
3583 | /*****************************************************************************/ | 3550 | /*****************************************************************************/ |
@@ -3609,8 +3576,7 @@ static void stl_cd1400startrxtx(stlport_t *portp, int rx, int tx) | |||
3609 | else if (rx > 0) | 3576 | else if (rx > 0) |
3610 | sreron |= SRER_RXDATA; | 3577 | sreron |= SRER_RXDATA; |
3611 | 3578 | ||
3612 | save_flags(flags); | 3579 | spin_lock_irqsave(&brd_lock, flags); |
3613 | cli(); | ||
3614 | BRDENABLE(portp->brdnr, portp->pagenr); | 3580 | BRDENABLE(portp->brdnr, portp->pagenr); |
3615 | stl_cd1400setreg(portp, CAR, (portp->portnr & 0x03)); | 3581 | stl_cd1400setreg(portp, CAR, (portp->portnr & 0x03)); |
3616 | stl_cd1400setreg(portp, SRER, | 3582 | stl_cd1400setreg(portp, SRER, |
@@ -3618,7 +3584,7 @@ static void stl_cd1400startrxtx(stlport_t *portp, int rx, int tx) | |||
3618 | BRDDISABLE(portp->brdnr); | 3584 | BRDDISABLE(portp->brdnr); |
3619 | if (tx > 0) | 3585 | if (tx > 0) |
3620 | set_bit(ASYI_TXBUSY, &portp->istate); | 3586 | set_bit(ASYI_TXBUSY, &portp->istate); |
3621 | restore_flags(flags); | 3587 | spin_unlock_irqrestore(&brd_lock, flags); |
3622 | } | 3588 | } |
3623 | 3589 | ||
3624 | /*****************************************************************************/ | 3590 | /*****************************************************************************/ |
@@ -3634,13 +3600,12 @@ static void stl_cd1400disableintrs(stlport_t *portp) | |||
3634 | #ifdef DEBUG | 3600 | #ifdef DEBUG |
3635 | printk("stl_cd1400disableintrs(portp=%x)\n", (int) portp); | 3601 | printk("stl_cd1400disableintrs(portp=%x)\n", (int) portp); |
3636 | #endif | 3602 | #endif |
3637 | save_flags(flags); | 3603 | spin_lock_irqsave(&brd_lock, flags); |
3638 | cli(); | ||
3639 | BRDENABLE(portp->brdnr, portp->pagenr); | 3604 | BRDENABLE(portp->brdnr, portp->pagenr); |
3640 | stl_cd1400setreg(portp, CAR, (portp->portnr & 0x03)); | 3605 | stl_cd1400setreg(portp, CAR, (portp->portnr & 0x03)); |
3641 | stl_cd1400setreg(portp, SRER, 0); | 3606 | stl_cd1400setreg(portp, SRER, 0); |
3642 | BRDDISABLE(portp->brdnr); | 3607 | BRDDISABLE(portp->brdnr); |
3643 | restore_flags(flags); | 3608 | spin_unlock_irqrestore(&brd_lock, flags); |
3644 | } | 3609 | } |
3645 | 3610 | ||
3646 | /*****************************************************************************/ | 3611 | /*****************************************************************************/ |
@@ -3653,8 +3618,7 @@ static void stl_cd1400sendbreak(stlport_t *portp, int len) | |||
3653 | printk("stl_cd1400sendbreak(portp=%x,len=%d)\n", (int) portp, len); | 3618 | printk("stl_cd1400sendbreak(portp=%x,len=%d)\n", (int) portp, len); |
3654 | #endif | 3619 | #endif |
3655 | 3620 | ||
3656 | save_flags(flags); | 3621 | spin_lock_irqsave(&brd_lock, flags); |
3657 | cli(); | ||
3658 | BRDENABLE(portp->brdnr, portp->pagenr); | 3622 | BRDENABLE(portp->brdnr, portp->pagenr); |
3659 | stl_cd1400setreg(portp, CAR, (portp->portnr & 0x03)); | 3623 | stl_cd1400setreg(portp, CAR, (portp->portnr & 0x03)); |
3660 | stl_cd1400setreg(portp, SRER, | 3624 | stl_cd1400setreg(portp, SRER, |
@@ -3664,7 +3628,7 @@ static void stl_cd1400sendbreak(stlport_t *portp, int len) | |||
3664 | portp->brklen = len; | 3628 | portp->brklen = len; |
3665 | if (len == 1) | 3629 | if (len == 1) |
3666 | portp->stats.txbreaks++; | 3630 | portp->stats.txbreaks++; |
3667 | restore_flags(flags); | 3631 | spin_unlock_irqrestore(&brd_lock, flags); |
3668 | } | 3632 | } |
3669 | 3633 | ||
3670 | /*****************************************************************************/ | 3634 | /*****************************************************************************/ |
@@ -3688,8 +3652,7 @@ static void stl_cd1400flowctrl(stlport_t *portp, int state) | |||
3688 | if (tty == (struct tty_struct *) NULL) | 3652 | if (tty == (struct tty_struct *) NULL) |
3689 | return; | 3653 | return; |
3690 | 3654 | ||
3691 | save_flags(flags); | 3655 | spin_lock_irqsave(&brd_lock, flags); |
3692 | cli(); | ||
3693 | BRDENABLE(portp->brdnr, portp->pagenr); | 3656 | BRDENABLE(portp->brdnr, portp->pagenr); |
3694 | stl_cd1400setreg(portp, CAR, (portp->portnr & 0x03)); | 3657 | stl_cd1400setreg(portp, CAR, (portp->portnr & 0x03)); |
3695 | 3658 | ||
@@ -3729,7 +3692,7 @@ static void stl_cd1400flowctrl(stlport_t *portp, int state) | |||
3729 | } | 3692 | } |
3730 | 3693 | ||
3731 | BRDDISABLE(portp->brdnr); | 3694 | BRDDISABLE(portp->brdnr); |
3732 | restore_flags(flags); | 3695 | spin_unlock_irqrestore(&brd_lock, flags); |
3733 | } | 3696 | } |
3734 | 3697 | ||
3735 | /*****************************************************************************/ | 3698 | /*****************************************************************************/ |
@@ -3753,8 +3716,7 @@ static void stl_cd1400sendflow(stlport_t *portp, int state) | |||
3753 | if (tty == (struct tty_struct *) NULL) | 3716 | if (tty == (struct tty_struct *) NULL) |
3754 | return; | 3717 | return; |
3755 | 3718 | ||
3756 | save_flags(flags); | 3719 | spin_lock_irqsave(&brd_lock, flags); |
3757 | cli(); | ||
3758 | BRDENABLE(portp->brdnr, portp->pagenr); | 3720 | BRDENABLE(portp->brdnr, portp->pagenr); |
3759 | stl_cd1400setreg(portp, CAR, (portp->portnr & 0x03)); | 3721 | stl_cd1400setreg(portp, CAR, (portp->portnr & 0x03)); |
3760 | if (state) { | 3722 | if (state) { |
@@ -3769,7 +3731,7 @@ static void stl_cd1400sendflow(stlport_t *portp, int state) | |||
3769 | stl_cd1400ccrwait(portp); | 3731 | stl_cd1400ccrwait(portp); |
3770 | } | 3732 | } |
3771 | BRDDISABLE(portp->brdnr); | 3733 | BRDDISABLE(portp->brdnr); |
3772 | restore_flags(flags); | 3734 | spin_unlock_irqrestore(&brd_lock, flags); |
3773 | } | 3735 | } |
3774 | 3736 | ||
3775 | /*****************************************************************************/ | 3737 | /*****************************************************************************/ |
@@ -3785,8 +3747,7 @@ static void stl_cd1400flush(stlport_t *portp) | |||
3785 | if (portp == (stlport_t *) NULL) | 3747 | if (portp == (stlport_t *) NULL) |
3786 | return; | 3748 | return; |
3787 | 3749 | ||
3788 | save_flags(flags); | 3750 | spin_lock_irqsave(&brd_lock, flags); |
3789 | cli(); | ||
3790 | BRDENABLE(portp->brdnr, portp->pagenr); | 3751 | BRDENABLE(portp->brdnr, portp->pagenr); |
3791 | stl_cd1400setreg(portp, CAR, (portp->portnr & 0x03)); | 3752 | stl_cd1400setreg(portp, CAR, (portp->portnr & 0x03)); |
3792 | stl_cd1400ccrwait(portp); | 3753 | stl_cd1400ccrwait(portp); |
@@ -3794,7 +3755,7 @@ static void stl_cd1400flush(stlport_t *portp) | |||
3794 | stl_cd1400ccrwait(portp); | 3755 | stl_cd1400ccrwait(portp); |
3795 | portp->tx.tail = portp->tx.head; | 3756 | portp->tx.tail = portp->tx.head; |
3796 | BRDDISABLE(portp->brdnr); | 3757 | BRDDISABLE(portp->brdnr); |
3797 | restore_flags(flags); | 3758 | spin_unlock_irqrestore(&brd_lock, flags); |
3798 | } | 3759 | } |
3799 | 3760 | ||
3800 | /*****************************************************************************/ | 3761 | /*****************************************************************************/ |
@@ -3833,6 +3794,7 @@ static void stl_cd1400eiointr(stlpanel_t *panelp, unsigned int iobase) | |||
3833 | (int) panelp, iobase); | 3794 | (int) panelp, iobase); |
3834 | #endif | 3795 | #endif |
3835 | 3796 | ||
3797 | spin_lock(&brd_lock); | ||
3836 | outb(SVRR, iobase); | 3798 | outb(SVRR, iobase); |
3837 | svrtype = inb(iobase + EREG_DATA); | 3799 | svrtype = inb(iobase + EREG_DATA); |
3838 | if (panelp->nrports > 4) { | 3800 | if (panelp->nrports > 4) { |
@@ -3846,6 +3808,8 @@ static void stl_cd1400eiointr(stlpanel_t *panelp, unsigned int iobase) | |||
3846 | stl_cd1400txisr(panelp, iobase); | 3808 | stl_cd1400txisr(panelp, iobase); |
3847 | else if (svrtype & SVRR_MDM) | 3809 | else if (svrtype & SVRR_MDM) |
3848 | stl_cd1400mdmisr(panelp, iobase); | 3810 | stl_cd1400mdmisr(panelp, iobase); |
3811 | |||
3812 | spin_unlock(&brd_lock); | ||
3849 | } | 3813 | } |
3850 | 3814 | ||
3851 | /*****************************************************************************/ | 3815 | /*****************************************************************************/ |
@@ -4433,8 +4397,7 @@ static void stl_sc26198setport(stlport_t *portp, struct termios *tiosp) | |||
4433 | tiosp->c_cc[VSTART], tiosp->c_cc[VSTOP]); | 4397 | tiosp->c_cc[VSTART], tiosp->c_cc[VSTOP]); |
4434 | #endif | 4398 | #endif |
4435 | 4399 | ||
4436 | save_flags(flags); | 4400 | spin_lock_irqsave(&brd_lock, flags); |
4437 | cli(); | ||
4438 | BRDENABLE(portp->brdnr, portp->pagenr); | 4401 | BRDENABLE(portp->brdnr, portp->pagenr); |
4439 | stl_sc26198setreg(portp, IMR, 0); | 4402 | stl_sc26198setreg(portp, IMR, 0); |
4440 | stl_sc26198updatereg(portp, MR0, mr0); | 4403 | stl_sc26198updatereg(portp, MR0, mr0); |
@@ -4461,7 +4424,7 @@ static void stl_sc26198setport(stlport_t *portp, struct termios *tiosp) | |||
4461 | portp->imr = (portp->imr & ~imroff) | imron; | 4424 | portp->imr = (portp->imr & ~imroff) | imron; |
4462 | stl_sc26198setreg(portp, IMR, portp->imr); | 4425 | stl_sc26198setreg(portp, IMR, portp->imr); |
4463 | BRDDISABLE(portp->brdnr); | 4426 | BRDDISABLE(portp->brdnr); |
4464 | restore_flags(flags); | 4427 | spin_unlock_irqrestore(&brd_lock, flags); |
4465 | } | 4428 | } |
4466 | 4429 | ||
4467 | /*****************************************************************************/ | 4430 | /*****************************************************************************/ |
@@ -4491,13 +4454,12 @@ static void stl_sc26198setsignals(stlport_t *portp, int dtr, int rts) | |||
4491 | else if (rts > 0) | 4454 | else if (rts > 0) |
4492 | iopioron |= IPR_RTS; | 4455 | iopioron |= IPR_RTS; |
4493 | 4456 | ||
4494 | save_flags(flags); | 4457 | spin_lock_irqsave(&brd_lock, flags); |
4495 | cli(); | ||
4496 | BRDENABLE(portp->brdnr, portp->pagenr); | 4458 | BRDENABLE(portp->brdnr, portp->pagenr); |
4497 | stl_sc26198setreg(portp, IOPIOR, | 4459 | stl_sc26198setreg(portp, IOPIOR, |
4498 | ((stl_sc26198getreg(portp, IOPIOR) & ~iopioroff) | iopioron)); | 4460 | ((stl_sc26198getreg(portp, IOPIOR) & ~iopioroff) | iopioron)); |
4499 | BRDDISABLE(portp->brdnr); | 4461 | BRDDISABLE(portp->brdnr); |
4500 | restore_flags(flags); | 4462 | spin_unlock_irqrestore(&brd_lock, flags); |
4501 | } | 4463 | } |
4502 | 4464 | ||
4503 | /*****************************************************************************/ | 4465 | /*****************************************************************************/ |
@@ -4516,12 +4478,11 @@ static int stl_sc26198getsignals(stlport_t *portp) | |||
4516 | printk("stl_sc26198getsignals(portp=%x)\n", (int) portp); | 4478 | printk("stl_sc26198getsignals(portp=%x)\n", (int) portp); |
4517 | #endif | 4479 | #endif |
4518 | 4480 | ||
4519 | save_flags(flags); | 4481 | spin_lock_irqsave(&brd_lock, flags); |
4520 | cli(); | ||
4521 | BRDENABLE(portp->brdnr, portp->pagenr); | 4482 | BRDENABLE(portp->brdnr, portp->pagenr); |
4522 | ipr = stl_sc26198getreg(portp, IPR); | 4483 | ipr = stl_sc26198getreg(portp, IPR); |
4523 | BRDDISABLE(portp->brdnr); | 4484 | BRDDISABLE(portp->brdnr); |
4524 | restore_flags(flags); | 4485 | spin_unlock_irqrestore(&brd_lock, flags); |
4525 | 4486 | ||
4526 | sigs = 0; | 4487 | sigs = 0; |
4527 | sigs |= (ipr & IPR_DCD) ? 0 : TIOCM_CD; | 4488 | sigs |= (ipr & IPR_DCD) ? 0 : TIOCM_CD; |
@@ -4558,13 +4519,12 @@ static void stl_sc26198enablerxtx(stlport_t *portp, int rx, int tx) | |||
4558 | else if (rx > 0) | 4519 | else if (rx > 0) |
4559 | ccr |= CR_RXENABLE; | 4520 | ccr |= CR_RXENABLE; |
4560 | 4521 | ||
4561 | save_flags(flags); | 4522 | spin_lock_irqsave(&brd_lock, flags); |
4562 | cli(); | ||
4563 | BRDENABLE(portp->brdnr, portp->pagenr); | 4523 | BRDENABLE(portp->brdnr, portp->pagenr); |
4564 | stl_sc26198setreg(portp, SCCR, ccr); | 4524 | stl_sc26198setreg(portp, SCCR, ccr); |
4565 | BRDDISABLE(portp->brdnr); | 4525 | BRDDISABLE(portp->brdnr); |
4566 | portp->crenable = ccr; | 4526 | portp->crenable = ccr; |
4567 | restore_flags(flags); | 4527 | spin_unlock_irqrestore(&brd_lock, flags); |
4568 | } | 4528 | } |
4569 | 4529 | ||
4570 | /*****************************************************************************/ | 4530 | /*****************************************************************************/ |
@@ -4593,15 +4553,14 @@ static void stl_sc26198startrxtx(stlport_t *portp, int rx, int tx) | |||
4593 | else if (rx > 0) | 4553 | else if (rx > 0) |
4594 | imr |= IR_RXRDY | IR_RXBREAK | IR_RXWATCHDOG; | 4554 | imr |= IR_RXRDY | IR_RXBREAK | IR_RXWATCHDOG; |
4595 | 4555 | ||
4596 | save_flags(flags); | 4556 | spin_lock_irqsave(&brd_lock, flags); |
4597 | cli(); | ||
4598 | BRDENABLE(portp->brdnr, portp->pagenr); | 4557 | BRDENABLE(portp->brdnr, portp->pagenr); |
4599 | stl_sc26198setreg(portp, IMR, imr); | 4558 | stl_sc26198setreg(portp, IMR, imr); |
4600 | BRDDISABLE(portp->brdnr); | 4559 | BRDDISABLE(portp->brdnr); |
4601 | portp->imr = imr; | 4560 | portp->imr = imr; |
4602 | if (tx > 0) | 4561 | if (tx > 0) |
4603 | set_bit(ASYI_TXBUSY, &portp->istate); | 4562 | set_bit(ASYI_TXBUSY, &portp->istate); |
4604 | restore_flags(flags); | 4563 | spin_unlock_irqrestore(&brd_lock, flags); |
4605 | } | 4564 | } |
4606 | 4565 | ||
4607 | /*****************************************************************************/ | 4566 | /*****************************************************************************/ |
@@ -4618,13 +4577,12 @@ static void stl_sc26198disableintrs(stlport_t *portp) | |||
4618 | printk("stl_sc26198disableintrs(portp=%x)\n", (int) portp); | 4577 | printk("stl_sc26198disableintrs(portp=%x)\n", (int) portp); |
4619 | #endif | 4578 | #endif |
4620 | 4579 | ||
4621 | save_flags(flags); | 4580 | spin_lock_irqsave(&brd_lock, flags); |
4622 | cli(); | ||
4623 | BRDENABLE(portp->brdnr, portp->pagenr); | 4581 | BRDENABLE(portp->brdnr, portp->pagenr); |
4624 | portp->imr = 0; | 4582 | portp->imr = 0; |
4625 | stl_sc26198setreg(portp, IMR, 0); | 4583 | stl_sc26198setreg(portp, IMR, 0); |
4626 | BRDDISABLE(portp->brdnr); | 4584 | BRDDISABLE(portp->brdnr); |
4627 | restore_flags(flags); | 4585 | spin_unlock_irqrestore(&brd_lock, flags); |
4628 | } | 4586 | } |
4629 | 4587 | ||
4630 | /*****************************************************************************/ | 4588 | /*****************************************************************************/ |
@@ -4637,8 +4595,7 @@ static void stl_sc26198sendbreak(stlport_t *portp, int len) | |||
4637 | printk("stl_sc26198sendbreak(portp=%x,len=%d)\n", (int) portp, len); | 4595 | printk("stl_sc26198sendbreak(portp=%x,len=%d)\n", (int) portp, len); |
4638 | #endif | 4596 | #endif |
4639 | 4597 | ||
4640 | save_flags(flags); | 4598 | spin_lock_irqsave(&brd_lock, flags); |
4641 | cli(); | ||
4642 | BRDENABLE(portp->brdnr, portp->pagenr); | 4599 | BRDENABLE(portp->brdnr, portp->pagenr); |
4643 | if (len == 1) { | 4600 | if (len == 1) { |
4644 | stl_sc26198setreg(portp, SCCR, CR_TXSTARTBREAK); | 4601 | stl_sc26198setreg(portp, SCCR, CR_TXSTARTBREAK); |
@@ -4647,7 +4604,7 @@ static void stl_sc26198sendbreak(stlport_t *portp, int len) | |||
4647 | stl_sc26198setreg(portp, SCCR, CR_TXSTOPBREAK); | 4604 | stl_sc26198setreg(portp, SCCR, CR_TXSTOPBREAK); |
4648 | } | 4605 | } |
4649 | BRDDISABLE(portp->brdnr); | 4606 | BRDDISABLE(portp->brdnr); |
4650 | restore_flags(flags); | 4607 | spin_unlock_irqrestore(&brd_lock, flags); |
4651 | } | 4608 | } |
4652 | 4609 | ||
4653 | /*****************************************************************************/ | 4610 | /*****************************************************************************/ |
@@ -4672,8 +4629,7 @@ static void stl_sc26198flowctrl(stlport_t *portp, int state) | |||
4672 | if (tty == (struct tty_struct *) NULL) | 4629 | if (tty == (struct tty_struct *) NULL) |
4673 | return; | 4630 | return; |
4674 | 4631 | ||
4675 | save_flags(flags); | 4632 | spin_lock_irqsave(&brd_lock, flags); |
4676 | cli(); | ||
4677 | BRDENABLE(portp->brdnr, portp->pagenr); | 4633 | BRDENABLE(portp->brdnr, portp->pagenr); |
4678 | 4634 | ||
4679 | if (state) { | 4635 | if (state) { |
@@ -4719,7 +4675,7 @@ static void stl_sc26198flowctrl(stlport_t *portp, int state) | |||
4719 | } | 4675 | } |
4720 | 4676 | ||
4721 | BRDDISABLE(portp->brdnr); | 4677 | BRDDISABLE(portp->brdnr); |
4722 | restore_flags(flags); | 4678 | spin_unlock_irqrestore(&brd_lock, flags); |
4723 | } | 4679 | } |
4724 | 4680 | ||
4725 | /*****************************************************************************/ | 4681 | /*****************************************************************************/ |
@@ -4744,8 +4700,7 @@ static void stl_sc26198sendflow(stlport_t *portp, int state) | |||
4744 | if (tty == (struct tty_struct *) NULL) | 4700 | if (tty == (struct tty_struct *) NULL) |
4745 | return; | 4701 | return; |
4746 | 4702 | ||
4747 | save_flags(flags); | 4703 | spin_lock_irqsave(&brd_lock, flags); |
4748 | cli(); | ||
4749 | BRDENABLE(portp->brdnr, portp->pagenr); | 4704 | BRDENABLE(portp->brdnr, portp->pagenr); |
4750 | if (state) { | 4705 | if (state) { |
4751 | mr0 = stl_sc26198getreg(portp, MR0); | 4706 | mr0 = stl_sc26198getreg(portp, MR0); |
@@ -4765,7 +4720,7 @@ static void stl_sc26198sendflow(stlport_t *portp, int state) | |||
4765 | stl_sc26198setreg(portp, MR0, mr0); | 4720 | stl_sc26198setreg(portp, MR0, mr0); |
4766 | } | 4721 | } |
4767 | BRDDISABLE(portp->brdnr); | 4722 | BRDDISABLE(portp->brdnr); |
4768 | restore_flags(flags); | 4723 | spin_unlock_irqrestore(&brd_lock, flags); |
4769 | } | 4724 | } |
4770 | 4725 | ||
4771 | /*****************************************************************************/ | 4726 | /*****************************************************************************/ |
@@ -4781,14 +4736,13 @@ static void stl_sc26198flush(stlport_t *portp) | |||
4781 | if (portp == (stlport_t *) NULL) | 4736 | if (portp == (stlport_t *) NULL) |
4782 | return; | 4737 | return; |
4783 | 4738 | ||
4784 | save_flags(flags); | 4739 | spin_lock_irqsave(&brd_lock, flags); |
4785 | cli(); | ||
4786 | BRDENABLE(portp->brdnr, portp->pagenr); | 4740 | BRDENABLE(portp->brdnr, portp->pagenr); |
4787 | stl_sc26198setreg(portp, SCCR, CR_TXRESET); | 4741 | stl_sc26198setreg(portp, SCCR, CR_TXRESET); |
4788 | stl_sc26198setreg(portp, SCCR, portp->crenable); | 4742 | stl_sc26198setreg(portp, SCCR, portp->crenable); |
4789 | BRDDISABLE(portp->brdnr); | 4743 | BRDDISABLE(portp->brdnr); |
4790 | portp->tx.tail = portp->tx.head; | 4744 | portp->tx.tail = portp->tx.head; |
4791 | restore_flags(flags); | 4745 | spin_unlock_irqrestore(&brd_lock, flags); |
4792 | } | 4746 | } |
4793 | 4747 | ||
4794 | /*****************************************************************************/ | 4748 | /*****************************************************************************/ |
@@ -4815,12 +4769,11 @@ static int stl_sc26198datastate(stlport_t *portp) | |||
4815 | if (test_bit(ASYI_TXBUSY, &portp->istate)) | 4769 | if (test_bit(ASYI_TXBUSY, &portp->istate)) |
4816 | return 1; | 4770 | return 1; |
4817 | 4771 | ||
4818 | save_flags(flags); | 4772 | spin_lock_irqsave(&brd_lock, flags); |
4819 | cli(); | ||
4820 | BRDENABLE(portp->brdnr, portp->pagenr); | 4773 | BRDENABLE(portp->brdnr, portp->pagenr); |
4821 | sr = stl_sc26198getreg(portp, SR); | 4774 | sr = stl_sc26198getreg(portp, SR); |
4822 | BRDDISABLE(portp->brdnr); | 4775 | BRDDISABLE(portp->brdnr); |
4823 | restore_flags(flags); | 4776 | spin_unlock_irqrestore(&brd_lock, flags); |
4824 | 4777 | ||
4825 | return (sr & SR_TXEMPTY) ? 0 : 1; | 4778 | return (sr & SR_TXEMPTY) ? 0 : 1; |
4826 | } | 4779 | } |
@@ -4878,6 +4831,8 @@ static void stl_sc26198intr(stlpanel_t *panelp, unsigned int iobase) | |||
4878 | stlport_t *portp; | 4831 | stlport_t *portp; |
4879 | unsigned int iack; | 4832 | unsigned int iack; |
4880 | 4833 | ||
4834 | spin_lock(&brd_lock); | ||
4835 | |||
4881 | /* | 4836 | /* |
4882 | * Work around bug in sc26198 chip... Cannot have A6 address | 4837 | * Work around bug in sc26198 chip... Cannot have A6 address |
4883 | * line of UART high, else iack will be returned as 0. | 4838 | * line of UART high, else iack will be returned as 0. |
@@ -4893,6 +4848,8 @@ static void stl_sc26198intr(stlpanel_t *panelp, unsigned int iobase) | |||
4893 | stl_sc26198txisr(portp); | 4848 | stl_sc26198txisr(portp); |
4894 | else | 4849 | else |
4895 | stl_sc26198otherisr(portp, iack); | 4850 | stl_sc26198otherisr(portp, iack); |
4851 | |||
4852 | spin_unlock(&brd_lock); | ||
4896 | } | 4853 | } |
4897 | 4854 | ||
4898 | /*****************************************************************************/ | 4855 | /*****************************************************************************/ |
diff --git a/drivers/char/sx.c b/drivers/char/sx.c index 3b4747230270..76b9107f7f81 100644 --- a/drivers/char/sx.c +++ b/drivers/char/sx.c | |||
@@ -2320,7 +2320,7 @@ static int sx_init_portstructs (int nboards, int nports) | |||
2320 | #ifdef NEW_WRITE_LOCKING | 2320 | #ifdef NEW_WRITE_LOCKING |
2321 | port->gs.port_write_mutex = MUTEX; | 2321 | port->gs.port_write_mutex = MUTEX; |
2322 | #endif | 2322 | #endif |
2323 | port->gs.driver_lock = SPIN_LOCK_UNLOCKED; | 2323 | spin_lock_init(&port->gs.driver_lock); |
2324 | /* | 2324 | /* |
2325 | * Initializing wait queue | 2325 | * Initializing wait queue |
2326 | */ | 2326 | */ |
diff --git a/drivers/char/tipar.c b/drivers/char/tipar.c index 079db5a935a1..f7802e5bd7ca 100644 --- a/drivers/char/tipar.c +++ b/drivers/char/tipar.c | |||
@@ -56,7 +56,6 @@ | |||
56 | #include <linux/ioport.h> | 56 | #include <linux/ioport.h> |
57 | #include <asm/io.h> | 57 | #include <asm/io.h> |
58 | #include <linux/bitops.h> | 58 | #include <linux/bitops.h> |
59 | #include <linux/devfs_fs_kernel.h> /* DevFs support */ | ||
60 | #include <linux/parport.h> /* Our code depend on parport */ | 59 | #include <linux/parport.h> /* Our code depend on parport */ |
61 | #include <linux/device.h> | 60 | #include <linux/device.h> |
62 | 61 | ||
@@ -443,12 +442,6 @@ tipar_register(int nr, struct parport *port) | |||
443 | 442 | ||
444 | class_device_create(tipar_class, NULL, MKDEV(TIPAR_MAJOR, | 443 | class_device_create(tipar_class, NULL, MKDEV(TIPAR_MAJOR, |
445 | TIPAR_MINOR + nr), NULL, "par%d", nr); | 444 | TIPAR_MINOR + nr), NULL, "par%d", nr); |
446 | /* Use devfs, tree: /dev/ticables/par/[0..2] */ | ||
447 | err = devfs_mk_cdev(MKDEV(TIPAR_MAJOR, TIPAR_MINOR + nr), | ||
448 | S_IFCHR | S_IRUGO | S_IWUGO, | ||
449 | "ticables/par/%d", nr); | ||
450 | if (err) | ||
451 | goto out_class; | ||
452 | 445 | ||
453 | /* Display informations */ | 446 | /* Display informations */ |
454 | pr_info("tipar%d: using %s (%s)\n", nr, port->name, (port->irq == | 447 | pr_info("tipar%d: using %s (%s)\n", nr, port->name, (port->irq == |
@@ -460,11 +453,7 @@ tipar_register(int nr, struct parport *port) | |||
460 | pr_info("tipar%d: link cable not found\n", nr); | 453 | pr_info("tipar%d: link cable not found\n", nr); |
461 | 454 | ||
462 | err = 0; | 455 | err = 0; |
463 | goto out; | ||
464 | 456 | ||
465 | out_class: | ||
466 | class_device_destroy(tipar_class, MKDEV(TIPAR_MAJOR, TIPAR_MINOR + nr)); | ||
467 | class_destroy(tipar_class); | ||
468 | out: | 457 | out: |
469 | return err; | 458 | return err; |
470 | } | 459 | } |
@@ -507,9 +496,6 @@ tipar_init_module(void) | |||
507 | goto out; | 496 | goto out; |
508 | } | 497 | } |
509 | 498 | ||
510 | /* Use devfs with tree: /dev/ticables/par/[0..2] */ | ||
511 | devfs_mk_dir("ticables/par"); | ||
512 | |||
513 | tipar_class = class_create(THIS_MODULE, "ticables"); | 499 | tipar_class = class_create(THIS_MODULE, "ticables"); |
514 | if (IS_ERR(tipar_class)) { | 500 | if (IS_ERR(tipar_class)) { |
515 | err = PTR_ERR(tipar_class); | 501 | err = PTR_ERR(tipar_class); |
@@ -528,7 +514,6 @@ out_class: | |||
528 | class_destroy(tipar_class); | 514 | class_destroy(tipar_class); |
529 | 515 | ||
530 | out_chrdev: | 516 | out_chrdev: |
531 | devfs_remove("ticables/par"); | ||
532 | unregister_chrdev(TIPAR_MAJOR, "tipar"); | 517 | unregister_chrdev(TIPAR_MAJOR, "tipar"); |
533 | out: | 518 | out: |
534 | return err; | 519 | return err; |
@@ -549,10 +534,8 @@ tipar_cleanup_module(void) | |||
549 | continue; | 534 | continue; |
550 | parport_unregister_device(table[i].dev); | 535 | parport_unregister_device(table[i].dev); |
551 | class_device_destroy(tipar_class, MKDEV(TIPAR_MAJOR, i)); | 536 | class_device_destroy(tipar_class, MKDEV(TIPAR_MAJOR, i)); |
552 | devfs_remove("ticables/par/%d", i); | ||
553 | } | 537 | } |
554 | class_destroy(tipar_class); | 538 | class_destroy(tipar_class); |
555 | devfs_remove("ticables/par"); | ||
556 | 539 | ||
557 | pr_info("tipar: module unloaded\n"); | 540 | pr_info("tipar: module unloaded\n"); |
558 | } | 541 | } |
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c index 8b2a59969868..a1143238feca 100644 --- a/drivers/char/tty_io.c +++ b/drivers/char/tty_io.c | |||
@@ -102,7 +102,6 @@ | |||
102 | #include <linux/kbd_kern.h> | 102 | #include <linux/kbd_kern.h> |
103 | #include <linux/vt_kern.h> | 103 | #include <linux/vt_kern.h> |
104 | #include <linux/selection.h> | 104 | #include <linux/selection.h> |
105 | #include <linux/devfs_fs_kernel.h> | ||
106 | 105 | ||
107 | #include <linux/kmod.h> | 106 | #include <linux/kmod.h> |
108 | 107 | ||
@@ -267,7 +266,6 @@ static struct tty_buffer *tty_buffer_alloc(size_t size) | |||
267 | p->used = 0; | 266 | p->used = 0; |
268 | p->size = size; | 267 | p->size = size; |
269 | p->next = NULL; | 268 | p->next = NULL; |
270 | p->active = 0; | ||
271 | p->commit = 0; | 269 | p->commit = 0; |
272 | p->read = 0; | 270 | p->read = 0; |
273 | p->char_buf_ptr = (char *)(p->data); | 271 | p->char_buf_ptr = (char *)(p->data); |
@@ -327,10 +325,9 @@ int tty_buffer_request_room(struct tty_struct *tty, size_t size) | |||
327 | /* OPTIMISATION: We could keep a per tty "zero" sized buffer to | 325 | /* OPTIMISATION: We could keep a per tty "zero" sized buffer to |
328 | remove this conditional if its worth it. This would be invisible | 326 | remove this conditional if its worth it. This would be invisible |
329 | to the callers */ | 327 | to the callers */ |
330 | if ((b = tty->buf.tail) != NULL) { | 328 | if ((b = tty->buf.tail) != NULL) |
331 | left = b->size - b->used; | 329 | left = b->size - b->used; |
332 | b->active = 1; | 330 | else |
333 | } else | ||
334 | left = 0; | 331 | left = 0; |
335 | 332 | ||
336 | if (left < size) { | 333 | if (left < size) { |
@@ -338,12 +335,10 @@ int tty_buffer_request_room(struct tty_struct *tty, size_t size) | |||
338 | if ((n = tty_buffer_find(tty, size)) != NULL) { | 335 | if ((n = tty_buffer_find(tty, size)) != NULL) { |
339 | if (b != NULL) { | 336 | if (b != NULL) { |
340 | b->next = n; | 337 | b->next = n; |
341 | b->active = 0; | ||
342 | b->commit = b->used; | 338 | b->commit = b->used; |
343 | } else | 339 | } else |
344 | tty->buf.head = n; | 340 | tty->buf.head = n; |
345 | tty->buf.tail = n; | 341 | tty->buf.tail = n; |
346 | n->active = 1; | ||
347 | } else | 342 | } else |
348 | size = left; | 343 | size = left; |
349 | } | 344 | } |
@@ -404,10 +399,8 @@ void tty_schedule_flip(struct tty_struct *tty) | |||
404 | { | 399 | { |
405 | unsigned long flags; | 400 | unsigned long flags; |
406 | spin_lock_irqsave(&tty->buf.lock, flags); | 401 | spin_lock_irqsave(&tty->buf.lock, flags); |
407 | if (tty->buf.tail != NULL) { | 402 | if (tty->buf.tail != NULL) |
408 | tty->buf.tail->active = 0; | ||
409 | tty->buf.tail->commit = tty->buf.tail->used; | 403 | tty->buf.tail->commit = tty->buf.tail->used; |
410 | } | ||
411 | spin_unlock_irqrestore(&tty->buf.lock, flags); | 404 | spin_unlock_irqrestore(&tty->buf.lock, flags); |
412 | schedule_delayed_work(&tty->buf.work, 1); | 405 | schedule_delayed_work(&tty->buf.work, 1); |
413 | } | 406 | } |
@@ -784,11 +777,8 @@ restart: | |||
784 | } | 777 | } |
785 | 778 | ||
786 | clear_bit(TTY_LDISC, &tty->flags); | 779 | clear_bit(TTY_LDISC, &tty->flags); |
787 | clear_bit(TTY_DONT_FLIP, &tty->flags); | 780 | if (o_tty) |
788 | if (o_tty) { | ||
789 | clear_bit(TTY_LDISC, &o_tty->flags); | 781 | clear_bit(TTY_LDISC, &o_tty->flags); |
790 | clear_bit(TTY_DONT_FLIP, &o_tty->flags); | ||
791 | } | ||
792 | spin_unlock_irqrestore(&tty_ldisc_lock, flags); | 782 | spin_unlock_irqrestore(&tty_ldisc_lock, flags); |
793 | 783 | ||
794 | /* | 784 | /* |
@@ -1955,7 +1945,6 @@ static void release_dev(struct file * filp) | |||
1955 | * race with the set_ldisc code path. | 1945 | * race with the set_ldisc code path. |
1956 | */ | 1946 | */ |
1957 | clear_bit(TTY_LDISC, &tty->flags); | 1947 | clear_bit(TTY_LDISC, &tty->flags); |
1958 | clear_bit(TTY_DONT_FLIP, &tty->flags); | ||
1959 | cancel_delayed_work(&tty->buf.work); | 1948 | cancel_delayed_work(&tty->buf.work); |
1960 | 1949 | ||
1961 | /* | 1950 | /* |
@@ -2621,10 +2610,9 @@ int tty_ioctl(struct inode * inode, struct file * file, | |||
2621 | tty->driver->break_ctl(tty, 0); | 2610 | tty->driver->break_ctl(tty, 0); |
2622 | return 0; | 2611 | return 0; |
2623 | case TCSBRK: /* SVID version: non-zero arg --> no break */ | 2612 | case TCSBRK: /* SVID version: non-zero arg --> no break */ |
2624 | /* | 2613 | /* non-zero arg means wait for all output data |
2625 | * XXX is the above comment correct, or the | 2614 | * to be sent (performed above) but don't send break. |
2626 | * code below correct? Is this ioctl used at | 2615 | * This is used by the tcdrain() termios function. |
2627 | * all by anyone? | ||
2628 | */ | 2616 | */ |
2629 | if (!arg) | 2617 | if (!arg) |
2630 | return send_break(tty, 250); | 2618 | return send_break(tty, 250); |
@@ -2776,8 +2764,7 @@ static void flush_to_ldisc(void *private_) | |||
2776 | struct tty_struct *tty = (struct tty_struct *) private_; | 2764 | struct tty_struct *tty = (struct tty_struct *) private_; |
2777 | unsigned long flags; | 2765 | unsigned long flags; |
2778 | struct tty_ldisc *disc; | 2766 | struct tty_ldisc *disc; |
2779 | struct tty_buffer *tbuf; | 2767 | struct tty_buffer *tbuf, *head; |
2780 | int count; | ||
2781 | char *char_buf; | 2768 | char *char_buf; |
2782 | unsigned char *flag_buf; | 2769 | unsigned char *flag_buf; |
2783 | 2770 | ||
@@ -2785,32 +2772,37 @@ static void flush_to_ldisc(void *private_) | |||
2785 | if (disc == NULL) /* !TTY_LDISC */ | 2772 | if (disc == NULL) /* !TTY_LDISC */ |
2786 | return; | 2773 | return; |
2787 | 2774 | ||
2788 | if (test_bit(TTY_DONT_FLIP, &tty->flags)) { | ||
2789 | /* | ||
2790 | * Do it after the next timer tick: | ||
2791 | */ | ||
2792 | schedule_delayed_work(&tty->buf.work, 1); | ||
2793 | goto out; | ||
2794 | } | ||
2795 | spin_lock_irqsave(&tty->buf.lock, flags); | 2775 | spin_lock_irqsave(&tty->buf.lock, flags); |
2796 | while((tbuf = tty->buf.head) != NULL) { | 2776 | head = tty->buf.head; |
2797 | while ((count = tbuf->commit - tbuf->read) != 0) { | 2777 | if (head != NULL) { |
2798 | char_buf = tbuf->char_buf_ptr + tbuf->read; | 2778 | tty->buf.head = NULL; |
2799 | flag_buf = tbuf->flag_buf_ptr + tbuf->read; | 2779 | for (;;) { |
2800 | tbuf->read += count; | 2780 | int count = head->commit - head->read; |
2781 | if (!count) { | ||
2782 | if (head->next == NULL) | ||
2783 | break; | ||
2784 | tbuf = head; | ||
2785 | head = head->next; | ||
2786 | tty_buffer_free(tty, tbuf); | ||
2787 | continue; | ||
2788 | } | ||
2789 | if (!tty->receive_room) { | ||
2790 | schedule_delayed_work(&tty->buf.work, 1); | ||
2791 | break; | ||
2792 | } | ||
2793 | if (count > tty->receive_room) | ||
2794 | count = tty->receive_room; | ||
2795 | char_buf = head->char_buf_ptr + head->read; | ||
2796 | flag_buf = head->flag_buf_ptr + head->read; | ||
2797 | head->read += count; | ||
2801 | spin_unlock_irqrestore(&tty->buf.lock, flags); | 2798 | spin_unlock_irqrestore(&tty->buf.lock, flags); |
2802 | disc->receive_buf(tty, char_buf, flag_buf, count); | 2799 | disc->receive_buf(tty, char_buf, flag_buf, count); |
2803 | spin_lock_irqsave(&tty->buf.lock, flags); | 2800 | spin_lock_irqsave(&tty->buf.lock, flags); |
2804 | } | 2801 | } |
2805 | if (tbuf->active) | 2802 | tty->buf.head = head; |
2806 | break; | ||
2807 | tty->buf.head = tbuf->next; | ||
2808 | if (tty->buf.head == NULL) | ||
2809 | tty->buf.tail = NULL; | ||
2810 | tty_buffer_free(tty, tbuf); | ||
2811 | } | 2803 | } |
2812 | spin_unlock_irqrestore(&tty->buf.lock, flags); | 2804 | spin_unlock_irqrestore(&tty->buf.lock, flags); |
2813 | out: | 2805 | |
2814 | tty_ldisc_deref(disc); | 2806 | tty_ldisc_deref(disc); |
2815 | } | 2807 | } |
2816 | 2808 | ||
@@ -2903,10 +2895,8 @@ void tty_flip_buffer_push(struct tty_struct *tty) | |||
2903 | { | 2895 | { |
2904 | unsigned long flags; | 2896 | unsigned long flags; |
2905 | spin_lock_irqsave(&tty->buf.lock, flags); | 2897 | spin_lock_irqsave(&tty->buf.lock, flags); |
2906 | if (tty->buf.tail != NULL) { | 2898 | if (tty->buf.tail != NULL) |
2907 | tty->buf.tail->active = 0; | ||
2908 | tty->buf.tail->commit = tty->buf.tail->used; | 2899 | tty->buf.tail->commit = tty->buf.tail->used; |
2909 | } | ||
2910 | spin_unlock_irqrestore(&tty->buf.lock, flags); | 2900 | spin_unlock_irqrestore(&tty->buf.lock, flags); |
2911 | 2901 | ||
2912 | if (tty->low_latency) | 2902 | if (tty->low_latency) |
@@ -2964,8 +2954,8 @@ static struct class *tty_class; | |||
2964 | * Returns a pointer to the class device (or ERR_PTR(-EFOO) on error). | 2954 | * Returns a pointer to the class device (or ERR_PTR(-EFOO) on error). |
2965 | * | 2955 | * |
2966 | * This call is required to be made to register an individual tty device if | 2956 | * This call is required to be made to register an individual tty device if |
2967 | * the tty driver's flags have the TTY_DRIVER_NO_DEVFS bit set. If that | 2957 | * the tty driver's flags have the TTY_DRIVER_DYNAMIC_DEV bit set. If that |
2968 | * bit is not set, this function should not be called. | 2958 | * bit is not set, this function should not be called by a tty driver. |
2969 | */ | 2959 | */ |
2970 | struct class_device *tty_register_device(struct tty_driver *driver, | 2960 | struct class_device *tty_register_device(struct tty_driver *driver, |
2971 | unsigned index, struct device *device) | 2961 | unsigned index, struct device *device) |
@@ -2979,9 +2969,6 @@ struct class_device *tty_register_device(struct tty_driver *driver, | |||
2979 | return ERR_PTR(-EINVAL); | 2969 | return ERR_PTR(-EINVAL); |
2980 | } | 2970 | } |
2981 | 2971 | ||
2982 | devfs_mk_cdev(dev, S_IFCHR | S_IRUSR | S_IWUSR, | ||
2983 | "%s%d", driver->devfs_name, index + driver->name_base); | ||
2984 | |||
2985 | if (driver->type == TTY_DRIVER_TYPE_PTY) | 2972 | if (driver->type == TTY_DRIVER_TYPE_PTY) |
2986 | pty_line_name(driver, index, name); | 2973 | pty_line_name(driver, index, name); |
2987 | else | 2974 | else |
@@ -3000,7 +2987,6 @@ struct class_device *tty_register_device(struct tty_driver *driver, | |||
3000 | */ | 2987 | */ |
3001 | void tty_unregister_device(struct tty_driver *driver, unsigned index) | 2988 | void tty_unregister_device(struct tty_driver *driver, unsigned index) |
3002 | { | 2989 | { |
3003 | devfs_remove("%s%d", driver->devfs_name, index + driver->name_base); | ||
3004 | class_device_destroy(tty_class, MKDEV(driver->major, driver->minor_start) + index); | 2990 | class_device_destroy(tty_class, MKDEV(driver->major, driver->minor_start) + index); |
3005 | } | 2991 | } |
3006 | 2992 | ||
@@ -3122,7 +3108,7 @@ int tty_register_driver(struct tty_driver *driver) | |||
3122 | 3108 | ||
3123 | list_add(&driver->tty_drivers, &tty_drivers); | 3109 | list_add(&driver->tty_drivers, &tty_drivers); |
3124 | 3110 | ||
3125 | if ( !(driver->flags & TTY_DRIVER_NO_DEVFS) ) { | 3111 | if ( !(driver->flags & TTY_DRIVER_DYNAMIC_DEV) ) { |
3126 | for(i = 0; i < driver->num; i++) | 3112 | for(i = 0; i < driver->num; i++) |
3127 | tty_register_device(driver, i, NULL); | 3113 | tty_register_device(driver, i, NULL); |
3128 | } | 3114 | } |
@@ -3165,7 +3151,7 @@ int tty_unregister_driver(struct tty_driver *driver) | |||
3165 | driver->termios_locked[i] = NULL; | 3151 | driver->termios_locked[i] = NULL; |
3166 | kfree(tp); | 3152 | kfree(tp); |
3167 | } | 3153 | } |
3168 | if (!(driver->flags & TTY_DRIVER_NO_DEVFS)) | 3154 | if (!(driver->flags & TTY_DRIVER_DYNAMIC_DEV)) |
3169 | tty_unregister_device(driver, i); | 3155 | tty_unregister_device(driver, i); |
3170 | } | 3156 | } |
3171 | p = driver->ttys; | 3157 | p = driver->ttys; |
@@ -3241,14 +3227,12 @@ static int __init tty_init(void) | |||
3241 | if (cdev_add(&tty_cdev, MKDEV(TTYAUX_MAJOR, 0), 1) || | 3227 | if (cdev_add(&tty_cdev, MKDEV(TTYAUX_MAJOR, 0), 1) || |
3242 | register_chrdev_region(MKDEV(TTYAUX_MAJOR, 0), 1, "/dev/tty") < 0) | 3228 | register_chrdev_region(MKDEV(TTYAUX_MAJOR, 0), 1, "/dev/tty") < 0) |
3243 | panic("Couldn't register /dev/tty driver\n"); | 3229 | panic("Couldn't register /dev/tty driver\n"); |
3244 | devfs_mk_cdev(MKDEV(TTYAUX_MAJOR, 0), S_IFCHR|S_IRUGO|S_IWUGO, "tty"); | ||
3245 | class_device_create(tty_class, NULL, MKDEV(TTYAUX_MAJOR, 0), NULL, "tty"); | 3230 | class_device_create(tty_class, NULL, MKDEV(TTYAUX_MAJOR, 0), NULL, "tty"); |
3246 | 3231 | ||
3247 | cdev_init(&console_cdev, &console_fops); | 3232 | cdev_init(&console_cdev, &console_fops); |
3248 | if (cdev_add(&console_cdev, MKDEV(TTYAUX_MAJOR, 1), 1) || | 3233 | if (cdev_add(&console_cdev, MKDEV(TTYAUX_MAJOR, 1), 1) || |
3249 | register_chrdev_region(MKDEV(TTYAUX_MAJOR, 1), 1, "/dev/console") < 0) | 3234 | register_chrdev_region(MKDEV(TTYAUX_MAJOR, 1), 1, "/dev/console") < 0) |
3250 | panic("Couldn't register /dev/console driver\n"); | 3235 | panic("Couldn't register /dev/console driver\n"); |
3251 | devfs_mk_cdev(MKDEV(TTYAUX_MAJOR, 1), S_IFCHR|S_IRUSR|S_IWUSR, "console"); | ||
3252 | class_device_create(tty_class, NULL, MKDEV(TTYAUX_MAJOR, 1), NULL, "console"); | 3236 | class_device_create(tty_class, NULL, MKDEV(TTYAUX_MAJOR, 1), NULL, "console"); |
3253 | 3237 | ||
3254 | #ifdef CONFIG_UNIX98_PTYS | 3238 | #ifdef CONFIG_UNIX98_PTYS |
@@ -3256,7 +3240,6 @@ static int __init tty_init(void) | |||
3256 | if (cdev_add(&ptmx_cdev, MKDEV(TTYAUX_MAJOR, 2), 1) || | 3240 | if (cdev_add(&ptmx_cdev, MKDEV(TTYAUX_MAJOR, 2), 1) || |
3257 | register_chrdev_region(MKDEV(TTYAUX_MAJOR, 2), 1, "/dev/ptmx") < 0) | 3241 | register_chrdev_region(MKDEV(TTYAUX_MAJOR, 2), 1, "/dev/ptmx") < 0) |
3258 | panic("Couldn't register /dev/ptmx driver\n"); | 3242 | panic("Couldn't register /dev/ptmx driver\n"); |
3259 | devfs_mk_cdev(MKDEV(TTYAUX_MAJOR, 2), S_IFCHR|S_IRUGO|S_IWUGO, "ptmx"); | ||
3260 | class_device_create(tty_class, NULL, MKDEV(TTYAUX_MAJOR, 2), NULL, "ptmx"); | 3243 | class_device_create(tty_class, NULL, MKDEV(TTYAUX_MAJOR, 2), NULL, "ptmx"); |
3261 | #endif | 3244 | #endif |
3262 | 3245 | ||
@@ -3265,7 +3248,6 @@ static int __init tty_init(void) | |||
3265 | if (cdev_add(&vc0_cdev, MKDEV(TTY_MAJOR, 0), 1) || | 3248 | if (cdev_add(&vc0_cdev, MKDEV(TTY_MAJOR, 0), 1) || |
3266 | register_chrdev_region(MKDEV(TTY_MAJOR, 0), 1, "/dev/vc/0") < 0) | 3249 | register_chrdev_region(MKDEV(TTY_MAJOR, 0), 1, "/dev/vc/0") < 0) |
3267 | panic("Couldn't register /dev/tty0 driver\n"); | 3250 | panic("Couldn't register /dev/tty0 driver\n"); |
3268 | devfs_mk_cdev(MKDEV(TTY_MAJOR, 0), S_IFCHR|S_IRUSR|S_IWUSR, "vc/0"); | ||
3269 | class_device_create(tty_class, NULL, MKDEV(TTY_MAJOR, 0), NULL, "tty0"); | 3251 | class_device_create(tty_class, NULL, MKDEV(TTY_MAJOR, 0), NULL, "tty0"); |
3270 | 3252 | ||
3271 | vty_init(); | 3253 | vty_init(); |
diff --git a/drivers/char/vc_screen.c b/drivers/char/vc_screen.c index 3c1dafaa3441..234d7f3fb114 100644 --- a/drivers/char/vc_screen.c +++ b/drivers/char/vc_screen.c | |||
@@ -26,7 +26,6 @@ | |||
26 | #include <linux/major.h> | 26 | #include <linux/major.h> |
27 | #include <linux/errno.h> | 27 | #include <linux/errno.h> |
28 | #include <linux/tty.h> | 28 | #include <linux/tty.h> |
29 | #include <linux/devfs_fs_kernel.h> | ||
30 | #include <linux/sched.h> | 29 | #include <linux/sched.h> |
31 | #include <linux/interrupt.h> | 30 | #include <linux/interrupt.h> |
32 | #include <linux/mm.h> | 31 | #include <linux/mm.h> |
@@ -478,12 +477,6 @@ static struct class *vc_class; | |||
478 | 477 | ||
479 | void vcs_make_devfs(struct tty_struct *tty) | 478 | void vcs_make_devfs(struct tty_struct *tty) |
480 | { | 479 | { |
481 | devfs_mk_cdev(MKDEV(VCS_MAJOR, tty->index + 1), | ||
482 | S_IFCHR|S_IRUSR|S_IWUSR, | ||
483 | "vcc/%u", tty->index + 1); | ||
484 | devfs_mk_cdev(MKDEV(VCS_MAJOR, tty->index + 129), | ||
485 | S_IFCHR|S_IRUSR|S_IWUSR, | ||
486 | "vcc/a%u", tty->index + 1); | ||
487 | class_device_create(vc_class, NULL, MKDEV(VCS_MAJOR, tty->index + 1), | 480 | class_device_create(vc_class, NULL, MKDEV(VCS_MAJOR, tty->index + 1), |
488 | NULL, "vcs%u", tty->index + 1); | 481 | NULL, "vcs%u", tty->index + 1); |
489 | class_device_create(vc_class, NULL, MKDEV(VCS_MAJOR, tty->index + 129), | 482 | class_device_create(vc_class, NULL, MKDEV(VCS_MAJOR, tty->index + 129), |
@@ -491,8 +484,6 @@ void vcs_make_devfs(struct tty_struct *tty) | |||
491 | } | 484 | } |
492 | void vcs_remove_devfs(struct tty_struct *tty) | 485 | void vcs_remove_devfs(struct tty_struct *tty) |
493 | { | 486 | { |
494 | devfs_remove("vcc/%u", tty->index + 1); | ||
495 | devfs_remove("vcc/a%u", tty->index + 1); | ||
496 | class_device_destroy(vc_class, MKDEV(VCS_MAJOR, tty->index + 1)); | 487 | class_device_destroy(vc_class, MKDEV(VCS_MAJOR, tty->index + 1)); |
497 | class_device_destroy(vc_class, MKDEV(VCS_MAJOR, tty->index + 129)); | 488 | class_device_destroy(vc_class, MKDEV(VCS_MAJOR, tty->index + 129)); |
498 | } | 489 | } |
@@ -503,8 +494,6 @@ int __init vcs_init(void) | |||
503 | panic("unable to get major %d for vcs device", VCS_MAJOR); | 494 | panic("unable to get major %d for vcs device", VCS_MAJOR); |
504 | vc_class = class_create(THIS_MODULE, "vc"); | 495 | vc_class = class_create(THIS_MODULE, "vc"); |
505 | 496 | ||
506 | devfs_mk_cdev(MKDEV(VCS_MAJOR, 0), S_IFCHR|S_IRUSR|S_IWUSR, "vcc/0"); | ||
507 | devfs_mk_cdev(MKDEV(VCS_MAJOR, 128), S_IFCHR|S_IRUSR|S_IWUSR, "vcc/a0"); | ||
508 | class_device_create(vc_class, NULL, MKDEV(VCS_MAJOR, 0), NULL, "vcs"); | 497 | class_device_create(vc_class, NULL, MKDEV(VCS_MAJOR, 0), NULL, "vcs"); |
509 | class_device_create(vc_class, NULL, MKDEV(VCS_MAJOR, 128), NULL, "vcsa"); | 498 | class_device_create(vc_class, NULL, MKDEV(VCS_MAJOR, 128), NULL, "vcsa"); |
510 | return 0; | 499 | return 0; |
diff --git a/drivers/char/viocons.c b/drivers/char/viocons.c index 4e5360388748..07f5ce4b28e3 100644 --- a/drivers/char/viocons.c +++ b/drivers/char/viocons.c | |||
@@ -1152,7 +1152,6 @@ static int __init viocons_init2(void) | |||
1152 | viotty_driver = alloc_tty_driver(VTTY_PORTS); | 1152 | viotty_driver = alloc_tty_driver(VTTY_PORTS); |
1153 | viotty_driver->owner = THIS_MODULE; | 1153 | viotty_driver->owner = THIS_MODULE; |
1154 | viotty_driver->driver_name = "vioconsole"; | 1154 | viotty_driver->driver_name = "vioconsole"; |
1155 | viotty_driver->devfs_name = "vcs/"; | ||
1156 | viotty_driver->name = "tty"; | 1155 | viotty_driver->name = "tty"; |
1157 | viotty_driver->name_base = 1; | 1156 | viotty_driver->name_base = 1; |
1158 | viotty_driver->major = TTY_MAJOR; | 1157 | viotty_driver->major = TTY_MAJOR; |
diff --git a/drivers/char/viotape.c b/drivers/char/viotape.c index 11c7e9de5958..198f1505ae23 100644 --- a/drivers/char/viotape.c +++ b/drivers/char/viotape.c | |||
@@ -43,7 +43,6 @@ | |||
43 | #include <linux/dma-mapping.h> | 43 | #include <linux/dma-mapping.h> |
44 | #include <linux/fs.h> | 44 | #include <linux/fs.h> |
45 | #include <linux/cdev.h> | 45 | #include <linux/cdev.h> |
46 | #include <linux/devfs_fs_kernel.h> | ||
47 | #include <linux/major.h> | 46 | #include <linux/major.h> |
48 | #include <linux/completion.h> | 47 | #include <linux/completion.h> |
49 | #include <linux/proc_fs.h> | 48 | #include <linux/proc_fs.h> |
@@ -246,7 +245,6 @@ static struct device *tape_device[VIOTAPE_MAX_TAPE]; | |||
246 | */ | 245 | */ |
247 | static struct { | 246 | static struct { |
248 | unsigned char cur_part; | 247 | unsigned char cur_part; |
249 | int dev_handle; | ||
250 | unsigned char part_stat_rwi[MAX_PARTITIONS]; | 248 | unsigned char part_stat_rwi[MAX_PARTITIONS]; |
251 | } state[VIOTAPE_MAX_TAPE]; | 249 | } state[VIOTAPE_MAX_TAPE]; |
252 | 250 | ||
@@ -959,12 +957,7 @@ static int viotape_probe(struct vio_dev *vdev, const struct vio_device_id *id) | |||
959 | "iseries!vt%d", i); | 957 | "iseries!vt%d", i); |
960 | class_device_create(tape_class, NULL, MKDEV(VIOTAPE_MAJOR, i | 0x80), | 958 | class_device_create(tape_class, NULL, MKDEV(VIOTAPE_MAJOR, i | 0x80), |
961 | NULL, "iseries!nvt%d", i); | 959 | NULL, "iseries!nvt%d", i); |
962 | devfs_mk_cdev(MKDEV(VIOTAPE_MAJOR, i), S_IFCHR | S_IRUSR | S_IWUSR, | ||
963 | "iseries/vt%d", i); | ||
964 | devfs_mk_cdev(MKDEV(VIOTAPE_MAJOR, i | 0x80), | ||
965 | S_IFCHR | S_IRUSR | S_IWUSR, "iseries/nvt%d", i); | ||
966 | sprintf(tapename, "iseries/vt%d", i); | 960 | sprintf(tapename, "iseries/vt%d", i); |
967 | state[i].dev_handle = devfs_register_tape(tapename); | ||
968 | printk(VIOTAPE_KERN_INFO "tape %s is iSeries " | 961 | printk(VIOTAPE_KERN_INFO "tape %s is iSeries " |
969 | "resource %10.10s type %4.4s, model %3.3s\n", | 962 | "resource %10.10s type %4.4s, model %3.3s\n", |
970 | tapename, viotape_unitinfo[i].rsrcname, | 963 | tapename, viotape_unitinfo[i].rsrcname, |
@@ -976,9 +969,6 @@ static int viotape_remove(struct vio_dev *vdev) | |||
976 | { | 969 | { |
977 | int i = vdev->unit_address; | 970 | int i = vdev->unit_address; |
978 | 971 | ||
979 | devfs_remove("iseries/nvt%d", i); | ||
980 | devfs_remove("iseries/vt%d", i); | ||
981 | devfs_unregister_tape(state[i].dev_handle); | ||
982 | class_device_destroy(tape_class, MKDEV(VIOTAPE_MAJOR, i | 0x80)); | 972 | class_device_destroy(tape_class, MKDEV(VIOTAPE_MAJOR, i | 0x80)); |
983 | class_device_destroy(tape_class, MKDEV(VIOTAPE_MAJOR, i)); | 973 | class_device_destroy(tape_class, MKDEV(VIOTAPE_MAJOR, i)); |
984 | return 0; | 974 | return 0; |
diff --git a/drivers/char/vme_scc.c b/drivers/char/vme_scc.c index fd00822ac145..fe99fc1aba45 100644 --- a/drivers/char/vme_scc.c +++ b/drivers/char/vme_scc.c | |||
@@ -147,7 +147,6 @@ static int scc_init_drivers(void) | |||
147 | scc_driver->owner = THIS_MODULE; | 147 | scc_driver->owner = THIS_MODULE; |
148 | scc_driver->driver_name = "scc"; | 148 | scc_driver->driver_name = "scc"; |
149 | scc_driver->name = "ttyS"; | 149 | scc_driver->name = "ttyS"; |
150 | scc_driver->devfs_name = "tts/"; | ||
151 | scc_driver->major = TTY_MAJOR; | 150 | scc_driver->major = TTY_MAJOR; |
152 | scc_driver->minor_start = SCC_MINOR_BASE; | 151 | scc_driver->minor_start = SCC_MINOR_BASE; |
153 | scc_driver->type = TTY_DRIVER_TYPE_SERIAL; | 152 | scc_driver->type = TTY_DRIVER_TYPE_SERIAL; |
diff --git a/drivers/char/vr41xx_giu.c b/drivers/char/vr41xx_giu.c index 05e6e814d86f..073da48c092e 100644 --- a/drivers/char/vr41xx_giu.c +++ b/drivers/char/vr41xx_giu.c | |||
@@ -689,9 +689,9 @@ static int __devinit giu_probe(struct platform_device *dev) | |||
689 | 689 | ||
690 | for (i = GIU_IRQ_BASE; i <= GIU_IRQ_LAST; i++) { | 690 | for (i = GIU_IRQ_BASE; i <= GIU_IRQ_LAST; i++) { |
691 | if (i < GIU_IRQ(GIUINT_HIGH_OFFSET)) | 691 | if (i < GIU_IRQ(GIUINT_HIGH_OFFSET)) |
692 | irq_desc[i].handler = &giuint_low_irq_type; | 692 | irq_desc[i].chip = &giuint_low_irq_type; |
693 | else | 693 | else |
694 | irq_desc[i].handler = &giuint_high_irq_type; | 694 | irq_desc[i].chip = &giuint_high_irq_type; |
695 | } | 695 | } |
696 | 696 | ||
697 | return cascade_irq(GIUINT_IRQ, giu_get_irq); | 697 | return cascade_irq(GIUINT_IRQ, giu_get_irq); |
diff --git a/drivers/char/vt.c b/drivers/char/vt.c index 714d95ff2f1e..d6f65032649a 100644 --- a/drivers/char/vt.c +++ b/drivers/char/vt.c | |||
@@ -79,7 +79,6 @@ | |||
79 | #include <linux/mm.h> | 79 | #include <linux/mm.h> |
80 | #include <linux/console.h> | 80 | #include <linux/console.h> |
81 | #include <linux/init.h> | 81 | #include <linux/init.h> |
82 | #include <linux/devfs_fs_kernel.h> | ||
83 | #include <linux/vt_kern.h> | 82 | #include <linux/vt_kern.h> |
84 | #include <linux/selection.h> | 83 | #include <linux/selection.h> |
85 | #include <linux/tiocl.h> | 84 | #include <linux/tiocl.h> |
@@ -2663,7 +2662,6 @@ int __init vty_init(void) | |||
2663 | if (!console_driver) | 2662 | if (!console_driver) |
2664 | panic("Couldn't allocate console driver\n"); | 2663 | panic("Couldn't allocate console driver\n"); |
2665 | console_driver->owner = THIS_MODULE; | 2664 | console_driver->owner = THIS_MODULE; |
2666 | console_driver->devfs_name = "vc/"; | ||
2667 | console_driver->name = "tty"; | 2665 | console_driver->name = "tty"; |
2668 | console_driver->name_base = 1; | 2666 | console_driver->name_base = 1; |
2669 | console_driver->major = TTY_MAJOR; | 2667 | console_driver->major = TTY_MAJOR; |
diff --git a/drivers/char/watchdog/at91_wdt.c b/drivers/char/watchdog/at91_wdt.c index ac83bc4b019a..00080655533d 100644 --- a/drivers/char/watchdog/at91_wdt.c +++ b/drivers/char/watchdog/at91_wdt.c | |||
@@ -17,14 +17,15 @@ | |||
17 | #include <linux/miscdevice.h> | 17 | #include <linux/miscdevice.h> |
18 | #include <linux/module.h> | 18 | #include <linux/module.h> |
19 | #include <linux/moduleparam.h> | 19 | #include <linux/moduleparam.h> |
20 | #include <linux/platform_device.h> | ||
20 | #include <linux/types.h> | 21 | #include <linux/types.h> |
21 | #include <linux/watchdog.h> | 22 | #include <linux/watchdog.h> |
22 | #include <asm/bitops.h> | 23 | #include <asm/bitops.h> |
23 | #include <asm/uaccess.h> | 24 | #include <asm/uaccess.h> |
24 | 25 | ||
25 | 26 | ||
26 | #define WDT_DEFAULT_TIME 5 /* 5 seconds */ | 27 | #define WDT_DEFAULT_TIME 5 /* seconds */ |
27 | #define WDT_MAX_TIME 256 /* 256 seconds */ | 28 | #define WDT_MAX_TIME 256 /* seconds */ |
28 | 29 | ||
29 | static int wdt_time = WDT_DEFAULT_TIME; | 30 | static int wdt_time = WDT_DEFAULT_TIME; |
30 | static int nowayout = WATCHDOG_NOWAYOUT; | 31 | static int nowayout = WATCHDOG_NOWAYOUT; |
@@ -32,8 +33,10 @@ static int nowayout = WATCHDOG_NOWAYOUT; | |||
32 | module_param(wdt_time, int, 0); | 33 | module_param(wdt_time, int, 0); |
33 | MODULE_PARM_DESC(wdt_time, "Watchdog time in seconds. (default="__MODULE_STRING(WDT_DEFAULT_TIME) ")"); | 34 | MODULE_PARM_DESC(wdt_time, "Watchdog time in seconds. (default="__MODULE_STRING(WDT_DEFAULT_TIME) ")"); |
34 | 35 | ||
36 | #ifdef CONFIG_WATCHDOG_NOWAYOUT | ||
35 | module_param(nowayout, int, 0); | 37 | module_param(nowayout, int, 0); |
36 | MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); | 38 | MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); |
39 | #endif | ||
37 | 40 | ||
38 | 41 | ||
39 | static unsigned long at91wdt_busy; | 42 | static unsigned long at91wdt_busy; |
@@ -138,7 +141,7 @@ static int at91_wdt_ioctl(struct inode *inode, struct file *file, | |||
138 | case WDIOC_SETTIMEOUT: | 141 | case WDIOC_SETTIMEOUT: |
139 | if (get_user(new_value, p)) | 142 | if (get_user(new_value, p)) |
140 | return -EFAULT; | 143 | return -EFAULT; |
141 | 144 | ||
142 | if (at91_wdt_settimeout(new_value)) | 145 | if (at91_wdt_settimeout(new_value)) |
143 | return -EINVAL; | 146 | return -EINVAL; |
144 | 147 | ||
@@ -196,27 +199,84 @@ static struct miscdevice at91wdt_miscdev = { | |||
196 | .fops = &at91wdt_fops, | 199 | .fops = &at91wdt_fops, |
197 | }; | 200 | }; |
198 | 201 | ||
199 | static int __init at91_wdt_init(void) | 202 | static int __init at91wdt_probe(struct platform_device *pdev) |
200 | { | 203 | { |
201 | int res; | 204 | int res; |
202 | 205 | ||
203 | /* Check that the heartbeat value is within range; if not reset to the default */ | 206 | if (at91wdt_miscdev.dev) |
204 | if (at91_wdt_settimeout(wdt_time)) { | 207 | return -EBUSY; |
205 | at91_wdt_settimeout(WDT_DEFAULT_TIME); | 208 | at91wdt_miscdev.dev = &pdev->dev; |
206 | printk(KERN_INFO "at91_wdt: wdt_time value must be 1 <= wdt_time <= 256, using %d\n", wdt_time); | ||
207 | } | ||
208 | 209 | ||
209 | res = misc_register(&at91wdt_miscdev); | 210 | res = misc_register(&at91wdt_miscdev); |
210 | if (res) | 211 | if (res) |
211 | return res; | 212 | return res; |
212 | 213 | ||
213 | printk("AT91 Watchdog Timer enabled (%d seconds, nowayout=%d)\n", wdt_time, nowayout); | 214 | printk("AT91 Watchdog Timer enabled (%d seconds%s)\n", wdt_time, nowayout ? ", nowayout" : ""); |
214 | return 0; | 215 | return 0; |
215 | } | 216 | } |
216 | 217 | ||
218 | static int __exit at91wdt_remove(struct platform_device *pdev) | ||
219 | { | ||
220 | int res; | ||
221 | |||
222 | res = misc_deregister(&at91wdt_miscdev); | ||
223 | if (!res) | ||
224 | at91wdt_miscdev.dev = NULL; | ||
225 | |||
226 | return res; | ||
227 | } | ||
228 | |||
229 | static void at91wdt_shutdown(struct platform_device *pdev) | ||
230 | { | ||
231 | at91_wdt_stop(); | ||
232 | } | ||
233 | |||
234 | #ifdef CONFIG_PM | ||
235 | |||
236 | static int at91wdt_suspend(struct platform_device *pdev, pm_message_t message) | ||
237 | { | ||
238 | at91_wdt_stop(); | ||
239 | return 0; | ||
240 | } | ||
241 | |||
242 | static int at91wdt_resume(struct platform_device *pdev) | ||
243 | { | ||
244 | if (at91wdt_busy) | ||
245 | at91_wdt_start(); | ||
246 | return 0; | ||
247 | } | ||
248 | |||
249 | #else | ||
250 | #define at91wdt_suspend NULL | ||
251 | #define at91wdt_resume NULL | ||
252 | #endif | ||
253 | |||
254 | static struct platform_driver at91wdt_driver = { | ||
255 | .probe = at91wdt_probe, | ||
256 | .remove = __exit_p(at91wdt_remove), | ||
257 | .shutdown = at91wdt_shutdown, | ||
258 | .suspend = at91wdt_suspend, | ||
259 | .resume = at91wdt_resume, | ||
260 | .driver = { | ||
261 | .name = "at91_wdt", | ||
262 | .owner = THIS_MODULE, | ||
263 | }, | ||
264 | }; | ||
265 | |||
266 | static int __init at91_wdt_init(void) | ||
267 | { | ||
268 | /* Check that the heartbeat value is within range; if not reset to the default */ | ||
269 | if (at91_wdt_settimeout(wdt_time)) { | ||
270 | at91_wdt_settimeout(WDT_DEFAULT_TIME); | ||
271 | pr_info("at91_wdt: wdt_time value must be 1 <= wdt_time <= 256, using %d\n", wdt_time); | ||
272 | } | ||
273 | |||
274 | return platform_driver_register(&at91wdt_driver); | ||
275 | } | ||
276 | |||
217 | static void __exit at91_wdt_exit(void) | 277 | static void __exit at91_wdt_exit(void) |
218 | { | 278 | { |
219 | misc_deregister(&at91wdt_miscdev); | 279 | platform_driver_unregister(&at91wdt_driver); |
220 | } | 280 | } |
221 | 281 | ||
222 | module_init(at91_wdt_init); | 282 | module_init(at91_wdt_init); |
diff --git a/drivers/char/watchdog/i8xx_tco.c b/drivers/char/watchdog/i8xx_tco.c index fa2ba9ebe42a..bfbdbbf3c2f2 100644 --- a/drivers/char/watchdog/i8xx_tco.c +++ b/drivers/char/watchdog/i8xx_tco.c | |||
@@ -205,6 +205,23 @@ static int tco_timer_set_heartbeat (int t) | |||
205 | return 0; | 205 | return 0; |
206 | } | 206 | } |
207 | 207 | ||
208 | static int tco_timer_get_timeleft (int *time_left) | ||
209 | { | ||
210 | unsigned char val; | ||
211 | |||
212 | spin_lock(&tco_lock); | ||
213 | |||
214 | /* read the TCO Timer */ | ||
215 | val = inb (TCO1_RLD); | ||
216 | val &= 0x3f; | ||
217 | |||
218 | spin_unlock(&tco_lock); | ||
219 | |||
220 | *time_left = (int)((val * 6) / 10); | ||
221 | |||
222 | return 0; | ||
223 | } | ||
224 | |||
208 | /* | 225 | /* |
209 | * /dev/watchdog handling | 226 | * /dev/watchdog handling |
210 | */ | 227 | */ |
@@ -272,6 +289,7 @@ static int i8xx_tco_ioctl (struct inode *inode, struct file *file, | |||
272 | { | 289 | { |
273 | int new_options, retval = -EINVAL; | 290 | int new_options, retval = -EINVAL; |
274 | int new_heartbeat; | 291 | int new_heartbeat; |
292 | int time_left; | ||
275 | void __user *argp = (void __user *)arg; | 293 | void __user *argp = (void __user *)arg; |
276 | int __user *p = argp; | 294 | int __user *p = argp; |
277 | static struct watchdog_info ident = { | 295 | static struct watchdog_info ident = { |
@@ -320,7 +338,7 @@ static int i8xx_tco_ioctl (struct inode *inode, struct file *file, | |||
320 | return -EFAULT; | 338 | return -EFAULT; |
321 | 339 | ||
322 | if (tco_timer_set_heartbeat(new_heartbeat)) | 340 | if (tco_timer_set_heartbeat(new_heartbeat)) |
323 | return -EINVAL; | 341 | return -EINVAL; |
324 | 342 | ||
325 | tco_timer_keepalive (); | 343 | tco_timer_keepalive (); |
326 | /* Fall */ | 344 | /* Fall */ |
@@ -329,6 +347,14 @@ static int i8xx_tco_ioctl (struct inode *inode, struct file *file, | |||
329 | case WDIOC_GETTIMEOUT: | 347 | case WDIOC_GETTIMEOUT: |
330 | return put_user(heartbeat, p); | 348 | return put_user(heartbeat, p); |
331 | 349 | ||
350 | case WDIOC_GETTIMELEFT: | ||
351 | { | ||
352 | if (tco_timer_get_timeleft(&time_left)) | ||
353 | return -EINVAL; | ||
354 | |||
355 | return put_user(time_left, p); | ||
356 | } | ||
357 | |||
332 | default: | 358 | default: |
333 | return -ENOIOCTLCMD; | 359 | return -ENOIOCTLCMD; |
334 | } | 360 | } |
diff --git a/drivers/char/watchdog/pcwd_pci.c b/drivers/char/watchdog/pcwd_pci.c index 2451edbefece..1f40ecefbf72 100644 --- a/drivers/char/watchdog/pcwd_pci.c +++ b/drivers/char/watchdog/pcwd_pci.c | |||
@@ -21,7 +21,7 @@ | |||
21 | */ | 21 | */ |
22 | 22 | ||
23 | /* | 23 | /* |
24 | * A bells and whistles driver is available from: | 24 | * A bells and whistles driver is available from: |
25 | * http://www.kernel.org/pub/linux/kernel/people/wim/pcwd/pcwd_pci/ | 25 | * http://www.kernel.org/pub/linux/kernel/people/wim/pcwd/pcwd_pci/ |
26 | * | 26 | * |
27 | * More info available at http://www.berkprod.com/ or http://www.pcwatchdog.com/ | 27 | * More info available at http://www.berkprod.com/ or http://www.pcwatchdog.com/ |
@@ -390,6 +390,24 @@ static int pcipcwd_get_temperature(int *temperature) | |||
390 | return 0; | 390 | return 0; |
391 | } | 391 | } |
392 | 392 | ||
393 | static int pcipcwd_get_timeleft(int *time_left) | ||
394 | { | ||
395 | int msb; | ||
396 | int lsb; | ||
397 | |||
398 | /* Read the time that's left before rebooting */ | ||
399 | /* Note: if the board is not yet armed then we will read 0xFFFF */ | ||
400 | send_command(CMD_READ_WATCHDOG_TIMEOUT, &msb, &lsb); | ||
401 | |||
402 | *time_left = (msb << 8) + lsb; | ||
403 | |||
404 | if (debug >= VERBOSE) | ||
405 | printk(KERN_DEBUG PFX "Time left before next reboot: %d\n", | ||
406 | *time_left); | ||
407 | |||
408 | return 0; | ||
409 | } | ||
410 | |||
393 | /* | 411 | /* |
394 | * /dev/watchdog handling | 412 | * /dev/watchdog handling |
395 | */ | 413 | */ |
@@ -512,6 +530,16 @@ static int pcipcwd_ioctl(struct inode *inode, struct file *file, | |||
512 | case WDIOC_GETTIMEOUT: | 530 | case WDIOC_GETTIMEOUT: |
513 | return put_user(heartbeat, p); | 531 | return put_user(heartbeat, p); |
514 | 532 | ||
533 | case WDIOC_GETTIMELEFT: | ||
534 | { | ||
535 | int time_left; | ||
536 | |||
537 | if (pcipcwd_get_timeleft(&time_left)) | ||
538 | return -EFAULT; | ||
539 | |||
540 | return put_user(time_left, p); | ||
541 | } | ||
542 | |||
515 | default: | 543 | default: |
516 | return -ENOIOCTLCMD; | 544 | return -ENOIOCTLCMD; |
517 | } | 545 | } |
diff --git a/drivers/char/watchdog/pcwd_usb.c b/drivers/char/watchdog/pcwd_usb.c index 3fdfda9324fa..0d072bed501d 100644 --- a/drivers/char/watchdog/pcwd_usb.c +++ b/drivers/char/watchdog/pcwd_usb.c | |||
@@ -317,6 +317,19 @@ static int usb_pcwd_get_temperature(struct usb_pcwd_private *usb_pcwd, int *temp | |||
317 | return 0; | 317 | return 0; |
318 | } | 318 | } |
319 | 319 | ||
320 | static int usb_pcwd_get_timeleft(struct usb_pcwd_private *usb_pcwd, int *time_left) | ||
321 | { | ||
322 | unsigned char msb, lsb; | ||
323 | |||
324 | /* Read the time that's left before rebooting */ | ||
325 | /* Note: if the board is not yet armed then we will read 0xFFFF */ | ||
326 | usb_pcwd_send_command(usb_pcwd, CMD_READ_WATCHDOG_TIMEOUT, &msb, &lsb); | ||
327 | |||
328 | *time_left = (msb << 8) + lsb; | ||
329 | |||
330 | return 0; | ||
331 | } | ||
332 | |||
320 | /* | 333 | /* |
321 | * /dev/watchdog handling | 334 | * /dev/watchdog handling |
322 | */ | 335 | */ |
@@ -422,6 +435,16 @@ static int usb_pcwd_ioctl(struct inode *inode, struct file *file, | |||
422 | case WDIOC_GETTIMEOUT: | 435 | case WDIOC_GETTIMEOUT: |
423 | return put_user(heartbeat, p); | 436 | return put_user(heartbeat, p); |
424 | 437 | ||
438 | case WDIOC_GETTIMELEFT: | ||
439 | { | ||
440 | int time_left; | ||
441 | |||
442 | if (usb_pcwd_get_timeleft(usb_pcwd_device, &time_left)) | ||
443 | return -EFAULT; | ||
444 | |||
445 | return put_user(time_left, p); | ||
446 | } | ||
447 | |||
425 | default: | 448 | default: |
426 | return -ENOIOCTLCMD; | 449 | return -ENOIOCTLCMD; |
427 | } | 450 | } |
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index 44d1eca83a72..35e0b9ceecf7 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c | |||
@@ -1497,6 +1497,7 @@ int cpufreq_update_policy(unsigned int cpu) | |||
1497 | } | 1497 | } |
1498 | EXPORT_SYMBOL(cpufreq_update_policy); | 1498 | EXPORT_SYMBOL(cpufreq_update_policy); |
1499 | 1499 | ||
1500 | #ifdef CONFIG_HOTPLUG_CPU | ||
1500 | static int cpufreq_cpu_callback(struct notifier_block *nfb, | 1501 | static int cpufreq_cpu_callback(struct notifier_block *nfb, |
1501 | unsigned long action, void *hcpu) | 1502 | unsigned long action, void *hcpu) |
1502 | { | 1503 | { |
@@ -1532,10 +1533,11 @@ static int cpufreq_cpu_callback(struct notifier_block *nfb, | |||
1532 | return NOTIFY_OK; | 1533 | return NOTIFY_OK; |
1533 | } | 1534 | } |
1534 | 1535 | ||
1535 | static struct notifier_block cpufreq_cpu_notifier = | 1536 | static struct notifier_block __cpuinitdata cpufreq_cpu_notifier = |
1536 | { | 1537 | { |
1537 | .notifier_call = cpufreq_cpu_callback, | 1538 | .notifier_call = cpufreq_cpu_callback, |
1538 | }; | 1539 | }; |
1540 | #endif /* CONFIG_HOTPLUG_CPU */ | ||
1539 | 1541 | ||
1540 | /********************************************************************* | 1542 | /********************************************************************* |
1541 | * REGISTER / UNREGISTER CPUFREQ DRIVER * | 1543 | * REGISTER / UNREGISTER CPUFREQ DRIVER * |
@@ -1596,7 +1598,7 @@ int cpufreq_register_driver(struct cpufreq_driver *driver_data) | |||
1596 | } | 1598 | } |
1597 | 1599 | ||
1598 | if (!ret) { | 1600 | if (!ret) { |
1599 | register_cpu_notifier(&cpufreq_cpu_notifier); | 1601 | register_hotcpu_notifier(&cpufreq_cpu_notifier); |
1600 | dprintk("driver %s up and running\n", driver_data->name); | 1602 | dprintk("driver %s up and running\n", driver_data->name); |
1601 | cpufreq_debug_enable_ratelimit(); | 1603 | cpufreq_debug_enable_ratelimit(); |
1602 | } | 1604 | } |
@@ -1628,7 +1630,7 @@ int cpufreq_unregister_driver(struct cpufreq_driver *driver) | |||
1628 | dprintk("unregistering driver %s\n", driver->name); | 1630 | dprintk("unregistering driver %s\n", driver->name); |
1629 | 1631 | ||
1630 | sysdev_driver_unregister(&cpu_sysdev_class, &cpufreq_sysdev_driver); | 1632 | sysdev_driver_unregister(&cpu_sysdev_class, &cpufreq_sysdev_driver); |
1631 | unregister_cpu_notifier(&cpufreq_cpu_notifier); | 1633 | unregister_hotcpu_notifier(&cpufreq_cpu_notifier); |
1632 | 1634 | ||
1633 | spin_lock_irqsave(&cpufreq_driver_lock, flags); | 1635 | spin_lock_irqsave(&cpufreq_driver_lock, flags); |
1634 | cpufreq_driver = NULL; | 1636 | cpufreq_driver = NULL; |
diff --git a/drivers/cpufreq/cpufreq_stats.c b/drivers/cpufreq/cpufreq_stats.c index c576c0b3f452..145061b8472a 100644 --- a/drivers/cpufreq/cpufreq_stats.c +++ b/drivers/cpufreq/cpufreq_stats.c | |||
@@ -350,7 +350,7 @@ __init cpufreq_stats_init(void) | |||
350 | return ret; | 350 | return ret; |
351 | } | 351 | } |
352 | 352 | ||
353 | register_cpu_notifier(&cpufreq_stat_cpu_notifier); | 353 | register_hotcpu_notifier(&cpufreq_stat_cpu_notifier); |
354 | lock_cpu_hotplug(); | 354 | lock_cpu_hotplug(); |
355 | for_each_online_cpu(cpu) { | 355 | for_each_online_cpu(cpu) { |
356 | cpufreq_stat_cpu_callback(&cpufreq_stat_cpu_notifier, CPU_ONLINE, | 356 | cpufreq_stat_cpu_callback(&cpufreq_stat_cpu_notifier, CPU_ONLINE, |
@@ -368,7 +368,7 @@ __exit cpufreq_stats_exit(void) | |||
368 | CPUFREQ_POLICY_NOTIFIER); | 368 | CPUFREQ_POLICY_NOTIFIER); |
369 | cpufreq_unregister_notifier(¬ifier_trans_block, | 369 | cpufreq_unregister_notifier(¬ifier_trans_block, |
370 | CPUFREQ_TRANSITION_NOTIFIER); | 370 | CPUFREQ_TRANSITION_NOTIFIER); |
371 | unregister_cpu_notifier(&cpufreq_stat_cpu_notifier); | 371 | unregister_hotcpu_notifier(&cpufreq_stat_cpu_notifier); |
372 | lock_cpu_hotplug(); | 372 | lock_cpu_hotplug(); |
373 | for_each_online_cpu(cpu) { | 373 | for_each_online_cpu(cpu) { |
374 | cpufreq_stat_cpu_callback(&cpufreq_stat_cpu_notifier, CPU_DEAD, | 374 | cpufreq_stat_cpu_callback(&cpufreq_stat_cpu_notifier, CPU_DEAD, |
diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c index 3e0d04d5a800..8b46ef7d9ff8 100644 --- a/drivers/i2c/busses/i2c-i801.c +++ b/drivers/i2c/busses/i2c-i801.c | |||
@@ -488,7 +488,7 @@ static int __devinit i801_probe(struct pci_dev *dev, const struct pci_device_id | |||
488 | dev_err(&dev->dev, "SMBus base address uninitialized, " | 488 | dev_err(&dev->dev, "SMBus base address uninitialized, " |
489 | "upgrade BIOS\n"); | 489 | "upgrade BIOS\n"); |
490 | err = -ENODEV; | 490 | err = -ENODEV; |
491 | goto exit_disable; | 491 | goto exit; |
492 | } | 492 | } |
493 | 493 | ||
494 | err = pci_request_region(dev, SMBBAR, i801_driver.name); | 494 | err = pci_request_region(dev, SMBBAR, i801_driver.name); |
@@ -496,7 +496,7 @@ static int __devinit i801_probe(struct pci_dev *dev, const struct pci_device_id | |||
496 | dev_err(&dev->dev, "Failed to request SMBus region " | 496 | dev_err(&dev->dev, "Failed to request SMBus region " |
497 | "0x%lx-0x%lx\n", i801_smba, | 497 | "0x%lx-0x%lx\n", i801_smba, |
498 | pci_resource_end(dev, SMBBAR)); | 498 | pci_resource_end(dev, SMBBAR)); |
499 | goto exit_disable; | 499 | goto exit; |
500 | } | 500 | } |
501 | 501 | ||
502 | pci_read_config_byte(I801_dev, SMBHSTCFG, &temp); | 502 | pci_read_config_byte(I801_dev, SMBHSTCFG, &temp); |
@@ -520,11 +520,12 @@ static int __devinit i801_probe(struct pci_dev *dev, const struct pci_device_id | |||
520 | err = i2c_add_adapter(&i801_adapter); | 520 | err = i2c_add_adapter(&i801_adapter); |
521 | if (err) { | 521 | if (err) { |
522 | dev_err(&dev->dev, "Failed to add SMBus adapter\n"); | 522 | dev_err(&dev->dev, "Failed to add SMBus adapter\n"); |
523 | goto exit_disable; | 523 | goto exit_release; |
524 | } | 524 | } |
525 | return 0; | ||
525 | 526 | ||
526 | exit_disable: | 527 | exit_release: |
527 | pci_disable_device(dev); | 528 | pci_release_region(dev, SMBBAR); |
528 | exit: | 529 | exit: |
529 | return err; | 530 | return err; |
530 | } | 531 | } |
@@ -533,7 +534,10 @@ static void __devexit i801_remove(struct pci_dev *dev) | |||
533 | { | 534 | { |
534 | i2c_del_adapter(&i801_adapter); | 535 | i2c_del_adapter(&i801_adapter); |
535 | pci_release_region(dev, SMBBAR); | 536 | pci_release_region(dev, SMBBAR); |
536 | pci_disable_device(dev); | 537 | /* |
538 | * do not call pci_disable_device(dev) since it can cause hard hangs on | ||
539 | * some systems during power-off (eg. Fujitsu-Siemens Lifebook E8010) | ||
540 | */ | ||
537 | } | 541 | } |
538 | 542 | ||
539 | static struct pci_driver i801_driver = { | 543 | static struct pci_driver i801_driver = { |
diff --git a/drivers/ide/Kconfig b/drivers/ide/Kconfig index d633081fa4c5..d1266fe2d1ab 100644 --- a/drivers/ide/Kconfig +++ b/drivers/ide/Kconfig | |||
@@ -774,11 +774,18 @@ config BLK_DEV_IDEDMA_PMAC | |||
774 | performance. | 774 | performance. |
775 | 775 | ||
776 | config BLK_DEV_IDE_PMAC_BLINK | 776 | config BLK_DEV_IDE_PMAC_BLINK |
777 | bool "Blink laptop LED on drive activity" | 777 | bool "Blink laptop LED on drive activity (DEPRECATED)" |
778 | depends on BLK_DEV_IDE_PMAC && ADB_PMU | 778 | depends on BLK_DEV_IDE_PMAC && ADB_PMU |
779 | select ADB_PMU_LED | ||
780 | select LEDS_TRIGGERS | ||
781 | select LEDS_TRIGGER_IDE_DISK | ||
779 | help | 782 | help |
780 | This option enables the use of the sleep LED as a hard drive | 783 | This option enables the use of the sleep LED as a hard drive |
781 | activity LED. | 784 | activity LED. |
785 | This option is deprecated, it only selects ADB_PMU_LED and | ||
786 | LEDS_TRIGGER_IDE_DISK and changes the code in the new led class | ||
787 | device to default to the ide-disk trigger (which should be set | ||
788 | from userspace via sysfs). | ||
782 | 789 | ||
783 | config BLK_DEV_IDE_SWARM | 790 | config BLK_DEV_IDE_SWARM |
784 | tristate "IDE for Sibyte evaluation boards" | 791 | tristate "IDE for Sibyte evaluation boards" |
diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c index 99fa42402e71..bfafd4846a08 100644 --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c | |||
@@ -3527,8 +3527,6 @@ static int ide_cd_probe(ide_drive_t *drive) | |||
3527 | drive->driver_data = info; | 3527 | drive->driver_data = info; |
3528 | 3528 | ||
3529 | g->minors = 1; | 3529 | g->minors = 1; |
3530 | snprintf(g->devfs_name, sizeof(g->devfs_name), | ||
3531 | "%s/cd", drive->devfs_name); | ||
3532 | g->driverfs_dev = &drive->gendev; | 3530 | g->driverfs_dev = &drive->gendev; |
3533 | g->flags = GENHD_FL_CD | GENHD_FL_REMOVABLE; | 3531 | g->flags = GENHD_FL_CD | GENHD_FL_REMOVABLE; |
3534 | if (ide_cdrom_setup(drive)) { | 3532 | if (ide_cdrom_setup(drive)) { |
diff --git a/drivers/ide/ide-disk.c b/drivers/ide/ide-disk.c index f033d732f387..d0227c39ced1 100644 --- a/drivers/ide/ide-disk.c +++ b/drivers/ide/ide-disk.c | |||
@@ -1018,7 +1018,6 @@ static void ide_disk_release(struct kref *kref) | |||
1018 | struct gendisk *g = idkp->disk; | 1018 | struct gendisk *g = idkp->disk; |
1019 | 1019 | ||
1020 | drive->driver_data = NULL; | 1020 | drive->driver_data = NULL; |
1021 | drive->devfs_name[0] = '\0'; | ||
1022 | g->private_data = NULL; | 1021 | g->private_data = NULL; |
1023 | put_disk(g); | 1022 | put_disk(g); |
1024 | kfree(idkp); | 1023 | kfree(idkp); |
@@ -1222,7 +1221,6 @@ static int ide_disk_probe(ide_drive_t *drive) | |||
1222 | drive->attach = 1; | 1221 | drive->attach = 1; |
1223 | 1222 | ||
1224 | g->minors = 1 << PARTN_BITS; | 1223 | g->minors = 1 << PARTN_BITS; |
1225 | strcpy(g->devfs_name, drive->devfs_name); | ||
1226 | g->driverfs_dev = &drive->gendev; | 1224 | g->driverfs_dev = &drive->gendev; |
1227 | g->flags = drive->removable ? GENHD_FL_REMOVABLE : 0; | 1225 | g->flags = drive->removable ? GENHD_FL_REMOVABLE : 0; |
1228 | set_capacity(g, idedisk_capacity(drive)); | 1226 | set_capacity(g, idedisk_capacity(drive)); |
diff --git a/drivers/ide/ide-floppy.c b/drivers/ide/ide-floppy.c index 4656587aa2f7..68628327c0f5 100644 --- a/drivers/ide/ide-floppy.c +++ b/drivers/ide/ide-floppy.c | |||
@@ -2176,7 +2176,6 @@ static int ide_floppy_probe(ide_drive_t *drive) | |||
2176 | 2176 | ||
2177 | g->minors = 1 << PARTN_BITS; | 2177 | g->minors = 1 << PARTN_BITS; |
2178 | g->driverfs_dev = &drive->gendev; | 2178 | g->driverfs_dev = &drive->gendev; |
2179 | strcpy(g->devfs_name, drive->devfs_name); | ||
2180 | g->flags = drive->removable ? GENHD_FL_REMOVABLE : 0; | 2179 | g->flags = drive->removable ? GENHD_FL_REMOVABLE : 0; |
2181 | g->fops = &idefloppy_ops; | 2180 | g->fops = &idefloppy_ops; |
2182 | drive->attach = 1; | 2181 | drive->attach = 1; |
diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c index 935cb2583770..26ceab1e90bb 100644 --- a/drivers/ide/ide-io.c +++ b/drivers/ide/ide-io.c | |||
@@ -505,7 +505,7 @@ static ide_startstop_t ide_ata_error(ide_drive_t *drive, struct request *rq, u8 | |||
505 | } | 505 | } |
506 | } | 506 | } |
507 | 507 | ||
508 | if ((stat & DRQ_STAT) && rq_data_dir(rq) == READ) | 508 | if ((stat & DRQ_STAT) && rq_data_dir(rq) == READ && hwif->err_stops_fifo == 0) |
509 | try_to_flush_leftover_data(drive); | 509 | try_to_flush_leftover_data(drive); |
510 | 510 | ||
511 | if (hwif->INB(IDE_STATUS_REG) & (BUSY_STAT|DRQ_STAT)) | 511 | if (hwif->INB(IDE_STATUS_REG) & (BUSY_STAT|DRQ_STAT)) |
diff --git a/drivers/ide/ide-iops.c b/drivers/ide/ide-iops.c index 97a49e77a8f1..32117f0ec5c0 100644 --- a/drivers/ide/ide-iops.c +++ b/drivers/ide/ide-iops.c | |||
@@ -597,6 +597,10 @@ u8 eighty_ninty_three (ide_drive_t *drive) | |||
597 | { | 597 | { |
598 | if(HWIF(drive)->udma_four == 0) | 598 | if(HWIF(drive)->udma_four == 0) |
599 | return 0; | 599 | return 0; |
600 | |||
601 | /* Check for SATA but only if we are ATA5 or higher */ | ||
602 | if (drive->id->hw_config == 0 && (drive->id->major_rev_num & 0x7FE0)) | ||
603 | return 1; | ||
600 | if (!(drive->id->hw_config & 0x6000)) | 604 | if (!(drive->id->hw_config & 0x6000)) |
601 | return 0; | 605 | return 0; |
602 | #ifndef CONFIG_IDEDMA_IVB | 606 | #ifndef CONFIG_IDEDMA_IVB |
diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c index 9ebf8ae2a5e3..0d5038a28560 100644 --- a/drivers/ide/ide-probe.c +++ b/drivers/ide/ide-probe.c | |||
@@ -47,7 +47,6 @@ | |||
47 | #include <linux/slab.h> | 47 | #include <linux/slab.h> |
48 | #include <linux/delay.h> | 48 | #include <linux/delay.h> |
49 | #include <linux/ide.h> | 49 | #include <linux/ide.h> |
50 | #include <linux/devfs_fs_kernel.h> | ||
51 | #include <linux/spinlock.h> | 50 | #include <linux/spinlock.h> |
52 | #include <linux/kmod.h> | 51 | #include <linux/kmod.h> |
53 | #include <linux/pci.h> | 52 | #include <linux/pci.h> |
@@ -1279,10 +1278,6 @@ static void drive_release_dev (struct device *dev) | |||
1279 | ide_drive_t *drive = container_of(dev, ide_drive_t, gendev); | 1278 | ide_drive_t *drive = container_of(dev, ide_drive_t, gendev); |
1280 | 1279 | ||
1281 | spin_lock_irq(&ide_lock); | 1280 | spin_lock_irq(&ide_lock); |
1282 | if (drive->devfs_name[0] != '\0') { | ||
1283 | devfs_remove(drive->devfs_name); | ||
1284 | drive->devfs_name[0] = '\0'; | ||
1285 | } | ||
1286 | ide_remove_drive_from_hwgroup(drive); | 1281 | ide_remove_drive_from_hwgroup(drive); |
1287 | kfree(drive->id); | 1282 | kfree(drive->id); |
1288 | drive->id = NULL; | 1283 | drive->id = NULL; |
@@ -1316,12 +1311,6 @@ static void init_gendisk (ide_hwif_t *hwif) | |||
1316 | drive->gendev.bus = &ide_bus_type; | 1311 | drive->gendev.bus = &ide_bus_type; |
1317 | drive->gendev.driver_data = drive; | 1312 | drive->gendev.driver_data = drive; |
1318 | drive->gendev.release = drive_release_dev; | 1313 | drive->gendev.release = drive_release_dev; |
1319 | if (drive->present) { | ||
1320 | sprintf(drive->devfs_name, "ide/host%d/bus%d/target%d/lun%d", | ||
1321 | (hwif->channel && hwif->mate) ? | ||
1322 | hwif->mate->index : hwif->index, | ||
1323 | hwif->channel, unit, drive->lun); | ||
1324 | } | ||
1325 | } | 1314 | } |
1326 | blk_register_region(MKDEV(hwif->major, 0), MAX_DRIVES << PARTN_BITS, | 1315 | blk_register_region(MKDEV(hwif->major, 0), MAX_DRIVES << PARTN_BITS, |
1327 | THIS_MODULE, ata_probe, ata_lock, hwif); | 1316 | THIS_MODULE, ata_probe, ata_lock, hwif); |
diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c index 09f3a7dab28a..4b91101e12b7 100644 --- a/drivers/ide/ide-tape.c +++ b/drivers/ide/ide-tape.c | |||
@@ -435,7 +435,6 @@ | |||
435 | #include <linux/interrupt.h> | 435 | #include <linux/interrupt.h> |
436 | #include <linux/jiffies.h> | 436 | #include <linux/jiffies.h> |
437 | #include <linux/major.h> | 437 | #include <linux/major.h> |
438 | #include <linux/devfs_fs_kernel.h> | ||
439 | #include <linux/errno.h> | 438 | #include <linux/errno.h> |
440 | #include <linux/genhd.h> | 439 | #include <linux/genhd.h> |
441 | #include <linux/slab.h> | 440 | #include <linux/slab.h> |
@@ -4726,9 +4725,6 @@ static void ide_tape_release(struct kref *kref) | |||
4726 | MKDEV(IDETAPE_MAJOR, tape->minor)); | 4725 | MKDEV(IDETAPE_MAJOR, tape->minor)); |
4727 | class_device_destroy(idetape_sysfs_class, | 4726 | class_device_destroy(idetape_sysfs_class, |
4728 | MKDEV(IDETAPE_MAJOR, tape->minor + 128)); | 4727 | MKDEV(IDETAPE_MAJOR, tape->minor + 128)); |
4729 | devfs_remove("%s/mt", drive->devfs_name); | ||
4730 | devfs_remove("%s/mtn", drive->devfs_name); | ||
4731 | devfs_unregister_tape(g->number); | ||
4732 | idetape_devs[tape->minor] = NULL; | 4728 | idetape_devs[tape->minor] = NULL; |
4733 | g->private_data = NULL; | 4729 | g->private_data = NULL; |
4734 | put_disk(g); | 4730 | put_disk(g); |
@@ -4902,14 +4898,6 @@ static int ide_tape_probe(ide_drive_t *drive) | |||
4902 | class_device_create(idetape_sysfs_class, NULL, | 4898 | class_device_create(idetape_sysfs_class, NULL, |
4903 | MKDEV(IDETAPE_MAJOR, minor + 128), &drive->gendev, "n%s", tape->name); | 4899 | MKDEV(IDETAPE_MAJOR, minor + 128), &drive->gendev, "n%s", tape->name); |
4904 | 4900 | ||
4905 | devfs_mk_cdev(MKDEV(HWIF(drive)->major, minor), | ||
4906 | S_IFCHR | S_IRUGO | S_IWUGO, | ||
4907 | "%s/mt", drive->devfs_name); | ||
4908 | devfs_mk_cdev(MKDEV(HWIF(drive)->major, minor + 128), | ||
4909 | S_IFCHR | S_IRUGO | S_IWUGO, | ||
4910 | "%s/mtn", drive->devfs_name); | ||
4911 | |||
4912 | g->number = devfs_register_tape(drive->devfs_name); | ||
4913 | g->fops = &idetape_block_ops; | 4901 | g->fops = &idetape_block_ops; |
4914 | ide_register_region(g); | 4902 | ide_register_region(g); |
4915 | 4903 | ||
diff --git a/drivers/ide/ide.c b/drivers/ide/ide.c index 59fe358048b3..1cdf44205162 100644 --- a/drivers/ide/ide.c +++ b/drivers/ide/ide.c | |||
@@ -147,7 +147,6 @@ | |||
147 | #include <linux/pci.h> | 147 | #include <linux/pci.h> |
148 | #include <linux/delay.h> | 148 | #include <linux/delay.h> |
149 | #include <linux/ide.h> | 149 | #include <linux/ide.h> |
150 | #include <linux/devfs_fs_kernel.h> | ||
151 | #include <linux/completion.h> | 150 | #include <linux/completion.h> |
152 | #include <linux/reboot.h> | 151 | #include <linux/reboot.h> |
153 | #include <linux/cdrom.h> | 152 | #include <linux/cdrom.h> |
@@ -592,13 +591,8 @@ void ide_unregister(unsigned int index) | |||
592 | goto abort; | 591 | goto abort; |
593 | for (unit = 0; unit < MAX_DRIVES; ++unit) { | 592 | for (unit = 0; unit < MAX_DRIVES; ++unit) { |
594 | drive = &hwif->drives[unit]; | 593 | drive = &hwif->drives[unit]; |
595 | if (!drive->present) { | 594 | if (!drive->present) |
596 | if (drive->devfs_name[0] != '\0') { | ||
597 | devfs_remove(drive->devfs_name); | ||
598 | drive->devfs_name[0] = '\0'; | ||
599 | } | ||
600 | continue; | 595 | continue; |
601 | } | ||
602 | spin_unlock_irq(&ide_lock); | 596 | spin_unlock_irq(&ide_lock); |
603 | device_unregister(&drive->gendev); | 597 | device_unregister(&drive->gendev); |
604 | wait_for_completion(&drive->gendev_rel_comp); | 598 | wait_for_completion(&drive->gendev_rel_comp); |
@@ -1996,7 +1990,6 @@ EXPORT_SYMBOL_GPL(ide_bus_type); | |||
1996 | static int __init ide_init(void) | 1990 | static int __init ide_init(void) |
1997 | { | 1991 | { |
1998 | printk(KERN_INFO "Uniform Multi-Platform E-IDE driver " REVISION "\n"); | 1992 | printk(KERN_INFO "Uniform Multi-Platform E-IDE driver " REVISION "\n"); |
1999 | devfs_mk_dir("ide"); | ||
2000 | system_bus_speed = ide_system_bus_speed(); | 1993 | system_bus_speed = ide_system_bus_speed(); |
2001 | 1994 | ||
2002 | bus_register(&ide_bus_type); | 1995 | bus_register(&ide_bus_type); |
@@ -2074,7 +2067,6 @@ void cleanup_module (void) | |||
2074 | #ifdef CONFIG_PROC_FS | 2067 | #ifdef CONFIG_PROC_FS |
2075 | proc_ide_destroy(); | 2068 | proc_ide_destroy(); |
2076 | #endif | 2069 | #endif |
2077 | devfs_remove("ide"); | ||
2078 | 2070 | ||
2079 | bus_unregister(&ide_bus_type); | 2071 | bus_unregister(&ide_bus_type); |
2080 | } | 2072 | } |
diff --git a/drivers/ide/pci/aec62xx.c b/drivers/ide/pci/aec62xx.c index c743e68c33aa..3edd7060510f 100644 --- a/drivers/ide/pci/aec62xx.c +++ b/drivers/ide/pci/aec62xx.c | |||
@@ -22,7 +22,7 @@ struct chipset_bus_clock_list_entry { | |||
22 | u8 ultra_settings; | 22 | u8 ultra_settings; |
23 | }; | 23 | }; |
24 | 24 | ||
25 | static struct chipset_bus_clock_list_entry aec6xxx_33_base [] = { | 25 | static const struct chipset_bus_clock_list_entry aec6xxx_33_base [] = { |
26 | { XFER_UDMA_6, 0x31, 0x07 }, | 26 | { XFER_UDMA_6, 0x31, 0x07 }, |
27 | { XFER_UDMA_5, 0x31, 0x06 }, | 27 | { XFER_UDMA_5, 0x31, 0x06 }, |
28 | { XFER_UDMA_4, 0x31, 0x05 }, | 28 | { XFER_UDMA_4, 0x31, 0x05 }, |
@@ -42,7 +42,7 @@ static struct chipset_bus_clock_list_entry aec6xxx_33_base [] = { | |||
42 | { 0, 0x00, 0x00 } | 42 | { 0, 0x00, 0x00 } |
43 | }; | 43 | }; |
44 | 44 | ||
45 | static struct chipset_bus_clock_list_entry aec6xxx_34_base [] = { | 45 | static const struct chipset_bus_clock_list_entry aec6xxx_34_base [] = { |
46 | { XFER_UDMA_6, 0x41, 0x06 }, | 46 | { XFER_UDMA_6, 0x41, 0x06 }, |
47 | { XFER_UDMA_5, 0x41, 0x05 }, | 47 | { XFER_UDMA_5, 0x41, 0x05 }, |
48 | { XFER_UDMA_4, 0x41, 0x04 }, | 48 | { XFER_UDMA_4, 0x41, 0x04 }, |
@@ -254,7 +254,8 @@ static unsigned int __devinit init_chipset_aec62xx(struct pci_dev *dev, const ch | |||
254 | 254 | ||
255 | if (dev->resource[PCI_ROM_RESOURCE].start) { | 255 | if (dev->resource[PCI_ROM_RESOURCE].start) { |
256 | pci_write_config_dword(dev, PCI_ROM_ADDRESS, dev->resource[PCI_ROM_RESOURCE].start | PCI_ROM_ADDRESS_ENABLE); | 256 | pci_write_config_dword(dev, PCI_ROM_ADDRESS, dev->resource[PCI_ROM_RESOURCE].start | PCI_ROM_ADDRESS_ENABLE); |
257 | printk(KERN_INFO "%s: ROM enabled at 0x%08lx\n", name, dev->resource[PCI_ROM_RESOURCE].start); | 257 | printk(KERN_INFO "%s: ROM enabled at 0x%08lx\n", name, |
258 | (unsigned long)dev->resource[PCI_ROM_RESOURCE].start); | ||
258 | } | 259 | } |
259 | 260 | ||
260 | if (bus_speed <= 33) | 261 | if (bus_speed <= 33) |
@@ -425,12 +426,12 @@ static int __devinit aec62xx_init_one(struct pci_dev *dev, const struct pci_devi | |||
425 | return d->init_setup(dev, d); | 426 | return d->init_setup(dev, d); |
426 | } | 427 | } |
427 | 428 | ||
428 | static struct pci_device_id aec62xx_pci_tbl[] = { | 429 | static const struct pci_device_id aec62xx_pci_tbl[] = { |
429 | { PCI_VENDOR_ID_ARTOP, PCI_DEVICE_ID_ARTOP_ATP850UF, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, | 430 | { PCI_DEVICE(PCI_VENDOR_ID_ARTOP, PCI_DEVICE_ID_ARTOP_ATP850UF), 0 }, |
430 | { PCI_VENDOR_ID_ARTOP, PCI_DEVICE_ID_ARTOP_ATP860, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1 }, | 431 | { PCI_DEVICE(PCI_VENDOR_ID_ARTOP, PCI_DEVICE_ID_ARTOP_ATP860), 1 }, |
431 | { PCI_VENDOR_ID_ARTOP, PCI_DEVICE_ID_ARTOP_ATP860R, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 2 }, | 432 | { PCI_DEVICE(PCI_VENDOR_ID_ARTOP, PCI_DEVICE_ID_ARTOP_ATP860R), 2 }, |
432 | { PCI_VENDOR_ID_ARTOP, PCI_DEVICE_ID_ARTOP_ATP865, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 3 }, | 433 | { PCI_DEVICE(PCI_VENDOR_ID_ARTOP, PCI_DEVICE_ID_ARTOP_ATP865), 3 }, |
433 | { PCI_VENDOR_ID_ARTOP, PCI_DEVICE_ID_ARTOP_ATP865R, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 4 }, | 434 | { PCI_DEVICE(PCI_VENDOR_ID_ARTOP, PCI_DEVICE_ID_ARTOP_ATP865R), 4 }, |
434 | { 0, }, | 435 | { 0, }, |
435 | }; | 436 | }; |
436 | MODULE_DEVICE_TABLE(pci, aec62xx_pci_tbl); | 437 | MODULE_DEVICE_TABLE(pci, aec62xx_pci_tbl); |
diff --git a/drivers/ide/pci/amd74xx.c b/drivers/ide/pci/amd74xx.c index 6e9dbf4d8077..85007cb12c52 100644 --- a/drivers/ide/pci/amd74xx.c +++ b/drivers/ide/pci/amd74xx.c | |||
@@ -75,6 +75,7 @@ static struct amd_ide_chip { | |||
75 | { PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_IDE, 0x50, AMD_UDMA_133 }, | 75 | { PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_IDE, 0x50, AMD_UDMA_133 }, |
76 | { PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_IDE, 0x50, AMD_UDMA_133 }, | 76 | { PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_IDE, 0x50, AMD_UDMA_133 }, |
77 | { PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_IDE, 0x50, AMD_UDMA_133 }, | 77 | { PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_IDE, 0x50, AMD_UDMA_133 }, |
78 | { PCI_DEVICE_ID_NVIDIA_NFORCE_MCP65_IDE, 0x50, AMD_UDMA_133 }, | ||
78 | { PCI_DEVICE_ID_AMD_CS5536_IDE, 0x40, AMD_UDMA_100 }, | 79 | { PCI_DEVICE_ID_AMD_CS5536_IDE, 0x40, AMD_UDMA_100 }, |
79 | { 0 } | 80 | { 0 } |
80 | }; | 81 | }; |
@@ -490,7 +491,8 @@ static ide_pci_device_t amd74xx_chipsets[] __devinitdata = { | |||
490 | /* 15 */ DECLARE_NV_DEV("NFORCE-MCP51"), | 491 | /* 15 */ DECLARE_NV_DEV("NFORCE-MCP51"), |
491 | /* 16 */ DECLARE_NV_DEV("NFORCE-MCP55"), | 492 | /* 16 */ DECLARE_NV_DEV("NFORCE-MCP55"), |
492 | /* 17 */ DECLARE_NV_DEV("NFORCE-MCP61"), | 493 | /* 17 */ DECLARE_NV_DEV("NFORCE-MCP61"), |
493 | /* 18 */ DECLARE_AMD_DEV("AMD5536"), | 494 | /* 18 */ DECLARE_NV_DEV("NFORCE-MCP65"), |
495 | /* 19 */ DECLARE_AMD_DEV("AMD5536"), | ||
494 | }; | 496 | }; |
495 | 497 | ||
496 | static int __devinit amd74xx_probe(struct pci_dev *dev, const struct pci_device_id *id) | 498 | static int __devinit amd74xx_probe(struct pci_dev *dev, const struct pci_device_id *id) |
@@ -528,7 +530,8 @@ static struct pci_device_id amd74xx_pci_tbl[] = { | |||
528 | { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 15 }, | 530 | { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 15 }, |
529 | { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 16 }, | 531 | { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 16 }, |
530 | { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 17 }, | 532 | { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 17 }, |
531 | { PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 18 }, | 533 | { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP65_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 18 }, |
534 | { PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 19 }, | ||
532 | { 0, }, | 535 | { 0, }, |
533 | }; | 536 | }; |
534 | MODULE_DEVICE_TABLE(pci, amd74xx_pci_tbl); | 537 | MODULE_DEVICE_TABLE(pci, amd74xx_pci_tbl); |
diff --git a/drivers/ide/pci/cmd64x.c b/drivers/ide/pci/cmd64x.c index 3d9c7afc8695..92b7b1549b16 100644 --- a/drivers/ide/pci/cmd64x.c +++ b/drivers/ide/pci/cmd64x.c | |||
@@ -190,14 +190,6 @@ static int cmd64x_get_info (char *buffer, char **addr, off_t offset, int count) | |||
190 | #endif /* defined(DISPLAY_CMD64X_TIMINGS) && defined(CONFIG_PROC_FS) */ | 190 | #endif /* defined(DISPLAY_CMD64X_TIMINGS) && defined(CONFIG_PROC_FS) */ |
191 | 191 | ||
192 | /* | 192 | /* |
193 | * Registers and masks for easy access by drive index: | ||
194 | */ | ||
195 | #if 0 | ||
196 | static u8 prefetch_regs[4] = {CNTRL, CNTRL, ARTTIM23, ARTTIM23}; | ||
197 | static u8 prefetch_masks[4] = {CNTRL_DIS_RA0, CNTRL_DIS_RA1, ARTTIM23_DIS_RA2, ARTTIM23_DIS_RA3}; | ||
198 | #endif | ||
199 | |||
200 | /* | ||
201 | * This routine writes the prepared setup/active/recovery counts | 193 | * This routine writes the prepared setup/active/recovery counts |
202 | * for a drive into the cmd646 chipset registers to active them. | 194 | * for a drive into the cmd646 chipset registers to active them. |
203 | */ | 195 | */ |
@@ -606,13 +598,6 @@ static unsigned int __devinit init_chipset_cmd64x(struct pci_dev *dev, const cha | |||
606 | pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev); | 598 | pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev); |
607 | class_rev &= 0xff; | 599 | class_rev &= 0xff; |
608 | 600 | ||
609 | #ifdef __i386__ | ||
610 | if (dev->resource[PCI_ROM_RESOURCE].start) { | ||
611 | pci_write_config_dword(dev, PCI_ROM_ADDRESS, dev->resource[PCI_ROM_RESOURCE].start | PCI_ROM_ADDRESS_ENABLE); | ||
612 | printk(KERN_INFO "%s: ROM enabled at 0x%08lx\n", name, dev->resource[PCI_ROM_RESOURCE].start); | ||
613 | } | ||
614 | #endif | ||
615 | |||
616 | switch(dev->device) { | 601 | switch(dev->device) { |
617 | case PCI_DEVICE_ID_CMD_643: | 602 | case PCI_DEVICE_ID_CMD_643: |
618 | break; | 603 | break; |
diff --git a/drivers/ide/pci/hpt34x.c b/drivers/ide/pci/hpt34x.c index be334da7a754..7da550281cf2 100644 --- a/drivers/ide/pci/hpt34x.c +++ b/drivers/ide/pci/hpt34x.c | |||
@@ -176,7 +176,7 @@ static unsigned int __devinit init_chipset_hpt34x(struct pci_dev *dev, const cha | |||
176 | pci_write_config_dword(dev, PCI_ROM_ADDRESS, | 176 | pci_write_config_dword(dev, PCI_ROM_ADDRESS, |
177 | dev->resource[PCI_ROM_RESOURCE].start | PCI_ROM_ADDRESS_ENABLE); | 177 | dev->resource[PCI_ROM_RESOURCE].start | PCI_ROM_ADDRESS_ENABLE); |
178 | printk(KERN_INFO "HPT345: ROM enabled at 0x%08lx\n", | 178 | printk(KERN_INFO "HPT345: ROM enabled at 0x%08lx\n", |
179 | dev->resource[PCI_ROM_RESOURCE].start); | 179 | (unsigned long)dev->resource[PCI_ROM_RESOURCE].start); |
180 | } | 180 | } |
181 | pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0xF0); | 181 | pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0xF0); |
182 | } else { | 182 | } else { |
diff --git a/drivers/ide/pci/pdc202xx_new.c b/drivers/ide/pci/pdc202xx_new.c index acd63173199b..5a8334d134fb 100644 --- a/drivers/ide/pci/pdc202xx_new.c +++ b/drivers/ide/pci/pdc202xx_new.c | |||
@@ -313,8 +313,8 @@ static unsigned int __devinit init_chipset_pdcnew(struct pci_dev *dev, const cha | |||
313 | if (dev->resource[PCI_ROM_RESOURCE].start) { | 313 | if (dev->resource[PCI_ROM_RESOURCE].start) { |
314 | pci_write_config_dword(dev, PCI_ROM_ADDRESS, | 314 | pci_write_config_dword(dev, PCI_ROM_ADDRESS, |
315 | dev->resource[PCI_ROM_RESOURCE].start | PCI_ROM_ADDRESS_ENABLE); | 315 | dev->resource[PCI_ROM_RESOURCE].start | PCI_ROM_ADDRESS_ENABLE); |
316 | printk(KERN_INFO "%s: ROM enabled at 0x%08lx\n", | 316 | printk(KERN_INFO "%s: ROM enabled at 0x%08lx\n", name, |
317 | name, dev->resource[PCI_ROM_RESOURCE].start); | 317 | (unsigned long)dev->resource[PCI_ROM_RESOURCE].start); |
318 | } | 318 | } |
319 | 319 | ||
320 | #ifdef CONFIG_PPC_PMAC | 320 | #ifdef CONFIG_PPC_PMAC |
@@ -338,6 +338,8 @@ static void __devinit init_hwif_pdc202new(ide_hwif_t *hwif) | |||
338 | hwif->ultra_mask = 0x7f; | 338 | hwif->ultra_mask = 0x7f; |
339 | hwif->mwdma_mask = 0x07; | 339 | hwif->mwdma_mask = 0x07; |
340 | 340 | ||
341 | hwif->err_stops_fifo = 1; | ||
342 | |||
341 | hwif->ide_dma_check = &pdcnew_config_drive_xfer_rate; | 343 | hwif->ide_dma_check = &pdcnew_config_drive_xfer_rate; |
342 | hwif->ide_dma_lostirq = &pdcnew_ide_dma_lostirq; | 344 | hwif->ide_dma_lostirq = &pdcnew_ide_dma_lostirq; |
343 | hwif->ide_dma_timeout = &pdcnew_ide_dma_timeout; | 345 | hwif->ide_dma_timeout = &pdcnew_ide_dma_timeout; |
diff --git a/drivers/ide/pci/pdc202xx_old.c b/drivers/ide/pci/pdc202xx_old.c index 22d17548ecdb..1e209d8f9437 100644 --- a/drivers/ide/pci/pdc202xx_old.c +++ b/drivers/ide/pci/pdc202xx_old.c | |||
@@ -101,31 +101,6 @@ static const char *pdc_quirk_drives[] = { | |||
101 | #define MC1 0x02 /* DMA"C" timing */ | 101 | #define MC1 0x02 /* DMA"C" timing */ |
102 | #define MC0 0x01 /* DMA"C" timing */ | 102 | #define MC0 0x01 /* DMA"C" timing */ |
103 | 103 | ||
104 | #if 0 | ||
105 | unsigned long bibma = pci_resource_start(dev, 4); | ||
106 | u8 hi = 0, lo = 0; | ||
107 | |||
108 | u8 sc1c = inb_p((u16)bibma + 0x1c); | ||
109 | u8 sc1e = inb_p((u16)bibma + 0x1e); | ||
110 | u8 sc1f = inb_p((u16)bibma + 0x1f); | ||
111 | |||
112 | p += sprintf(p, "Host Mode : %s\n", | ||
113 | (sc1f & 0x08) ? "Tri-Stated" : "Normal"); | ||
114 | p += sprintf(p, "Bus Clocking : %s\n", | ||
115 | ((sc1f & 0xC0) == 0xC0) ? "100 External" : | ||
116 | ((sc1f & 0x80) == 0x80) ? "66 External" : | ||
117 | ((sc1f & 0x40) == 0x40) ? "33 External" : "33 PCI Internal"); | ||
118 | p += sprintf(p, "IO pad select : %s mA\n", | ||
119 | ((sc1c & 0x03) == 0x03) ? "10" : | ||
120 | ((sc1c & 0x02) == 0x02) ? "8" : | ||
121 | ((sc1c & 0x01) == 0x01) ? "6" : | ||
122 | ((sc1c & 0x00) == 0x00) ? "4" : "??"); | ||
123 | hi = sc1e >> 4; | ||
124 | lo = sc1e & 0xf; | ||
125 | p += sprintf(p, "Status Polling Period : %d\n", hi); | ||
126 | p += sprintf(p, "Interrupt Check Status Polling Delay : %d\n", lo); | ||
127 | #endif | ||
128 | |||
129 | static u8 pdc202xx_ratemask (ide_drive_t *drive) | 104 | static u8 pdc202xx_ratemask (ide_drive_t *drive) |
130 | { | 105 | { |
131 | u8 mode; | 106 | u8 mode; |
@@ -505,73 +480,20 @@ static void pdc202xx_reset (ide_drive_t *drive) | |||
505 | 480 | ||
506 | pdc202xx_reset_host(hwif); | 481 | pdc202xx_reset_host(hwif); |
507 | pdc202xx_reset_host(mate); | 482 | pdc202xx_reset_host(mate); |
508 | #if 0 | ||
509 | /* | ||
510 | * FIXME: Have to kick all the drives again :-/ | ||
511 | * What a pain in the ACE! | ||
512 | */ | ||
513 | if (hwif->present) { | ||
514 | u16 hunit = 0; | ||
515 | for (hunit = 0; hunit < MAX_DRIVES; ++hunit) { | ||
516 | ide_drive_t *hdrive = &hwif->drives[hunit]; | ||
517 | if (hdrive->present) { | ||
518 | if (hwif->ide_dma_check) | ||
519 | hwif->ide_dma_check(hdrive); | ||
520 | else | ||
521 | hwif->tuneproc(hdrive, 5); | ||
522 | } | ||
523 | } | ||
524 | } | ||
525 | if (mate->present) { | ||
526 | u16 munit = 0; | ||
527 | for (munit = 0; munit < MAX_DRIVES; ++munit) { | ||
528 | ide_drive_t *mdrive = &mate->drives[munit]; | ||
529 | if (mdrive->present) { | ||
530 | if (mate->ide_dma_check) | ||
531 | mate->ide_dma_check(mdrive); | ||
532 | else | ||
533 | mate->tuneproc(mdrive, 5); | ||
534 | } | ||
535 | } | ||
536 | } | ||
537 | #else | ||
538 | hwif->tuneproc(drive, 5); | 483 | hwif->tuneproc(drive, 5); |
539 | #endif | ||
540 | } | 484 | } |
541 | 485 | ||
542 | static unsigned int __devinit init_chipset_pdc202xx(struct pci_dev *dev, const char *name) | 486 | static unsigned int __devinit init_chipset_pdc202xx(struct pci_dev *dev, |
487 | const char *name) | ||
543 | { | 488 | { |
489 | /* This doesn't appear needed */ | ||
544 | if (dev->resource[PCI_ROM_RESOURCE].start) { | 490 | if (dev->resource[PCI_ROM_RESOURCE].start) { |
545 | pci_write_config_dword(dev, PCI_ROM_ADDRESS, | 491 | pci_write_config_dword(dev, PCI_ROM_ADDRESS, |
546 | dev->resource[PCI_ROM_RESOURCE].start | PCI_ROM_ADDRESS_ENABLE); | 492 | dev->resource[PCI_ROM_RESOURCE].start | PCI_ROM_ADDRESS_ENABLE); |
547 | printk(KERN_INFO "%s: ROM enabled at 0x%08lx\n", | 493 | printk(KERN_INFO "%s: ROM enabled at 0x%08lx\n", name, |
548 | name, dev->resource[PCI_ROM_RESOURCE].start); | 494 | (unsigned long)dev->resource[PCI_ROM_RESOURCE].start); |
549 | } | ||
550 | |||
551 | /* | ||
552 | * software reset - this is required because the bios | ||
553 | * will set UDMA timing on if the hdd supports it. The | ||
554 | * user may want to turn udma off. A bug in the pdc20262 | ||
555 | * is that it cannot handle a downgrade in timing from | ||
556 | * UDMA to DMA. Disk accesses after issuing a set | ||
557 | * feature command will result in errors. A software | ||
558 | * reset leaves the timing registers intact, | ||
559 | * but resets the drives. | ||
560 | */ | ||
561 | #if 0 | ||
562 | if ((dev->device == PCI_DEVICE_ID_PROMISE_20267) || | ||
563 | (dev->device == PCI_DEVICE_ID_PROMISE_20265) || | ||
564 | (dev->device == PCI_DEVICE_ID_PROMISE_20263) || | ||
565 | (dev->device == PCI_DEVICE_ID_PROMISE_20262)) { | ||
566 | unsigned long high_16 = pci_resource_start(dev, 4); | ||
567 | byte udma_speed_flag = inb(high_16 + 0x001f); | ||
568 | outb(udma_speed_flag | 0x10, high_16 + 0x001f); | ||
569 | mdelay(100); | ||
570 | outb(udma_speed_flag & ~0x10, high_16 + 0x001f); | ||
571 | mdelay(2000); /* 2 seconds ?! */ | ||
572 | } | 495 | } |
573 | 496 | ||
574 | #endif | ||
575 | return dev->irq; | 497 | return dev->irq; |
576 | } | 498 | } |
577 | 499 | ||
@@ -599,6 +521,8 @@ static void __devinit init_hwif_pdc202xx(ide_hwif_t *hwif) | |||
599 | hwif->mwdma_mask = 0x07; | 521 | hwif->mwdma_mask = 0x07; |
600 | hwif->swdma_mask = 0x07; | 522 | hwif->swdma_mask = 0x07; |
601 | 523 | ||
524 | hwif->err_stops_fifo = 1; | ||
525 | |||
602 | hwif->ide_dma_check = &pdc202xx_config_drive_xfer_rate; | 526 | hwif->ide_dma_check = &pdc202xx_config_drive_xfer_rate; |
603 | hwif->ide_dma_lostirq = &pdc202xx_ide_dma_lostirq; | 527 | hwif->ide_dma_lostirq = &pdc202xx_ide_dma_lostirq; |
604 | hwif->ide_dma_timeout = &pdc202xx_ide_dma_timeout; | 528 | hwif->ide_dma_timeout = &pdc202xx_ide_dma_timeout; |
@@ -687,19 +611,6 @@ static int __devinit init_setup_pdc202ata4(struct pci_dev *dev, | |||
687 | "mirror fixed.\n", d->name); | 611 | "mirror fixed.\n", d->name); |
688 | } | 612 | } |
689 | } | 613 | } |
690 | |||
691 | #if 0 | ||
692 | if (dev->device == PCI_DEVICE_ID_PROMISE_20262) | ||
693 | if (e->reg && (pci_read_config_byte(dev, e->reg, &tmp) || | ||
694 | (tmp & e->mask) != e->val)) | ||
695 | |||
696 | if (d->enablebits[0].reg != d->enablebits[1].reg) { | ||
697 | d->enablebits[0].reg = d->enablebits[1].reg; | ||
698 | d->enablebits[0].mask = d->enablebits[1].mask; | ||
699 | d->enablebits[0].val = d->enablebits[1].val; | ||
700 | } | ||
701 | #endif | ||
702 | |||
703 | return ide_setup_pci_device(dev, d); | 614 | return ide_setup_pci_device(dev, d); |
704 | } | 615 | } |
705 | 616 | ||
@@ -714,22 +625,6 @@ static int __devinit init_setup_pdc20265(struct pci_dev *dev, | |||
714 | "attached to I2O RAID controller.\n"); | 625 | "attached to I2O RAID controller.\n"); |
715 | return -ENODEV; | 626 | return -ENODEV; |
716 | } | 627 | } |
717 | |||
718 | #if 0 | ||
719 | { | ||
720 | u8 pri = 0, sec = 0; | ||
721 | |||
722 | if (e->reg && (pci_read_config_byte(dev, e->reg, &tmp) || | ||
723 | (tmp & e->mask) != e->val)) | ||
724 | |||
725 | if (d->enablebits[0].reg != d->enablebits[1].reg) { | ||
726 | d->enablebits[0].reg = d->enablebits[1].reg; | ||
727 | d->enablebits[0].mask = d->enablebits[1].mask; | ||
728 | d->enablebits[0].val = d->enablebits[1].val; | ||
729 | } | ||
730 | } | ||
731 | #endif | ||
732 | |||
733 | return ide_setup_pci_device(dev, d); | 628 | return ide_setup_pci_device(dev, d); |
734 | } | 629 | } |
735 | 630 | ||
diff --git a/drivers/ide/pci/sc1200.c b/drivers/ide/pci/sc1200.c index 24e21b2838c1..778b82ae964d 100644 --- a/drivers/ide/pci/sc1200.c +++ b/drivers/ide/pci/sc1200.c | |||
@@ -395,7 +395,6 @@ static int sc1200_resume (struct pci_dev *dev) | |||
395 | { | 395 | { |
396 | ide_hwif_t *hwif = NULL; | 396 | ide_hwif_t *hwif = NULL; |
397 | 397 | ||
398 | printk("SC1200: resume\n"); | ||
399 | pci_set_power_state(dev, PCI_D0); // bring chip back from sleep state | 398 | pci_set_power_state(dev, PCI_D0); // bring chip back from sleep state |
400 | dev->current_state = PM_EVENT_ON; | 399 | dev->current_state = PM_EVENT_ON; |
401 | pci_enable_device(dev); | 400 | pci_enable_device(dev); |
@@ -405,7 +404,6 @@ printk("SC1200: resume\n"); | |||
405 | while ((hwif = lookup_pci_dev(hwif, dev)) != NULL) { | 404 | while ((hwif = lookup_pci_dev(hwif, dev)) != NULL) { |
406 | unsigned int basereg, r, d, format; | 405 | unsigned int basereg, r, d, format; |
407 | sc1200_saved_state_t *ss = (sc1200_saved_state_t *)hwif->config_data; | 406 | sc1200_saved_state_t *ss = (sc1200_saved_state_t *)hwif->config_data; |
408 | printk("%s: SC1200: resume\n", hwif->name); | ||
409 | 407 | ||
410 | // | 408 | // |
411 | // Restore timing registers: this may be unnecessary if BIOS also does it | 409 | // Restore timing registers: this may be unnecessary if BIOS also does it |
@@ -493,7 +491,7 @@ static int __devinit sc1200_init_one(struct pci_dev *dev, const struct pci_devic | |||
493 | } | 491 | } |
494 | 492 | ||
495 | static struct pci_device_id sc1200_pci_tbl[] = { | 493 | static struct pci_device_id sc1200_pci_tbl[] = { |
496 | { PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_SCx200_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, | 494 | { PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_SCx200_IDE), 0}, |
497 | { 0, }, | 495 | { 0, }, |
498 | }; | 496 | }; |
499 | MODULE_DEVICE_TABLE(pci, sc1200_pci_tbl); | 497 | MODULE_DEVICE_TABLE(pci, sc1200_pci_tbl); |
diff --git a/drivers/ide/pci/serverworks.c b/drivers/ide/pci/serverworks.c index 0d3073f4eab4..5100b827a935 100644 --- a/drivers/ide/pci/serverworks.c +++ b/drivers/ide/pci/serverworks.c | |||
@@ -123,11 +123,11 @@ static u8 svwks_csb_check (struct pci_dev *dev) | |||
123 | } | 123 | } |
124 | static int svwks_tune_chipset (ide_drive_t *drive, u8 xferspeed) | 124 | static int svwks_tune_chipset (ide_drive_t *drive, u8 xferspeed) |
125 | { | 125 | { |
126 | u8 udma_modes[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05 }; | 126 | static const u8 udma_modes[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05 }; |
127 | u8 dma_modes[] = { 0x77, 0x21, 0x20 }; | 127 | static const u8 dma_modes[] = { 0x77, 0x21, 0x20 }; |
128 | u8 pio_modes[] = { 0x5d, 0x47, 0x34, 0x22, 0x20 }; | 128 | static const u8 pio_modes[] = { 0x5d, 0x47, 0x34, 0x22, 0x20 }; |
129 | u8 drive_pci[] = { 0x41, 0x40, 0x43, 0x42 }; | 129 | static const u8 drive_pci[] = { 0x41, 0x40, 0x43, 0x42 }; |
130 | u8 drive_pci2[] = { 0x45, 0x44, 0x47, 0x46 }; | 130 | static const u8 drive_pci2[] = { 0x45, 0x44, 0x47, 0x46 }; |
131 | 131 | ||
132 | ide_hwif_t *hwif = HWIF(drive); | 132 | ide_hwif_t *hwif = HWIF(drive); |
133 | struct pci_dev *dev = hwif->pci_dev; | 133 | struct pci_dev *dev = hwif->pci_dev; |
@@ -392,16 +392,6 @@ static unsigned int __devinit init_chipset_svwks (struct pci_dev *dev, const cha | |||
392 | } | 392 | } |
393 | outb_p(0x06, 0x0c00); | 393 | outb_p(0x06, 0x0c00); |
394 | dev->irq = inb_p(0x0c01); | 394 | dev->irq = inb_p(0x0c01); |
395 | #if 0 | ||
396 | printk("%s: device class (0x%04x)\n", | ||
397 | name, dev->class); | ||
398 | if ((dev->class >> 8) != PCI_CLASS_STORAGE_IDE) { | ||
399 | dev->class &= ~0x000F0F00; | ||
400 | // dev->class |= ~0x00000400; | ||
401 | dev->class |= ~0x00010100; | ||
402 | /**/ | ||
403 | } | ||
404 | #endif | ||
405 | } else { | 395 | } else { |
406 | struct pci_dev * findev = NULL; | 396 | struct pci_dev * findev = NULL; |
407 | u8 reg41 = 0; | 397 | u8 reg41 = 0; |
@@ -452,7 +442,7 @@ static unsigned int __devinit init_chipset_svwks (struct pci_dev *dev, const cha | |||
452 | pci_write_config_byte(dev, 0x5A, btr); | 442 | pci_write_config_byte(dev, 0x5A, btr); |
453 | } | 443 | } |
454 | 444 | ||
455 | return (dev->irq) ? dev->irq : 0; | 445 | return dev->irq; |
456 | } | 446 | } |
457 | 447 | ||
458 | static unsigned int __devinit ata66_svwks_svwks (ide_hwif_t *hwif) | 448 | static unsigned int __devinit ata66_svwks_svwks (ide_hwif_t *hwif) |
@@ -500,11 +490,6 @@ static unsigned int __devinit ata66_svwks (ide_hwif_t *hwif) | |||
500 | { | 490 | { |
501 | struct pci_dev *dev = hwif->pci_dev; | 491 | struct pci_dev *dev = hwif->pci_dev; |
502 | 492 | ||
503 | /* Per Specified Design by OEM, and ASIC Architect */ | ||
504 | if ((dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB6IDE) || | ||
505 | (dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB6IDE2)) | ||
506 | return 1; | ||
507 | |||
508 | /* Server Works */ | 493 | /* Server Works */ |
509 | if (dev->subsystem_vendor == PCI_VENDOR_ID_SERVERWORKS) | 494 | if (dev->subsystem_vendor == PCI_VENDOR_ID_SERVERWORKS) |
510 | return ata66_svwks_svwks (hwif); | 495 | return ata66_svwks_svwks (hwif); |
@@ -517,10 +502,14 @@ static unsigned int __devinit ata66_svwks (ide_hwif_t *hwif) | |||
517 | if (dev->subsystem_vendor == PCI_VENDOR_ID_SUN) | 502 | if (dev->subsystem_vendor == PCI_VENDOR_ID_SUN) |
518 | return ata66_svwks_cobalt (hwif); | 503 | return ata66_svwks_cobalt (hwif); |
519 | 504 | ||
505 | /* Per Specified Design by OEM, and ASIC Architect */ | ||
506 | if ((dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB6IDE) || | ||
507 | (dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB6IDE2)) | ||
508 | return 1; | ||
509 | |||
520 | return 0; | 510 | return 0; |
521 | } | 511 | } |
522 | 512 | ||
523 | #undef CAN_SW_DMA | ||
524 | static void __devinit init_hwif_svwks (ide_hwif_t *hwif) | 513 | static void __devinit init_hwif_svwks (ide_hwif_t *hwif) |
525 | { | 514 | { |
526 | u8 dma_stat = 0; | 515 | u8 dma_stat = 0; |
@@ -537,9 +526,6 @@ static void __devinit init_hwif_svwks (ide_hwif_t *hwif) | |||
537 | hwif->ultra_mask = 0x3f; | 526 | hwif->ultra_mask = 0x3f; |
538 | 527 | ||
539 | hwif->mwdma_mask = 0x07; | 528 | hwif->mwdma_mask = 0x07; |
540 | #ifdef CAN_SW_DMA | ||
541 | hwif->swdma_mask = 0x07; | ||
542 | #endif /* CAN_SW_DMA */ | ||
543 | 529 | ||
544 | hwif->autodma = 0; | 530 | hwif->autodma = 0; |
545 | 531 | ||
@@ -562,8 +548,6 @@ static void __devinit init_hwif_svwks (ide_hwif_t *hwif) | |||
562 | hwif->drives[1].autodma = (dma_stat & 0x40); | 548 | hwif->drives[1].autodma = (dma_stat & 0x40); |
563 | hwif->drives[0].autotune = (!(dma_stat & 0x20)); | 549 | hwif->drives[0].autotune = (!(dma_stat & 0x20)); |
564 | hwif->drives[1].autotune = (!(dma_stat & 0x40)); | 550 | hwif->drives[1].autotune = (!(dma_stat & 0x40)); |
565 | // hwif->drives[0].autodma = hwif->autodma; | ||
566 | // hwif->drives[1].autodma = hwif->autodma; | ||
567 | } | 551 | } |
568 | 552 | ||
569 | /* | 553 | /* |
@@ -593,11 +577,6 @@ static int __devinit init_setup_csb6 (struct pci_dev *dev, ide_pci_device_t *d) | |||
593 | if (dev->resource[0].start == 0x01f1) | 577 | if (dev->resource[0].start == 0x01f1) |
594 | d->bootable = ON_BOARD; | 578 | d->bootable = ON_BOARD; |
595 | } | 579 | } |
596 | #if 0 | ||
597 | if ((IDE_PCI_DEVID_EQ(d->devid, DEVID_CSB6) && | ||
598 | (!(PCI_FUNC(dev->devfn) & 1))) | ||
599 | d->autodma = AUTODMA; | ||
600 | #endif | ||
601 | 580 | ||
602 | d->channels = ((dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB6IDE || | 581 | d->channels = ((dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB6IDE || |
603 | dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB6IDE2) && | 582 | dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB6IDE2) && |
@@ -671,11 +650,11 @@ static int __devinit svwks_init_one(struct pci_dev *dev, const struct pci_device | |||
671 | } | 650 | } |
672 | 651 | ||
673 | static struct pci_device_id svwks_pci_tbl[] = { | 652 | static struct pci_device_id svwks_pci_tbl[] = { |
674 | { PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_OSB4IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, | 653 | { PCI_DEVICE(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_OSB4IDE), 0}, |
675 | { PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_CSB5IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1}, | 654 | { PCI_DEVICE(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_CSB5IDE), 1}, |
676 | { PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_CSB6IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 2}, | 655 | { PCI_DEVICE(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_CSB6IDE), 2}, |
677 | { PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_CSB6IDE2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 3}, | 656 | { PCI_DEVICE(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_CSB6IDE2), 3}, |
678 | { PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_HT1000IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 4}, | 657 | { PCI_DEVICE(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_HT1000IDE), 4}, |
679 | { 0, }, | 658 | { 0, }, |
680 | }; | 659 | }; |
681 | MODULE_DEVICE_TABLE(pci, svwks_pci_tbl); | 660 | MODULE_DEVICE_TABLE(pci, svwks_pci_tbl); |
diff --git a/drivers/ide/pci/siimage.c b/drivers/ide/pci/siimage.c index f1ca154dd52c..72dade14c725 100644 --- a/drivers/ide/pci/siimage.c +++ b/drivers/ide/pci/siimage.c | |||
@@ -38,9 +38,6 @@ | |||
38 | 38 | ||
39 | #include <asm/io.h> | 39 | #include <asm/io.h> |
40 | 40 | ||
41 | #undef SIIMAGE_VIRTUAL_DMAPIO | ||
42 | #undef SIIMAGE_LARGE_DMA | ||
43 | |||
44 | /** | 41 | /** |
45 | * pdev_is_sata - check if device is SATA | 42 | * pdev_is_sata - check if device is SATA |
46 | * @pdev: PCI device to check | 43 | * @pdev: PCI device to check |
@@ -461,36 +458,6 @@ static int siimage_io_ide_dma_test_irq (ide_drive_t *drive) | |||
461 | return 0; | 458 | return 0; |
462 | } | 459 | } |
463 | 460 | ||
464 | #if 0 | ||
465 | /** | ||
466 | * siimage_mmio_ide_dma_count - DMA bytes done | ||
467 | * @drive | ||
468 | * | ||
469 | * If we are doing VDMA the CMD680 requires a little bit | ||
470 | * of more careful handling and we have to read the counts | ||
471 | * off ourselves. For non VDMA life is normal. | ||
472 | */ | ||
473 | |||
474 | static int siimage_mmio_ide_dma_count (ide_drive_t *drive) | ||
475 | { | ||
476 | #ifdef SIIMAGE_VIRTUAL_DMAPIO | ||
477 | struct request *rq = HWGROUP(drive)->rq; | ||
478 | ide_hwif_t *hwif = HWIF(drive); | ||
479 | u32 count = (rq->nr_sectors * SECTOR_SIZE); | ||
480 | u32 rcount = 0; | ||
481 | unsigned long addr = siimage_selreg(hwif, 0x1C); | ||
482 | |||
483 | hwif->OUTL(count, addr); | ||
484 | rcount = hwif->INL(addr); | ||
485 | |||
486 | printk("\n%s: count = %d, rcount = %d, nr_sectors = %lu\n", | ||
487 | drive->name, count, rcount, rq->nr_sectors); | ||
488 | |||
489 | #endif /* SIIMAGE_VIRTUAL_DMAPIO */ | ||
490 | return __ide_dma_count(drive); | ||
491 | } | ||
492 | #endif | ||
493 | |||
494 | /** | 461 | /** |
495 | * siimage_mmio_ide_dma_test_irq - check we caused an IRQ | 462 | * siimage_mmio_ide_dma_test_irq - check we caused an IRQ |
496 | * @drive: drive we are testing | 463 | * @drive: drive we are testing |
@@ -512,12 +479,10 @@ static int siimage_mmio_ide_dma_test_irq (ide_drive_t *drive) | |||
512 | u32 sata_error = hwif->INL(SATA_ERROR_REG); | 479 | u32 sata_error = hwif->INL(SATA_ERROR_REG); |
513 | hwif->OUTL(sata_error, SATA_ERROR_REG); | 480 | hwif->OUTL(sata_error, SATA_ERROR_REG); |
514 | watchdog = (sata_error & 0x00680000) ? 1 : 0; | 481 | watchdog = (sata_error & 0x00680000) ? 1 : 0; |
515 | #if 1 | ||
516 | printk(KERN_WARNING "%s: sata_error = 0x%08x, " | 482 | printk(KERN_WARNING "%s: sata_error = 0x%08x, " |
517 | "watchdog = %d, %s\n", | 483 | "watchdog = %d, %s\n", |
518 | drive->name, sata_error, watchdog, | 484 | drive->name, sata_error, watchdog, |
519 | __FUNCTION__); | 485 | __FUNCTION__); |
520 | #endif | ||
521 | 486 | ||
522 | } else { | 487 | } else { |
523 | watchdog = (ext_stat & 0x8000) ? 1 : 0; | 488 | watchdog = (ext_stat & 0x8000) ? 1 : 0; |
@@ -863,7 +828,7 @@ static unsigned int __devinit init_chipset_siimage(struct pci_dev *dev, const ch | |||
863 | * time. | 828 | * time. |
864 | * | 829 | * |
865 | * The hardware supports buffered taskfiles and also some rather nice | 830 | * The hardware supports buffered taskfiles and also some rather nice |
866 | * extended PRD tables. Unfortunately right now we don't. | 831 | * extended PRD tables. For better SI3112 support use the libata driver |
867 | */ | 832 | */ |
868 | 833 | ||
869 | static void __devinit init_mmio_iops_siimage(ide_hwif_t *hwif) | 834 | static void __devinit init_mmio_iops_siimage(ide_hwif_t *hwif) |
@@ -900,9 +865,6 @@ static void __devinit init_mmio_iops_siimage(ide_hwif_t *hwif) | |||
900 | * so we can't currently use it sanely since we want to | 865 | * so we can't currently use it sanely since we want to |
901 | * use LBA48 mode. | 866 | * use LBA48 mode. |
902 | */ | 867 | */ |
903 | // base += 0x10; | ||
904 | // hwif->no_lba48 = 1; | ||
905 | |||
906 | hw.io_ports[IDE_DATA_OFFSET] = base; | 868 | hw.io_ports[IDE_DATA_OFFSET] = base; |
907 | hw.io_ports[IDE_ERROR_OFFSET] = base + 1; | 869 | hw.io_ports[IDE_ERROR_OFFSET] = base + 1; |
908 | hw.io_ports[IDE_NSECTOR_OFFSET] = base + 2; | 870 | hw.io_ports[IDE_NSECTOR_OFFSET] = base + 2; |
@@ -936,15 +898,8 @@ static void __devinit init_mmio_iops_siimage(ide_hwif_t *hwif) | |||
936 | 898 | ||
937 | base = (unsigned long) addr; | 899 | base = (unsigned long) addr; |
938 | 900 | ||
939 | #ifdef SIIMAGE_LARGE_DMA | ||
940 | /* Watch the brackets - even Ken and Dennis get some language design wrong */ | ||
941 | hwif->dma_base = base + (ch ? 0x18 : 0x10); | ||
942 | hwif->dma_base2 = base + (ch ? 0x08 : 0x00); | ||
943 | hwif->dma_prdtable = hwif->dma_base2 + 4; | ||
944 | #else /* ! SIIMAGE_LARGE_DMA */ | ||
945 | hwif->dma_base = base + (ch ? 0x08 : 0x00); | 901 | hwif->dma_base = base + (ch ? 0x08 : 0x00); |
946 | hwif->dma_base2 = base + (ch ? 0x18 : 0x10); | 902 | hwif->dma_base2 = base + (ch ? 0x18 : 0x10); |
947 | #endif /* SIIMAGE_LARGE_DMA */ | ||
948 | hwif->mmio = 2; | 903 | hwif->mmio = 2; |
949 | } | 904 | } |
950 | 905 | ||
@@ -1052,9 +1007,16 @@ static void __devinit init_hwif_siimage(ide_hwif_t *hwif) | |||
1052 | hwif->reset_poll = &siimage_reset_poll; | 1007 | hwif->reset_poll = &siimage_reset_poll; |
1053 | hwif->pre_reset = &siimage_pre_reset; | 1008 | hwif->pre_reset = &siimage_pre_reset; |
1054 | 1009 | ||
1055 | if(is_sata(hwif)) | 1010 | if(is_sata(hwif)) { |
1011 | static int first = 1; | ||
1012 | |||
1056 | hwif->busproc = &siimage_busproc; | 1013 | hwif->busproc = &siimage_busproc; |
1057 | 1014 | ||
1015 | if (first) { | ||
1016 | printk(KERN_INFO "siimage: For full SATA support you should use the libata sata_sil module.\n"); | ||
1017 | first = 0; | ||
1018 | } | ||
1019 | } | ||
1058 | if (!hwif->dma_base) { | 1020 | if (!hwif->dma_base) { |
1059 | hwif->drives[0].autotune = 1; | 1021 | hwif->drives[0].autotune = 1; |
1060 | hwif->drives[1].autotune = 1; | 1022 | hwif->drives[1].autotune = 1; |
@@ -1121,10 +1083,10 @@ static int __devinit siimage_init_one(struct pci_dev *dev, const struct pci_devi | |||
1121 | } | 1083 | } |
1122 | 1084 | ||
1123 | static struct pci_device_id siimage_pci_tbl[] = { | 1085 | static struct pci_device_id siimage_pci_tbl[] = { |
1124 | { PCI_VENDOR_ID_CMD, PCI_DEVICE_ID_SII_680, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, | 1086 | { PCI_DEVICE(PCI_VENDOR_ID_CMD, PCI_DEVICE_ID_SII_680), 0}, |
1125 | #ifdef CONFIG_BLK_DEV_IDE_SATA | 1087 | #ifdef CONFIG_BLK_DEV_IDE_SATA |
1126 | { PCI_VENDOR_ID_CMD, PCI_DEVICE_ID_SII_3112, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1}, | 1088 | { PCI_DEVICE(PCI_VENDOR_ID_CMD, PCI_DEVICE_ID_SII_3112), 1}, |
1127 | { PCI_VENDOR_ID_CMD, PCI_DEVICE_ID_SII_1210SA, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 2}, | 1089 | { PCI_DEVICE(PCI_VENDOR_ID_CMD, PCI_DEVICE_ID_SII_1210SA), 2}, |
1128 | #endif | 1090 | #endif |
1129 | { 0, }, | 1091 | { 0, }, |
1130 | }; | 1092 | }; |
diff --git a/drivers/ide/pci/sl82c105.c b/drivers/ide/pci/sl82c105.c index 8a5c7b286b2b..900301e43818 100644 --- a/drivers/ide/pci/sl82c105.c +++ b/drivers/ide/pci/sl82c105.c | |||
@@ -447,7 +447,6 @@ static void __devinit init_hwif_sl82c105(ide_hwif_t *hwif) | |||
447 | printk(" %s: Winbond 553 bridge revision %d, BM-DMA disabled\n", | 447 | printk(" %s: Winbond 553 bridge revision %d, BM-DMA disabled\n", |
448 | hwif->name, rev); | 448 | hwif->name, rev); |
449 | } else { | 449 | } else { |
450 | #ifdef CONFIG_BLK_DEV_IDEDMA | ||
451 | dma_state |= 0x60; | 450 | dma_state |= 0x60; |
452 | 451 | ||
453 | hwif->atapi_dma = 1; | 452 | hwif->atapi_dma = 1; |
@@ -468,7 +467,6 @@ static void __devinit init_hwif_sl82c105(ide_hwif_t *hwif) | |||
468 | 467 | ||
469 | if (hwif->mate) | 468 | if (hwif->mate) |
470 | hwif->serialized = hwif->mate->serialized = 1; | 469 | hwif->serialized = hwif->mate->serialized = 1; |
471 | #endif /* CONFIG_BLK_DEV_IDEDMA */ | ||
472 | } | 470 | } |
473 | hwif->OUTB(dma_state, hwif->dma_base + 2); | 471 | hwif->OUTB(dma_state, hwif->dma_base + 2); |
474 | } | 472 | } |
@@ -489,7 +487,7 @@ static int __devinit sl82c105_init_one(struct pci_dev *dev, const struct pci_dev | |||
489 | } | 487 | } |
490 | 488 | ||
491 | static struct pci_device_id sl82c105_pci_tbl[] = { | 489 | static struct pci_device_id sl82c105_pci_tbl[] = { |
492 | { PCI_VENDOR_ID_WINBOND, PCI_DEVICE_ID_WINBOND_82C105, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, | 490 | { PCI_DEVICE(PCI_VENDOR_ID_WINBOND, PCI_DEVICE_ID_WINBOND_82C105), 0}, |
493 | { 0, }, | 491 | { 0, }, |
494 | }; | 492 | }; |
495 | MODULE_DEVICE_TABLE(pci, sl82c105_pci_tbl); | 493 | MODULE_DEVICE_TABLE(pci, sl82c105_pci_tbl); |
diff --git a/drivers/ide/pci/slc90e66.c b/drivers/ide/pci/slc90e66.c index 5112c726633b..0968f6bc669a 100644 --- a/drivers/ide/pci/slc90e66.c +++ b/drivers/ide/pci/slc90e66.c | |||
@@ -72,7 +72,8 @@ static void slc90e66_tune_drive (ide_drive_t *drive, u8 pio) | |||
72 | u16 master_data; | 72 | u16 master_data; |
73 | u8 slave_data; | 73 | u8 slave_data; |
74 | /* ISP RTC */ | 74 | /* ISP RTC */ |
75 | u8 timings[][2] = { { 0, 0 }, | 75 | static const u8 timings[][2]= { |
76 | { 0, 0 }, | ||
76 | { 0, 0 }, | 77 | { 0, 0 }, |
77 | { 1, 0 }, | 78 | { 1, 0 }, |
78 | { 2, 1 }, | 79 | { 2, 1 }, |
@@ -119,7 +120,6 @@ static int slc90e66_tune_chipset (ide_drive_t *drive, u8 xferspeed) | |||
119 | pci_read_config_word(dev, 0x4a, ®4a); | 120 | pci_read_config_word(dev, 0x4a, ®4a); |
120 | 121 | ||
121 | switch(speed) { | 122 | switch(speed) { |
122 | #ifdef CONFIG_BLK_DEV_IDEDMA | ||
123 | case XFER_UDMA_4: u_speed = 4 << (drive->dn * 4); break; | 123 | case XFER_UDMA_4: u_speed = 4 << (drive->dn * 4); break; |
124 | case XFER_UDMA_3: u_speed = 3 << (drive->dn * 4); break; | 124 | case XFER_UDMA_3: u_speed = 3 << (drive->dn * 4); break; |
125 | case XFER_UDMA_2: u_speed = 2 << (drive->dn * 4); break; | 125 | case XFER_UDMA_2: u_speed = 2 << (drive->dn * 4); break; |
@@ -128,7 +128,6 @@ static int slc90e66_tune_chipset (ide_drive_t *drive, u8 xferspeed) | |||
128 | case XFER_MW_DMA_2: | 128 | case XFER_MW_DMA_2: |
129 | case XFER_MW_DMA_1: | 129 | case XFER_MW_DMA_1: |
130 | case XFER_SW_DMA_2: break; | 130 | case XFER_SW_DMA_2: break; |
131 | #endif /* CONFIG_BLK_DEV_IDEDMA */ | ||
132 | case XFER_PIO_4: | 131 | case XFER_PIO_4: |
133 | case XFER_PIO_3: | 132 | case XFER_PIO_3: |
134 | case XFER_PIO_2: | 133 | case XFER_PIO_2: |
@@ -156,7 +155,6 @@ static int slc90e66_tune_chipset (ide_drive_t *drive, u8 xferspeed) | |||
156 | return (ide_config_drive_speed(drive, speed)); | 155 | return (ide_config_drive_speed(drive, speed)); |
157 | } | 156 | } |
158 | 157 | ||
159 | #ifdef CONFIG_BLK_DEV_IDEDMA | ||
160 | static int slc90e66_config_drive_for_dma (ide_drive_t *drive) | 158 | static int slc90e66_config_drive_for_dma (ide_drive_t *drive) |
161 | { | 159 | { |
162 | u8 speed = ide_dma_speed(drive, slc90e66_ratemask(drive)); | 160 | u8 speed = ide_dma_speed(drive, slc90e66_ratemask(drive)); |
@@ -194,7 +192,6 @@ fast_ata_pio: | |||
194 | /* IORDY not supported */ | 192 | /* IORDY not supported */ |
195 | return 0; | 193 | return 0; |
196 | } | 194 | } |
197 | #endif /* CONFIG_BLK_DEV_IDEDMA */ | ||
198 | 195 | ||
199 | static void __devinit init_hwif_slc90e66 (ide_hwif_t *hwif) | 196 | static void __devinit init_hwif_slc90e66 (ide_hwif_t *hwif) |
200 | { | 197 | { |
@@ -222,7 +219,6 @@ static void __devinit init_hwif_slc90e66 (ide_hwif_t *hwif) | |||
222 | hwif->mwdma_mask = 0x07; | 219 | hwif->mwdma_mask = 0x07; |
223 | hwif->swdma_mask = 0x07; | 220 | hwif->swdma_mask = 0x07; |
224 | 221 | ||
225 | #ifdef CONFIG_BLK_DEV_IDEDMA | ||
226 | if (!(hwif->udma_four)) | 222 | if (!(hwif->udma_four)) |
227 | /* bit[0(1)]: 0:80, 1:40 */ | 223 | /* bit[0(1)]: 0:80, 1:40 */ |
228 | hwif->udma_four = (reg47 & mask) ? 0 : 1; | 224 | hwif->udma_four = (reg47 & mask) ? 0 : 1; |
@@ -232,7 +228,6 @@ static void __devinit init_hwif_slc90e66 (ide_hwif_t *hwif) | |||
232 | hwif->autodma = 1; | 228 | hwif->autodma = 1; |
233 | hwif->drives[0].autodma = hwif->autodma; | 229 | hwif->drives[0].autodma = hwif->autodma; |
234 | hwif->drives[1].autodma = hwif->autodma; | 230 | hwif->drives[1].autodma = hwif->autodma; |
235 | #endif /* !CONFIG_BLK_DEV_IDEDMA */ | ||
236 | } | 231 | } |
237 | 232 | ||
238 | static ide_pci_device_t slc90e66_chipset __devinitdata = { | 233 | static ide_pci_device_t slc90e66_chipset __devinitdata = { |
@@ -250,7 +245,7 @@ static int __devinit slc90e66_init_one(struct pci_dev *dev, const struct pci_dev | |||
250 | } | 245 | } |
251 | 246 | ||
252 | static struct pci_device_id slc90e66_pci_tbl[] = { | 247 | static struct pci_device_id slc90e66_pci_tbl[] = { |
253 | { PCI_VENDOR_ID_EFAR, PCI_DEVICE_ID_EFAR_SLC90E66_1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, | 248 | { PCI_DEVICE(PCI_VENDOR_ID_EFAR, PCI_DEVICE_ID_EFAR_SLC90E66_1), 0}, |
254 | { 0, }, | 249 | { 0, }, |
255 | }; | 250 | }; |
256 | MODULE_DEVICE_TABLE(pci, slc90e66_pci_tbl); | 251 | MODULE_DEVICE_TABLE(pci, slc90e66_pci_tbl); |
diff --git a/drivers/ide/ppc/pmac.c b/drivers/ide/ppc/pmac.c index ffca8b63ee79..e8ef3455ec35 100644 --- a/drivers/ide/ppc/pmac.c +++ b/drivers/ide/ppc/pmac.c | |||
@@ -421,107 +421,6 @@ static void pmac_ide_kauai_selectproc(ide_drive_t *drive); | |||
421 | #endif /* CONFIG_BLK_DEV_IDEDMA_PMAC */ | 421 | #endif /* CONFIG_BLK_DEV_IDEDMA_PMAC */ |
422 | 422 | ||
423 | /* | 423 | /* |
424 | * Below is the code for blinking the laptop LED along with hard | ||
425 | * disk activity. | ||
426 | */ | ||
427 | |||
428 | #ifdef CONFIG_BLK_DEV_IDE_PMAC_BLINK | ||
429 | |||
430 | /* Set to 50ms minimum led-on time (also used to limit frequency | ||
431 | * of requests sent to the PMU | ||
432 | */ | ||
433 | #define PMU_HD_BLINK_TIME (HZ/50) | ||
434 | |||
435 | static struct adb_request pmu_blink_on, pmu_blink_off; | ||
436 | static spinlock_t pmu_blink_lock; | ||
437 | static unsigned long pmu_blink_stoptime; | ||
438 | static int pmu_blink_ledstate; | ||
439 | static struct timer_list pmu_blink_timer; | ||
440 | static int pmu_ide_blink_enabled; | ||
441 | |||
442 | |||
443 | static void | ||
444 | pmu_hd_blink_timeout(unsigned long data) | ||
445 | { | ||
446 | unsigned long flags; | ||
447 | |||
448 | spin_lock_irqsave(&pmu_blink_lock, flags); | ||
449 | |||
450 | /* We may have been triggered again in a racy way, check | ||
451 | * that we really want to switch it off | ||
452 | */ | ||
453 | if (time_after(pmu_blink_stoptime, jiffies)) | ||
454 | goto done; | ||
455 | |||
456 | /* Previous req. not complete, try 100ms more */ | ||
457 | if (pmu_blink_off.complete == 0) | ||
458 | mod_timer(&pmu_blink_timer, jiffies + PMU_HD_BLINK_TIME); | ||
459 | else if (pmu_blink_ledstate) { | ||
460 | pmu_request(&pmu_blink_off, NULL, 4, 0xee, 4, 0, 0); | ||
461 | pmu_blink_ledstate = 0; | ||
462 | } | ||
463 | done: | ||
464 | spin_unlock_irqrestore(&pmu_blink_lock, flags); | ||
465 | } | ||
466 | |||
467 | static void | ||
468 | pmu_hd_kick_blink(void *data, int rw) | ||
469 | { | ||
470 | unsigned long flags; | ||
471 | |||
472 | pmu_blink_stoptime = jiffies + PMU_HD_BLINK_TIME; | ||
473 | wmb(); | ||
474 | mod_timer(&pmu_blink_timer, pmu_blink_stoptime); | ||
475 | /* Fast path when LED is already ON */ | ||
476 | if (pmu_blink_ledstate == 1) | ||
477 | return; | ||
478 | spin_lock_irqsave(&pmu_blink_lock, flags); | ||
479 | if (pmu_blink_on.complete && !pmu_blink_ledstate) { | ||
480 | pmu_request(&pmu_blink_on, NULL, 4, 0xee, 4, 0, 1); | ||
481 | pmu_blink_ledstate = 1; | ||
482 | } | ||
483 | spin_unlock_irqrestore(&pmu_blink_lock, flags); | ||
484 | } | ||
485 | |||
486 | static int | ||
487 | pmu_hd_blink_init(void) | ||
488 | { | ||
489 | struct device_node *dt; | ||
490 | const char *model; | ||
491 | |||
492 | /* Currently, I only enable this feature on KeyLargo based laptops, | ||
493 | * older laptops may support it (at least heathrow/paddington) but | ||
494 | * I don't feel like loading those venerable old machines with so | ||
495 | * much additional interrupt & PMU activity... | ||
496 | */ | ||
497 | if (pmu_get_model() != PMU_KEYLARGO_BASED) | ||
498 | return 0; | ||
499 | |||
500 | dt = of_find_node_by_path("/"); | ||
501 | if (dt == NULL) | ||
502 | return 0; | ||
503 | model = (const char *)get_property(dt, "model", NULL); | ||
504 | if (model == NULL) | ||
505 | return 0; | ||
506 | if (strncmp(model, "PowerBook", strlen("PowerBook")) != 0 && | ||
507 | strncmp(model, "iBook", strlen("iBook")) != 0) { | ||
508 | of_node_put(dt); | ||
509 | return 0; | ||
510 | } | ||
511 | of_node_put(dt); | ||
512 | |||
513 | pmu_blink_on.complete = 1; | ||
514 | pmu_blink_off.complete = 1; | ||
515 | spin_lock_init(&pmu_blink_lock); | ||
516 | init_timer(&pmu_blink_timer); | ||
517 | pmu_blink_timer.function = pmu_hd_blink_timeout; | ||
518 | |||
519 | return 1; | ||
520 | } | ||
521 | |||
522 | #endif /* CONFIG_BLK_DEV_IDE_PMAC_BLINK */ | ||
523 | |||
524 | /* | ||
525 | * N.B. this can't be an initfunc, because the media-bay task can | 424 | * N.B. this can't be an initfunc, because the media-bay task can |
526 | * call ide_[un]register at any time. | 425 | * call ide_[un]register at any time. |
527 | */ | 426 | */ |
@@ -1192,23 +1091,6 @@ pmac_ide_do_suspend(ide_hwif_t *hwif) | |||
1192 | pmif->timings[0] = 0; | 1091 | pmif->timings[0] = 0; |
1193 | pmif->timings[1] = 0; | 1092 | pmif->timings[1] = 0; |
1194 | 1093 | ||
1195 | #ifdef CONFIG_BLK_DEV_IDE_PMAC_BLINK | ||
1196 | /* Note: This code will be called for every hwif, thus we'll | ||
1197 | * try several time to stop the LED blinker timer, but that | ||
1198 | * should be harmless | ||
1199 | */ | ||
1200 | if (pmu_ide_blink_enabled) { | ||
1201 | unsigned long flags; | ||
1202 | |||
1203 | /* Make sure we don't hit the PMU blink */ | ||
1204 | spin_lock_irqsave(&pmu_blink_lock, flags); | ||
1205 | if (pmu_blink_ledstate) | ||
1206 | del_timer(&pmu_blink_timer); | ||
1207 | pmu_blink_ledstate = 0; | ||
1208 | spin_unlock_irqrestore(&pmu_blink_lock, flags); | ||
1209 | } | ||
1210 | #endif /* CONFIG_BLK_DEV_IDE_PMAC_BLINK */ | ||
1211 | |||
1212 | disable_irq(pmif->irq); | 1094 | disable_irq(pmif->irq); |
1213 | 1095 | ||
1214 | /* The media bay will handle itself just fine */ | 1096 | /* The media bay will handle itself just fine */ |
@@ -1376,13 +1258,6 @@ pmac_ide_setup_device(pmac_ide_hwif_t *pmif, ide_hwif_t *hwif) | |||
1376 | hwif->selectproc = pmac_ide_selectproc; | 1258 | hwif->selectproc = pmac_ide_selectproc; |
1377 | hwif->speedproc = pmac_ide_tune_chipset; | 1259 | hwif->speedproc = pmac_ide_tune_chipset; |
1378 | 1260 | ||
1379 | #ifdef CONFIG_BLK_DEV_IDE_PMAC_BLINK | ||
1380 | pmu_ide_blink_enabled = pmu_hd_blink_init(); | ||
1381 | |||
1382 | if (pmu_ide_blink_enabled) | ||
1383 | hwif->led_act = pmu_hd_kick_blink; | ||
1384 | #endif | ||
1385 | |||
1386 | printk(KERN_INFO "ide%d: Found Apple %s controller, bus ID %d%s, irq %d\n", | 1261 | printk(KERN_INFO "ide%d: Found Apple %s controller, bus ID %d%s, irq %d\n", |
1387 | hwif->index, model_name[pmif->kind], pmif->aapl_bus_id, | 1262 | hwif->index, model_name[pmif->kind], pmif->aapl_bus_id, |
1388 | pmif->mediabay ? " (mediabay)" : "", hwif->irq); | 1263 | pmif->mediabay ? " (mediabay)" : "", hwif->irq); |
diff --git a/drivers/ieee1394/ohci1394.c b/drivers/ieee1394/ohci1394.c index 3d278412e1ca..800c8d518430 100644 --- a/drivers/ieee1394/ohci1394.c +++ b/drivers/ieee1394/ohci1394.c | |||
@@ -590,11 +590,11 @@ static void ohci_initialize(struct ti_ohci *ohci) | |||
590 | buf = reg_read(ohci, OHCI1394_Version); | 590 | buf = reg_read(ohci, OHCI1394_Version); |
591 | sprintf (irq_buf, "%d", ohci->dev->irq); | 591 | sprintf (irq_buf, "%d", ohci->dev->irq); |
592 | PRINT(KERN_INFO, "OHCI-1394 %d.%d (PCI): IRQ=[%s] " | 592 | PRINT(KERN_INFO, "OHCI-1394 %d.%d (PCI): IRQ=[%s] " |
593 | "MMIO=[%lx-%lx] Max Packet=[%d] IR/IT contexts=[%d/%d]", | 593 | "MMIO=[%llx-%llx] Max Packet=[%d] IR/IT contexts=[%d/%d]", |
594 | ((((buf) >> 16) & 0xf) + (((buf) >> 20) & 0xf) * 10), | 594 | ((((buf) >> 16) & 0xf) + (((buf) >> 20) & 0xf) * 10), |
595 | ((((buf) >> 4) & 0xf) + ((buf) & 0xf) * 10), irq_buf, | 595 | ((((buf) >> 4) & 0xf) + ((buf) & 0xf) * 10), irq_buf, |
596 | pci_resource_start(ohci->dev, 0), | 596 | (unsigned long long)pci_resource_start(ohci->dev, 0), |
597 | pci_resource_start(ohci->dev, 0) + OHCI1394_REGISTER_SIZE - 1, | 597 | (unsigned long long)pci_resource_start(ohci->dev, 0) + OHCI1394_REGISTER_SIZE - 1, |
598 | ohci->max_packet_size, | 598 | ohci->max_packet_size, |
599 | ohci->nb_iso_rcv_ctx, ohci->nb_iso_xmit_ctx); | 599 | ohci->nb_iso_rcv_ctx, ohci->nb_iso_xmit_ctx); |
600 | 600 | ||
@@ -3217,7 +3217,7 @@ static int __devinit ohci1394_pci_probe(struct pci_dev *dev, | |||
3217 | { | 3217 | { |
3218 | struct hpsb_host *host; | 3218 | struct hpsb_host *host; |
3219 | struct ti_ohci *ohci; /* shortcut to currently handled device */ | 3219 | struct ti_ohci *ohci; /* shortcut to currently handled device */ |
3220 | unsigned long ohci_base; | 3220 | resource_size_t ohci_base; |
3221 | 3221 | ||
3222 | if (pci_enable_device(dev)) | 3222 | if (pci_enable_device(dev)) |
3223 | FAIL(-ENXIO, "Failed to enable OHCI hardware"); | 3223 | FAIL(-ENXIO, "Failed to enable OHCI hardware"); |
@@ -3270,15 +3270,16 @@ static int __devinit ohci1394_pci_probe(struct pci_dev *dev, | |||
3270 | * clearly says it's 2kb, so this shouldn't be a problem. */ | 3270 | * clearly says it's 2kb, so this shouldn't be a problem. */ |
3271 | ohci_base = pci_resource_start(dev, 0); | 3271 | ohci_base = pci_resource_start(dev, 0); |
3272 | if (pci_resource_len(dev, 0) < OHCI1394_REGISTER_SIZE) | 3272 | if (pci_resource_len(dev, 0) < OHCI1394_REGISTER_SIZE) |
3273 | PRINT(KERN_WARNING, "PCI resource length of %lx too small!", | 3273 | PRINT(KERN_WARNING, "PCI resource length of 0x%llx too small!", |
3274 | pci_resource_len(dev, 0)); | 3274 | (unsigned long long)pci_resource_len(dev, 0)); |
3275 | 3275 | ||
3276 | /* Seems PCMCIA handles this internally. Not sure why. Seems | 3276 | /* Seems PCMCIA handles this internally. Not sure why. Seems |
3277 | * pretty bogus to force a driver to special case this. */ | 3277 | * pretty bogus to force a driver to special case this. */ |
3278 | #ifndef PCMCIA | 3278 | #ifndef PCMCIA |
3279 | if (!request_mem_region (ohci_base, OHCI1394_REGISTER_SIZE, OHCI1394_DRIVER_NAME)) | 3279 | if (!request_mem_region (ohci_base, OHCI1394_REGISTER_SIZE, OHCI1394_DRIVER_NAME)) |
3280 | FAIL(-ENOMEM, "MMIO resource (0x%lx - 0x%lx) unavailable", | 3280 | FAIL(-ENOMEM, "MMIO resource (0x%llx - 0x%llx) unavailable", |
3281 | ohci_base, ohci_base + OHCI1394_REGISTER_SIZE); | 3281 | (unsigned long long)ohci_base, |
3282 | (unsigned long long)ohci_base + OHCI1394_REGISTER_SIZE); | ||
3282 | #endif | 3283 | #endif |
3283 | ohci->init_state = OHCI_INIT_HAVE_MEM_REGION; | 3284 | ohci->init_state = OHCI_INIT_HAVE_MEM_REGION; |
3284 | 3285 | ||
diff --git a/drivers/infiniband/hw/ipath/ipath_driver.c b/drivers/infiniband/hw/ipath/ipath_driver.c index dddcdae736ac..e4b897fa569a 100644 --- a/drivers/infiniband/hw/ipath/ipath_driver.c +++ b/drivers/infiniband/hw/ipath/ipath_driver.c | |||
@@ -460,10 +460,10 @@ static int __devinit ipath_init_one(struct pci_dev *pdev, | |||
460 | for (j = 0; j < 6; j++) { | 460 | for (j = 0; j < 6; j++) { |
461 | if (!pdev->resource[j].start) | 461 | if (!pdev->resource[j].start) |
462 | continue; | 462 | continue; |
463 | ipath_cdbg(VERBOSE, "BAR %d start %lx, end %lx, len %lx\n", | 463 | ipath_cdbg(VERBOSE, "BAR %d start %llx, end %llx, len %llx\n", |
464 | j, pdev->resource[j].start, | 464 | j, (unsigned long long)pdev->resource[j].start, |
465 | pdev->resource[j].end, | 465 | (unsigned long long)pdev->resource[j].end, |
466 | pci_resource_len(pdev, j)); | 466 | (unsigned long long)pci_resource_len(pdev, j)); |
467 | } | 467 | } |
468 | 468 | ||
469 | if (!addr) { | 469 | if (!addr) { |
diff --git a/drivers/infiniband/hw/mthca/mthca_main.c b/drivers/infiniband/hw/mthca/mthca_main.c index 9b9ff7bff357..465fd220569c 100644 --- a/drivers/infiniband/hw/mthca/mthca_main.c +++ b/drivers/infiniband/hw/mthca/mthca_main.c | |||
@@ -172,8 +172,9 @@ static int __devinit mthca_dev_lim(struct mthca_dev *mdev, struct mthca_dev_lim | |||
172 | 172 | ||
173 | if (dev_lim->uar_size > pci_resource_len(mdev->pdev, 2)) { | 173 | if (dev_lim->uar_size > pci_resource_len(mdev->pdev, 2)) { |
174 | mthca_err(mdev, "HCA reported UAR size of 0x%x bigger than " | 174 | mthca_err(mdev, "HCA reported UAR size of 0x%x bigger than " |
175 | "PCI resource 2 size of 0x%lx, aborting.\n", | 175 | "PCI resource 2 size of 0x%llx, aborting.\n", |
176 | dev_lim->uar_size, pci_resource_len(mdev->pdev, 2)); | 176 | dev_lim->uar_size, |
177 | (unsigned long long)pci_resource_len(mdev->pdev, 2)); | ||
177 | return -ENODEV; | 178 | return -ENODEV; |
178 | } | 179 | } |
179 | 180 | ||
diff --git a/drivers/input/input.c b/drivers/input/input.c index de2e7546b491..a90486f5e491 100644 --- a/drivers/input/input.c +++ b/drivers/input/input.c | |||
@@ -998,12 +998,13 @@ void input_unregister_device(struct input_dev *dev) | |||
998 | sysfs_remove_group(&dev->cdev.kobj, &input_dev_caps_attr_group); | 998 | sysfs_remove_group(&dev->cdev.kobj, &input_dev_caps_attr_group); |
999 | sysfs_remove_group(&dev->cdev.kobj, &input_dev_id_attr_group); | 999 | sysfs_remove_group(&dev->cdev.kobj, &input_dev_id_attr_group); |
1000 | sysfs_remove_group(&dev->cdev.kobj, &input_dev_attr_group); | 1000 | sysfs_remove_group(&dev->cdev.kobj, &input_dev_attr_group); |
1001 | class_device_unregister(&dev->cdev); | ||
1002 | 1001 | ||
1003 | mutex_lock(&dev->mutex); | 1002 | mutex_lock(&dev->mutex); |
1004 | dev->name = dev->phys = dev->uniq = NULL; | 1003 | dev->name = dev->phys = dev->uniq = NULL; |
1005 | mutex_unlock(&dev->mutex); | 1004 | mutex_unlock(&dev->mutex); |
1006 | 1005 | ||
1006 | class_device_unregister(&dev->cdev); | ||
1007 | |||
1007 | input_wakeup_procfs_readers(); | 1008 | input_wakeup_procfs_readers(); |
1008 | } | 1009 | } |
1009 | EXPORT_SYMBOL(input_unregister_device); | 1010 | EXPORT_SYMBOL(input_unregister_device); |
diff --git a/drivers/input/joystick/db9.c b/drivers/input/joystick/db9.c index 6f31f054d1bb..5080e15c6d30 100644 --- a/drivers/input/joystick/db9.c +++ b/drivers/input/joystick/db9.c | |||
@@ -584,7 +584,7 @@ static struct db9 __init *db9_probe(int parport, int mode) | |||
584 | goto err_out; | 584 | goto err_out; |
585 | } | 585 | } |
586 | 586 | ||
587 | if (db9_mode[mode].bidirectional && !(pp->modes & PARPORT_MODE_TRISTATE)) { | 587 | if (db9_mode->bidirectional && !(pp->modes & PARPORT_MODE_TRISTATE)) { |
588 | printk(KERN_ERR "db9.c: specified parport is not bidirectional\n"); | 588 | printk(KERN_ERR "db9.c: specified parport is not bidirectional\n"); |
589 | err = -EINVAL; | 589 | err = -EINVAL; |
590 | goto err_put_pp; | 590 | goto err_put_pp; |
diff --git a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c index ffde8f86e0fb..ce1f10e8984b 100644 --- a/drivers/input/keyboard/atkbd.c +++ b/drivers/input/keyboard/atkbd.c | |||
@@ -459,7 +459,7 @@ static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data, | |||
459 | } | 459 | } |
460 | 460 | ||
461 | input_regs(dev, regs); | 461 | input_regs(dev, regs); |
462 | input_report_key(dev, keycode, value); | 462 | input_event(dev, EV_KEY, keycode, value); |
463 | input_sync(dev); | 463 | input_sync(dev); |
464 | 464 | ||
465 | if (value && add_release_event) { | 465 | if (value && add_release_event) { |
diff --git a/drivers/input/misc/wistron_btns.c b/drivers/input/misc/wistron_btns.c index e4e5be111c96..ccf0faeee5c1 100644 --- a/drivers/input/misc/wistron_btns.c +++ b/drivers/input/misc/wistron_btns.c | |||
@@ -285,6 +285,15 @@ static struct key_entry keymap_fujitsu_n3510[] = { | |||
285 | { KE_END, 0 } | 285 | { KE_END, 0 } |
286 | }; | 286 | }; |
287 | 287 | ||
288 | static struct key_entry keymap_wistron_ms2111[] = { | ||
289 | { KE_KEY, 0x11, KEY_PROG1 }, | ||
290 | { KE_KEY, 0x12, KEY_PROG2 }, | ||
291 | { KE_KEY, 0x13, KEY_PROG3 }, | ||
292 | { KE_KEY, 0x31, KEY_MAIL }, | ||
293 | { KE_KEY, 0x36, KEY_WWW }, | ||
294 | { KE_END, 0 } | ||
295 | }; | ||
296 | |||
288 | static struct key_entry keymap_wistron_ms2141[] = { | 297 | static struct key_entry keymap_wistron_ms2141[] = { |
289 | { KE_KEY, 0x11, KEY_PROG1 }, | 298 | { KE_KEY, 0x11, KEY_PROG1 }, |
290 | { KE_KEY, 0x12, KEY_PROG2 }, | 299 | { KE_KEY, 0x12, KEY_PROG2 }, |
@@ -326,6 +335,7 @@ static struct key_entry keymap_aopen_1559as[] = { | |||
326 | { KE_WIFI, 0x30, 0 }, | 335 | { KE_WIFI, 0x30, 0 }, |
327 | { KE_KEY, 0x31, KEY_MAIL }, | 336 | { KE_KEY, 0x31, KEY_MAIL }, |
328 | { KE_KEY, 0x36, KEY_WWW }, | 337 | { KE_KEY, 0x36, KEY_WWW }, |
338 | { KE_END, 0 }, | ||
329 | }; | 339 | }; |
330 | 340 | ||
331 | /* | 341 | /* |
@@ -388,6 +398,15 @@ static struct dmi_system_id dmi_ids[] = { | |||
388 | }, | 398 | }, |
389 | .driver_data = keymap_aopen_1559as | 399 | .driver_data = keymap_aopen_1559as |
390 | }, | 400 | }, |
401 | { | ||
402 | .callback = dmi_matched, | ||
403 | .ident = "Medion MD 9783", | ||
404 | .matches = { | ||
405 | DMI_MATCH(DMI_SYS_VENDOR, "MEDIONNB"), | ||
406 | DMI_MATCH(DMI_PRODUCT_NAME, "MD 9783"), | ||
407 | }, | ||
408 | .driver_data = keymap_wistron_ms2111 | ||
409 | }, | ||
391 | { NULL, } | 410 | { NULL, } |
392 | }; | 411 | }; |
393 | 412 | ||
diff --git a/drivers/input/serio/ct82c710.c b/drivers/input/serio/ct82c710.c index 096b6a0b5cca..1ac739ef2ffa 100644 --- a/drivers/input/serio/ct82c710.c +++ b/drivers/input/serio/ct82c710.c | |||
@@ -189,7 +189,7 @@ static int __devinit ct82c710_probe(struct platform_device *dev) | |||
189 | strlcpy(ct82c710_port->name, "C&T 82c710 mouse port", | 189 | strlcpy(ct82c710_port->name, "C&T 82c710 mouse port", |
190 | sizeof(ct82c710_port->name)); | 190 | sizeof(ct82c710_port->name)); |
191 | snprintf(ct82c710_port->phys, sizeof(ct82c710_port->phys), | 191 | snprintf(ct82c710_port->phys, sizeof(ct82c710_port->phys), |
192 | "isa%04lx/serio0", CT82C710_DATA); | 192 | "isa%16llx/serio0", (unsigned long long)CT82C710_DATA); |
193 | 193 | ||
194 | serio_register_port(ct82c710_port); | 194 | serio_register_port(ct82c710_port); |
195 | 195 | ||
@@ -241,8 +241,8 @@ static int __init ct82c710_init(void) | |||
241 | 241 | ||
242 | serio_register_port(ct82c710_port); | 242 | serio_register_port(ct82c710_port); |
243 | 243 | ||
244 | printk(KERN_INFO "serio: C&T 82c710 mouse port at %#lx irq %d\n", | 244 | printk(KERN_INFO "serio: C&T 82c710 mouse port at %#llx irq %d\n", |
245 | CT82C710_DATA, CT82C710_IRQ); | 245 | (unsigned long long)CT82C710_DATA, CT82C710_IRQ); |
246 | 246 | ||
247 | return 0; | 247 | return 0; |
248 | 248 | ||
diff --git a/drivers/input/serio/serio_raw.c b/drivers/input/serio/serio_raw.c index 5a2703b536dc..71a8eea816cb 100644 --- a/drivers/input/serio/serio_raw.c +++ b/drivers/input/serio/serio_raw.c | |||
@@ -16,7 +16,6 @@ | |||
16 | #include <linux/init.h> | 16 | #include <linux/init.h> |
17 | #include <linux/major.h> | 17 | #include <linux/major.h> |
18 | #include <linux/device.h> | 18 | #include <linux/device.h> |
19 | #include <linux/devfs_fs_kernel.h> | ||
20 | #include <linux/miscdevice.h> | 19 | #include <linux/miscdevice.h> |
21 | #include <linux/wait.h> | 20 | #include <linux/wait.h> |
22 | #include <linux/mutex.h> | 21 | #include <linux/mutex.h> |
diff --git a/drivers/isdn/capi/capi.c b/drivers/isdn/capi/capi.c index 2e541fa02024..a518ec531021 100644 --- a/drivers/isdn/capi/capi.c +++ b/drivers/isdn/capi/capi.c | |||
@@ -39,7 +39,6 @@ | |||
39 | #include <linux/init.h> | 39 | #include <linux/init.h> |
40 | #include <linux/device.h> | 40 | #include <linux/device.h> |
41 | #include <linux/moduleparam.h> | 41 | #include <linux/moduleparam.h> |
42 | #include <linux/devfs_fs_kernel.h> | ||
43 | #include <linux/isdn/capiutil.h> | 42 | #include <linux/isdn/capiutil.h> |
44 | #include <linux/isdn/capicmd.h> | 43 | #include <linux/isdn/capicmd.h> |
45 | #if defined(CONFIG_ISDN_CAPI_CAPIFS) || defined(CONFIG_ISDN_CAPI_CAPIFS_MODULE) | 44 | #if defined(CONFIG_ISDN_CAPI_CAPIFS) || defined(CONFIG_ISDN_CAPI_CAPIFS_MODULE) |
@@ -1337,7 +1336,6 @@ static int capinc_tty_init(void) | |||
1337 | 1336 | ||
1338 | drv->owner = THIS_MODULE; | 1337 | drv->owner = THIS_MODULE; |
1339 | drv->driver_name = "capi_nc"; | 1338 | drv->driver_name = "capi_nc"; |
1340 | drv->devfs_name = "capi/"; | ||
1341 | drv->name = "capi"; | 1339 | drv->name = "capi"; |
1342 | drv->major = capi_ttymajor; | 1340 | drv->major = capi_ttymajor; |
1343 | drv->minor_start = 0; | 1341 | drv->minor_start = 0; |
@@ -1516,8 +1514,6 @@ static int __init capi_init(void) | |||
1516 | } | 1514 | } |
1517 | 1515 | ||
1518 | class_device_create(capi_class, NULL, MKDEV(capi_major, 0), NULL, "capi"); | 1516 | class_device_create(capi_class, NULL, MKDEV(capi_major, 0), NULL, "capi"); |
1519 | devfs_mk_cdev(MKDEV(capi_major, 0), S_IFCHR | S_IRUSR | S_IWUSR, | ||
1520 | "isdn/capi20"); | ||
1521 | 1517 | ||
1522 | #ifdef CONFIG_ISDN_CAPI_MIDDLEWARE | 1518 | #ifdef CONFIG_ISDN_CAPI_MIDDLEWARE |
1523 | if (capinc_tty_init() < 0) { | 1519 | if (capinc_tty_init() < 0) { |
@@ -1552,7 +1548,6 @@ static void __exit capi_exit(void) | |||
1552 | class_device_destroy(capi_class, MKDEV(capi_major, 0)); | 1548 | class_device_destroy(capi_class, MKDEV(capi_major, 0)); |
1553 | class_destroy(capi_class); | 1549 | class_destroy(capi_class); |
1554 | unregister_chrdev(capi_major, "capi20"); | 1550 | unregister_chrdev(capi_major, "capi20"); |
1555 | devfs_remove("isdn/capi20"); | ||
1556 | 1551 | ||
1557 | #ifdef CONFIG_ISDN_CAPI_MIDDLEWARE | 1552 | #ifdef CONFIG_ISDN_CAPI_MIDDLEWARE |
1558 | capinc_tty_exit(); | 1553 | capinc_tty_exit(); |
diff --git a/drivers/isdn/gigaset/bas-gigaset.c b/drivers/isdn/gigaset/bas-gigaset.c index 8a45715dd4c1..3845defd4901 100644 --- a/drivers/isdn/gigaset/bas-gigaset.c +++ b/drivers/isdn/gigaset/bas-gigaset.c | |||
@@ -41,7 +41,6 @@ MODULE_PARM_DESC(cidmode, "Call-ID mode"); | |||
41 | #define GIGASET_MINORS 1 | 41 | #define GIGASET_MINORS 1 |
42 | #define GIGASET_MINOR 16 | 42 | #define GIGASET_MINOR 16 |
43 | #define GIGASET_MODULENAME "bas_gigaset" | 43 | #define GIGASET_MODULENAME "bas_gigaset" |
44 | #define GIGASET_DEVFSNAME "gig/bas/" | ||
45 | #define GIGASET_DEVNAME "ttyGB" | 44 | #define GIGASET_DEVNAME "ttyGB" |
46 | 45 | ||
47 | /* length limit according to Siemens 3070usb-protokoll.doc ch. 2.1 */ | 46 | /* length limit according to Siemens 3070usb-protokoll.doc ch. 2.1 */ |
@@ -2349,8 +2348,7 @@ static int __init bas_gigaset_init(void) | |||
2349 | /* allocate memory for our driver state and intialize it */ | 2348 | /* allocate memory for our driver state and intialize it */ |
2350 | if ((driver = gigaset_initdriver(GIGASET_MINOR, GIGASET_MINORS, | 2349 | if ((driver = gigaset_initdriver(GIGASET_MINOR, GIGASET_MINORS, |
2351 | GIGASET_MODULENAME, GIGASET_DEVNAME, | 2350 | GIGASET_MODULENAME, GIGASET_DEVNAME, |
2352 | GIGASET_DEVFSNAME, &gigops, | 2351 | &gigops, THIS_MODULE)) == NULL) |
2353 | THIS_MODULE)) == NULL) | ||
2354 | goto error; | 2352 | goto error; |
2355 | 2353 | ||
2356 | /* allocate memory for our device state and intialize it */ | 2354 | /* allocate memory for our device state and intialize it */ |
diff --git a/drivers/isdn/gigaset/common.c b/drivers/isdn/gigaset/common.c index acb7e2656780..aca165d43aa0 100644 --- a/drivers/isdn/gigaset/common.c +++ b/drivers/isdn/gigaset/common.c | |||
@@ -981,7 +981,7 @@ exit: | |||
981 | EXPORT_SYMBOL_GPL(gigaset_stop); | 981 | EXPORT_SYMBOL_GPL(gigaset_stop); |
982 | 982 | ||
983 | static LIST_HEAD(drivers); | 983 | static LIST_HEAD(drivers); |
984 | static spinlock_t driver_lock = SPIN_LOCK_UNLOCKED; | 984 | static DEFINE_SPINLOCK(driver_lock); |
985 | 985 | ||
986 | struct cardstate *gigaset_get_cs_by_id(int id) | 986 | struct cardstate *gigaset_get_cs_by_id(int id) |
987 | { | 987 | { |
@@ -1092,14 +1092,12 @@ EXPORT_SYMBOL_GPL(gigaset_freedriver); | |||
1092 | * minors Number of minors this driver can handle | 1092 | * minors Number of minors this driver can handle |
1093 | * procname Name of the driver | 1093 | * procname Name of the driver |
1094 | * devname Name of the device files (prefix without minor number) | 1094 | * devname Name of the device files (prefix without minor number) |
1095 | * devfsname Devfs name of the device files without %d | ||
1096 | * return value: | 1095 | * return value: |
1097 | * Pointer to the gigaset_driver structure on success, NULL on failure. | 1096 | * Pointer to the gigaset_driver structure on success, NULL on failure. |
1098 | */ | 1097 | */ |
1099 | struct gigaset_driver *gigaset_initdriver(unsigned minor, unsigned minors, | 1098 | struct gigaset_driver *gigaset_initdriver(unsigned minor, unsigned minors, |
1100 | const char *procname, | 1099 | const char *procname, |
1101 | const char *devname, | 1100 | const char *devname, |
1102 | const char *devfsname, | ||
1103 | const struct gigaset_ops *ops, | 1101 | const struct gigaset_ops *ops, |
1104 | struct module *owner) | 1102 | struct module *owner) |
1105 | { | 1103 | { |
@@ -1139,7 +1137,7 @@ struct gigaset_driver *gigaset_initdriver(unsigned minor, unsigned minors, | |||
1139 | drv->cs[i].minor_index = i; | 1137 | drv->cs[i].minor_index = i; |
1140 | } | 1138 | } |
1141 | 1139 | ||
1142 | gigaset_if_initdriver(drv, procname, devname, devfsname); | 1140 | gigaset_if_initdriver(drv, procname, devname); |
1143 | 1141 | ||
1144 | spin_lock_irqsave(&driver_lock, flags); | 1142 | spin_lock_irqsave(&driver_lock, flags); |
1145 | list_add(&drv->list, &drivers); | 1143 | list_add(&drv->list, &drivers); |
diff --git a/drivers/isdn/gigaset/gigaset.h b/drivers/isdn/gigaset/gigaset.h index 8d63d822104f..1ca3bfdef51d 100644 --- a/drivers/isdn/gigaset/gigaset.h +++ b/drivers/isdn/gigaset/gigaset.h | |||
@@ -769,7 +769,6 @@ void gigaset_block_channels(struct cardstate *cs); | |||
769 | struct gigaset_driver *gigaset_initdriver(unsigned minor, unsigned minors, | 769 | struct gigaset_driver *gigaset_initdriver(unsigned minor, unsigned minors, |
770 | const char *procname, | 770 | const char *procname, |
771 | const char *devname, | 771 | const char *devname, |
772 | const char *devfsname, | ||
773 | const struct gigaset_ops *ops, | 772 | const struct gigaset_ops *ops, |
774 | struct module *owner); | 773 | struct module *owner); |
775 | 774 | ||
@@ -892,7 +891,7 @@ int gigaset_fill_inbuf(struct inbuf_t *inbuf, const unsigned char *src, | |||
892 | 891 | ||
893 | /* initialize interface */ | 892 | /* initialize interface */ |
894 | void gigaset_if_initdriver(struct gigaset_driver *drv, const char *procname, | 893 | void gigaset_if_initdriver(struct gigaset_driver *drv, const char *procname, |
895 | const char *devname, const char *devfsname); | 894 | const char *devname); |
896 | /* release interface */ | 895 | /* release interface */ |
897 | void gigaset_if_freedriver(struct gigaset_driver *drv); | 896 | void gigaset_if_freedriver(struct gigaset_driver *drv); |
898 | /* add minor */ | 897 | /* add minor */ |
diff --git a/drivers/isdn/gigaset/interface.c b/drivers/isdn/gigaset/interface.c index 74fd234956c8..bd2e4267528e 100644 --- a/drivers/isdn/gigaset/interface.c +++ b/drivers/isdn/gigaset/interface.c | |||
@@ -673,10 +673,9 @@ EXPORT_SYMBOL_GPL(gigaset_if_receive); | |||
673 | * drv Driver | 673 | * drv Driver |
674 | * procname Name of the driver (e.g. for /proc/tty/drivers) | 674 | * procname Name of the driver (e.g. for /proc/tty/drivers) |
675 | * devname Name of the device files (prefix without minor number) | 675 | * devname Name of the device files (prefix without minor number) |
676 | * devfsname Devfs name of the device files without %d | ||
677 | */ | 676 | */ |
678 | void gigaset_if_initdriver(struct gigaset_driver *drv, const char *procname, | 677 | void gigaset_if_initdriver(struct gigaset_driver *drv, const char *procname, |
679 | const char *devname, const char *devfsname) | 678 | const char *devname) |
680 | { | 679 | { |
681 | unsigned minors = drv->minors; | 680 | unsigned minors = drv->minors; |
682 | int ret; | 681 | int ret; |
@@ -692,7 +691,7 @@ void gigaset_if_initdriver(struct gigaset_driver *drv, const char *procname, | |||
692 | tty->major = GIG_MAJOR, | 691 | tty->major = GIG_MAJOR, |
693 | tty->type = TTY_DRIVER_TYPE_SERIAL, | 692 | tty->type = TTY_DRIVER_TYPE_SERIAL, |
694 | tty->subtype = SERIAL_TYPE_NORMAL, | 693 | tty->subtype = SERIAL_TYPE_NORMAL, |
695 | tty->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_NO_DEVFS, | 694 | tty->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV; |
696 | 695 | ||
697 | tty->driver_name = procname; | 696 | tty->driver_name = procname; |
698 | tty->name = devname; | 697 | tty->name = devname; |
@@ -700,7 +699,6 @@ void gigaset_if_initdriver(struct gigaset_driver *drv, const char *procname, | |||
700 | tty->num = drv->minors; | 699 | tty->num = drv->minors; |
701 | 700 | ||
702 | tty->owner = THIS_MODULE; | 701 | tty->owner = THIS_MODULE; |
703 | tty->devfs_name = devfsname; | ||
704 | 702 | ||
705 | tty->init_termios = tty_std_termios; //FIXME | 703 | tty->init_termios = tty_std_termios; //FIXME |
706 | tty->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL; //FIXME | 704 | tty->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL; //FIXME |
diff --git a/drivers/isdn/gigaset/usb-gigaset.c b/drivers/isdn/gigaset/usb-gigaset.c index d86ab68114b0..6e05d9d4a51a 100644 --- a/drivers/isdn/gigaset/usb-gigaset.c +++ b/drivers/isdn/gigaset/usb-gigaset.c | |||
@@ -41,7 +41,6 @@ MODULE_PARM_DESC(cidmode, "Call-ID mode"); | |||
41 | #define GIGASET_MINORS 1 | 41 | #define GIGASET_MINORS 1 |
42 | #define GIGASET_MINOR 8 | 42 | #define GIGASET_MINOR 8 |
43 | #define GIGASET_MODULENAME "usb_gigaset" | 43 | #define GIGASET_MODULENAME "usb_gigaset" |
44 | #define GIGASET_DEVFSNAME "gig/usb/" | ||
45 | #define GIGASET_DEVNAME "ttyGU" | 44 | #define GIGASET_DEVNAME "ttyGU" |
46 | 45 | ||
47 | #define IF_WRITEBUF 2000 //FIXME // WAKEUP_CHARS: 256 | 46 | #define IF_WRITEBUF 2000 //FIXME // WAKEUP_CHARS: 256 |
@@ -896,8 +895,7 @@ static int __init usb_gigaset_init(void) | |||
896 | /* allocate memory for our driver state and intialize it */ | 895 | /* allocate memory for our driver state and intialize it */ |
897 | if ((driver = gigaset_initdriver(GIGASET_MINOR, GIGASET_MINORS, | 896 | if ((driver = gigaset_initdriver(GIGASET_MINOR, GIGASET_MINORS, |
898 | GIGASET_MODULENAME, GIGASET_DEVNAME, | 897 | GIGASET_MODULENAME, GIGASET_DEVNAME, |
899 | GIGASET_DEVFSNAME, &ops, | 898 | &ops, THIS_MODULE)) == NULL) |
900 | THIS_MODULE)) == NULL) | ||
901 | goto error; | 899 | goto error; |
902 | 900 | ||
903 | /* allocate memory for our device state and intialize it */ | 901 | /* allocate memory for our device state and intialize it */ |
diff --git a/drivers/isdn/hardware/avm/b1pcmcia.c b/drivers/isdn/hardware/avm/b1pcmcia.c index 9746cc5ffff8..ad5025155b4e 100644 --- a/drivers/isdn/hardware/avm/b1pcmcia.c +++ b/drivers/isdn/hardware/avm/b1pcmcia.c | |||
@@ -82,7 +82,7 @@ static int b1pcmcia_add_card(unsigned int port, unsigned irq, | |||
82 | card->irq = irq; | 82 | card->irq = irq; |
83 | card->cardtype = cardtype; | 83 | card->cardtype = cardtype; |
84 | 84 | ||
85 | retval = request_irq(card->irq, b1_interrupt, 0, card->name, card); | 85 | retval = request_irq(card->irq, b1_interrupt, SA_SHIRQ, card->name, card); |
86 | if (retval) { | 86 | if (retval) { |
87 | printk(KERN_ERR "b1pcmcia: unable to get IRQ %d.\n", | 87 | printk(KERN_ERR "b1pcmcia: unable to get IRQ %d.\n", |
88 | card->irq); | 88 | card->irq); |
diff --git a/drivers/isdn/hardware/eicon/divamnt.c b/drivers/isdn/hardware/eicon/divamnt.c index 6146f7633be5..b163c5909182 100644 --- a/drivers/isdn/hardware/eicon/divamnt.c +++ b/drivers/isdn/hardware/eicon/divamnt.c | |||
@@ -17,7 +17,6 @@ | |||
17 | #include <linux/sched.h> | 17 | #include <linux/sched.h> |
18 | #include <linux/smp_lock.h> | 18 | #include <linux/smp_lock.h> |
19 | #include <linux/poll.h> | 19 | #include <linux/poll.h> |
20 | #include <linux/devfs_fs_kernel.h> | ||
21 | #include <asm/uaccess.h> | 20 | #include <asm/uaccess.h> |
22 | 21 | ||
23 | #include "platform.h" | 22 | #include "platform.h" |
@@ -178,7 +177,6 @@ static struct file_operations divas_maint_fops = { | |||
178 | 177 | ||
179 | static void divas_maint_unregister_chrdev(void) | 178 | static void divas_maint_unregister_chrdev(void) |
180 | { | 179 | { |
181 | devfs_remove(DEVNAME); | ||
182 | unregister_chrdev(major, DEVNAME); | 180 | unregister_chrdev(major, DEVNAME); |
183 | } | 181 | } |
184 | 182 | ||
@@ -190,7 +188,6 @@ static int DIVA_INIT_FUNCTION divas_maint_register_chrdev(void) | |||
190 | DRIVERLNAME); | 188 | DRIVERLNAME); |
191 | return (0); | 189 | return (0); |
192 | } | 190 | } |
193 | devfs_mk_cdev(MKDEV(major, 0), S_IFCHR|S_IRUSR|S_IWUSR, DEVNAME); | ||
194 | 191 | ||
195 | return (1); | 192 | return (1); |
196 | } | 193 | } |
diff --git a/drivers/isdn/hardware/eicon/divasi.c b/drivers/isdn/hardware/eicon/divasi.c index df715b47e2b4..6e7d89a31c1d 100644 --- a/drivers/isdn/hardware/eicon/divasi.c +++ b/drivers/isdn/hardware/eicon/divasi.c | |||
@@ -19,7 +19,6 @@ | |||
19 | #include <linux/poll.h> | 19 | #include <linux/poll.h> |
20 | #include <linux/proc_fs.h> | 20 | #include <linux/proc_fs.h> |
21 | #include <linux/skbuff.h> | 21 | #include <linux/skbuff.h> |
22 | #include <linux/devfs_fs_kernel.h> | ||
23 | #include <asm/uaccess.h> | 22 | #include <asm/uaccess.h> |
24 | 23 | ||
25 | #include "platform.h" | 24 | #include "platform.h" |
@@ -145,7 +144,6 @@ static struct file_operations divas_idi_fops = { | |||
145 | 144 | ||
146 | static void divas_idi_unregister_chrdev(void) | 145 | static void divas_idi_unregister_chrdev(void) |
147 | { | 146 | { |
148 | devfs_remove(DEVNAME); | ||
149 | unregister_chrdev(major, DEVNAME); | 147 | unregister_chrdev(major, DEVNAME); |
150 | } | 148 | } |
151 | 149 | ||
@@ -157,7 +155,6 @@ static int DIVA_INIT_FUNCTION divas_idi_register_chrdev(void) | |||
157 | DRIVERLNAME); | 155 | DRIVERLNAME); |
158 | return (0); | 156 | return (0); |
159 | } | 157 | } |
160 | devfs_mk_cdev(MKDEV(major, 0), S_IFCHR|S_IRUSR|S_IWUSR, DEVNAME); | ||
161 | 158 | ||
162 | return (1); | 159 | return (1); |
163 | } | 160 | } |
diff --git a/drivers/isdn/hardware/eicon/divasmain.c b/drivers/isdn/hardware/eicon/divasmain.c index c9b26e86d183..9dee6a39104c 100644 --- a/drivers/isdn/hardware/eicon/divasmain.c +++ b/drivers/isdn/hardware/eicon/divasmain.c | |||
@@ -14,7 +14,6 @@ | |||
14 | #include <linux/init.h> | 14 | #include <linux/init.h> |
15 | #include <linux/kernel.h> | 15 | #include <linux/kernel.h> |
16 | #include <linux/sched.h> | 16 | #include <linux/sched.h> |
17 | #include <linux/devfs_fs_kernel.h> | ||
18 | #include <asm/uaccess.h> | 17 | #include <asm/uaccess.h> |
19 | #include <asm/io.h> | 18 | #include <asm/io.h> |
20 | #include <linux/ioport.h> | 19 | #include <linux/ioport.h> |
@@ -678,7 +677,6 @@ static struct file_operations divas_fops = { | |||
678 | 677 | ||
679 | static void divas_unregister_chrdev(void) | 678 | static void divas_unregister_chrdev(void) |
680 | { | 679 | { |
681 | devfs_remove(DEVNAME); | ||
682 | unregister_chrdev(major, DEVNAME); | 680 | unregister_chrdev(major, DEVNAME); |
683 | } | 681 | } |
684 | 682 | ||
@@ -690,7 +688,6 @@ static int DIVA_INIT_FUNCTION divas_register_chrdev(void) | |||
690 | DRIVERLNAME); | 688 | DRIVERLNAME); |
691 | return (0); | 689 | return (0); |
692 | } | 690 | } |
693 | devfs_mk_cdev(MKDEV(major, 0), S_IFCHR|S_IRUSR|S_IWUSR, DEVNAME); | ||
694 | 691 | ||
695 | return (1); | 692 | return (1); |
696 | } | 693 | } |
diff --git a/drivers/isdn/hisax/hfc_pci.c b/drivers/isdn/hisax/hfc_pci.c index 91d25acb5ede..3622720f0505 100644 --- a/drivers/isdn/hisax/hfc_pci.c +++ b/drivers/isdn/hisax/hfc_pci.c | |||
@@ -1688,7 +1688,7 @@ setup_hfcpci(struct IsdnCard *card) | |||
1688 | printk(KERN_WARNING "HFC-PCI: No IRQ for PCI card found\n"); | 1688 | printk(KERN_WARNING "HFC-PCI: No IRQ for PCI card found\n"); |
1689 | return (0); | 1689 | return (0); |
1690 | } | 1690 | } |
1691 | cs->hw.hfcpci.pci_io = (char *) dev_hfcpci->resource[ 1].start; | 1691 | cs->hw.hfcpci.pci_io = (char *)(unsigned long)dev_hfcpci->resource[1].start; |
1692 | printk(KERN_INFO "HiSax: HFC-PCI card manufacturer: %s card name: %s\n", id_list[i].vendor_name, id_list[i].card_name); | 1692 | printk(KERN_INFO "HiSax: HFC-PCI card manufacturer: %s card name: %s\n", id_list[i].vendor_name, id_list[i].card_name); |
1693 | } else { | 1693 | } else { |
1694 | printk(KERN_WARNING "HFC-PCI: No PCI card found\n"); | 1694 | printk(KERN_WARNING "HFC-PCI: No PCI card found\n"); |
diff --git a/drivers/isdn/hisax/sedlbauer_cs.c b/drivers/isdn/hisax/sedlbauer_cs.c index 9bb18f3f7829..f9c14a2970bc 100644 --- a/drivers/isdn/hisax/sedlbauer_cs.c +++ b/drivers/isdn/hisax/sedlbauer_cs.c | |||
@@ -164,7 +164,7 @@ static int sedlbauer_probe(struct pcmcia_device *link) | |||
164 | link->priv = local; | 164 | link->priv = local; |
165 | 165 | ||
166 | /* Interrupt setup */ | 166 | /* Interrupt setup */ |
167 | link->irq.Attributes = IRQ_TYPE_EXCLUSIVE; | 167 | link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING|IRQ_FIRST_SHARED; |
168 | link->irq.IRQInfo1 = IRQ_LEVEL_ID; | 168 | link->irq.IRQInfo1 = IRQ_LEVEL_ID; |
169 | link->irq.Handler = NULL; | 169 | link->irq.Handler = NULL; |
170 | 170 | ||
diff --git a/drivers/isdn/hisax/teles3.c b/drivers/isdn/hisax/teles3.c index a3eaf4d65707..090abd16b4bc 100644 --- a/drivers/isdn/hisax/teles3.c +++ b/drivers/isdn/hisax/teles3.c | |||
@@ -369,6 +369,7 @@ setup_teles3(struct IsdnCard *card) | |||
369 | cs->hw.teles3.hscx[1] + 96); | 369 | cs->hw.teles3.hscx[1] + 96); |
370 | return (0); | 370 | return (0); |
371 | } | 371 | } |
372 | cs->irq_flags |= SA_SHIRQ; /* cardbus can share */ | ||
372 | } else { | 373 | } else { |
373 | if (cs->hw.teles3.cfg_reg) { | 374 | if (cs->hw.teles3.cfg_reg) { |
374 | if (cs->typ == ISDN_CTYPE_COMPAQ_ISA) { | 375 | if (cs->typ == ISDN_CTYPE_COMPAQ_ISA) { |
diff --git a/drivers/isdn/hisax/telespci.c b/drivers/isdn/hisax/telespci.c index e2bb4fd8e25e..e82ab2251b82 100644 --- a/drivers/isdn/hisax/telespci.c +++ b/drivers/isdn/hisax/telespci.c | |||
@@ -311,8 +311,9 @@ setup_telespci(struct IsdnCard *card) | |||
311 | } | 311 | } |
312 | cs->hw.teles0.membase = ioremap(pci_resource_start(dev_tel, 0), | 312 | cs->hw.teles0.membase = ioremap(pci_resource_start(dev_tel, 0), |
313 | PAGE_SIZE); | 313 | PAGE_SIZE); |
314 | printk(KERN_INFO "Found: Zoran, base-address: 0x%lx, irq: 0x%x\n", | 314 | printk(KERN_INFO "Found: Zoran, base-address: 0x%llx, irq: 0x%x\n", |
315 | pci_resource_start(dev_tel, 0), dev_tel->irq); | 315 | (unsigned long long)pci_resource_start(dev_tel, 0), |
316 | dev_tel->irq); | ||
316 | } else { | 317 | } else { |
317 | printk(KERN_WARNING "TelesPCI: No PCI card found\n"); | 318 | printk(KERN_WARNING "TelesPCI: No PCI card found\n"); |
318 | return(0); | 319 | return(0); |
diff --git a/drivers/isdn/i4l/isdn_common.c b/drivers/isdn/i4l/isdn_common.c index b26e509ec759..eb21063e6f63 100644 --- a/drivers/isdn/i4l/isdn_common.c +++ b/drivers/isdn/i4l/isdn_common.c | |||
@@ -340,6 +340,16 @@ isdn_command(isdn_ctrl *cmd) | |||
340 | printk(KERN_WARNING "isdn_command command(%x) driver -1\n", cmd->command); | 340 | printk(KERN_WARNING "isdn_command command(%x) driver -1\n", cmd->command); |
341 | return(1); | 341 | return(1); |
342 | } | 342 | } |
343 | if (!dev->drv[cmd->driver]) { | ||
344 | printk(KERN_WARNING "isdn_command command(%x) dev->drv[%d] NULL\n", | ||
345 | cmd->command, cmd->driver); | ||
346 | return(1); | ||
347 | } | ||
348 | if (!dev->drv[cmd->driver]->interface) { | ||
349 | printk(KERN_WARNING "isdn_command command(%x) dev->drv[%d]->interface NULL\n", | ||
350 | cmd->command, cmd->driver); | ||
351 | return(1); | ||
352 | } | ||
343 | if (cmd->command == ISDN_CMD_SETL2) { | 353 | if (cmd->command == ISDN_CMD_SETL2) { |
344 | int idx = isdn_dc2minor(cmd->driver, cmd->arg & 255); | 354 | int idx = isdn_dc2minor(cmd->driver, cmd->arg & 255); |
345 | unsigned long l2prot = (cmd->arg >> 8) & 255; | 355 | unsigned long l2prot = (cmd->arg >> 8) & 255; |
@@ -1903,6 +1913,11 @@ isdn_free_channel(int di, int ch, int usage) | |||
1903 | { | 1913 | { |
1904 | int i; | 1914 | int i; |
1905 | 1915 | ||
1916 | if ((di < 0) || (ch < 0)) { | ||
1917 | printk(KERN_WARNING "%s: called with invalid drv(%d) or channel(%d)\n", | ||
1918 | __FUNCTION__, di, ch); | ||
1919 | return; | ||
1920 | } | ||
1906 | for (i = 0; i < ISDN_MAX_CHANNELS; i++) | 1921 | for (i = 0; i < ISDN_MAX_CHANNELS; i++) |
1907 | if (((!usage) || ((dev->usage[i] & ISDN_USAGE_MASK) == usage)) && | 1922 | if (((!usage) || ((dev->usage[i] & ISDN_USAGE_MASK) == usage)) && |
1908 | (dev->drvmap[i] == di) && | 1923 | (dev->drvmap[i] == di) && |
@@ -1918,7 +1933,8 @@ isdn_free_channel(int di, int ch, int usage) | |||
1918 | dev->v110[i] = NULL; | 1933 | dev->v110[i] = NULL; |
1919 | // 20.10.99 JIM, try to reinitialize v110 ! | 1934 | // 20.10.99 JIM, try to reinitialize v110 ! |
1920 | isdn_info_update(); | 1935 | isdn_info_update(); |
1921 | skb_queue_purge(&dev->drv[di]->rpqueue[ch]); | 1936 | if (dev->drv[di]) |
1937 | skb_queue_purge(&dev->drv[di]->rpqueue[ch]); | ||
1922 | } | 1938 | } |
1923 | } | 1939 | } |
1924 | 1940 | ||
diff --git a/drivers/isdn/i4l/isdn_tty.c b/drivers/isdn/i4l/isdn_tty.c index 2ac90242d263..0a53a990c100 100644 --- a/drivers/isdn/i4l/isdn_tty.c +++ b/drivers/isdn/i4l/isdn_tty.c | |||
@@ -82,7 +82,7 @@ isdn_tty_try_read(modem_info * info, struct sk_buff *skb) | |||
82 | int l = skb->len; | 82 | int l = skb->len; |
83 | unsigned char *dp = skb->data; | 83 | unsigned char *dp = skb->data; |
84 | while (--l) { | 84 | while (--l) { |
85 | if (*skb->data == DLE) | 85 | if (*dp == DLE) |
86 | tty_insert_flip_char(tty, DLE, 0); | 86 | tty_insert_flip_char(tty, DLE, 0); |
87 | tty_insert_flip_char(tty, *dp++, 0); | 87 | tty_insert_flip_char(tty, *dp++, 0); |
88 | } | 88 | } |
@@ -1890,14 +1890,13 @@ isdn_tty_modem_init(void) | |||
1890 | if (!m->tty_modem) | 1890 | if (!m->tty_modem) |
1891 | return -ENOMEM; | 1891 | return -ENOMEM; |
1892 | m->tty_modem->name = "ttyI"; | 1892 | m->tty_modem->name = "ttyI"; |
1893 | m->tty_modem->devfs_name = "isdn/ttyI"; | ||
1894 | m->tty_modem->major = ISDN_TTY_MAJOR; | 1893 | m->tty_modem->major = ISDN_TTY_MAJOR; |
1895 | m->tty_modem->minor_start = 0; | 1894 | m->tty_modem->minor_start = 0; |
1896 | m->tty_modem->type = TTY_DRIVER_TYPE_SERIAL; | 1895 | m->tty_modem->type = TTY_DRIVER_TYPE_SERIAL; |
1897 | m->tty_modem->subtype = SERIAL_TYPE_NORMAL; | 1896 | m->tty_modem->subtype = SERIAL_TYPE_NORMAL; |
1898 | m->tty_modem->init_termios = tty_std_termios; | 1897 | m->tty_modem->init_termios = tty_std_termios; |
1899 | m->tty_modem->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL; | 1898 | m->tty_modem->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL; |
1900 | m->tty_modem->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_NO_DEVFS; | 1899 | m->tty_modem->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV; |
1901 | m->tty_modem->driver_name = "isdn_tty"; | 1900 | m->tty_modem->driver_name = "isdn_tty"; |
1902 | tty_set_operations(m->tty_modem, &modem_ops); | 1901 | tty_set_operations(m->tty_modem, &modem_ops); |
1903 | retval = tty_register_driver(m->tty_modem); | 1902 | retval = tty_register_driver(m->tty_modem); |
diff --git a/drivers/isdn/i4l/isdn_x25iface.c b/drivers/isdn/i4l/isdn_x25iface.c index 743ac4077f35..8b3efc243161 100644 --- a/drivers/isdn/i4l/isdn_x25iface.c +++ b/drivers/isdn/i4l/isdn_x25iface.c | |||
@@ -208,7 +208,7 @@ static int isdn_x25iface_receive(struct concap_proto *cprot, struct sk_buff *skb | |||
208 | */ | 208 | */ |
209 | static int isdn_x25iface_connect_ind(struct concap_proto *cprot) | 209 | static int isdn_x25iface_connect_ind(struct concap_proto *cprot) |
210 | { | 210 | { |
211 | struct sk_buff * skb = dev_alloc_skb(1); | 211 | struct sk_buff * skb; |
212 | enum wan_states *state_p | 212 | enum wan_states *state_p |
213 | = &( ( (ix25_pdata_t*) (cprot->proto_data) ) -> state); | 213 | = &( ( (ix25_pdata_t*) (cprot->proto_data) ) -> state); |
214 | IX25DEBUG( "isdn_x25iface_connect_ind %s \n" | 214 | IX25DEBUG( "isdn_x25iface_connect_ind %s \n" |
@@ -220,6 +220,8 @@ static int isdn_x25iface_connect_ind(struct concap_proto *cprot) | |||
220 | return -1; | 220 | return -1; |
221 | } | 221 | } |
222 | *state_p = WAN_CONNECTED; | 222 | *state_p = WAN_CONNECTED; |
223 | |||
224 | skb = dev_alloc_skb(1); | ||
223 | if( skb ){ | 225 | if( skb ){ |
224 | *( skb_put(skb, 1) ) = 0x01; | 226 | *( skb_put(skb, 1) ) = 0x01; |
225 | skb->protocol = x25_type_trans(skb, cprot->net_dev); | 227 | skb->protocol = x25_type_trans(skb, cprot->net_dev); |
diff --git a/drivers/leds/led-core.c b/drivers/leds/led-core.c index fe6541326c71..9b015f9af351 100644 --- a/drivers/leds/led-core.c +++ b/drivers/leds/led-core.c | |||
@@ -18,7 +18,7 @@ | |||
18 | #include <linux/leds.h> | 18 | #include <linux/leds.h> |
19 | #include "leds.h" | 19 | #include "leds.h" |
20 | 20 | ||
21 | rwlock_t leds_list_lock = RW_LOCK_UNLOCKED; | 21 | DEFINE_RWLOCK(leds_list_lock); |
22 | LIST_HEAD(leds_list); | 22 | LIST_HEAD(leds_list); |
23 | 23 | ||
24 | EXPORT_SYMBOL_GPL(leds_list); | 24 | EXPORT_SYMBOL_GPL(leds_list); |
diff --git a/drivers/leds/led-triggers.c b/drivers/leds/led-triggers.c index 5e2cd8be1191..1b1ce6523960 100644 --- a/drivers/leds/led-triggers.c +++ b/drivers/leds/led-triggers.c | |||
@@ -26,7 +26,7 @@ | |||
26 | /* | 26 | /* |
27 | * Nests outside led_cdev->trigger_lock | 27 | * Nests outside led_cdev->trigger_lock |
28 | */ | 28 | */ |
29 | static rwlock_t triggers_list_lock = RW_LOCK_UNLOCKED; | 29 | static DEFINE_RWLOCK(triggers_list_lock); |
30 | static LIST_HEAD(trigger_list); | 30 | static LIST_HEAD(trigger_list); |
31 | 31 | ||
32 | ssize_t led_trigger_store(struct class_device *dev, const char *buf, | 32 | ssize_t led_trigger_store(struct class_device *dev, const char *buf, |
diff --git a/drivers/macintosh/Kconfig b/drivers/macintosh/Kconfig index 37cd6ee4586b..54f3f6b94efc 100644 --- a/drivers/macintosh/Kconfig +++ b/drivers/macintosh/Kconfig | |||
@@ -78,6 +78,18 @@ config ADB_PMU | |||
78 | this device; you should do so if your machine is one of those | 78 | this device; you should do so if your machine is one of those |
79 | mentioned above. | 79 | mentioned above. |
80 | 80 | ||
81 | config ADB_PMU_LED | ||
82 | bool "Support for the Power/iBook front LED" | ||
83 | depends on ADB_PMU | ||
84 | select NEW_LEDS | ||
85 | select LEDS_CLASS | ||
86 | help | ||
87 | Support the front LED on Power/iBooks as a generic LED that can | ||
88 | be triggered by any of the supported triggers. To get the | ||
89 | behaviour of the old CONFIG_BLK_DEV_IDE_PMAC_BLINK, select this | ||
90 | and the ide-disk LED trigger and configure appropriately through | ||
91 | sysfs. | ||
92 | |||
81 | config PMAC_SMU | 93 | config PMAC_SMU |
82 | bool "Support for SMU based PowerMacs" | 94 | bool "Support for SMU based PowerMacs" |
83 | depends on PPC_PMAC64 | 95 | depends on PPC_PMAC64 |
diff --git a/drivers/macintosh/Makefile b/drivers/macintosh/Makefile index 45a268f8047e..b53d45f87b0b 100644 --- a/drivers/macintosh/Makefile +++ b/drivers/macintosh/Makefile | |||
@@ -12,6 +12,7 @@ obj-$(CONFIG_INPUT_ADBHID) += adbhid.o | |||
12 | obj-$(CONFIG_ANSLCD) += ans-lcd.o | 12 | obj-$(CONFIG_ANSLCD) += ans-lcd.o |
13 | 13 | ||
14 | obj-$(CONFIG_ADB_PMU) += via-pmu.o via-pmu-event.o | 14 | obj-$(CONFIG_ADB_PMU) += via-pmu.o via-pmu-event.o |
15 | obj-$(CONFIG_ADB_PMU_LED) += via-pmu-led.o | ||
15 | obj-$(CONFIG_PMAC_BACKLIGHT) += via-pmu-backlight.o | 16 | obj-$(CONFIG_PMAC_BACKLIGHT) += via-pmu-backlight.o |
16 | obj-$(CONFIG_ADB_CUDA) += via-cuda.o | 17 | obj-$(CONFIG_ADB_CUDA) += via-cuda.o |
17 | obj-$(CONFIG_PMAC_APM_EMU) += apm_emu.o | 18 | obj-$(CONFIG_PMAC_APM_EMU) += apm_emu.o |
diff --git a/drivers/macintosh/adb.c b/drivers/macintosh/adb.c index 259fd8973ce9..9f1a049dc226 100644 --- a/drivers/macintosh/adb.c +++ b/drivers/macintosh/adb.c | |||
@@ -36,7 +36,6 @@ | |||
36 | #include <linux/spinlock.h> | 36 | #include <linux/spinlock.h> |
37 | #include <linux/completion.h> | 37 | #include <linux/completion.h> |
38 | #include <linux/device.h> | 38 | #include <linux/device.h> |
39 | #include <linux/devfs_fs_kernel.h> | ||
40 | 39 | ||
41 | #include <asm/uaccess.h> | 40 | #include <asm/uaccess.h> |
42 | #include <asm/semaphore.h> | 41 | #include <asm/semaphore.h> |
@@ -904,8 +903,6 @@ adbdev_init(void) | |||
904 | return; | 903 | return; |
905 | } | 904 | } |
906 | 905 | ||
907 | devfs_mk_cdev(MKDEV(ADB_MAJOR, 0), S_IFCHR | S_IRUSR | S_IWUSR, "adb"); | ||
908 | |||
909 | adb_dev_class = class_create(THIS_MODULE, "adb"); | 906 | adb_dev_class = class_create(THIS_MODULE, "adb"); |
910 | if (IS_ERR(adb_dev_class)) | 907 | if (IS_ERR(adb_dev_class)) |
911 | return; | 908 | return; |
diff --git a/drivers/macintosh/macio_asic.c b/drivers/macintosh/macio_asic.c index 431bd37225a1..c687ac703941 100644 --- a/drivers/macintosh/macio_asic.c +++ b/drivers/macintosh/macio_asic.c | |||
@@ -428,10 +428,10 @@ static struct macio_dev * macio_add_one_device(struct macio_chip *chip, | |||
428 | 428 | ||
429 | /* MacIO itself has a different reg, we use it's PCI base */ | 429 | /* MacIO itself has a different reg, we use it's PCI base */ |
430 | if (np == chip->of_node) { | 430 | if (np == chip->of_node) { |
431 | sprintf(dev->ofdev.dev.bus_id, "%1d.%08lx:%.*s", | 431 | sprintf(dev->ofdev.dev.bus_id, "%1d.%016llx:%.*s", |
432 | chip->lbus.index, | 432 | chip->lbus.index, |
433 | #ifdef CONFIG_PCI | 433 | #ifdef CONFIG_PCI |
434 | pci_resource_start(chip->lbus.pdev, 0), | 434 | (unsigned long long)pci_resource_start(chip->lbus.pdev, 0), |
435 | #else | 435 | #else |
436 | 0, /* NuBus may want to do something better here */ | 436 | 0, /* NuBus may want to do something better here */ |
437 | #endif | 437 | #endif |
diff --git a/drivers/macintosh/via-pmu-led.c b/drivers/macintosh/via-pmu-led.c new file mode 100644 index 000000000000..af8375ed0f5e --- /dev/null +++ b/drivers/macintosh/via-pmu-led.c | |||
@@ -0,0 +1,144 @@ | |||
1 | /* | ||
2 | * via-pmu LED class device | ||
3 | * | ||
4 | * Copyright 2006 Johannes Berg <johannes@sipsolutions.net> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, but | ||
12 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or | ||
14 | * NON INFRINGEMENT. See the GNU General Public License for more | ||
15 | * details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU General Public License | ||
18 | * along with this program; if not, write to the Free Software | ||
19 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
20 | * | ||
21 | */ | ||
22 | #include <linux/types.h> | ||
23 | #include <linux/kernel.h> | ||
24 | #include <linux/device.h> | ||
25 | #include <linux/leds.h> | ||
26 | #include <linux/adb.h> | ||
27 | #include <linux/pmu.h> | ||
28 | #include <asm/prom.h> | ||
29 | |||
30 | static spinlock_t pmu_blink_lock; | ||
31 | static struct adb_request pmu_blink_req; | ||
32 | /* -1: no change, 0: request off, 1: request on */ | ||
33 | static int requested_change; | ||
34 | static int sleeping; | ||
35 | |||
36 | static void pmu_req_done(struct adb_request * req) | ||
37 | { | ||
38 | unsigned long flags; | ||
39 | |||
40 | spin_lock_irqsave(&pmu_blink_lock, flags); | ||
41 | /* if someone requested a change in the meantime | ||
42 | * (we only see the last one which is fine) | ||
43 | * then apply it now */ | ||
44 | if (requested_change != -1 && !sleeping) | ||
45 | pmu_request(&pmu_blink_req, NULL, 4, 0xee, 4, 0, requested_change); | ||
46 | /* reset requested change */ | ||
47 | requested_change = -1; | ||
48 | spin_unlock_irqrestore(&pmu_blink_lock, flags); | ||
49 | } | ||
50 | |||
51 | static void pmu_led_set(struct led_classdev *led_cdev, | ||
52 | enum led_brightness brightness) | ||
53 | { | ||
54 | unsigned long flags; | ||
55 | |||
56 | spin_lock_irqsave(&pmu_blink_lock, flags); | ||
57 | switch (brightness) { | ||
58 | case LED_OFF: | ||
59 | requested_change = 0; | ||
60 | break; | ||
61 | case LED_FULL: | ||
62 | requested_change = 1; | ||
63 | break; | ||
64 | default: | ||
65 | goto out; | ||
66 | break; | ||
67 | } | ||
68 | /* if request isn't done, then don't do anything */ | ||
69 | if (pmu_blink_req.complete && !sleeping) | ||
70 | pmu_request(&pmu_blink_req, NULL, 4, 0xee, 4, 0, requested_change); | ||
71 | out: | ||
72 | spin_unlock_irqrestore(&pmu_blink_lock, flags); | ||
73 | } | ||
74 | |||
75 | static struct led_classdev pmu_led = { | ||
76 | .name = "pmu-front-led", | ||
77 | #ifdef CONFIG_BLK_DEV_IDE_PMAC_BLINK | ||
78 | .default_trigger = "ide-disk", | ||
79 | #endif | ||
80 | .brightness_set = pmu_led_set, | ||
81 | }; | ||
82 | |||
83 | #ifdef CONFIG_PM | ||
84 | static int pmu_led_sleep_call(struct pmu_sleep_notifier *self, int when) | ||
85 | { | ||
86 | unsigned long flags; | ||
87 | |||
88 | spin_lock_irqsave(&pmu_blink_lock, flags); | ||
89 | |||
90 | switch (when) { | ||
91 | case PBOOK_SLEEP_REQUEST: | ||
92 | sleeping = 1; | ||
93 | break; | ||
94 | case PBOOK_WAKE: | ||
95 | sleeping = 0; | ||
96 | break; | ||
97 | default: | ||
98 | /* do nothing */ | ||
99 | break; | ||
100 | } | ||
101 | spin_unlock_irqrestore(&pmu_blink_lock, flags); | ||
102 | |||
103 | return PBOOK_SLEEP_OK; | ||
104 | } | ||
105 | |||
106 | static struct pmu_sleep_notifier via_pmu_led_sleep_notif = { | ||
107 | .notifier_call = pmu_led_sleep_call, | ||
108 | }; | ||
109 | #endif | ||
110 | |||
111 | static int __init via_pmu_led_init(void) | ||
112 | { | ||
113 | struct device_node *dt; | ||
114 | const char *model; | ||
115 | |||
116 | /* only do this on keylargo based models */ | ||
117 | if (pmu_get_model() != PMU_KEYLARGO_BASED) | ||
118 | return -ENODEV; | ||
119 | |||
120 | dt = of_find_node_by_path("/"); | ||
121 | if (dt == NULL) | ||
122 | return -ENODEV; | ||
123 | model = (const char *)get_property(dt, "model", NULL); | ||
124 | if (model == NULL) | ||
125 | return -ENODEV; | ||
126 | if (strncmp(model, "PowerBook", strlen("PowerBook")) != 0 && | ||
127 | strncmp(model, "iBook", strlen("iBook")) != 0) { | ||
128 | of_node_put(dt); | ||
129 | /* ignore */ | ||
130 | return -ENODEV; | ||
131 | } | ||
132 | of_node_put(dt); | ||
133 | |||
134 | spin_lock_init(&pmu_blink_lock); | ||
135 | /* no outstanding req */ | ||
136 | pmu_blink_req.complete = 1; | ||
137 | pmu_blink_req.done = pmu_req_done; | ||
138 | #ifdef CONFIG_PM | ||
139 | pmu_register_sleep_notifier(&via_pmu_led_sleep_notif); | ||
140 | #endif | ||
141 | return led_classdev_register(NULL, &pmu_led); | ||
142 | } | ||
143 | |||
144 | late_initcall(via_pmu_led_init); | ||
diff --git a/drivers/md/dm-ioctl.c b/drivers/md/dm-ioctl.c index 3edb3477f987..d13bb15a8a02 100644 --- a/drivers/md/dm-ioctl.c +++ b/drivers/md/dm-ioctl.c | |||
@@ -13,7 +13,6 @@ | |||
13 | #include <linux/init.h> | 13 | #include <linux/init.h> |
14 | #include <linux/wait.h> | 14 | #include <linux/wait.h> |
15 | #include <linux/slab.h> | 15 | #include <linux/slab.h> |
16 | #include <linux/devfs_fs_kernel.h> | ||
17 | #include <linux/dm-ioctl.h> | 16 | #include <linux/dm-ioctl.h> |
18 | #include <linux/hdreg.h> | 17 | #include <linux/hdreg.h> |
19 | 18 | ||
@@ -68,14 +67,12 @@ static int dm_hash_init(void) | |||
68 | { | 67 | { |
69 | init_buckets(_name_buckets); | 68 | init_buckets(_name_buckets); |
70 | init_buckets(_uuid_buckets); | 69 | init_buckets(_uuid_buckets); |
71 | devfs_mk_dir(DM_DIR); | ||
72 | return 0; | 70 | return 0; |
73 | } | 71 | } |
74 | 72 | ||
75 | static void dm_hash_exit(void) | 73 | static void dm_hash_exit(void) |
76 | { | 74 | { |
77 | dm_hash_remove_all(0); | 75 | dm_hash_remove_all(0); |
78 | devfs_remove(DM_DIR); | ||
79 | } | 76 | } |
80 | 77 | ||
81 | /*----------------------------------------------------------------- | 78 | /*----------------------------------------------------------------- |
@@ -172,25 +169,6 @@ static void free_cell(struct hash_cell *hc) | |||
172 | } | 169 | } |
173 | 170 | ||
174 | /* | 171 | /* |
175 | * devfs stuff. | ||
176 | */ | ||
177 | static int register_with_devfs(struct hash_cell *hc) | ||
178 | { | ||
179 | struct gendisk *disk = dm_disk(hc->md); | ||
180 | |||
181 | devfs_mk_bdev(MKDEV(disk->major, disk->first_minor), | ||
182 | S_IFBLK | S_IRUSR | S_IWUSR | S_IRGRP, | ||
183 | DM_DIR "/%s", hc->name); | ||
184 | return 0; | ||
185 | } | ||
186 | |||
187 | static int unregister_with_devfs(struct hash_cell *hc) | ||
188 | { | ||
189 | devfs_remove(DM_DIR"/%s", hc->name); | ||
190 | return 0; | ||
191 | } | ||
192 | |||
193 | /* | ||
194 | * The kdev_t and uuid of a device can never change once it is | 172 | * The kdev_t and uuid of a device can never change once it is |
195 | * initially inserted. | 173 | * initially inserted. |
196 | */ | 174 | */ |
@@ -226,7 +204,6 @@ static int dm_hash_insert(const char *name, const char *uuid, struct mapped_devi | |||
226 | } | 204 | } |
227 | list_add(&cell->uuid_list, _uuid_buckets + hash_str(uuid)); | 205 | list_add(&cell->uuid_list, _uuid_buckets + hash_str(uuid)); |
228 | } | 206 | } |
229 | register_with_devfs(cell); | ||
230 | dm_get(md); | 207 | dm_get(md); |
231 | dm_set_mdptr(md, cell); | 208 | dm_set_mdptr(md, cell); |
232 | up_write(&_hash_lock); | 209 | up_write(&_hash_lock); |
@@ -246,7 +223,6 @@ static void __hash_remove(struct hash_cell *hc) | |||
246 | /* remove from the dev hash */ | 223 | /* remove from the dev hash */ |
247 | list_del(&hc->uuid_list); | 224 | list_del(&hc->uuid_list); |
248 | list_del(&hc->name_list); | 225 | list_del(&hc->name_list); |
249 | unregister_with_devfs(hc); | ||
250 | dm_set_mdptr(hc->md, NULL); | 226 | dm_set_mdptr(hc->md, NULL); |
251 | 227 | ||
252 | table = dm_get_table(hc->md); | 228 | table = dm_get_table(hc->md); |
@@ -342,16 +318,11 @@ static int dm_hash_rename(const char *old, const char *new) | |||
342 | /* | 318 | /* |
343 | * rename and move the name cell. | 319 | * rename and move the name cell. |
344 | */ | 320 | */ |
345 | unregister_with_devfs(hc); | ||
346 | |||
347 | list_del(&hc->name_list); | 321 | list_del(&hc->name_list); |
348 | old_name = hc->name; | 322 | old_name = hc->name; |
349 | hc->name = new_name; | 323 | hc->name = new_name; |
350 | list_add(&hc->name_list, _name_buckets + hash_str(new_name)); | 324 | list_add(&hc->name_list, _name_buckets + hash_str(new_name)); |
351 | 325 | ||
352 | /* rename the device node in devfs */ | ||
353 | register_with_devfs(hc); | ||
354 | |||
355 | /* | 326 | /* |
356 | * Wake up any dm event waiters. | 327 | * Wake up any dm event waiters. |
357 | */ | 328 | */ |
@@ -1501,7 +1472,6 @@ static struct file_operations _ctl_fops = { | |||
1501 | static struct miscdevice _dm_misc = { | 1472 | static struct miscdevice _dm_misc = { |
1502 | .minor = MISC_DYNAMIC_MINOR, | 1473 | .minor = MISC_DYNAMIC_MINOR, |
1503 | .name = DM_NAME, | 1474 | .name = DM_NAME, |
1504 | .devfs_name = "mapper/control", | ||
1505 | .fops = &_ctl_fops | 1475 | .fops = &_ctl_fops |
1506 | }; | 1476 | }; |
1507 | 1477 | ||
diff --git a/drivers/md/dm.c b/drivers/md/dm.c index 3ed2e53b9eb6..c99bf9f01759 100644 --- a/drivers/md/dm.c +++ b/drivers/md/dm.c | |||
@@ -167,7 +167,7 @@ static void local_exit(void) | |||
167 | bioset_free(dm_set); | 167 | bioset_free(dm_set); |
168 | 168 | ||
169 | if (unregister_blkdev(_major, _name) < 0) | 169 | if (unregister_blkdev(_major, _name) < 0) |
170 | DMERR("devfs_unregister_blkdev failed"); | 170 | DMERR("unregister_blkdev failed"); |
171 | 171 | ||
172 | _major = 0; | 172 | _major = 0; |
173 | 173 | ||
diff --git a/drivers/md/md.c b/drivers/md/md.c index 306268ec99ff..2ec1b3520a0b 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c | |||
@@ -39,7 +39,6 @@ | |||
39 | #include <linux/raid/md.h> | 39 | #include <linux/raid/md.h> |
40 | #include <linux/raid/bitmap.h> | 40 | #include <linux/raid/bitmap.h> |
41 | #include <linux/sysctl.h> | 41 | #include <linux/sysctl.h> |
42 | #include <linux/devfs_fs_kernel.h> | ||
43 | #include <linux/buffer_head.h> /* for invalidate_bdev */ | 42 | #include <linux/buffer_head.h> /* for invalidate_bdev */ |
44 | #include <linux/suspend.h> | 43 | #include <linux/suspend.h> |
45 | #include <linux/poll.h> | 44 | #include <linux/poll.h> |
@@ -2911,13 +2910,10 @@ static struct kobject *md_probe(dev_t dev, int *part, void *data) | |||
2911 | } | 2910 | } |
2912 | disk->major = MAJOR(dev); | 2911 | disk->major = MAJOR(dev); |
2913 | disk->first_minor = unit << shift; | 2912 | disk->first_minor = unit << shift; |
2914 | if (partitioned) { | 2913 | if (partitioned) |
2915 | sprintf(disk->disk_name, "md_d%d", unit); | 2914 | sprintf(disk->disk_name, "md_d%d", unit); |
2916 | sprintf(disk->devfs_name, "md/d%d", unit); | 2915 | else |
2917 | } else { | ||
2918 | sprintf(disk->disk_name, "md%d", unit); | 2916 | sprintf(disk->disk_name, "md%d", unit); |
2919 | sprintf(disk->devfs_name, "md/%d", unit); | ||
2920 | } | ||
2921 | disk->fops = &md_fops; | 2917 | disk->fops = &md_fops; |
2922 | disk->private_data = mddev; | 2918 | disk->private_data = mddev; |
2923 | disk->queue = mddev->queue; | 2919 | disk->queue = mddev->queue; |
@@ -5538,8 +5534,6 @@ static void md_geninit(void) | |||
5538 | 5534 | ||
5539 | static int __init md_init(void) | 5535 | static int __init md_init(void) |
5540 | { | 5536 | { |
5541 | int minor; | ||
5542 | |||
5543 | printk(KERN_INFO "md: md driver %d.%d.%d MAX_MD_DEVS=%d," | 5537 | printk(KERN_INFO "md: md driver %d.%d.%d MAX_MD_DEVS=%d," |
5544 | " MD_SB_DISKS=%d\n", | 5538 | " MD_SB_DISKS=%d\n", |
5545 | MD_MAJOR_VERSION, MD_MINOR_VERSION, | 5539 | MD_MAJOR_VERSION, MD_MINOR_VERSION, |
@@ -5553,23 +5547,11 @@ static int __init md_init(void) | |||
5553 | unregister_blkdev(MAJOR_NR, "md"); | 5547 | unregister_blkdev(MAJOR_NR, "md"); |
5554 | return -1; | 5548 | return -1; |
5555 | } | 5549 | } |
5556 | devfs_mk_dir("md"); | ||
5557 | blk_register_region(MKDEV(MAJOR_NR, 0), MAX_MD_DEVS, THIS_MODULE, | 5550 | blk_register_region(MKDEV(MAJOR_NR, 0), MAX_MD_DEVS, THIS_MODULE, |
5558 | md_probe, NULL, NULL); | 5551 | md_probe, NULL, NULL); |
5559 | blk_register_region(MKDEV(mdp_major, 0), MAX_MD_DEVS<<MdpMinorShift, THIS_MODULE, | 5552 | blk_register_region(MKDEV(mdp_major, 0), MAX_MD_DEVS<<MdpMinorShift, THIS_MODULE, |
5560 | md_probe, NULL, NULL); | 5553 | md_probe, NULL, NULL); |
5561 | 5554 | ||
5562 | for (minor=0; minor < MAX_MD_DEVS; ++minor) | ||
5563 | devfs_mk_bdev(MKDEV(MAJOR_NR, minor), | ||
5564 | S_IFBLK|S_IRUSR|S_IWUSR, | ||
5565 | "md/%d", minor); | ||
5566 | |||
5567 | for (minor=0; minor < MAX_MD_DEVS; ++minor) | ||
5568 | devfs_mk_bdev(MKDEV(mdp_major, minor<<MdpMinorShift), | ||
5569 | S_IFBLK|S_IRUSR|S_IWUSR, | ||
5570 | "md/mdp%d", minor); | ||
5571 | |||
5572 | |||
5573 | register_reboot_notifier(&md_notifier); | 5555 | register_reboot_notifier(&md_notifier); |
5574 | raid_table_header = register_sysctl_table(raid_root_table, 1); | 5556 | raid_table_header = register_sysctl_table(raid_root_table, 1); |
5575 | 5557 | ||
@@ -5625,15 +5607,9 @@ static __exit void md_exit(void) | |||
5625 | { | 5607 | { |
5626 | mddev_t *mddev; | 5608 | mddev_t *mddev; |
5627 | struct list_head *tmp; | 5609 | struct list_head *tmp; |
5628 | int i; | 5610 | |
5629 | blk_unregister_region(MKDEV(MAJOR_NR,0), MAX_MD_DEVS); | 5611 | blk_unregister_region(MKDEV(MAJOR_NR,0), MAX_MD_DEVS); |
5630 | blk_unregister_region(MKDEV(mdp_major,0), MAX_MD_DEVS << MdpMinorShift); | 5612 | blk_unregister_region(MKDEV(mdp_major,0), MAX_MD_DEVS << MdpMinorShift); |
5631 | for (i=0; i < MAX_MD_DEVS; i++) | ||
5632 | devfs_remove("md/%d", i); | ||
5633 | for (i=0; i < MAX_MD_DEVS; i++) | ||
5634 | devfs_remove("md/d%d", i); | ||
5635 | |||
5636 | devfs_remove("md"); | ||
5637 | 5613 | ||
5638 | unregister_blkdev(MAJOR_NR,"md"); | 5614 | unregister_blkdev(MAJOR_NR,"md"); |
5639 | unregister_blkdev(mdp_major, "mdp"); | 5615 | unregister_blkdev(mdp_major, "mdp"); |
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index f920e50ea124..837ec4eb3d60 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c | |||
@@ -2827,7 +2827,6 @@ static inline sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *ski | |||
2827 | struct stripe_head *sh; | 2827 | struct stripe_head *sh; |
2828 | int pd_idx; | 2828 | int pd_idx; |
2829 | int raid_disks = conf->raid_disks; | 2829 | int raid_disks = conf->raid_disks; |
2830 | int data_disks = raid_disks - conf->max_degraded; | ||
2831 | sector_t max_sector = mddev->size << 1; | 2830 | sector_t max_sector = mddev->size << 1; |
2832 | int sync_blocks; | 2831 | int sync_blocks; |
2833 | int still_degraded = 0; | 2832 | int still_degraded = 0; |
diff --git a/drivers/media/dvb/dvb-core/dvbdev.c b/drivers/media/dvb/dvb-core/dvbdev.c index 134c2bbbeeb5..40774feb8953 100644 --- a/drivers/media/dvb/dvb-core/dvbdev.c +++ b/drivers/media/dvb/dvb-core/dvbdev.c | |||
@@ -231,10 +231,6 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev, | |||
231 | 231 | ||
232 | mutex_unlock(&dvbdev_register_lock); | 232 | mutex_unlock(&dvbdev_register_lock); |
233 | 233 | ||
234 | devfs_mk_cdev(MKDEV(DVB_MAJOR, nums2minor(adap->num, type, id)), | ||
235 | S_IFCHR | S_IRUSR | S_IWUSR, | ||
236 | "dvb/adapter%d/%s%d", adap->num, dnames[type], id); | ||
237 | |||
238 | class_device_create(dvb_class, NULL, MKDEV(DVB_MAJOR, nums2minor(adap->num, type, id)), | 234 | class_device_create(dvb_class, NULL, MKDEV(DVB_MAJOR, nums2minor(adap->num, type, id)), |
239 | adap->device, "dvb%d.%s%d", adap->num, dnames[type], id); | 235 | adap->device, "dvb%d.%s%d", adap->num, dnames[type], id); |
240 | 236 | ||
@@ -252,9 +248,6 @@ void dvb_unregister_device(struct dvb_device *dvbdev) | |||
252 | if (!dvbdev) | 248 | if (!dvbdev) |
253 | return; | 249 | return; |
254 | 250 | ||
255 | devfs_remove("dvb/adapter%d/%s%d", dvbdev->adapter->num, | ||
256 | dnames[dvbdev->type], dvbdev->id); | ||
257 | |||
258 | class_device_destroy(dvb_class, MKDEV(DVB_MAJOR, nums2minor(dvbdev->adapter->num, | 251 | class_device_destroy(dvb_class, MKDEV(DVB_MAJOR, nums2minor(dvbdev->adapter->num, |
259 | dvbdev->type, dvbdev->id))); | 252 | dvbdev->type, dvbdev->id))); |
260 | 253 | ||
@@ -302,7 +295,6 @@ int dvb_register_adapter(struct dvb_adapter *adap, const char *name, struct modu | |||
302 | 295 | ||
303 | printk ("DVB: registering new adapter (%s).\n", name); | 296 | printk ("DVB: registering new adapter (%s).\n", name); |
304 | 297 | ||
305 | devfs_mk_dir("dvb/adapter%d", num); | ||
306 | adap->num = num; | 298 | adap->num = num; |
307 | adap->name = name; | 299 | adap->name = name; |
308 | adap->module = module; | 300 | adap->module = module; |
@@ -319,8 +311,6 @@ EXPORT_SYMBOL(dvb_register_adapter); | |||
319 | 311 | ||
320 | int dvb_unregister_adapter(struct dvb_adapter *adap) | 312 | int dvb_unregister_adapter(struct dvb_adapter *adap) |
321 | { | 313 | { |
322 | devfs_remove("dvb/adapter%d", adap->num); | ||
323 | |||
324 | if (mutex_lock_interruptible(&dvbdev_register_lock)) | 314 | if (mutex_lock_interruptible(&dvbdev_register_lock)) |
325 | return -ERESTARTSYS; | 315 | return -ERESTARTSYS; |
326 | list_del (&adap->list_head); | 316 | list_del (&adap->list_head); |
@@ -410,8 +400,6 @@ static int __init init_dvbdev(void) | |||
410 | goto error; | 400 | goto error; |
411 | } | 401 | } |
412 | 402 | ||
413 | devfs_mk_dir("dvb"); | ||
414 | |||
415 | dvb_class = class_create(THIS_MODULE, "dvb"); | 403 | dvb_class = class_create(THIS_MODULE, "dvb"); |
416 | if (IS_ERR(dvb_class)) { | 404 | if (IS_ERR(dvb_class)) { |
417 | retval = PTR_ERR(dvb_class); | 405 | retval = PTR_ERR(dvb_class); |
@@ -428,7 +416,6 @@ error: | |||
428 | 416 | ||
429 | static void __exit exit_dvbdev(void) | 417 | static void __exit exit_dvbdev(void) |
430 | { | 418 | { |
431 | devfs_remove("dvb"); | ||
432 | class_destroy(dvb_class); | 419 | class_destroy(dvb_class); |
433 | cdev_del(&dvb_device_cdev); | 420 | cdev_del(&dvb_device_cdev); |
434 | unregister_chrdev_region(MKDEV(DVB_MAJOR, 0), MAX_DVB_MINORS); | 421 | unregister_chrdev_region(MKDEV(DVB_MAJOR, 0), MAX_DVB_MINORS); |
diff --git a/drivers/media/dvb/dvb-core/dvbdev.h b/drivers/media/dvb/dvb-core/dvbdev.h index d7a976d040d7..7a7f75fd168c 100644 --- a/drivers/media/dvb/dvb-core/dvbdev.h +++ b/drivers/media/dvb/dvb-core/dvbdev.h | |||
@@ -27,7 +27,6 @@ | |||
27 | #include <linux/poll.h> | 27 | #include <linux/poll.h> |
28 | #include <linux/fs.h> | 28 | #include <linux/fs.h> |
29 | #include <linux/list.h> | 29 | #include <linux/list.h> |
30 | #include <linux/devfs_fs_kernel.h> | ||
31 | #include <linux/smp_lock.h> | 30 | #include <linux/smp_lock.h> |
32 | 31 | ||
33 | #define DVB_MAJOR 212 | 32 | #define DVB_MAJOR 212 |
diff --git a/drivers/media/dvb/ttpci/av7110.h b/drivers/media/dvb/ttpci/av7110.h index 3e2e12124bae..9c79696da08a 100644 --- a/drivers/media/dvb/ttpci/av7110.h +++ b/drivers/media/dvb/ttpci/av7110.h | |||
@@ -6,10 +6,6 @@ | |||
6 | #include <linux/netdevice.h> | 6 | #include <linux/netdevice.h> |
7 | #include <linux/i2c.h> | 7 | #include <linux/i2c.h> |
8 | 8 | ||
9 | #ifdef CONFIG_DEVFS_FS | ||
10 | #include <linux/devfs_fs_kernel.h> | ||
11 | #endif | ||
12 | |||
13 | #include <linux/dvb/video.h> | 9 | #include <linux/dvb/video.h> |
14 | #include <linux/dvb/audio.h> | 10 | #include <linux/dvb/audio.h> |
15 | #include <linux/dvb/dmx.h> | 11 | #include <linux/dvb/dmx.h> |
diff --git a/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c b/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c index 14559ef6153c..336b2fe1a5f2 100644 --- a/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c +++ b/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c | |||
@@ -126,10 +126,6 @@ struct ttusb { | |||
126 | 126 | ||
127 | int revision; | 127 | int revision; |
128 | 128 | ||
129 | #if 0 | ||
130 | devfs_handle_t stc_devfs_handle; | ||
131 | #endif | ||
132 | |||
133 | struct dvb_frontend* fe; | 129 | struct dvb_frontend* fe; |
134 | }; | 130 | }; |
135 | 131 | ||
@@ -1746,13 +1742,6 @@ static int ttusb_probe(struct usb_interface *intf, const struct usb_device_id *i | |||
1746 | return -ENODEV; | 1742 | return -ENODEV; |
1747 | } | 1743 | } |
1748 | 1744 | ||
1749 | #if 0 | ||
1750 | ttusb->stc_devfs_handle = | ||
1751 | devfs_register(ttusb->adapter->devfs_handle, TTUSB_BUDGET_NAME, | ||
1752 | DEVFS_FL_DEFAULT, 0, 192, | ||
1753 | S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | ||
1754 | | S_IROTH | S_IWOTH, &stc_fops, ttusb); | ||
1755 | #endif | ||
1756 | usb_set_intfdata(intf, (void *) ttusb); | 1745 | usb_set_intfdata(intf, (void *) ttusb); |
1757 | 1746 | ||
1758 | frontend_init(ttusb); | 1747 | frontend_init(ttusb); |
diff --git a/drivers/media/radio/miropcm20-rds.c b/drivers/media/radio/miropcm20-rds.c index 87b37b7691da..c1b1db65e668 100644 --- a/drivers/media/radio/miropcm20-rds.c +++ b/drivers/media/radio/miropcm20-rds.c | |||
@@ -115,7 +115,6 @@ static struct file_operations rds_fops = { | |||
115 | static struct miscdevice rds_miscdev = { | 115 | static struct miscdevice rds_miscdev = { |
116 | .minor = MISC_DYNAMIC_MINOR, | 116 | .minor = MISC_DYNAMIC_MINOR, |
117 | .name = "radiotext", | 117 | .name = "radiotext", |
118 | .devfs_name = "v4l/rds/radiotext", | ||
119 | .fops = &rds_fops, | 118 | .fops = &rds_fops, |
120 | }; | 119 | }; |
121 | 120 | ||
diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig index e4290491fa9e..6d532f170ce5 100644 --- a/drivers/media/video/Kconfig +++ b/drivers/media/video/Kconfig | |||
@@ -445,6 +445,8 @@ endmenu # encoder / decoder chips | |||
445 | menu "V4L USB devices" | 445 | menu "V4L USB devices" |
446 | depends on USB && VIDEO_DEV | 446 | depends on USB && VIDEO_DEV |
447 | 447 | ||
448 | source "drivers/media/video/pvrusb2/Kconfig" | ||
449 | |||
448 | source "drivers/media/video/em28xx/Kconfig" | 450 | source "drivers/media/video/em28xx/Kconfig" |
449 | 451 | ||
450 | config USB_DSBR | 452 | config USB_DSBR |
diff --git a/drivers/media/video/Makefile b/drivers/media/video/Makefile index 6c401b46398a..353d61cfac1b 100644 --- a/drivers/media/video/Makefile +++ b/drivers/media/video/Makefile | |||
@@ -47,6 +47,7 @@ obj-$(CONFIG_VIDEO_SAA7134) += ir-kbd-i2c.o saa7134/ | |||
47 | obj-$(CONFIG_VIDEO_CX88) += cx88/ | 47 | obj-$(CONFIG_VIDEO_CX88) += cx88/ |
48 | obj-$(CONFIG_VIDEO_EM28XX) += em28xx/ | 48 | obj-$(CONFIG_VIDEO_EM28XX) += em28xx/ |
49 | obj-$(CONFIG_VIDEO_EM28XX) += tvp5150.o | 49 | obj-$(CONFIG_VIDEO_EM28XX) += tvp5150.o |
50 | obj-$(CONFIG_VIDEO_PVRUSB2) += pvrusb2/ | ||
50 | obj-$(CONFIG_VIDEO_MSP3400) += msp3400.o | 51 | obj-$(CONFIG_VIDEO_MSP3400) += msp3400.o |
51 | obj-$(CONFIG_VIDEO_CS53L32A) += cs53l32a.o | 52 | obj-$(CONFIG_VIDEO_CS53L32A) += cs53l32a.o |
52 | obj-$(CONFIG_VIDEO_TLV320AIC23B) += tlv320aic23b.o | 53 | obj-$(CONFIG_VIDEO_TLV320AIC23B) += tlv320aic23b.o |
diff --git a/drivers/media/video/arv.c b/drivers/media/video/arv.c index 6e08e32346eb..ae14f5f32039 100644 --- a/drivers/media/video/arv.c +++ b/drivers/media/video/arv.c | |||
@@ -20,7 +20,6 @@ | |||
20 | 20 | ||
21 | #include <linux/config.h> | 21 | #include <linux/config.h> |
22 | #include <linux/init.h> | 22 | #include <linux/init.h> |
23 | #include <linux/devfs_fs_kernel.h> | ||
24 | #include <linux/module.h> | 23 | #include <linux/module.h> |
25 | #include <linux/delay.h> | 24 | #include <linux/delay.h> |
26 | #include <linux/errno.h> | 25 | #include <linux/errno.h> |
diff --git a/drivers/media/video/bt8xx/bttv-driver.c b/drivers/media/video/bt8xx/bttv-driver.c index 423e954948be..aa3203ae670c 100644 --- a/drivers/media/video/bt8xx/bttv-driver.c +++ b/drivers/media/video/bt8xx/bttv-driver.c | |||
@@ -4019,8 +4019,9 @@ static int __devinit bttv_probe(struct pci_dev *dev, | |||
4019 | if (!request_mem_region(pci_resource_start(dev,0), | 4019 | if (!request_mem_region(pci_resource_start(dev,0), |
4020 | pci_resource_len(dev,0), | 4020 | pci_resource_len(dev,0), |
4021 | btv->c.name)) { | 4021 | btv->c.name)) { |
4022 | printk(KERN_WARNING "bttv%d: can't request iomem (0x%lx).\n", | 4022 | printk(KERN_WARNING "bttv%d: can't request iomem (0x%llx).\n", |
4023 | btv->c.nr, pci_resource_start(dev,0)); | 4023 | btv->c.nr, |
4024 | (unsigned long long)pci_resource_start(dev,0)); | ||
4024 | return -EBUSY; | 4025 | return -EBUSY; |
4025 | } | 4026 | } |
4026 | pci_set_master(dev); | 4027 | pci_set_master(dev); |
@@ -4031,8 +4032,9 @@ static int __devinit bttv_probe(struct pci_dev *dev, | |||
4031 | pci_read_config_byte(dev, PCI_LATENCY_TIMER, &lat); | 4032 | pci_read_config_byte(dev, PCI_LATENCY_TIMER, &lat); |
4032 | printk(KERN_INFO "bttv%d: Bt%d (rev %d) at %s, ", | 4033 | printk(KERN_INFO "bttv%d: Bt%d (rev %d) at %s, ", |
4033 | bttv_num,btv->id, btv->revision, pci_name(dev)); | 4034 | bttv_num,btv->id, btv->revision, pci_name(dev)); |
4034 | printk("irq: %d, latency: %d, mmio: 0x%lx\n", | 4035 | printk("irq: %d, latency: %d, mmio: 0x%llx\n", |
4035 | btv->c.pci->irq, lat, pci_resource_start(dev,0)); | 4036 | btv->c.pci->irq, lat, |
4037 | (unsigned long long)pci_resource_start(dev,0)); | ||
4036 | schedule(); | 4038 | schedule(); |
4037 | 4039 | ||
4038 | btv->bt848_mmio=ioremap(pci_resource_start(dev,0), 0x1000); | 4040 | btv->bt848_mmio=ioremap(pci_resource_start(dev,0), 0x1000); |
diff --git a/drivers/media/video/cx2341x.c b/drivers/media/video/cx2341x.c index 01b22eab5725..65f00fc08fa9 100644 --- a/drivers/media/video/cx2341x.c +++ b/drivers/media/video/cx2341x.c | |||
@@ -601,7 +601,7 @@ static void cx2341x_calc_audio_properties(struct cx2341x_mpeg_params *params) | |||
601 | } | 601 | } |
602 | 602 | ||
603 | int cx2341x_ext_ctrls(struct cx2341x_mpeg_params *params, | 603 | int cx2341x_ext_ctrls(struct cx2341x_mpeg_params *params, |
604 | struct v4l2_ext_controls *ctrls, int cmd) | 604 | struct v4l2_ext_controls *ctrls, unsigned int cmd) |
605 | { | 605 | { |
606 | int err = 0; | 606 | int err = 0; |
607 | int i; | 607 | int i; |
@@ -847,22 +847,22 @@ invalid: | |||
847 | return "<invalid>"; | 847 | return "<invalid>"; |
848 | } | 848 | } |
849 | 849 | ||
850 | void cx2341x_log_status(struct cx2341x_mpeg_params *p, int card_id) | 850 | void cx2341x_log_status(struct cx2341x_mpeg_params *p, const char *prefix) |
851 | { | 851 | { |
852 | int is_mpeg1 = p->video_encoding == V4L2_MPEG_VIDEO_ENCODING_MPEG_1; | 852 | int is_mpeg1 = p->video_encoding == V4L2_MPEG_VIDEO_ENCODING_MPEG_1; |
853 | 853 | ||
854 | /* Stream */ | 854 | /* Stream */ |
855 | printk(KERN_INFO "cx2341x-%d: Stream: %s\n", | 855 | printk(KERN_INFO "%s: Stream: %s\n", |
856 | card_id, | 856 | prefix, |
857 | cx2341x_menu_item(p, V4L2_CID_MPEG_STREAM_TYPE)); | 857 | cx2341x_menu_item(p, V4L2_CID_MPEG_STREAM_TYPE)); |
858 | 858 | ||
859 | /* Video */ | 859 | /* Video */ |
860 | printk(KERN_INFO "cx2341x-%d: Video: %dx%d, %d fps\n", | 860 | printk(KERN_INFO "%s: Video: %dx%d, %d fps\n", |
861 | card_id, | 861 | prefix, |
862 | p->width / (is_mpeg1 ? 2 : 1), p->height / (is_mpeg1 ? 2 : 1), | 862 | p->width / (is_mpeg1 ? 2 : 1), p->height / (is_mpeg1 ? 2 : 1), |
863 | p->is_50hz ? 25 : 30); | 863 | p->is_50hz ? 25 : 30); |
864 | printk(KERN_INFO "cx2341x-%d: Video: %s, %s, %s, %d", | 864 | printk(KERN_INFO "%s: Video: %s, %s, %s, %d", |
865 | card_id, | 865 | prefix, |
866 | cx2341x_menu_item(p, V4L2_CID_MPEG_VIDEO_ENCODING), | 866 | cx2341x_menu_item(p, V4L2_CID_MPEG_VIDEO_ENCODING), |
867 | cx2341x_menu_item(p, V4L2_CID_MPEG_VIDEO_ASPECT), | 867 | cx2341x_menu_item(p, V4L2_CID_MPEG_VIDEO_ASPECT), |
868 | cx2341x_menu_item(p, V4L2_CID_MPEG_VIDEO_BITRATE_MODE), | 868 | cx2341x_menu_item(p, V4L2_CID_MPEG_VIDEO_BITRATE_MODE), |
@@ -871,19 +871,19 @@ void cx2341x_log_status(struct cx2341x_mpeg_params *p, int card_id) | |||
871 | printk(", Peak %d", p->video_bitrate_peak); | 871 | printk(", Peak %d", p->video_bitrate_peak); |
872 | } | 872 | } |
873 | printk("\n"); | 873 | printk("\n"); |
874 | printk(KERN_INFO "cx2341x-%d: Video: GOP Size %d, %d B-Frames, %sGOP Closure, %s3:2 Pulldown\n", | 874 | printk(KERN_INFO "%s: Video: GOP Size %d, %d B-Frames, %sGOP Closure, %s3:2 Pulldown\n", |
875 | card_id, | 875 | prefix, |
876 | p->video_gop_size, p->video_b_frames, | 876 | p->video_gop_size, p->video_b_frames, |
877 | p->video_gop_closure ? "" : "No ", | 877 | p->video_gop_closure ? "" : "No ", |
878 | p->video_pulldown ? "" : "No "); | 878 | p->video_pulldown ? "" : "No "); |
879 | if (p->video_temporal_decimation) { | 879 | if (p->video_temporal_decimation) { |
880 | printk(KERN_INFO "cx2341x-%d: Video: Temporal Decimation %d\n", | 880 | printk(KERN_INFO "%s: Video: Temporal Decimation %d\n", |
881 | card_id, p->video_temporal_decimation); | 881 | prefix, p->video_temporal_decimation); |
882 | } | 882 | } |
883 | 883 | ||
884 | /* Audio */ | 884 | /* Audio */ |
885 | printk(KERN_INFO "cx2341x-%d: Audio: %s, %s, %s, %s", | 885 | printk(KERN_INFO "%s: Audio: %s, %s, %s, %s", |
886 | card_id, | 886 | prefix, |
887 | cx2341x_menu_item(p, V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ), | 887 | cx2341x_menu_item(p, V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ), |
888 | cx2341x_menu_item(p, V4L2_CID_MPEG_AUDIO_ENCODING), | 888 | cx2341x_menu_item(p, V4L2_CID_MPEG_AUDIO_ENCODING), |
889 | cx2341x_menu_item(p, V4L2_CID_MPEG_AUDIO_L2_BITRATE), | 889 | cx2341x_menu_item(p, V4L2_CID_MPEG_AUDIO_L2_BITRATE), |
@@ -897,18 +897,18 @@ void cx2341x_log_status(struct cx2341x_mpeg_params *p, int card_id) | |||
897 | cx2341x_menu_item(p, V4L2_CID_MPEG_AUDIO_CRC)); | 897 | cx2341x_menu_item(p, V4L2_CID_MPEG_AUDIO_CRC)); |
898 | 898 | ||
899 | /* Encoding filters */ | 899 | /* Encoding filters */ |
900 | printk(KERN_INFO "cx2341x-%d: Spatial Filter: %s, Luma %s, Chroma %s, %d\n", | 900 | printk(KERN_INFO "%s: Spatial Filter: %s, Luma %s, Chroma %s, %d\n", |
901 | card_id, | 901 | prefix, |
902 | cx2341x_menu_item(p, V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE), | 902 | cx2341x_menu_item(p, V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE), |
903 | cx2341x_menu_item(p, V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE), | 903 | cx2341x_menu_item(p, V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE), |
904 | cx2341x_menu_item(p, V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE), | 904 | cx2341x_menu_item(p, V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE), |
905 | p->video_spatial_filter); | 905 | p->video_spatial_filter); |
906 | printk(KERN_INFO "cx2341x-%d: Temporal Filter: %s, %d\n", | 906 | printk(KERN_INFO "%s: Temporal Filter: %s, %d\n", |
907 | card_id, | 907 | prefix, |
908 | cx2341x_menu_item(p, V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE), | 908 | cx2341x_menu_item(p, V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE), |
909 | p->video_temporal_filter); | 909 | p->video_temporal_filter); |
910 | printk(KERN_INFO "cx2341x-%d: Median Filter: %s, Luma [%d, %d], Chroma [%d, %d]\n", | 910 | printk(KERN_INFO "%s: Median Filter: %s, Luma [%d, %d], Chroma [%d, %d]\n", |
911 | card_id, | 911 | prefix, |
912 | cx2341x_menu_item(p, V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE), | 912 | cx2341x_menu_item(p, V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE), |
913 | p->video_luma_median_filter_bottom, | 913 | p->video_luma_median_filter_bottom, |
914 | p->video_luma_median_filter_top, | 914 | p->video_luma_median_filter_top, |
diff --git a/drivers/media/video/cx88/cx88-alsa.c b/drivers/media/video/cx88/cx88-alsa.c index 2194cbeca33b..292a5e81eb75 100644 --- a/drivers/media/video/cx88/cx88-alsa.c +++ b/drivers/media/video/cx88/cx88-alsa.c | |||
@@ -712,9 +712,9 @@ static int __devinit snd_cx88_create(struct snd_card *card, | |||
712 | pci_read_config_byte(pci, PCI_LATENCY_TIMER, &chip->pci_lat); | 712 | pci_read_config_byte(pci, PCI_LATENCY_TIMER, &chip->pci_lat); |
713 | 713 | ||
714 | dprintk(1,"ALSA %s/%i: found at %s, rev: %d, irq: %d, " | 714 | dprintk(1,"ALSA %s/%i: found at %s, rev: %d, irq: %d, " |
715 | "latency: %d, mmio: 0x%lx\n", core->name, devno, | 715 | "latency: %d, mmio: 0x%llx\n", core->name, devno, |
716 | pci_name(pci), chip->pci_rev, pci->irq, | 716 | pci_name(pci), chip->pci_rev, pci->irq, |
717 | chip->pci_lat,pci_resource_start(pci,0)); | 717 | chip->pci_lat,(unsigned long long)pci_resource_start(pci,0)); |
718 | 718 | ||
719 | chip->irq = pci->irq; | 719 | chip->irq = pci->irq; |
720 | synchronize_irq(chip->irq); | 720 | synchronize_irq(chip->irq); |
@@ -766,8 +766,8 @@ static int __devinit cx88_audio_initdev(struct pci_dev *pci, | |||
766 | 766 | ||
767 | strcpy (card->driver, "CX88x"); | 767 | strcpy (card->driver, "CX88x"); |
768 | sprintf(card->shortname, "Conexant CX%x", pci->device); | 768 | sprintf(card->shortname, "Conexant CX%x", pci->device); |
769 | sprintf(card->longname, "%s at %#lx", | 769 | sprintf(card->longname, "%s at %#llx", |
770 | card->shortname, pci_resource_start(pci, 0)); | 770 | card->shortname,(unsigned long long)pci_resource_start(pci, 0)); |
771 | strcpy (card->mixername, "CX88"); | 771 | strcpy (card->mixername, "CX88"); |
772 | 772 | ||
773 | dprintk (0, "%s/%i: ALSA support for cx2388x boards\n", | 773 | dprintk (0, "%s/%i: ALSA support for cx2388x boards\n", |
diff --git a/drivers/media/video/cx88/cx88-blackbird.c b/drivers/media/video/cx88/cx88-blackbird.c index 78df66671ea2..4ff81582ec56 100644 --- a/drivers/media/video/cx88/cx88-blackbird.c +++ b/drivers/media/video/cx88/cx88-blackbird.c | |||
@@ -853,6 +853,19 @@ static int mpeg_do_ioctl(struct inode *inode, struct file *file, | |||
853 | fh->mpegq.field); | 853 | fh->mpegq.field); |
854 | return 0; | 854 | return 0; |
855 | } | 855 | } |
856 | case VIDIOC_LOG_STATUS: | ||
857 | { | ||
858 | char name[32 + 2]; | ||
859 | |||
860 | snprintf(name, sizeof(name), "%s/2", core->name); | ||
861 | printk("%s/2: ============ START LOG STATUS ============\n", | ||
862 | core->name); | ||
863 | cx88_call_i2c_clients(core, VIDIOC_LOG_STATUS, 0); | ||
864 | cx2341x_log_status(&dev->params, name); | ||
865 | printk("%s/2: ============= END LOG STATUS =============\n", | ||
866 | core->name); | ||
867 | return 0; | ||
868 | } | ||
856 | 869 | ||
857 | default: | 870 | default: |
858 | return cx88_do_ioctl(inode, file, 0, dev->core, cmd, arg, mpeg_do_ioctl); | 871 | return cx88_do_ioctl(inode, file, 0, dev->core, cmd, arg, mpeg_do_ioctl); |
diff --git a/drivers/media/video/cx88/cx88-core.c b/drivers/media/video/cx88/cx88-core.c index 26f4c0fb8c36..973d3f39b2d5 100644 --- a/drivers/media/video/cx88/cx88-core.c +++ b/drivers/media/video/cx88/cx88-core.c | |||
@@ -1031,8 +1031,8 @@ static int get_ressources(struct cx88_core *core, struct pci_dev *pci) | |||
1031 | pci_resource_len(pci,0), | 1031 | pci_resource_len(pci,0), |
1032 | core->name)) | 1032 | core->name)) |
1033 | return 0; | 1033 | return 0; |
1034 | printk(KERN_ERR "%s: can't get MMIO memory @ 0x%lx\n", | 1034 | printk(KERN_ERR "%s: can't get MMIO memory @ 0x%llx\n", |
1035 | core->name,pci_resource_start(pci,0)); | 1035 | core->name,(unsigned long long)pci_resource_start(pci,0)); |
1036 | return -EBUSY; | 1036 | return -EBUSY; |
1037 | } | 1037 | } |
1038 | 1038 | ||
diff --git a/drivers/media/video/cx88/cx88-mpeg.c b/drivers/media/video/cx88/cx88-mpeg.c index a9d7795a8e14..2c12aca1b6a3 100644 --- a/drivers/media/video/cx88/cx88-mpeg.c +++ b/drivers/media/video/cx88/cx88-mpeg.c | |||
@@ -420,9 +420,9 @@ int cx8802_init_common(struct cx8802_dev *dev) | |||
420 | pci_read_config_byte(dev->pci, PCI_CLASS_REVISION, &dev->pci_rev); | 420 | pci_read_config_byte(dev->pci, PCI_CLASS_REVISION, &dev->pci_rev); |
421 | pci_read_config_byte(dev->pci, PCI_LATENCY_TIMER, &dev->pci_lat); | 421 | pci_read_config_byte(dev->pci, PCI_LATENCY_TIMER, &dev->pci_lat); |
422 | printk(KERN_INFO "%s/2: found at %s, rev: %d, irq: %d, " | 422 | printk(KERN_INFO "%s/2: found at %s, rev: %d, irq: %d, " |
423 | "latency: %d, mmio: 0x%lx\n", dev->core->name, | 423 | "latency: %d, mmio: 0x%llx\n", dev->core->name, |
424 | pci_name(dev->pci), dev->pci_rev, dev->pci->irq, | 424 | pci_name(dev->pci), dev->pci_rev, dev->pci->irq, |
425 | dev->pci_lat,pci_resource_start(dev->pci,0)); | 425 | dev->pci_lat,(unsigned long long)pci_resource_start(dev->pci,0)); |
426 | 426 | ||
427 | /* initialize driver struct */ | 427 | /* initialize driver struct */ |
428 | spin_lock_init(&dev->slock); | 428 | spin_lock_init(&dev->slock); |
diff --git a/drivers/media/video/cx88/cx88-video.c b/drivers/media/video/cx88/cx88-video.c index dcda5291b990..8d5cf474b68e 100644 --- a/drivers/media/video/cx88/cx88-video.c +++ b/drivers/media/video/cx88/cx88-video.c | |||
@@ -1847,9 +1847,9 @@ static int __devinit cx8800_initdev(struct pci_dev *pci_dev, | |||
1847 | pci_read_config_byte(pci_dev, PCI_CLASS_REVISION, &dev->pci_rev); | 1847 | pci_read_config_byte(pci_dev, PCI_CLASS_REVISION, &dev->pci_rev); |
1848 | pci_read_config_byte(pci_dev, PCI_LATENCY_TIMER, &dev->pci_lat); | 1848 | pci_read_config_byte(pci_dev, PCI_LATENCY_TIMER, &dev->pci_lat); |
1849 | printk(KERN_INFO "%s/0: found at %s, rev: %d, irq: %d, " | 1849 | printk(KERN_INFO "%s/0: found at %s, rev: %d, irq: %d, " |
1850 | "latency: %d, mmio: 0x%lx\n", core->name, | 1850 | "latency: %d, mmio: 0x%llx\n", core->name, |
1851 | pci_name(pci_dev), dev->pci_rev, pci_dev->irq, | 1851 | pci_name(pci_dev), dev->pci_rev, pci_dev->irq, |
1852 | dev->pci_lat,pci_resource_start(pci_dev,0)); | 1852 | dev->pci_lat,(unsigned long long)pci_resource_start(pci_dev,0)); |
1853 | 1853 | ||
1854 | pci_set_master(pci_dev); | 1854 | pci_set_master(pci_dev); |
1855 | if (!pci_dma_supported(pci_dev,0xffffffff)) { | 1855 | if (!pci_dma_supported(pci_dev,0xffffffff)) { |
diff --git a/drivers/media/video/pvrusb2/Kconfig b/drivers/media/video/pvrusb2/Kconfig new file mode 100644 index 000000000000..7e727fe14b32 --- /dev/null +++ b/drivers/media/video/pvrusb2/Kconfig | |||
@@ -0,0 +1,62 @@ | |||
1 | config VIDEO_PVRUSB2 | ||
2 | tristate "Hauppauge WinTV-PVR USB2 support" | ||
3 | depends on VIDEO_V4L2 && USB && I2C && EXPERIMENTAL | ||
4 | select FW_LOADER | ||
5 | select VIDEO_TUNER | ||
6 | select VIDEO_TVEEPROM | ||
7 | select VIDEO_CX2341X | ||
8 | select VIDEO_SAA711X | ||
9 | select VIDEO_MSP3400 | ||
10 | ---help--- | ||
11 | This is a video4linux driver for Conexant 23416 based | ||
12 | usb2 personal video recorder devices. | ||
13 | |||
14 | To compile this driver as a module, choose M here: the | ||
15 | module will be called pvrusb2 | ||
16 | |||
17 | config VIDEO_PVRUSB2_24XXX | ||
18 | bool "Hauppauge WinTV-PVR USB2 support for 24xxx model series" | ||
19 | depends on VIDEO_PVRUSB2 && EXPERIMENTAL | ||
20 | select VIDEO_CX25840 | ||
21 | select VIDEO_WM8775 | ||
22 | ---help--- | ||
23 | This option enables inclusion of additional logic to operate | ||
24 | newer WinTV-PVR USB2 devices whose model number is of the | ||
25 | form "24xxx" (leading prefix of "24" followed by 3 digits). | ||
26 | To see if you may need this option, examine the white | ||
27 | sticker on the underside of your device. Enabling this | ||
28 | option will not harm support for older devices, however it | ||
29 | is a separate option because of the experimental nature of | ||
30 | this new feature. | ||
31 | |||
32 | If you are in doubt, say N. | ||
33 | |||
34 | Note: This feature is _very_ experimental. You have been | ||
35 | warned. | ||
36 | |||
37 | config VIDEO_PVRUSB2_SYSFS | ||
38 | bool "pvrusb2 sysfs support (EXPERIMENTAL)" | ||
39 | default y | ||
40 | depends on VIDEO_PVRUSB2 && SYSFS && EXPERIMENTAL | ||
41 | ---help--- | ||
42 | This option enables the operation of a sysfs based | ||
43 | interface for query and control of the pvrusb2 driver. | ||
44 | |||
45 | This is not generally needed for v4l applications, | ||
46 | although certain applications are optimized to take | ||
47 | advantage of this feature. | ||
48 | |||
49 | If you are in doubt, say Y. | ||
50 | |||
51 | Note: This feature is experimental and subject to change. | ||
52 | |||
53 | config VIDEO_PVRUSB2_DEBUGIFC | ||
54 | bool "pvrusb2 debug interface" | ||
55 | depends on VIDEO_PVRUSB2_SYSFS | ||
56 | ---help--- | ||
57 | This option enables the inclusion of a debug interface | ||
58 | in the pvrusb2 driver, hosted through sysfs. | ||
59 | |||
60 | You do not need to select this option unless you plan | ||
61 | on debugging the driver or performing a manual firmware | ||
62 | extraction. | ||
diff --git a/drivers/media/video/pvrusb2/Makefile b/drivers/media/video/pvrusb2/Makefile new file mode 100644 index 000000000000..fed603ad0a67 --- /dev/null +++ b/drivers/media/video/pvrusb2/Makefile | |||
@@ -0,0 +1,18 @@ | |||
1 | obj-pvrusb2-sysfs-$(CONFIG_VIDEO_PVRUSB2_SYSFS) := pvrusb2-sysfs.o | ||
2 | obj-pvrusb2-debugifc-$(CONFIG_VIDEO_PVRUSB2_DEBUGIFC) := pvrusb2-debugifc.o | ||
3 | |||
4 | obj-pvrusb2-24xxx-$(CONFIG_VIDEO_PVRUSB2_24XXX) := \ | ||
5 | pvrusb2-cx2584x-v4l.o \ | ||
6 | pvrusb2-wm8775.o | ||
7 | |||
8 | pvrusb2-objs := pvrusb2-i2c-core.o pvrusb2-i2c-cmd-v4l2.o \ | ||
9 | pvrusb2-audio.o pvrusb2-i2c-chips-v4l2.o \ | ||
10 | pvrusb2-encoder.o pvrusb2-video-v4l.o \ | ||
11 | pvrusb2-eeprom.o pvrusb2-tuner.o pvrusb2-demod.o \ | ||
12 | pvrusb2-main.o pvrusb2-hdw.o pvrusb2-v4l2.o \ | ||
13 | pvrusb2-ctrl.o pvrusb2-std.o \ | ||
14 | pvrusb2-context.o pvrusb2-io.o pvrusb2-ioread.o \ | ||
15 | $(obj-pvrusb2-24xxx-y) \ | ||
16 | $(obj-pvrusb2-sysfs-y) $(obj-pvrusb2-debugifc-y) | ||
17 | |||
18 | obj-$(CONFIG_VIDEO_PVRUSB2) += pvrusb2.o | ||
diff --git a/drivers/media/video/pvrusb2/pvrusb2-audio.c b/drivers/media/video/pvrusb2/pvrusb2-audio.c new file mode 100644 index 000000000000..313d2dcf9e4b --- /dev/null +++ b/drivers/media/video/pvrusb2/pvrusb2-audio.c | |||
@@ -0,0 +1,204 @@ | |||
1 | /* | ||
2 | * | ||
3 | * $Id$ | ||
4 | * | ||
5 | * Copyright (C) 2005 Mike Isely <isely@pobox.com> | ||
6 | * Copyright (C) 2004 Aurelien Alleaume <slts@free.fr> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License as published by | ||
10 | * the Free Software Foundation; either version 2 of the License | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | * GNU General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU General Public License | ||
18 | * along with this program; if not, write to the Free Software | ||
19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
20 | * | ||
21 | */ | ||
22 | |||
23 | #include "pvrusb2-audio.h" | ||
24 | #include "pvrusb2-hdw-internal.h" | ||
25 | #include "pvrusb2-debug.h" | ||
26 | #include <linux/videodev2.h> | ||
27 | #include <media/msp3400.h> | ||
28 | #include <media/v4l2-common.h> | ||
29 | |||
30 | struct pvr2_msp3400_handler { | ||
31 | struct pvr2_hdw *hdw; | ||
32 | struct pvr2_i2c_client *client; | ||
33 | struct pvr2_i2c_handler i2c_handler; | ||
34 | struct pvr2_audio_stat astat; | ||
35 | unsigned long stale_mask; | ||
36 | }; | ||
37 | |||
38 | |||
39 | /* This function selects the correct audio input source */ | ||
40 | static void set_stereo(struct pvr2_msp3400_handler *ctxt) | ||
41 | { | ||
42 | struct pvr2_hdw *hdw = ctxt->hdw; | ||
43 | struct v4l2_routing route; | ||
44 | |||
45 | pvr2_trace(PVR2_TRACE_CHIPS,"i2c msp3400 v4l2 set_stereo"); | ||
46 | |||
47 | if (hdw->input_val == PVR2_CVAL_INPUT_TV) { | ||
48 | struct v4l2_tuner vt; | ||
49 | memset(&vt,0,sizeof(vt)); | ||
50 | vt.audmode = hdw->audiomode_val; | ||
51 | pvr2_i2c_client_cmd(ctxt->client,VIDIOC_S_TUNER,&vt); | ||
52 | } | ||
53 | |||
54 | route.input = MSP_INPUT_DEFAULT; | ||
55 | route.output = MSP_OUTPUT(MSP_SC_IN_DSP_SCART1); | ||
56 | switch (hdw->input_val) { | ||
57 | case PVR2_CVAL_INPUT_TV: | ||
58 | break; | ||
59 | case PVR2_CVAL_INPUT_RADIO: | ||
60 | /* Assume that msp34xx also handle FM decoding, in which case | ||
61 | we're still using the tuner. */ | ||
62 | /* HV: actually it is more likely to be the SCART2 input if | ||
63 | the ivtv experience is any indication. */ | ||
64 | route.input = MSP_INPUT(MSP_IN_SCART2, MSP_IN_TUNER1, | ||
65 | MSP_DSP_IN_SCART, MSP_DSP_IN_SCART); | ||
66 | break; | ||
67 | case PVR2_CVAL_INPUT_SVIDEO: | ||
68 | case PVR2_CVAL_INPUT_COMPOSITE: | ||
69 | /* SCART 1 input */ | ||
70 | route.input = MSP_INPUT(MSP_IN_SCART1, MSP_IN_TUNER1, | ||
71 | MSP_DSP_IN_SCART, MSP_DSP_IN_SCART); | ||
72 | break; | ||
73 | } | ||
74 | pvr2_i2c_client_cmd(ctxt->client,VIDIOC_INT_S_AUDIO_ROUTING,&route); | ||
75 | } | ||
76 | |||
77 | |||
78 | static int check_stereo(struct pvr2_msp3400_handler *ctxt) | ||
79 | { | ||
80 | struct pvr2_hdw *hdw = ctxt->hdw; | ||
81 | return (hdw->input_dirty || | ||
82 | hdw->audiomode_dirty); | ||
83 | } | ||
84 | |||
85 | |||
86 | struct pvr2_msp3400_ops { | ||
87 | void (*update)(struct pvr2_msp3400_handler *); | ||
88 | int (*check)(struct pvr2_msp3400_handler *); | ||
89 | }; | ||
90 | |||
91 | |||
92 | static const struct pvr2_msp3400_ops msp3400_ops[] = { | ||
93 | { .update = set_stereo, .check = check_stereo}, | ||
94 | }; | ||
95 | |||
96 | |||
97 | static int msp3400_check(struct pvr2_msp3400_handler *ctxt) | ||
98 | { | ||
99 | unsigned long msk; | ||
100 | unsigned int idx; | ||
101 | |||
102 | for (idx = 0; idx < sizeof(msp3400_ops)/sizeof(msp3400_ops[0]); | ||
103 | idx++) { | ||
104 | msk = 1 << idx; | ||
105 | if (ctxt->stale_mask & msk) continue; | ||
106 | if (msp3400_ops[idx].check(ctxt)) { | ||
107 | ctxt->stale_mask |= msk; | ||
108 | } | ||
109 | } | ||
110 | return ctxt->stale_mask != 0; | ||
111 | } | ||
112 | |||
113 | |||
114 | static void msp3400_update(struct pvr2_msp3400_handler *ctxt) | ||
115 | { | ||
116 | unsigned long msk; | ||
117 | unsigned int idx; | ||
118 | |||
119 | for (idx = 0; idx < sizeof(msp3400_ops)/sizeof(msp3400_ops[0]); | ||
120 | idx++) { | ||
121 | msk = 1 << idx; | ||
122 | if (!(ctxt->stale_mask & msk)) continue; | ||
123 | ctxt->stale_mask &= ~msk; | ||
124 | msp3400_ops[idx].update(ctxt); | ||
125 | } | ||
126 | } | ||
127 | |||
128 | |||
129 | /* This reads back the current signal type */ | ||
130 | static int get_audio_status(struct pvr2_msp3400_handler *ctxt) | ||
131 | { | ||
132 | struct v4l2_tuner vt; | ||
133 | int stat; | ||
134 | |||
135 | memset(&vt,0,sizeof(vt)); | ||
136 | stat = pvr2_i2c_client_cmd(ctxt->client,VIDIOC_G_TUNER,&vt); | ||
137 | if (stat < 0) return stat; | ||
138 | |||
139 | ctxt->hdw->flag_stereo = (vt.audmode & V4L2_TUNER_MODE_STEREO) != 0; | ||
140 | ctxt->hdw->flag_bilingual = | ||
141 | (vt.audmode & V4L2_TUNER_MODE_LANG2) != 0; | ||
142 | return 0; | ||
143 | } | ||
144 | |||
145 | |||
146 | static void pvr2_msp3400_detach(struct pvr2_msp3400_handler *ctxt) | ||
147 | { | ||
148 | ctxt->client->handler = 0; | ||
149 | ctxt->hdw->audio_stat = 0; | ||
150 | kfree(ctxt); | ||
151 | } | ||
152 | |||
153 | |||
154 | static unsigned int pvr2_msp3400_describe(struct pvr2_msp3400_handler *ctxt, | ||
155 | char *buf,unsigned int cnt) | ||
156 | { | ||
157 | return scnprintf(buf,cnt,"handler: pvrusb2-audio v4l2"); | ||
158 | } | ||
159 | |||
160 | |||
161 | const static struct pvr2_i2c_handler_functions msp3400_funcs = { | ||
162 | .detach = (void (*)(void *))pvr2_msp3400_detach, | ||
163 | .check = (int (*)(void *))msp3400_check, | ||
164 | .update = (void (*)(void *))msp3400_update, | ||
165 | .describe = (unsigned int (*)(void *,char *,unsigned int))pvr2_msp3400_describe, | ||
166 | }; | ||
167 | |||
168 | |||
169 | int pvr2_i2c_msp3400_setup(struct pvr2_hdw *hdw,struct pvr2_i2c_client *cp) | ||
170 | { | ||
171 | struct pvr2_msp3400_handler *ctxt; | ||
172 | if (hdw->audio_stat) return 0; | ||
173 | if (cp->handler) return 0; | ||
174 | |||
175 | ctxt = kmalloc(sizeof(*ctxt),GFP_KERNEL); | ||
176 | if (!ctxt) return 0; | ||
177 | memset(ctxt,0,sizeof(*ctxt)); | ||
178 | |||
179 | ctxt->i2c_handler.func_data = ctxt; | ||
180 | ctxt->i2c_handler.func_table = &msp3400_funcs; | ||
181 | ctxt->client = cp; | ||
182 | ctxt->hdw = hdw; | ||
183 | ctxt->astat.ctxt = ctxt; | ||
184 | ctxt->astat.status = (int (*)(void *))get_audio_status; | ||
185 | ctxt->astat.detach = (void (*)(void *))pvr2_msp3400_detach; | ||
186 | ctxt->stale_mask = (1 << (sizeof(msp3400_ops)/ | ||
187 | sizeof(msp3400_ops[0]))) - 1; | ||
188 | cp->handler = &ctxt->i2c_handler; | ||
189 | hdw->audio_stat = &ctxt->astat; | ||
190 | pvr2_trace(PVR2_TRACE_CHIPS,"i2c 0x%x msp3400 V4L2 handler set up", | ||
191 | cp->client->addr); | ||
192 | return !0; | ||
193 | } | ||
194 | |||
195 | |||
196 | /* | ||
197 | Stuff for Emacs to see, in order to encourage consistent editing style: | ||
198 | *** Local Variables: *** | ||
199 | *** mode: c *** | ||
200 | *** fill-column: 70 *** | ||
201 | *** tab-width: 8 *** | ||
202 | *** c-basic-offset: 8 *** | ||
203 | *** End: *** | ||
204 | */ | ||
diff --git a/drivers/media/video/pvrusb2/pvrusb2-audio.h b/drivers/media/video/pvrusb2/pvrusb2-audio.h new file mode 100644 index 000000000000..536339b68843 --- /dev/null +++ b/drivers/media/video/pvrusb2/pvrusb2-audio.h | |||
@@ -0,0 +1,40 @@ | |||
1 | /* | ||
2 | * | ||
3 | * $Id$ | ||
4 | * | ||
5 | * Copyright (C) 2005 Mike Isely <isely@pobox.com> | ||
6 | * Copyright (C) 2004 Aurelien Alleaume <slts@free.fr> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License as published by | ||
10 | * the Free Software Foundation; either version 2 of the License | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | * GNU General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU General Public License | ||
18 | * along with this program; if not, write to the Free Software | ||
19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
20 | * | ||
21 | */ | ||
22 | |||
23 | #ifndef __PVRUSB2_AUDIO_H | ||
24 | #define __PVRUSB2_AUDIO_H | ||
25 | |||
26 | #include "pvrusb2-i2c-core.h" | ||
27 | |||
28 | int pvr2_i2c_msp3400_setup(struct pvr2_hdw *,struct pvr2_i2c_client *); | ||
29 | |||
30 | #endif /* __PVRUSB2_AUDIO_H */ | ||
31 | |||
32 | /* | ||
33 | Stuff for Emacs to see, in order to encourage consistent editing style: | ||
34 | *** Local Variables: *** | ||
35 | *** mode: c *** | ||
36 | *** fill-column: 70 *** | ||
37 | *** tab-width: 8 *** | ||
38 | *** c-basic-offset: 8 *** | ||
39 | *** End: *** | ||
40 | */ | ||
diff --git a/drivers/media/video/pvrusb2/pvrusb2-context.c b/drivers/media/video/pvrusb2/pvrusb2-context.c new file mode 100644 index 000000000000..40dc59871a45 --- /dev/null +++ b/drivers/media/video/pvrusb2/pvrusb2-context.c | |||
@@ -0,0 +1,230 @@ | |||
1 | /* | ||
2 | * $Id$ | ||
3 | * | ||
4 | * Copyright (C) 2005 Mike Isely <isely@pobox.com> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | * GNU General Public License for more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU General Public License | ||
16 | * along with this program; if not, write to the Free Software | ||
17 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
18 | * | ||
19 | */ | ||
20 | |||
21 | #include "pvrusb2-context.h" | ||
22 | #include "pvrusb2-io.h" | ||
23 | #include "pvrusb2-ioread.h" | ||
24 | #include "pvrusb2-hdw.h" | ||
25 | #include "pvrusb2-debug.h" | ||
26 | #include <linux/errno.h> | ||
27 | #include <linux/string.h> | ||
28 | #include <linux/slab.h> | ||
29 | #include <asm/semaphore.h> | ||
30 | |||
31 | |||
32 | static void pvr2_context_destroy(struct pvr2_context *mp) | ||
33 | { | ||
34 | if (mp->hdw) pvr2_hdw_destroy(mp->hdw); | ||
35 | pvr2_trace(PVR2_TRACE_STRUCT,"Destroying pvr_main id=%p",mp); | ||
36 | flush_workqueue(mp->workqueue); | ||
37 | destroy_workqueue(mp->workqueue); | ||
38 | kfree(mp); | ||
39 | } | ||
40 | |||
41 | |||
42 | static void pvr2_context_trigger_poll(struct pvr2_context *mp) | ||
43 | { | ||
44 | queue_work(mp->workqueue,&mp->workpoll); | ||
45 | } | ||
46 | |||
47 | |||
48 | static void pvr2_context_poll(struct pvr2_context *mp) | ||
49 | { | ||
50 | pvr2_context_enter(mp); do { | ||
51 | pvr2_hdw_poll(mp->hdw); | ||
52 | } while (0); pvr2_context_exit(mp); | ||
53 | } | ||
54 | |||
55 | |||
56 | static void pvr2_context_setup(struct pvr2_context *mp) | ||
57 | { | ||
58 | pvr2_context_enter(mp); do { | ||
59 | if (!pvr2_hdw_dev_ok(mp->hdw)) break; | ||
60 | pvr2_hdw_setup(mp->hdw); | ||
61 | pvr2_hdw_setup_poll_trigger( | ||
62 | mp->hdw, | ||
63 | (void (*)(void *))pvr2_context_trigger_poll, | ||
64 | mp); | ||
65 | if (!pvr2_hdw_dev_ok(mp->hdw)) break; | ||
66 | if (!pvr2_hdw_init_ok(mp->hdw)) break; | ||
67 | mp->video_stream.stream = pvr2_hdw_get_video_stream(mp->hdw); | ||
68 | if (mp->setup_func) { | ||
69 | mp->setup_func(mp); | ||
70 | } | ||
71 | } while (0); pvr2_context_exit(mp); | ||
72 | } | ||
73 | |||
74 | |||
75 | struct pvr2_context *pvr2_context_create( | ||
76 | struct usb_interface *intf, | ||
77 | const struct usb_device_id *devid, | ||
78 | void (*setup_func)(struct pvr2_context *)) | ||
79 | { | ||
80 | struct pvr2_context *mp = 0; | ||
81 | mp = kmalloc(sizeof(*mp),GFP_KERNEL); | ||
82 | if (!mp) goto done; | ||
83 | memset(mp,0,sizeof(*mp)); | ||
84 | pvr2_trace(PVR2_TRACE_STRUCT,"Creating pvr_main id=%p",mp); | ||
85 | mp->setup_func = setup_func; | ||
86 | mutex_init(&mp->mutex); | ||
87 | mp->hdw = pvr2_hdw_create(intf,devid); | ||
88 | if (!mp->hdw) { | ||
89 | pvr2_context_destroy(mp); | ||
90 | mp = 0; | ||
91 | goto done; | ||
92 | } | ||
93 | |||
94 | mp->workqueue = create_singlethread_workqueue("pvrusb2"); | ||
95 | INIT_WORK(&mp->workinit,(void (*)(void*))pvr2_context_setup,mp); | ||
96 | INIT_WORK(&mp->workpoll,(void (*)(void*))pvr2_context_poll,mp); | ||
97 | queue_work(mp->workqueue,&mp->workinit); | ||
98 | done: | ||
99 | return mp; | ||
100 | } | ||
101 | |||
102 | |||
103 | void pvr2_context_enter(struct pvr2_context *mp) | ||
104 | { | ||
105 | mutex_lock(&mp->mutex); | ||
106 | pvr2_trace(PVR2_TRACE_CREG,"pvr2_context_enter(id=%p)",mp); | ||
107 | } | ||
108 | |||
109 | |||
110 | void pvr2_context_exit(struct pvr2_context *mp) | ||
111 | { | ||
112 | int destroy_flag = 0; | ||
113 | if (!(mp->mc_first || !mp->disconnect_flag)) { | ||
114 | destroy_flag = !0; | ||
115 | } | ||
116 | pvr2_trace(PVR2_TRACE_CREG,"pvr2_context_exit(id=%p) outside",mp); | ||
117 | mutex_unlock(&mp->mutex); | ||
118 | if (destroy_flag) pvr2_context_destroy(mp); | ||
119 | } | ||
120 | |||
121 | |||
122 | static void pvr2_context_run_checks(struct pvr2_context *mp) | ||
123 | { | ||
124 | struct pvr2_channel *ch1,*ch2; | ||
125 | for (ch1 = mp->mc_first; ch1; ch1 = ch2) { | ||
126 | ch2 = ch1->mc_next; | ||
127 | if (ch1->check_func) { | ||
128 | ch1->check_func(ch1); | ||
129 | } | ||
130 | } | ||
131 | } | ||
132 | |||
133 | |||
134 | void pvr2_context_disconnect(struct pvr2_context *mp) | ||
135 | { | ||
136 | pvr2_context_enter(mp); do { | ||
137 | pvr2_hdw_disconnect(mp->hdw); | ||
138 | mp->disconnect_flag = !0; | ||
139 | pvr2_context_run_checks(mp); | ||
140 | } while (0); pvr2_context_exit(mp); | ||
141 | } | ||
142 | |||
143 | |||
144 | void pvr2_channel_init(struct pvr2_channel *cp,struct pvr2_context *mp) | ||
145 | { | ||
146 | cp->hdw = mp->hdw; | ||
147 | cp->mc_head = mp; | ||
148 | cp->mc_next = 0; | ||
149 | cp->mc_prev = mp->mc_last; | ||
150 | if (mp->mc_last) { | ||
151 | mp->mc_last->mc_next = cp; | ||
152 | } else { | ||
153 | mp->mc_first = cp; | ||
154 | } | ||
155 | mp->mc_last = cp; | ||
156 | } | ||
157 | |||
158 | |||
159 | static void pvr2_channel_disclaim_stream(struct pvr2_channel *cp) | ||
160 | { | ||
161 | if (!cp->stream) return; | ||
162 | pvr2_stream_kill(cp->stream->stream); | ||
163 | cp->stream->user = 0; | ||
164 | cp->stream = 0; | ||
165 | } | ||
166 | |||
167 | |||
168 | void pvr2_channel_done(struct pvr2_channel *cp) | ||
169 | { | ||
170 | struct pvr2_context *mp = cp->mc_head; | ||
171 | pvr2_channel_disclaim_stream(cp); | ||
172 | if (cp->mc_next) { | ||
173 | cp->mc_next->mc_prev = cp->mc_prev; | ||
174 | } else { | ||
175 | mp->mc_last = cp->mc_prev; | ||
176 | } | ||
177 | if (cp->mc_prev) { | ||
178 | cp->mc_prev->mc_next = cp->mc_next; | ||
179 | } else { | ||
180 | mp->mc_first = cp->mc_next; | ||
181 | } | ||
182 | cp->hdw = 0; | ||
183 | } | ||
184 | |||
185 | |||
186 | int pvr2_channel_claim_stream(struct pvr2_channel *cp, | ||
187 | struct pvr2_context_stream *sp) | ||
188 | { | ||
189 | int code = 0; | ||
190 | pvr2_context_enter(cp->mc_head); do { | ||
191 | if (sp == cp->stream) break; | ||
192 | if (sp->user) { | ||
193 | code = -EBUSY; | ||
194 | break; | ||
195 | } | ||
196 | pvr2_channel_disclaim_stream(cp); | ||
197 | if (!sp) break; | ||
198 | sp->user = cp; | ||
199 | cp->stream = sp; | ||
200 | } while (0); pvr2_context_exit(cp->mc_head); | ||
201 | return code; | ||
202 | } | ||
203 | |||
204 | |||
205 | // This is the marker for the real beginning of a legitimate mpeg2 stream. | ||
206 | static char stream_sync_key[] = { | ||
207 | 0x00, 0x00, 0x01, 0xba, | ||
208 | }; | ||
209 | |||
210 | struct pvr2_ioread *pvr2_channel_create_mpeg_stream( | ||
211 | struct pvr2_context_stream *sp) | ||
212 | { | ||
213 | struct pvr2_ioread *cp; | ||
214 | cp = pvr2_ioread_create(); | ||
215 | if (!cp) return 0; | ||
216 | pvr2_ioread_setup(cp,sp->stream); | ||
217 | pvr2_ioread_set_sync_key(cp,stream_sync_key,sizeof(stream_sync_key)); | ||
218 | return cp; | ||
219 | } | ||
220 | |||
221 | |||
222 | /* | ||
223 | Stuff for Emacs to see, in order to encourage consistent editing style: | ||
224 | *** Local Variables: *** | ||
225 | *** mode: c *** | ||
226 | *** fill-column: 75 *** | ||
227 | *** tab-width: 8 *** | ||
228 | *** c-basic-offset: 8 *** | ||
229 | *** End: *** | ||
230 | */ | ||
diff --git a/drivers/media/video/pvrusb2/pvrusb2-context.h b/drivers/media/video/pvrusb2/pvrusb2-context.h new file mode 100644 index 000000000000..6327fa1f7e4f --- /dev/null +++ b/drivers/media/video/pvrusb2/pvrusb2-context.h | |||
@@ -0,0 +1,92 @@ | |||
1 | /* | ||
2 | * $Id$ | ||
3 | * | ||
4 | * Copyright (C) 2005 Mike Isely <isely@pobox.com> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | * GNU General Public License for more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU General Public License | ||
16 | * along with this program; if not, write to the Free Software | ||
17 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
18 | * | ||
19 | */ | ||
20 | #ifndef __PVRUSB2_BASE_H | ||
21 | #define __PVRUSB2_BASE_H | ||
22 | |||
23 | #include <linux/mutex.h> | ||
24 | #include <linux/usb.h> | ||
25 | #include <linux/workqueue.h> | ||
26 | |||
27 | struct pvr2_hdw; /* hardware interface - defined elsewhere */ | ||
28 | struct pvr2_stream; /* stream interface - defined elsewhere */ | ||
29 | |||
30 | struct pvr2_context; /* All central state */ | ||
31 | struct pvr2_channel; /* One I/O pathway to a user */ | ||
32 | struct pvr2_context_stream; /* Wrapper for a stream */ | ||
33 | struct pvr2_crit_reg; /* Critical region pointer */ | ||
34 | struct pvr2_ioread; /* Low level stream structure */ | ||
35 | |||
36 | struct pvr2_context_stream { | ||
37 | struct pvr2_channel *user; | ||
38 | struct pvr2_stream *stream; | ||
39 | }; | ||
40 | |||
41 | struct pvr2_context { | ||
42 | struct pvr2_channel *mc_first; | ||
43 | struct pvr2_channel *mc_last; | ||
44 | struct pvr2_hdw *hdw; | ||
45 | struct pvr2_context_stream video_stream; | ||
46 | struct mutex mutex; | ||
47 | int disconnect_flag; | ||
48 | |||
49 | /* Called after pvr2_context initialization is complete */ | ||
50 | void (*setup_func)(struct pvr2_context *); | ||
51 | |||
52 | /* Work queue overhead for out-of-line processing */ | ||
53 | struct workqueue_struct *workqueue; | ||
54 | struct work_struct workinit; | ||
55 | struct work_struct workpoll; | ||
56 | }; | ||
57 | |||
58 | struct pvr2_channel { | ||
59 | struct pvr2_context *mc_head; | ||
60 | struct pvr2_channel *mc_next; | ||
61 | struct pvr2_channel *mc_prev; | ||
62 | struct pvr2_context_stream *stream; | ||
63 | struct pvr2_hdw *hdw; | ||
64 | void (*check_func)(struct pvr2_channel *); | ||
65 | }; | ||
66 | |||
67 | void pvr2_context_enter(struct pvr2_context *); | ||
68 | void pvr2_context_exit(struct pvr2_context *); | ||
69 | |||
70 | struct pvr2_context *pvr2_context_create(struct usb_interface *intf, | ||
71 | const struct usb_device_id *devid, | ||
72 | void (*setup_func)(struct pvr2_context *)); | ||
73 | void pvr2_context_disconnect(struct pvr2_context *); | ||
74 | |||
75 | void pvr2_channel_init(struct pvr2_channel *,struct pvr2_context *); | ||
76 | void pvr2_channel_done(struct pvr2_channel *); | ||
77 | int pvr2_channel_claim_stream(struct pvr2_channel *, | ||
78 | struct pvr2_context_stream *); | ||
79 | struct pvr2_ioread *pvr2_channel_create_mpeg_stream( | ||
80 | struct pvr2_context_stream *); | ||
81 | |||
82 | |||
83 | #endif /* __PVRUSB2_CONTEXT_H */ | ||
84 | /* | ||
85 | Stuff for Emacs to see, in order to encourage consistent editing style: | ||
86 | *** Local Variables: *** | ||
87 | *** mode: c *** | ||
88 | *** fill-column: 75 *** | ||
89 | *** tab-width: 8 *** | ||
90 | *** c-basic-offset: 8 *** | ||
91 | *** End: *** | ||
92 | */ | ||
diff --git a/drivers/media/video/pvrusb2/pvrusb2-ctrl.c b/drivers/media/video/pvrusb2/pvrusb2-ctrl.c new file mode 100644 index 000000000000..d5df9fbeba2f --- /dev/null +++ b/drivers/media/video/pvrusb2/pvrusb2-ctrl.c | |||
@@ -0,0 +1,593 @@ | |||
1 | /* | ||
2 | * | ||
3 | * $Id$ | ||
4 | * | ||
5 | * Copyright (C) 2005 Mike Isely <isely@pobox.com> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License as published by | ||
9 | * the Free Software Foundation; either version 2 of the License | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
19 | * | ||
20 | */ | ||
21 | |||
22 | #include "pvrusb2-ctrl.h" | ||
23 | #include "pvrusb2-hdw-internal.h" | ||
24 | #include <linux/errno.h> | ||
25 | #include <linux/string.h> | ||
26 | #include <linux/mutex.h> | ||
27 | |||
28 | |||
29 | /* Set the given control. */ | ||
30 | int pvr2_ctrl_set_value(struct pvr2_ctrl *cptr,int val) | ||
31 | { | ||
32 | return pvr2_ctrl_set_mask_value(cptr,~0,val); | ||
33 | } | ||
34 | |||
35 | |||
36 | /* Set/clear specific bits of the given control. */ | ||
37 | int pvr2_ctrl_set_mask_value(struct pvr2_ctrl *cptr,int mask,int val) | ||
38 | { | ||
39 | int ret = 0; | ||
40 | if (!cptr) return -EINVAL; | ||
41 | LOCK_TAKE(cptr->hdw->big_lock); do { | ||
42 | if (cptr->info->set_value != 0) { | ||
43 | if (cptr->info->type == pvr2_ctl_bitmask) { | ||
44 | mask &= cptr->info->def.type_bitmask.valid_bits; | ||
45 | } else if (cptr->info->type == pvr2_ctl_int) { | ||
46 | if (val < cptr->info->def.type_int.min_value) { | ||
47 | break; | ||
48 | } | ||
49 | if (val > cptr->info->def.type_int.max_value) { | ||
50 | break; | ||
51 | } | ||
52 | } else if (cptr->info->type == pvr2_ctl_enum) { | ||
53 | if (val >= cptr->info->def.type_enum.count) { | ||
54 | break; | ||
55 | } | ||
56 | } else if (cptr->info->type != pvr2_ctl_bool) { | ||
57 | break; | ||
58 | } | ||
59 | ret = cptr->info->set_value(cptr,mask,val); | ||
60 | } else { | ||
61 | ret = -EPERM; | ||
62 | } | ||
63 | } while(0); LOCK_GIVE(cptr->hdw->big_lock); | ||
64 | return ret; | ||
65 | } | ||
66 | |||
67 | |||
68 | /* Get the current value of the given control. */ | ||
69 | int pvr2_ctrl_get_value(struct pvr2_ctrl *cptr,int *valptr) | ||
70 | { | ||
71 | int ret = 0; | ||
72 | if (!cptr) return -EINVAL; | ||
73 | LOCK_TAKE(cptr->hdw->big_lock); do { | ||
74 | ret = cptr->info->get_value(cptr,valptr); | ||
75 | } while(0); LOCK_GIVE(cptr->hdw->big_lock); | ||
76 | return ret; | ||
77 | } | ||
78 | |||
79 | |||
80 | /* Retrieve control's type */ | ||
81 | enum pvr2_ctl_type pvr2_ctrl_get_type(struct pvr2_ctrl *cptr) | ||
82 | { | ||
83 | if (!cptr) return pvr2_ctl_int; | ||
84 | return cptr->info->type; | ||
85 | } | ||
86 | |||
87 | |||
88 | /* Retrieve control's maximum value (int type) */ | ||
89 | int pvr2_ctrl_get_max(struct pvr2_ctrl *cptr) | ||
90 | { | ||
91 | int ret = 0; | ||
92 | if (!cptr) return 0; | ||
93 | LOCK_TAKE(cptr->hdw->big_lock); do { | ||
94 | if (cptr->info->type == pvr2_ctl_int) { | ||
95 | ret = cptr->info->def.type_int.max_value; | ||
96 | } | ||
97 | } while(0); LOCK_GIVE(cptr->hdw->big_lock); | ||
98 | return ret; | ||
99 | } | ||
100 | |||
101 | |||
102 | /* Retrieve control's minimum value (int type) */ | ||
103 | int pvr2_ctrl_get_min(struct pvr2_ctrl *cptr) | ||
104 | { | ||
105 | int ret = 0; | ||
106 | if (!cptr) return 0; | ||
107 | LOCK_TAKE(cptr->hdw->big_lock); do { | ||
108 | if (cptr->info->type == pvr2_ctl_int) { | ||
109 | ret = cptr->info->def.type_int.min_value; | ||
110 | } | ||
111 | } while(0); LOCK_GIVE(cptr->hdw->big_lock); | ||
112 | return ret; | ||
113 | } | ||
114 | |||
115 | |||
116 | /* Retrieve control's default value (any type) */ | ||
117 | int pvr2_ctrl_get_def(struct pvr2_ctrl *cptr) | ||
118 | { | ||
119 | int ret = 0; | ||
120 | if (!cptr) return 0; | ||
121 | LOCK_TAKE(cptr->hdw->big_lock); do { | ||
122 | if (cptr->info->type == pvr2_ctl_int) { | ||
123 | ret = cptr->info->default_value; | ||
124 | } | ||
125 | } while(0); LOCK_GIVE(cptr->hdw->big_lock); | ||
126 | return ret; | ||
127 | } | ||
128 | |||
129 | |||
130 | /* Retrieve control's enumeration count (enum only) */ | ||
131 | int pvr2_ctrl_get_cnt(struct pvr2_ctrl *cptr) | ||
132 | { | ||
133 | int ret = 0; | ||
134 | if (!cptr) return 0; | ||
135 | LOCK_TAKE(cptr->hdw->big_lock); do { | ||
136 | if (cptr->info->type == pvr2_ctl_enum) { | ||
137 | ret = cptr->info->def.type_enum.count; | ||
138 | } | ||
139 | } while(0); LOCK_GIVE(cptr->hdw->big_lock); | ||
140 | return ret; | ||
141 | } | ||
142 | |||
143 | |||
144 | /* Retrieve control's valid mask bits (bit mask only) */ | ||
145 | int pvr2_ctrl_get_mask(struct pvr2_ctrl *cptr) | ||
146 | { | ||
147 | int ret = 0; | ||
148 | if (!cptr) return 0; | ||
149 | LOCK_TAKE(cptr->hdw->big_lock); do { | ||
150 | if (cptr->info->type == pvr2_ctl_bitmask) { | ||
151 | ret = cptr->info->def.type_bitmask.valid_bits; | ||
152 | } | ||
153 | } while(0); LOCK_GIVE(cptr->hdw->big_lock); | ||
154 | return ret; | ||
155 | } | ||
156 | |||
157 | |||
158 | /* Retrieve the control's name */ | ||
159 | const char *pvr2_ctrl_get_name(struct pvr2_ctrl *cptr) | ||
160 | { | ||
161 | if (!cptr) return 0; | ||
162 | return cptr->info->name; | ||
163 | } | ||
164 | |||
165 | |||
166 | /* Retrieve the control's desc */ | ||
167 | const char *pvr2_ctrl_get_desc(struct pvr2_ctrl *cptr) | ||
168 | { | ||
169 | if (!cptr) return 0; | ||
170 | return cptr->info->desc; | ||
171 | } | ||
172 | |||
173 | |||
174 | /* Retrieve a control enumeration or bit mask value */ | ||
175 | int pvr2_ctrl_get_valname(struct pvr2_ctrl *cptr,int val, | ||
176 | char *bptr,unsigned int bmax, | ||
177 | unsigned int *blen) | ||
178 | { | ||
179 | int ret = -EINVAL; | ||
180 | if (!cptr) return 0; | ||
181 | *blen = 0; | ||
182 | LOCK_TAKE(cptr->hdw->big_lock); do { | ||
183 | if (cptr->info->type == pvr2_ctl_enum) { | ||
184 | const char **names; | ||
185 | names = cptr->info->def.type_enum.value_names; | ||
186 | if ((val >= 0) && | ||
187 | (val < cptr->info->def.type_enum.count)) { | ||
188 | if (names[val]) { | ||
189 | *blen = scnprintf( | ||
190 | bptr,bmax,"%s", | ||
191 | names[val]); | ||
192 | } else { | ||
193 | *blen = 0; | ||
194 | } | ||
195 | ret = 0; | ||
196 | } | ||
197 | } else if (cptr->info->type == pvr2_ctl_bitmask) { | ||
198 | const char **names; | ||
199 | unsigned int idx; | ||
200 | int msk; | ||
201 | names = cptr->info->def.type_bitmask.bit_names; | ||
202 | val &= cptr->info->def.type_bitmask.valid_bits; | ||
203 | for (idx = 0, msk = 1; val; idx++, msk <<= 1) { | ||
204 | if (val & msk) { | ||
205 | *blen = scnprintf(bptr,bmax,"%s", | ||
206 | names[idx]); | ||
207 | ret = 0; | ||
208 | break; | ||
209 | } | ||
210 | } | ||
211 | } | ||
212 | } while(0); LOCK_GIVE(cptr->hdw->big_lock); | ||
213 | return ret; | ||
214 | } | ||
215 | |||
216 | |||
217 | /* Return V4L ID for this control or zero if none */ | ||
218 | int pvr2_ctrl_get_v4lid(struct pvr2_ctrl *cptr) | ||
219 | { | ||
220 | if (!cptr) return 0; | ||
221 | return cptr->info->v4l_id; | ||
222 | } | ||
223 | |||
224 | |||
225 | unsigned int pvr2_ctrl_get_v4lflags(struct pvr2_ctrl *cptr) | ||
226 | { | ||
227 | unsigned int flags = 0; | ||
228 | |||
229 | if (cptr->info->get_v4lflags) { | ||
230 | flags = cptr->info->get_v4lflags(cptr); | ||
231 | } | ||
232 | |||
233 | if (cptr->info->set_value) { | ||
234 | flags &= ~V4L2_CTRL_FLAG_READ_ONLY; | ||
235 | } else { | ||
236 | flags |= V4L2_CTRL_FLAG_READ_ONLY; | ||
237 | } | ||
238 | |||
239 | return flags; | ||
240 | } | ||
241 | |||
242 | |||
243 | /* Return true if control is writable */ | ||
244 | int pvr2_ctrl_is_writable(struct pvr2_ctrl *cptr) | ||
245 | { | ||
246 | if (!cptr) return 0; | ||
247 | return cptr->info->set_value != 0; | ||
248 | } | ||
249 | |||
250 | |||
251 | /* Return true if control has custom symbolic representation */ | ||
252 | int pvr2_ctrl_has_custom_symbols(struct pvr2_ctrl *cptr) | ||
253 | { | ||
254 | if (!cptr) return 0; | ||
255 | if (!cptr->info->val_to_sym) return 0; | ||
256 | if (!cptr->info->sym_to_val) return 0; | ||
257 | return !0; | ||
258 | } | ||
259 | |||
260 | |||
261 | /* Convert a given mask/val to a custom symbolic value */ | ||
262 | int pvr2_ctrl_custom_value_to_sym(struct pvr2_ctrl *cptr, | ||
263 | int mask,int val, | ||
264 | char *buf,unsigned int maxlen, | ||
265 | unsigned int *len) | ||
266 | { | ||
267 | if (!cptr) return -EINVAL; | ||
268 | if (!cptr->info->val_to_sym) return -EINVAL; | ||
269 | return cptr->info->val_to_sym(cptr,mask,val,buf,maxlen,len); | ||
270 | } | ||
271 | |||
272 | |||
273 | /* Convert a symbolic value to a mask/value pair */ | ||
274 | int pvr2_ctrl_custom_sym_to_value(struct pvr2_ctrl *cptr, | ||
275 | const char *buf,unsigned int len, | ||
276 | int *maskptr,int *valptr) | ||
277 | { | ||
278 | if (!cptr) return -EINVAL; | ||
279 | if (!cptr->info->sym_to_val) return -EINVAL; | ||
280 | return cptr->info->sym_to_val(cptr,buf,len,maskptr,valptr); | ||
281 | } | ||
282 | |||
283 | |||
284 | static unsigned int gen_bitmask_string(int msk,int val,int msk_only, | ||
285 | const char **names, | ||
286 | char *ptr,unsigned int len) | ||
287 | { | ||
288 | unsigned int idx; | ||
289 | long sm,um; | ||
290 | int spcFl; | ||
291 | unsigned int uc,cnt; | ||
292 | const char *idStr; | ||
293 | |||
294 | spcFl = 0; | ||
295 | uc = 0; | ||
296 | um = 0; | ||
297 | for (idx = 0, sm = 1; msk; idx++, sm <<= 1) { | ||
298 | if (sm & msk) { | ||
299 | msk &= ~sm; | ||
300 | idStr = names[idx]; | ||
301 | if (idStr) { | ||
302 | cnt = scnprintf(ptr,len,"%s%s%s", | ||
303 | (spcFl ? " " : ""), | ||
304 | (msk_only ? "" : | ||
305 | ((val & sm) ? "+" : "-")), | ||
306 | idStr); | ||
307 | ptr += cnt; len -= cnt; uc += cnt; | ||
308 | spcFl = !0; | ||
309 | } else { | ||
310 | um |= sm; | ||
311 | } | ||
312 | } | ||
313 | } | ||
314 | if (um) { | ||
315 | if (msk_only) { | ||
316 | cnt = scnprintf(ptr,len,"%s0x%lx", | ||
317 | (spcFl ? " " : ""), | ||
318 | um); | ||
319 | ptr += cnt; len -= cnt; uc += cnt; | ||
320 | spcFl = !0; | ||
321 | } else if (um & val) { | ||
322 | cnt = scnprintf(ptr,len,"%s+0x%lx", | ||
323 | (spcFl ? " " : ""), | ||
324 | um & val); | ||
325 | ptr += cnt; len -= cnt; uc += cnt; | ||
326 | spcFl = !0; | ||
327 | } else if (um & ~val) { | ||
328 | cnt = scnprintf(ptr,len,"%s+0x%lx", | ||
329 | (spcFl ? " " : ""), | ||
330 | um & ~val); | ||
331 | ptr += cnt; len -= cnt; uc += cnt; | ||
332 | spcFl = !0; | ||
333 | } | ||
334 | } | ||
335 | return uc; | ||
336 | } | ||
337 | |||
338 | |||
339 | static const char *boolNames[] = { | ||
340 | "false", | ||
341 | "true", | ||
342 | "no", | ||
343 | "yes", | ||
344 | }; | ||
345 | |||
346 | |||
347 | static int parse_token(const char *ptr,unsigned int len, | ||
348 | int *valptr, | ||
349 | const char **names,unsigned int namecnt) | ||
350 | { | ||
351 | char buf[33]; | ||
352 | unsigned int slen; | ||
353 | unsigned int idx; | ||
354 | int negfl; | ||
355 | char *p2; | ||
356 | *valptr = 0; | ||
357 | if (!names) namecnt = 0; | ||
358 | for (idx = 0; idx < namecnt; idx++) { | ||
359 | if (!names[idx]) continue; | ||
360 | slen = strlen(names[idx]); | ||
361 | if (slen != len) continue; | ||
362 | if (memcmp(names[idx],ptr,slen)) continue; | ||
363 | *valptr = idx; | ||
364 | return 0; | ||
365 | } | ||
366 | negfl = 0; | ||
367 | if ((*ptr == '-') || (*ptr == '+')) { | ||
368 | negfl = (*ptr == '-'); | ||
369 | ptr++; len--; | ||
370 | } | ||
371 | if (len >= sizeof(buf)) return -EINVAL; | ||
372 | memcpy(buf,ptr,len); | ||
373 | buf[len] = 0; | ||
374 | *valptr = simple_strtol(buf,&p2,0); | ||
375 | if (negfl) *valptr = -(*valptr); | ||
376 | if (*p2) return -EINVAL; | ||
377 | return 1; | ||
378 | } | ||
379 | |||
380 | |||
381 | static int parse_mtoken(const char *ptr,unsigned int len, | ||
382 | int *valptr, | ||
383 | const char **names,int valid_bits) | ||
384 | { | ||
385 | char buf[33]; | ||
386 | unsigned int slen; | ||
387 | unsigned int idx; | ||
388 | char *p2; | ||
389 | int msk; | ||
390 | *valptr = 0; | ||
391 | for (idx = 0, msk = 1; valid_bits; idx++, msk <<= 1) { | ||
392 | if (!msk & valid_bits) continue; | ||
393 | valid_bits &= ~msk; | ||
394 | if (!names[idx]) continue; | ||
395 | slen = strlen(names[idx]); | ||
396 | if (slen != len) continue; | ||
397 | if (memcmp(names[idx],ptr,slen)) continue; | ||
398 | *valptr = msk; | ||
399 | return 0; | ||
400 | } | ||
401 | if (len >= sizeof(buf)) return -EINVAL; | ||
402 | memcpy(buf,ptr,len); | ||
403 | buf[len] = 0; | ||
404 | *valptr = simple_strtol(buf,&p2,0); | ||
405 | if (*p2) return -EINVAL; | ||
406 | return 0; | ||
407 | } | ||
408 | |||
409 | |||
410 | static int parse_tlist(const char *ptr,unsigned int len, | ||
411 | int *maskptr,int *valptr, | ||
412 | const char **names,int valid_bits) | ||
413 | { | ||
414 | unsigned int cnt; | ||
415 | int mask,val,kv,mode,ret; | ||
416 | mask = 0; | ||
417 | val = 0; | ||
418 | ret = 0; | ||
419 | while (len) { | ||
420 | cnt = 0; | ||
421 | while ((cnt < len) && | ||
422 | ((ptr[cnt] <= 32) || | ||
423 | (ptr[cnt] >= 127))) cnt++; | ||
424 | ptr += cnt; | ||
425 | len -= cnt; | ||
426 | mode = 0; | ||
427 | if ((*ptr == '-') || (*ptr == '+')) { | ||
428 | mode = (*ptr == '-') ? -1 : 1; | ||
429 | ptr++; | ||
430 | len--; | ||
431 | } | ||
432 | cnt = 0; | ||
433 | while (cnt < len) { | ||
434 | if (ptr[cnt] <= 32) break; | ||
435 | if (ptr[cnt] >= 127) break; | ||
436 | cnt++; | ||
437 | } | ||
438 | if (!cnt) break; | ||
439 | if (parse_mtoken(ptr,cnt,&kv,names,valid_bits)) { | ||
440 | ret = -EINVAL; | ||
441 | break; | ||
442 | } | ||
443 | ptr += cnt; | ||
444 | len -= cnt; | ||
445 | switch (mode) { | ||
446 | case 0: | ||
447 | mask = valid_bits; | ||
448 | val |= kv; | ||
449 | break; | ||
450 | case -1: | ||
451 | mask |= kv; | ||
452 | val &= ~kv; | ||
453 | break; | ||
454 | case 1: | ||
455 | mask |= kv; | ||
456 | val |= kv; | ||
457 | break; | ||
458 | default: | ||
459 | break; | ||
460 | } | ||
461 | } | ||
462 | *maskptr = mask; | ||
463 | *valptr = val; | ||
464 | return ret; | ||
465 | } | ||
466 | |||
467 | |||
468 | /* Convert a symbolic value to a mask/value pair */ | ||
469 | int pvr2_ctrl_sym_to_value(struct pvr2_ctrl *cptr, | ||
470 | const char *ptr,unsigned int len, | ||
471 | int *maskptr,int *valptr) | ||
472 | { | ||
473 | int ret = -EINVAL; | ||
474 | unsigned int cnt; | ||
475 | |||
476 | *maskptr = 0; | ||
477 | *valptr = 0; | ||
478 | |||
479 | cnt = 0; | ||
480 | while ((cnt < len) && ((ptr[cnt] <= 32) || (ptr[cnt] >= 127))) cnt++; | ||
481 | len -= cnt; ptr += cnt; | ||
482 | cnt = 0; | ||
483 | while ((cnt < len) && ((ptr[len-(cnt+1)] <= 32) || | ||
484 | (ptr[len-(cnt+1)] >= 127))) cnt++; | ||
485 | len -= cnt; | ||
486 | |||
487 | if (!len) return -EINVAL; | ||
488 | |||
489 | LOCK_TAKE(cptr->hdw->big_lock); do { | ||
490 | if (cptr->info->type == pvr2_ctl_int) { | ||
491 | ret = parse_token(ptr,len,valptr,0,0); | ||
492 | if ((ret >= 0) && | ||
493 | ((*valptr < cptr->info->def.type_int.min_value) || | ||
494 | (*valptr > cptr->info->def.type_int.max_value))) { | ||
495 | ret = -ERANGE; | ||
496 | } | ||
497 | if (maskptr) *maskptr = ~0; | ||
498 | } else if (cptr->info->type == pvr2_ctl_bool) { | ||
499 | ret = parse_token( | ||
500 | ptr,len,valptr,boolNames, | ||
501 | sizeof(boolNames)/sizeof(boolNames[0])); | ||
502 | if (ret == 1) { | ||
503 | *valptr = *valptr ? !0 : 0; | ||
504 | } else if (ret == 0) { | ||
505 | *valptr = (*valptr & 1) ? !0 : 0; | ||
506 | } | ||
507 | if (maskptr) *maskptr = 1; | ||
508 | } else if (cptr->info->type == pvr2_ctl_enum) { | ||
509 | ret = parse_token( | ||
510 | ptr,len,valptr, | ||
511 | cptr->info->def.type_enum.value_names, | ||
512 | cptr->info->def.type_enum.count); | ||
513 | if ((ret >= 0) && | ||
514 | ((*valptr < 0) || | ||
515 | (*valptr >= cptr->info->def.type_enum.count))) { | ||
516 | ret = -ERANGE; | ||
517 | } | ||
518 | if (maskptr) *maskptr = ~0; | ||
519 | } else if (cptr->info->type == pvr2_ctl_bitmask) { | ||
520 | ret = parse_tlist( | ||
521 | ptr,len,maskptr,valptr, | ||
522 | cptr->info->def.type_bitmask.bit_names, | ||
523 | cptr->info->def.type_bitmask.valid_bits); | ||
524 | } | ||
525 | } while(0); LOCK_GIVE(cptr->hdw->big_lock); | ||
526 | return ret; | ||
527 | } | ||
528 | |||
529 | |||
530 | /* Convert a given mask/val to a symbolic value */ | ||
531 | int pvr2_ctrl_value_to_sym_internal(struct pvr2_ctrl *cptr, | ||
532 | int mask,int val, | ||
533 | char *buf,unsigned int maxlen, | ||
534 | unsigned int *len) | ||
535 | { | ||
536 | int ret = -EINVAL; | ||
537 | |||
538 | *len = 0; | ||
539 | if (cptr->info->type == pvr2_ctl_int) { | ||
540 | *len = scnprintf(buf,maxlen,"%d",val); | ||
541 | ret = 0; | ||
542 | } else if (cptr->info->type == pvr2_ctl_bool) { | ||
543 | *len = scnprintf(buf,maxlen,"%s",val ? "true" : "false"); | ||
544 | ret = 0; | ||
545 | } else if (cptr->info->type == pvr2_ctl_enum) { | ||
546 | const char **names; | ||
547 | names = cptr->info->def.type_enum.value_names; | ||
548 | if ((val >= 0) && | ||
549 | (val < cptr->info->def.type_enum.count)) { | ||
550 | if (names[val]) { | ||
551 | *len = scnprintf( | ||
552 | buf,maxlen,"%s", | ||
553 | names[val]); | ||
554 | } else { | ||
555 | *len = 0; | ||
556 | } | ||
557 | ret = 0; | ||
558 | } | ||
559 | } else if (cptr->info->type == pvr2_ctl_bitmask) { | ||
560 | *len = gen_bitmask_string( | ||
561 | val & mask & cptr->info->def.type_bitmask.valid_bits, | ||
562 | ~0,!0, | ||
563 | cptr->info->def.type_bitmask.bit_names, | ||
564 | buf,maxlen); | ||
565 | } | ||
566 | return ret; | ||
567 | } | ||
568 | |||
569 | |||
570 | /* Convert a given mask/val to a symbolic value */ | ||
571 | int pvr2_ctrl_value_to_sym(struct pvr2_ctrl *cptr, | ||
572 | int mask,int val, | ||
573 | char *buf,unsigned int maxlen, | ||
574 | unsigned int *len) | ||
575 | { | ||
576 | int ret; | ||
577 | LOCK_TAKE(cptr->hdw->big_lock); do { | ||
578 | ret = pvr2_ctrl_value_to_sym_internal(cptr,mask,val, | ||
579 | buf,maxlen,len); | ||
580 | } while(0); LOCK_GIVE(cptr->hdw->big_lock); | ||
581 | return ret; | ||
582 | } | ||
583 | |||
584 | |||
585 | /* | ||
586 | Stuff for Emacs to see, in order to encourage consistent editing style: | ||
587 | *** Local Variables: *** | ||
588 | *** mode: c *** | ||
589 | *** fill-column: 75 *** | ||
590 | *** tab-width: 8 *** | ||
591 | *** c-basic-offset: 8 *** | ||
592 | *** End: *** | ||
593 | */ | ||
diff --git a/drivers/media/video/pvrusb2/pvrusb2-ctrl.h b/drivers/media/video/pvrusb2/pvrusb2-ctrl.h new file mode 100644 index 000000000000..c1680053cd64 --- /dev/null +++ b/drivers/media/video/pvrusb2/pvrusb2-ctrl.h | |||
@@ -0,0 +1,123 @@ | |||
1 | /* | ||
2 | * | ||
3 | * $Id$ | ||
4 | * | ||
5 | * Copyright (C) 2005 Mike Isely <isely@pobox.com> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License as published by | ||
9 | * the Free Software Foundation; either version 2 of the License | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
19 | * | ||
20 | */ | ||
21 | #ifndef __PVRUSB2_CTRL_H | ||
22 | #define __PVRUSB2_CTRL_H | ||
23 | |||
24 | struct pvr2_ctrl; | ||
25 | |||
26 | enum pvr2_ctl_type { | ||
27 | pvr2_ctl_int = 0, | ||
28 | pvr2_ctl_enum = 1, | ||
29 | pvr2_ctl_bitmask = 2, | ||
30 | pvr2_ctl_bool = 3, | ||
31 | }; | ||
32 | |||
33 | |||
34 | /* Set the given control. */ | ||
35 | int pvr2_ctrl_set_value(struct pvr2_ctrl *,int val); | ||
36 | |||
37 | /* Set/clear specific bits of the given control. */ | ||
38 | int pvr2_ctrl_set_mask_value(struct pvr2_ctrl *,int mask,int val); | ||
39 | |||
40 | /* Get the current value of the given control. */ | ||
41 | int pvr2_ctrl_get_value(struct pvr2_ctrl *,int *valptr); | ||
42 | |||
43 | /* Retrieve control's type */ | ||
44 | enum pvr2_ctl_type pvr2_ctrl_get_type(struct pvr2_ctrl *); | ||
45 | |||
46 | /* Retrieve control's maximum value (int type) */ | ||
47 | int pvr2_ctrl_get_max(struct pvr2_ctrl *); | ||
48 | |||
49 | /* Retrieve control's minimum value (int type) */ | ||
50 | int pvr2_ctrl_get_min(struct pvr2_ctrl *); | ||
51 | |||
52 | /* Retrieve control's default value (any type) */ | ||
53 | int pvr2_ctrl_get_def(struct pvr2_ctrl *); | ||
54 | |||
55 | /* Retrieve control's enumeration count (enum only) */ | ||
56 | int pvr2_ctrl_get_cnt(struct pvr2_ctrl *); | ||
57 | |||
58 | /* Retrieve control's valid mask bits (bit mask only) */ | ||
59 | int pvr2_ctrl_get_mask(struct pvr2_ctrl *); | ||
60 | |||
61 | /* Retrieve the control's name */ | ||
62 | const char *pvr2_ctrl_get_name(struct pvr2_ctrl *); | ||
63 | |||
64 | /* Retrieve the control's desc */ | ||
65 | const char *pvr2_ctrl_get_desc(struct pvr2_ctrl *); | ||
66 | |||
67 | /* Retrieve a control enumeration or bit mask value */ | ||
68 | int pvr2_ctrl_get_valname(struct pvr2_ctrl *,int,char *,unsigned int, | ||
69 | unsigned int *); | ||
70 | |||
71 | /* Return true if control is writable */ | ||
72 | int pvr2_ctrl_is_writable(struct pvr2_ctrl *); | ||
73 | |||
74 | /* Return V4L flags value for control (or zero if there is no v4l control | ||
75 | actually under this control) */ | ||
76 | unsigned int pvr2_ctrl_get_v4lflags(struct pvr2_ctrl *); | ||
77 | |||
78 | /* Return V4L ID for this control or zero if none */ | ||
79 | int pvr2_ctrl_get_v4lid(struct pvr2_ctrl *); | ||
80 | |||
81 | /* Return true if control has custom symbolic representation */ | ||
82 | int pvr2_ctrl_has_custom_symbols(struct pvr2_ctrl *); | ||
83 | |||
84 | /* Convert a given mask/val to a custom symbolic value */ | ||
85 | int pvr2_ctrl_custom_value_to_sym(struct pvr2_ctrl *, | ||
86 | int mask,int val, | ||
87 | char *buf,unsigned int maxlen, | ||
88 | unsigned int *len); | ||
89 | |||
90 | /* Convert a symbolic value to a mask/value pair */ | ||
91 | int pvr2_ctrl_custom_sym_to_value(struct pvr2_ctrl *, | ||
92 | const char *buf,unsigned int len, | ||
93 | int *maskptr,int *valptr); | ||
94 | |||
95 | /* Convert a given mask/val to a symbolic value */ | ||
96 | int pvr2_ctrl_value_to_sym(struct pvr2_ctrl *, | ||
97 | int mask,int val, | ||
98 | char *buf,unsigned int maxlen, | ||
99 | unsigned int *len); | ||
100 | |||
101 | /* Convert a symbolic value to a mask/value pair */ | ||
102 | int pvr2_ctrl_sym_to_value(struct pvr2_ctrl *, | ||
103 | const char *buf,unsigned int len, | ||
104 | int *maskptr,int *valptr); | ||
105 | |||
106 | /* Convert a given mask/val to a symbolic value - must already be | ||
107 | inside of critical region. */ | ||
108 | int pvr2_ctrl_value_to_sym_internal(struct pvr2_ctrl *, | ||
109 | int mask,int val, | ||
110 | char *buf,unsigned int maxlen, | ||
111 | unsigned int *len); | ||
112 | |||
113 | #endif /* __PVRUSB2_CTRL_H */ | ||
114 | |||
115 | /* | ||
116 | Stuff for Emacs to see, in order to encourage consistent editing style: | ||
117 | *** Local Variables: *** | ||
118 | *** mode: c *** | ||
119 | *** fill-column: 75 *** | ||
120 | *** tab-width: 8 *** | ||
121 | *** c-basic-offset: 8 *** | ||
122 | *** End: *** | ||
123 | */ | ||
diff --git a/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.c b/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.c new file mode 100644 index 000000000000..27eadaff75a0 --- /dev/null +++ b/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.c | |||
@@ -0,0 +1,279 @@ | |||
1 | /* | ||
2 | * | ||
3 | * $Id$ | ||
4 | * | ||
5 | * Copyright (C) 2005 Mike Isely <isely@pobox.com> | ||
6 | * Copyright (C) 2004 Aurelien Alleaume <slts@free.fr> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License as published by | ||
10 | * the Free Software Foundation; either version 2 of the License | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | * GNU General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU General Public License | ||
18 | * along with this program; if not, write to the Free Software | ||
19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
20 | * | ||
21 | */ | ||
22 | |||
23 | /* | ||
24 | |||
25 | This source file is specifically designed to interface with the | ||
26 | cx2584x, in kernels 2.6.16 or newer. | ||
27 | |||
28 | */ | ||
29 | |||
30 | #include "pvrusb2-cx2584x-v4l.h" | ||
31 | #include "pvrusb2-video-v4l.h" | ||
32 | #include "pvrusb2-i2c-cmd-v4l2.h" | ||
33 | |||
34 | |||
35 | #include "pvrusb2-hdw-internal.h" | ||
36 | #include "pvrusb2-debug.h" | ||
37 | #include <media/cx25840.h> | ||
38 | #include <linux/videodev2.h> | ||
39 | #include <media/v4l2-common.h> | ||
40 | #include <linux/errno.h> | ||
41 | #include <linux/slab.h> | ||
42 | |||
43 | struct pvr2_v4l_cx2584x { | ||
44 | struct pvr2_i2c_handler handler; | ||
45 | struct pvr2_decoder_ctrl ctrl; | ||
46 | struct pvr2_i2c_client *client; | ||
47 | struct pvr2_hdw *hdw; | ||
48 | unsigned long stale_mask; | ||
49 | }; | ||
50 | |||
51 | |||
52 | static void set_input(struct pvr2_v4l_cx2584x *ctxt) | ||
53 | { | ||
54 | struct pvr2_hdw *hdw = ctxt->hdw; | ||
55 | struct v4l2_routing route; | ||
56 | enum cx25840_video_input vid_input; | ||
57 | enum cx25840_audio_input aud_input; | ||
58 | |||
59 | memset(&route,0,sizeof(route)); | ||
60 | |||
61 | switch(hdw->input_val) { | ||
62 | case PVR2_CVAL_INPUT_TV: | ||
63 | vid_input = CX25840_COMPOSITE7; | ||
64 | aud_input = CX25840_AUDIO8; | ||
65 | break; | ||
66 | case PVR2_CVAL_INPUT_COMPOSITE: | ||
67 | vid_input = CX25840_COMPOSITE3; | ||
68 | aud_input = CX25840_AUDIO_SERIAL; | ||
69 | break; | ||
70 | case PVR2_CVAL_INPUT_SVIDEO: | ||
71 | vid_input = CX25840_SVIDEO1; | ||
72 | aud_input = CX25840_AUDIO_SERIAL; | ||
73 | break; | ||
74 | case PVR2_CVAL_INPUT_RADIO: | ||
75 | default: | ||
76 | // Just set it to be composite input for now... | ||
77 | vid_input = CX25840_COMPOSITE3; | ||
78 | aud_input = CX25840_AUDIO_SERIAL; | ||
79 | break; | ||
80 | } | ||
81 | |||
82 | pvr2_trace(PVR2_TRACE_CHIPS,"i2c cx2584x set_input vid=0x%x aud=0x%x", | ||
83 | vid_input,aud_input); | ||
84 | route.input = (u32)vid_input; | ||
85 | pvr2_i2c_client_cmd(ctxt->client,VIDIOC_INT_S_VIDEO_ROUTING,&route); | ||
86 | route.input = (u32)aud_input; | ||
87 | pvr2_i2c_client_cmd(ctxt->client,VIDIOC_INT_S_AUDIO_ROUTING,&route); | ||
88 | } | ||
89 | |||
90 | |||
91 | static int check_input(struct pvr2_v4l_cx2584x *ctxt) | ||
92 | { | ||
93 | struct pvr2_hdw *hdw = ctxt->hdw; | ||
94 | return hdw->input_dirty != 0; | ||
95 | } | ||
96 | |||
97 | |||
98 | static void set_audio(struct pvr2_v4l_cx2584x *ctxt) | ||
99 | { | ||
100 | u32 val; | ||
101 | struct pvr2_hdw *hdw = ctxt->hdw; | ||
102 | |||
103 | pvr2_trace(PVR2_TRACE_CHIPS,"i2c cx2584x set_audio %d", | ||
104 | hdw->srate_val); | ||
105 | switch (hdw->srate_val) { | ||
106 | default: | ||
107 | case V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000: | ||
108 | val = 48000; | ||
109 | break; | ||
110 | case V4L2_MPEG_AUDIO_SAMPLING_FREQ_44100: | ||
111 | val = 44100; | ||
112 | break; | ||
113 | case V4L2_MPEG_AUDIO_SAMPLING_FREQ_32000: | ||
114 | val = 32000; | ||
115 | break; | ||
116 | } | ||
117 | pvr2_i2c_client_cmd(ctxt->client,VIDIOC_INT_AUDIO_CLOCK_FREQ,&val); | ||
118 | } | ||
119 | |||
120 | |||
121 | static int check_audio(struct pvr2_v4l_cx2584x *ctxt) | ||
122 | { | ||
123 | struct pvr2_hdw *hdw = ctxt->hdw; | ||
124 | return hdw->srate_dirty != 0; | ||
125 | } | ||
126 | |||
127 | |||
128 | struct pvr2_v4l_cx2584x_ops { | ||
129 | void (*update)(struct pvr2_v4l_cx2584x *); | ||
130 | int (*check)(struct pvr2_v4l_cx2584x *); | ||
131 | }; | ||
132 | |||
133 | |||
134 | static const struct pvr2_v4l_cx2584x_ops decoder_ops[] = { | ||
135 | { .update = set_input, .check = check_input}, | ||
136 | { .update = set_audio, .check = check_audio}, | ||
137 | }; | ||
138 | |||
139 | |||
140 | static void decoder_detach(struct pvr2_v4l_cx2584x *ctxt) | ||
141 | { | ||
142 | ctxt->client->handler = 0; | ||
143 | ctxt->hdw->decoder_ctrl = 0; | ||
144 | kfree(ctxt); | ||
145 | } | ||
146 | |||
147 | |||
148 | static int decoder_check(struct pvr2_v4l_cx2584x *ctxt) | ||
149 | { | ||
150 | unsigned long msk; | ||
151 | unsigned int idx; | ||
152 | |||
153 | for (idx = 0; idx < sizeof(decoder_ops)/sizeof(decoder_ops[0]); | ||
154 | idx++) { | ||
155 | msk = 1 << idx; | ||
156 | if (ctxt->stale_mask & msk) continue; | ||
157 | if (decoder_ops[idx].check(ctxt)) { | ||
158 | ctxt->stale_mask |= msk; | ||
159 | } | ||
160 | } | ||
161 | return ctxt->stale_mask != 0; | ||
162 | } | ||
163 | |||
164 | |||
165 | static void decoder_update(struct pvr2_v4l_cx2584x *ctxt) | ||
166 | { | ||
167 | unsigned long msk; | ||
168 | unsigned int idx; | ||
169 | |||
170 | for (idx = 0; idx < sizeof(decoder_ops)/sizeof(decoder_ops[0]); | ||
171 | idx++) { | ||
172 | msk = 1 << idx; | ||
173 | if (!(ctxt->stale_mask & msk)) continue; | ||
174 | ctxt->stale_mask &= ~msk; | ||
175 | decoder_ops[idx].update(ctxt); | ||
176 | } | ||
177 | } | ||
178 | |||
179 | |||
180 | static void decoder_enable(struct pvr2_v4l_cx2584x *ctxt,int fl) | ||
181 | { | ||
182 | pvr2_trace(PVR2_TRACE_CHIPS,"i2c cx25840 decoder_enable(%d)",fl); | ||
183 | pvr2_v4l2_cmd_stream(ctxt->client,fl); | ||
184 | } | ||
185 | |||
186 | |||
187 | static int decoder_detect(struct pvr2_i2c_client *cp) | ||
188 | { | ||
189 | int ret; | ||
190 | /* Attempt to query the decoder - let's see if it will answer */ | ||
191 | struct v4l2_queryctrl qc; | ||
192 | |||
193 | memset(&qc,0,sizeof(qc)); | ||
194 | |||
195 | qc.id = V4L2_CID_BRIGHTNESS; | ||
196 | |||
197 | ret = pvr2_i2c_client_cmd(cp,VIDIOC_QUERYCTRL,&qc); | ||
198 | return ret == 0; /* Return true if it answered */ | ||
199 | } | ||
200 | |||
201 | |||
202 | static int decoder_is_tuned(struct pvr2_v4l_cx2584x *ctxt) | ||
203 | { | ||
204 | struct v4l2_tuner vt; | ||
205 | int ret; | ||
206 | |||
207 | memset(&vt,0,sizeof(vt)); | ||
208 | ret = pvr2_i2c_client_cmd(ctxt->client,VIDIOC_G_TUNER,&vt); | ||
209 | if (ret < 0) return -EINVAL; | ||
210 | return vt.signal ? 1 : 0; | ||
211 | } | ||
212 | |||
213 | |||
214 | static unsigned int decoder_describe(struct pvr2_v4l_cx2584x *ctxt, | ||
215 | char *buf,unsigned int cnt) | ||
216 | { | ||
217 | return scnprintf(buf,cnt,"handler: pvrusb2-cx2584x-v4l"); | ||
218 | } | ||
219 | |||
220 | |||
221 | static void decoder_reset(struct pvr2_v4l_cx2584x *ctxt) | ||
222 | { | ||
223 | int ret; | ||
224 | ret = pvr2_i2c_client_cmd(ctxt->client,VIDIOC_INT_RESET,0); | ||
225 | pvr2_trace(PVR2_TRACE_CHIPS,"i2c cx25840 decoder_reset (ret=%d)",ret); | ||
226 | } | ||
227 | |||
228 | |||
229 | const static struct pvr2_i2c_handler_functions hfuncs = { | ||
230 | .detach = (void (*)(void *))decoder_detach, | ||
231 | .check = (int (*)(void *))decoder_check, | ||
232 | .update = (void (*)(void *))decoder_update, | ||
233 | .describe = (unsigned int (*)(void *,char *,unsigned int))decoder_describe, | ||
234 | }; | ||
235 | |||
236 | |||
237 | int pvr2_i2c_cx2584x_v4l_setup(struct pvr2_hdw *hdw, | ||
238 | struct pvr2_i2c_client *cp) | ||
239 | { | ||
240 | struct pvr2_v4l_cx2584x *ctxt; | ||
241 | |||
242 | if (hdw->decoder_ctrl) return 0; | ||
243 | if (cp->handler) return 0; | ||
244 | if (!decoder_detect(cp)) return 0; | ||
245 | |||
246 | ctxt = kmalloc(sizeof(*ctxt),GFP_KERNEL); | ||
247 | if (!ctxt) return 0; | ||
248 | memset(ctxt,0,sizeof(*ctxt)); | ||
249 | |||
250 | ctxt->handler.func_data = ctxt; | ||
251 | ctxt->handler.func_table = &hfuncs; | ||
252 | ctxt->ctrl.ctxt = ctxt; | ||
253 | ctxt->ctrl.detach = (void (*)(void *))decoder_detach; | ||
254 | ctxt->ctrl.enable = (void (*)(void *,int))decoder_enable; | ||
255 | ctxt->ctrl.tuned = (int (*)(void *))decoder_is_tuned; | ||
256 | ctxt->ctrl.force_reset = (void (*)(void*))decoder_reset; | ||
257 | ctxt->client = cp; | ||
258 | ctxt->hdw = hdw; | ||
259 | ctxt->stale_mask = (1 << (sizeof(decoder_ops)/ | ||
260 | sizeof(decoder_ops[0]))) - 1; | ||
261 | hdw->decoder_ctrl = &ctxt->ctrl; | ||
262 | cp->handler = &ctxt->handler; | ||
263 | pvr2_trace(PVR2_TRACE_CHIPS,"i2c 0x%x cx2584x V4L2 handler set up", | ||
264 | cp->client->addr); | ||
265 | return !0; | ||
266 | } | ||
267 | |||
268 | |||
269 | |||
270 | |||
271 | /* | ||
272 | Stuff for Emacs to see, in order to encourage consistent editing style: | ||
273 | *** Local Variables: *** | ||
274 | *** mode: c *** | ||
275 | *** fill-column: 70 *** | ||
276 | *** tab-width: 8 *** | ||
277 | *** c-basic-offset: 8 *** | ||
278 | *** End: *** | ||
279 | */ | ||
diff --git a/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.h b/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.h new file mode 100644 index 000000000000..54b2844e7a71 --- /dev/null +++ b/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.h | |||
@@ -0,0 +1,53 @@ | |||
1 | /* | ||
2 | * | ||
3 | * $Id$ | ||
4 | * | ||
5 | * Copyright (C) 2005 Mike Isely <isely@pobox.com> | ||
6 | * Copyright (C) 2004 Aurelien Alleaume <slts@free.fr> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License as published by | ||
10 | * the Free Software Foundation; either version 2 of the License | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | * GNU General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU General Public License | ||
18 | * along with this program; if not, write to the Free Software | ||
19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
20 | * | ||
21 | */ | ||
22 | |||
23 | #ifndef __PVRUSB2_CX2584X_V4L_H | ||
24 | #define __PVRUSB2_CX2584X_V4L_H | ||
25 | |||
26 | /* | ||
27 | |||
28 | This module connects the pvrusb2 driver to the I2C chip level | ||
29 | driver which handles combined device audio & video processing. | ||
30 | This interface is used internally by the driver; higher level code | ||
31 | should only interact through the interface provided by | ||
32 | pvrusb2-hdw.h. | ||
33 | |||
34 | */ | ||
35 | |||
36 | |||
37 | |||
38 | #include "pvrusb2-i2c-core.h" | ||
39 | |||
40 | int pvr2_i2c_cx2584x_v4l_setup(struct pvr2_hdw *,struct pvr2_i2c_client *); | ||
41 | |||
42 | |||
43 | #endif /* __PVRUSB2_CX2584X_V4L_H */ | ||
44 | |||
45 | /* | ||
46 | Stuff for Emacs to see, in order to encourage consistent editing style: | ||
47 | *** Local Variables: *** | ||
48 | *** mode: c *** | ||
49 | *** fill-column: 70 *** | ||
50 | *** tab-width: 8 *** | ||
51 | *** c-basic-offset: 8 *** | ||
52 | *** End: *** | ||
53 | */ | ||
diff --git a/drivers/media/video/pvrusb2/pvrusb2-debug.h b/drivers/media/video/pvrusb2/pvrusb2-debug.h new file mode 100644 index 000000000000..d95a8588e4f8 --- /dev/null +++ b/drivers/media/video/pvrusb2/pvrusb2-debug.h | |||
@@ -0,0 +1,67 @@ | |||
1 | /* | ||
2 | * $Id$ | ||
3 | * | ||
4 | * Copyright (C) 2005 Mike Isely <isely@pobox.com> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | * GNU General Public License for more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU General Public License | ||
16 | * along with this program; if not, write to the Free Software | ||
17 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
18 | * | ||
19 | */ | ||
20 | #ifndef __PVRUSB2_DEBUG_H | ||
21 | #define __PVRUSB2_DEBUG_H | ||
22 | |||
23 | extern int pvrusb2_debug; | ||
24 | |||
25 | #define pvr2_trace(msk, fmt, arg...) do {if(msk & pvrusb2_debug) printk(KERN_INFO "pvrusb2: " fmt "\n", ##arg); } while (0) | ||
26 | |||
27 | /* These are listed in *rough* order of decreasing usefulness and | ||
28 | increasing noise level. */ | ||
29 | #define PVR2_TRACE_INFO (1 << 0) // Normal messages | ||
30 | #define PVR2_TRACE_ERROR_LEGS (1 << 1) // error messages | ||
31 | #define PVR2_TRACE_TOLERANCE (1 << 2) // track tolerance-affected errors | ||
32 | #define PVR2_TRACE_TRAP (1 << 3) // Trap & report misbehavior from app | ||
33 | #define PVR2_TRACE_INIT (1 << 4) // misc initialization steps | ||
34 | #define PVR2_TRACE_START_STOP (1 << 5) // Streaming start / stop | ||
35 | #define PVR2_TRACE_CTL (1 << 6) // commit of control changes | ||
36 | #define PVR2_TRACE_DEBUG (1 << 7) // Temporary debug code | ||
37 | #define PVR2_TRACE_EEPROM (1 << 8) // eeprom parsing / report | ||
38 | #define PVR2_TRACE_STRUCT (1 << 9) // internal struct creation | ||
39 | #define PVR2_TRACE_OPEN_CLOSE (1 << 10) // application open / close | ||
40 | #define PVR2_TRACE_CREG (1 << 11) // Main critical region entry / exit | ||
41 | #define PVR2_TRACE_SYSFS (1 << 12) // Sysfs driven I/O | ||
42 | #define PVR2_TRACE_FIRMWARE (1 << 13) // firmware upload actions | ||
43 | #define PVR2_TRACE_CHIPS (1 << 14) // chip broadcast operation | ||
44 | #define PVR2_TRACE_I2C (1 << 15) // I2C related stuff | ||
45 | #define PVR2_TRACE_I2C_CMD (1 << 16) // Software commands to I2C modules | ||
46 | #define PVR2_TRACE_I2C_CORE (1 << 17) // I2C core debugging | ||
47 | #define PVR2_TRACE_I2C_TRAF (1 << 18) // I2C traffic through the adapter | ||
48 | #define PVR2_TRACE_V4LIOCTL (1 << 19) // v4l ioctl details | ||
49 | #define PVR2_TRACE_ENCODER (1 << 20) // mpeg2 encoder operation | ||
50 | #define PVR2_TRACE_BUF_POOL (1 << 21) // Track buffer pool management | ||
51 | #define PVR2_TRACE_BUF_FLOW (1 << 22) // Track buffer flow in system | ||
52 | #define PVR2_TRACE_DATA_FLOW (1 << 23) // Track data flow | ||
53 | #define PVR2_TRACE_DEBUGIFC (1 << 24) // Debug interface actions | ||
54 | #define PVR2_TRACE_GPIO (1 << 25) // GPIO state bit changes | ||
55 | |||
56 | |||
57 | #endif /* __PVRUSB2_HDW_INTERNAL_H */ | ||
58 | |||
59 | /* | ||
60 | Stuff for Emacs to see, in order to encourage consistent editing style: | ||
61 | *** Local Variables: *** | ||
62 | *** mode: c *** | ||
63 | *** fill-column: 75 *** | ||
64 | *** tab-width: 8 *** | ||
65 | *** c-basic-offset: 8 *** | ||
66 | *** End: *** | ||
67 | */ | ||
diff --git a/drivers/media/video/pvrusb2/pvrusb2-debugifc.c b/drivers/media/video/pvrusb2/pvrusb2-debugifc.c new file mode 100644 index 000000000000..586900e365ff --- /dev/null +++ b/drivers/media/video/pvrusb2/pvrusb2-debugifc.c | |||
@@ -0,0 +1,478 @@ | |||
1 | /* | ||
2 | * | ||
3 | * $Id$ | ||
4 | * | ||
5 | * Copyright (C) 2005 Mike Isely <isely@pobox.com> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License as published by | ||
9 | * the Free Software Foundation; either version 2 of the License | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
19 | * | ||
20 | */ | ||
21 | |||
22 | #include <linux/string.h> | ||
23 | #include <linux/slab.h> | ||
24 | #include "pvrusb2-debugifc.h" | ||
25 | #include "pvrusb2-hdw.h" | ||
26 | #include "pvrusb2-debug.h" | ||
27 | #include "pvrusb2-i2c-core.h" | ||
28 | |||
29 | struct debugifc_mask_item { | ||
30 | const char *name; | ||
31 | unsigned long msk; | ||
32 | }; | ||
33 | |||
34 | static struct debugifc_mask_item mask_items[] = { | ||
35 | {"ENC_FIRMWARE",(1<<PVR2_SUBSYS_B_ENC_FIRMWARE)}, | ||
36 | {"ENC_CFG",(1<<PVR2_SUBSYS_B_ENC_CFG)}, | ||
37 | {"DIG_RUN",(1<<PVR2_SUBSYS_B_DIGITIZER_RUN)}, | ||
38 | {"USB_RUN",(1<<PVR2_SUBSYS_B_USBSTREAM_RUN)}, | ||
39 | {"ENC_RUN",(1<<PVR2_SUBSYS_B_ENC_RUN)}, | ||
40 | }; | ||
41 | |||
42 | |||
43 | static unsigned int debugifc_count_whitespace(const char *buf, | ||
44 | unsigned int count) | ||
45 | { | ||
46 | unsigned int scnt; | ||
47 | char ch; | ||
48 | |||
49 | for (scnt = 0; scnt < count; scnt++) { | ||
50 | ch = buf[scnt]; | ||
51 | if (ch == ' ') continue; | ||
52 | if (ch == '\t') continue; | ||
53 | if (ch == '\n') continue; | ||
54 | break; | ||
55 | } | ||
56 | return scnt; | ||
57 | } | ||
58 | |||
59 | |||
60 | static unsigned int debugifc_count_nonwhitespace(const char *buf, | ||
61 | unsigned int count) | ||
62 | { | ||
63 | unsigned int scnt; | ||
64 | char ch; | ||
65 | |||
66 | for (scnt = 0; scnt < count; scnt++) { | ||
67 | ch = buf[scnt]; | ||
68 | if (ch == ' ') break; | ||
69 | if (ch == '\t') break; | ||
70 | if (ch == '\n') break; | ||
71 | } | ||
72 | return scnt; | ||
73 | } | ||
74 | |||
75 | |||
76 | static unsigned int debugifc_isolate_word(const char *buf,unsigned int count, | ||
77 | const char **wstrPtr, | ||
78 | unsigned int *wlenPtr) | ||
79 | { | ||
80 | const char *wptr; | ||
81 | unsigned int consume_cnt = 0; | ||
82 | unsigned int wlen; | ||
83 | unsigned int scnt; | ||
84 | |||
85 | wptr = 0; | ||
86 | wlen = 0; | ||
87 | scnt = debugifc_count_whitespace(buf,count); | ||
88 | consume_cnt += scnt; count -= scnt; buf += scnt; | ||
89 | if (!count) goto done; | ||
90 | |||
91 | scnt = debugifc_count_nonwhitespace(buf,count); | ||
92 | if (!scnt) goto done; | ||
93 | wptr = buf; | ||
94 | wlen = scnt; | ||
95 | consume_cnt += scnt; count -= scnt; buf += scnt; | ||
96 | |||
97 | done: | ||
98 | *wstrPtr = wptr; | ||
99 | *wlenPtr = wlen; | ||
100 | return consume_cnt; | ||
101 | } | ||
102 | |||
103 | |||
104 | static int debugifc_parse_unsigned_number(const char *buf,unsigned int count, | ||
105 | u32 *num_ptr) | ||
106 | { | ||
107 | u32 result = 0; | ||
108 | u32 val; | ||
109 | int ch; | ||
110 | int radix = 10; | ||
111 | if ((count >= 2) && (buf[0] == '0') && | ||
112 | ((buf[1] == 'x') || (buf[1] == 'X'))) { | ||
113 | radix = 16; | ||
114 | count -= 2; | ||
115 | buf += 2; | ||
116 | } else if ((count >= 1) && (buf[0] == '0')) { | ||
117 | radix = 8; | ||
118 | } | ||
119 | |||
120 | while (count--) { | ||
121 | ch = *buf++; | ||
122 | if ((ch >= '0') && (ch <= '9')) { | ||
123 | val = ch - '0'; | ||
124 | } else if ((ch >= 'a') && (ch <= 'f')) { | ||
125 | val = ch - 'a' + 10; | ||
126 | } else if ((ch >= 'A') && (ch <= 'F')) { | ||
127 | val = ch - 'A' + 10; | ||
128 | } else { | ||
129 | return -EINVAL; | ||
130 | } | ||
131 | if (val >= radix) return -EINVAL; | ||
132 | result *= radix; | ||
133 | result += val; | ||
134 | } | ||
135 | *num_ptr = result; | ||
136 | return 0; | ||
137 | } | ||
138 | |||
139 | |||
140 | static int debugifc_match_keyword(const char *buf,unsigned int count, | ||
141 | const char *keyword) | ||
142 | { | ||
143 | unsigned int kl; | ||
144 | if (!keyword) return 0; | ||
145 | kl = strlen(keyword); | ||
146 | if (kl != count) return 0; | ||
147 | return !memcmp(buf,keyword,kl); | ||
148 | } | ||
149 | |||
150 | |||
151 | static unsigned long debugifc_find_mask(const char *buf,unsigned int count) | ||
152 | { | ||
153 | struct debugifc_mask_item *mip; | ||
154 | unsigned int idx; | ||
155 | for (idx = 0; idx < sizeof(mask_items)/sizeof(mask_items[0]); idx++) { | ||
156 | mip = mask_items + idx; | ||
157 | if (debugifc_match_keyword(buf,count,mip->name)) { | ||
158 | return mip->msk; | ||
159 | } | ||
160 | } | ||
161 | return 0; | ||
162 | } | ||
163 | |||
164 | |||
165 | static int debugifc_print_mask(char *buf,unsigned int sz, | ||
166 | unsigned long msk,unsigned long val) | ||
167 | { | ||
168 | struct debugifc_mask_item *mip; | ||
169 | unsigned int idx; | ||
170 | int bcnt = 0; | ||
171 | int ccnt; | ||
172 | for (idx = 0; idx < sizeof(mask_items)/sizeof(mask_items[0]); idx++) { | ||
173 | mip = mask_items + idx; | ||
174 | if (!(mip->msk & msk)) continue; | ||
175 | ccnt = scnprintf(buf,sz,"%s%c%s", | ||
176 | (bcnt ? " " : ""), | ||
177 | ((mip->msk & val) ? '+' : '-'), | ||
178 | mip->name); | ||
179 | sz -= ccnt; | ||
180 | buf += ccnt; | ||
181 | bcnt += ccnt; | ||
182 | } | ||
183 | return bcnt; | ||
184 | } | ||
185 | |||
186 | static unsigned int debugifc_parse_subsys_mask(const char *buf, | ||
187 | unsigned int count, | ||
188 | unsigned long *mskPtr, | ||
189 | unsigned long *valPtr) | ||
190 | { | ||
191 | const char *wptr; | ||
192 | unsigned int consume_cnt = 0; | ||
193 | unsigned int scnt; | ||
194 | unsigned int wlen; | ||
195 | int mode; | ||
196 | unsigned long m1,msk,val; | ||
197 | |||
198 | msk = 0; | ||
199 | val = 0; | ||
200 | |||
201 | while (count) { | ||
202 | scnt = debugifc_isolate_word(buf,count,&wptr,&wlen); | ||
203 | if (!scnt) break; | ||
204 | consume_cnt += scnt; count -= scnt; buf += scnt; | ||
205 | if (!wptr) break; | ||
206 | |||
207 | mode = 0; | ||
208 | if (wlen) switch (wptr[0]) { | ||
209 | case '+': | ||
210 | wptr++; | ||
211 | wlen--; | ||
212 | break; | ||
213 | case '-': | ||
214 | mode = 1; | ||
215 | wptr++; | ||
216 | wlen--; | ||
217 | break; | ||
218 | } | ||
219 | if (!wlen) continue; | ||
220 | m1 = debugifc_find_mask(wptr,wlen); | ||
221 | if (!m1) break; | ||
222 | msk |= m1; | ||
223 | if (!mode) val |= m1; | ||
224 | } | ||
225 | *mskPtr = msk; | ||
226 | *valPtr = val; | ||
227 | return consume_cnt; | ||
228 | } | ||
229 | |||
230 | |||
231 | int pvr2_debugifc_print_info(struct pvr2_hdw *hdw,char *buf,unsigned int acnt) | ||
232 | { | ||
233 | int bcnt = 0; | ||
234 | int ccnt; | ||
235 | struct pvr2_hdw_debug_info dbg; | ||
236 | |||
237 | pvr2_hdw_get_debug_info(hdw,&dbg); | ||
238 | |||
239 | ccnt = scnprintf(buf,acnt,"big lock %s; ctl lock %s", | ||
240 | (dbg.big_lock_held ? "held" : "free"), | ||
241 | (dbg.ctl_lock_held ? "held" : "free")); | ||
242 | bcnt += ccnt; acnt -= ccnt; buf += ccnt; | ||
243 | if (dbg.ctl_lock_held) { | ||
244 | ccnt = scnprintf(buf,acnt,"; cmd_state=%d cmd_code=%d" | ||
245 | " cmd_wlen=%d cmd_rlen=%d" | ||
246 | " wpend=%d rpend=%d tmout=%d rstatus=%d" | ||
247 | " wstatus=%d", | ||
248 | dbg.cmd_debug_state,dbg.cmd_code, | ||
249 | dbg.cmd_debug_write_len, | ||
250 | dbg.cmd_debug_read_len, | ||
251 | dbg.cmd_debug_write_pend, | ||
252 | dbg.cmd_debug_read_pend, | ||
253 | dbg.cmd_debug_timeout, | ||
254 | dbg.cmd_debug_rstatus, | ||
255 | dbg.cmd_debug_wstatus); | ||
256 | bcnt += ccnt; acnt -= ccnt; buf += ccnt; | ||
257 | } | ||
258 | ccnt = scnprintf(buf,acnt,"\n"); | ||
259 | bcnt += ccnt; acnt -= ccnt; buf += ccnt; | ||
260 | ccnt = scnprintf( | ||
261 | buf,acnt,"driver flags: %s %s %s\n", | ||
262 | (dbg.flag_init_ok ? "initialized" : "uninitialized"), | ||
263 | (dbg.flag_ok ? "ok" : "fail"), | ||
264 | (dbg.flag_disconnected ? "disconnected" : "connected")); | ||
265 | bcnt += ccnt; acnt -= ccnt; buf += ccnt; | ||
266 | ccnt = scnprintf(buf,acnt,"Subsystems enabled / configured: "); | ||
267 | bcnt += ccnt; acnt -= ccnt; buf += ccnt; | ||
268 | ccnt = debugifc_print_mask(buf,acnt,dbg.subsys_flags,dbg.subsys_flags); | ||
269 | bcnt += ccnt; acnt -= ccnt; buf += ccnt; | ||
270 | ccnt = scnprintf(buf,acnt,"\n"); | ||
271 | bcnt += ccnt; acnt -= ccnt; buf += ccnt; | ||
272 | ccnt = scnprintf(buf,acnt,"Subsystems disabled / unconfigured: "); | ||
273 | bcnt += ccnt; acnt -= ccnt; buf += ccnt; | ||
274 | ccnt = debugifc_print_mask(buf,acnt,~dbg.subsys_flags,dbg.subsys_flags); | ||
275 | bcnt += ccnt; acnt -= ccnt; buf += ccnt; | ||
276 | ccnt = scnprintf(buf,acnt,"\n"); | ||
277 | bcnt += ccnt; acnt -= ccnt; buf += ccnt; | ||
278 | |||
279 | ccnt = scnprintf(buf,acnt,"Attached I2C modules:\n"); | ||
280 | bcnt += ccnt; acnt -= ccnt; buf += ccnt; | ||
281 | ccnt = pvr2_i2c_report(hdw,buf,acnt); | ||
282 | bcnt += ccnt; acnt -= ccnt; buf += ccnt; | ||
283 | |||
284 | return bcnt; | ||
285 | } | ||
286 | |||
287 | |||
288 | int pvr2_debugifc_print_status(struct pvr2_hdw *hdw, | ||
289 | char *buf,unsigned int acnt) | ||
290 | { | ||
291 | int bcnt = 0; | ||
292 | int ccnt; | ||
293 | unsigned long msk; | ||
294 | int ret; | ||
295 | u32 gpio_dir,gpio_in,gpio_out; | ||
296 | |||
297 | ret = pvr2_hdw_is_hsm(hdw); | ||
298 | ccnt = scnprintf(buf,acnt,"USB link speed: %s\n", | ||
299 | (ret < 0 ? "FAIL" : (ret ? "high" : "full"))); | ||
300 | bcnt += ccnt; acnt -= ccnt; buf += ccnt; | ||
301 | |||
302 | gpio_dir = 0; gpio_in = 0; gpio_out = 0; | ||
303 | pvr2_hdw_gpio_get_dir(hdw,&gpio_dir); | ||
304 | pvr2_hdw_gpio_get_out(hdw,&gpio_out); | ||
305 | pvr2_hdw_gpio_get_in(hdw,&gpio_in); | ||
306 | ccnt = scnprintf(buf,acnt,"GPIO state: dir=0x%x in=0x%x out=0x%x\n", | ||
307 | gpio_dir,gpio_in,gpio_out); | ||
308 | bcnt += ccnt; acnt -= ccnt; buf += ccnt; | ||
309 | |||
310 | ccnt = scnprintf(buf,acnt,"Streaming is %s\n", | ||
311 | pvr2_hdw_get_streaming(hdw) ? "on" : "off"); | ||
312 | bcnt += ccnt; acnt -= ccnt; buf += ccnt; | ||
313 | |||
314 | msk = pvr2_hdw_subsys_get(hdw); | ||
315 | ccnt = scnprintf(buf,acnt,"Subsystems enabled / configured: "); | ||
316 | bcnt += ccnt; acnt -= ccnt; buf += ccnt; | ||
317 | ccnt = debugifc_print_mask(buf,acnt,msk,msk); | ||
318 | bcnt += ccnt; acnt -= ccnt; buf += ccnt; | ||
319 | ccnt = scnprintf(buf,acnt,"\n"); | ||
320 | bcnt += ccnt; acnt -= ccnt; buf += ccnt; | ||
321 | ccnt = scnprintf(buf,acnt,"Subsystems disabled / unconfigured: "); | ||
322 | bcnt += ccnt; acnt -= ccnt; buf += ccnt; | ||
323 | ccnt = debugifc_print_mask(buf,acnt,~msk,msk); | ||
324 | bcnt += ccnt; acnt -= ccnt; buf += ccnt; | ||
325 | ccnt = scnprintf(buf,acnt,"\n"); | ||
326 | bcnt += ccnt; acnt -= ccnt; buf += ccnt; | ||
327 | |||
328 | msk = pvr2_hdw_subsys_stream_get(hdw); | ||
329 | ccnt = scnprintf(buf,acnt,"Subsystems stopped on stream shutdown: "); | ||
330 | bcnt += ccnt; acnt -= ccnt; buf += ccnt; | ||
331 | ccnt = debugifc_print_mask(buf,acnt,msk,msk); | ||
332 | bcnt += ccnt; acnt -= ccnt; buf += ccnt; | ||
333 | ccnt = scnprintf(buf,acnt,"\n"); | ||
334 | bcnt += ccnt; acnt -= ccnt; buf += ccnt; | ||
335 | |||
336 | return bcnt; | ||
337 | } | ||
338 | |||
339 | |||
340 | int pvr2_debugifc_do1cmd(struct pvr2_hdw *hdw,const char *buf, | ||
341 | unsigned int count) | ||
342 | { | ||
343 | const char *wptr; | ||
344 | unsigned int wlen; | ||
345 | unsigned int scnt; | ||
346 | |||
347 | scnt = debugifc_isolate_word(buf,count,&wptr,&wlen); | ||
348 | if (!scnt) return 0; | ||
349 | count -= scnt; buf += scnt; | ||
350 | if (!wptr) return 0; | ||
351 | |||
352 | pvr2_trace(PVR2_TRACE_DEBUGIFC,"debugifc cmd: \"%.*s\"",wlen,wptr); | ||
353 | if (debugifc_match_keyword(wptr,wlen,"reset")) { | ||
354 | scnt = debugifc_isolate_word(buf,count,&wptr,&wlen); | ||
355 | if (!scnt) return -EINVAL; | ||
356 | count -= scnt; buf += scnt; | ||
357 | if (!wptr) return -EINVAL; | ||
358 | if (debugifc_match_keyword(wptr,wlen,"cpu")) { | ||
359 | pvr2_hdw_cpureset_assert(hdw,!0); | ||
360 | pvr2_hdw_cpureset_assert(hdw,0); | ||
361 | return 0; | ||
362 | } else if (debugifc_match_keyword(wptr,wlen,"bus")) { | ||
363 | pvr2_hdw_device_reset(hdw); | ||
364 | } else if (debugifc_match_keyword(wptr,wlen,"soft")) { | ||
365 | return pvr2_hdw_cmd_powerup(hdw); | ||
366 | } else if (debugifc_match_keyword(wptr,wlen,"deep")) { | ||
367 | return pvr2_hdw_cmd_deep_reset(hdw); | ||
368 | } else if (debugifc_match_keyword(wptr,wlen,"firmware")) { | ||
369 | return pvr2_upload_firmware2(hdw); | ||
370 | } else if (debugifc_match_keyword(wptr,wlen,"decoder")) { | ||
371 | return pvr2_hdw_cmd_decoder_reset(hdw); | ||
372 | } | ||
373 | return -EINVAL; | ||
374 | } else if (debugifc_match_keyword(wptr,wlen,"subsys_flags")) { | ||
375 | unsigned long msk = 0; | ||
376 | unsigned long val = 0; | ||
377 | if (debugifc_parse_subsys_mask(buf,count,&msk,&val) != count) { | ||
378 | pvr2_trace(PVR2_TRACE_DEBUGIFC, | ||
379 | "debugifc parse error on subsys mask"); | ||
380 | return -EINVAL; | ||
381 | } | ||
382 | pvr2_hdw_subsys_bit_chg(hdw,msk,val); | ||
383 | return 0; | ||
384 | } else if (debugifc_match_keyword(wptr,wlen,"stream_flags")) { | ||
385 | unsigned long msk = 0; | ||
386 | unsigned long val = 0; | ||
387 | if (debugifc_parse_subsys_mask(buf,count,&msk,&val) != count) { | ||
388 | pvr2_trace(PVR2_TRACE_DEBUGIFC, | ||
389 | "debugifc parse error on stream mask"); | ||
390 | return -EINVAL; | ||
391 | } | ||
392 | pvr2_hdw_subsys_stream_bit_chg(hdw,msk,val); | ||
393 | return 0; | ||
394 | } else if (debugifc_match_keyword(wptr,wlen,"cpufw")) { | ||
395 | scnt = debugifc_isolate_word(buf,count,&wptr,&wlen); | ||
396 | if (!scnt) return -EINVAL; | ||
397 | count -= scnt; buf += scnt; | ||
398 | if (!wptr) return -EINVAL; | ||
399 | if (debugifc_match_keyword(wptr,wlen,"fetch")) { | ||
400 | pvr2_hdw_cpufw_set_enabled(hdw,!0); | ||
401 | return 0; | ||
402 | } else if (debugifc_match_keyword(wptr,wlen,"done")) { | ||
403 | pvr2_hdw_cpufw_set_enabled(hdw,0); | ||
404 | return 0; | ||
405 | } else { | ||
406 | return -EINVAL; | ||
407 | } | ||
408 | } else if (debugifc_match_keyword(wptr,wlen,"gpio")) { | ||
409 | int dir_fl = 0; | ||
410 | int ret; | ||
411 | u32 msk,val; | ||
412 | scnt = debugifc_isolate_word(buf,count,&wptr,&wlen); | ||
413 | if (!scnt) return -EINVAL; | ||
414 | count -= scnt; buf += scnt; | ||
415 | if (!wptr) return -EINVAL; | ||
416 | if (debugifc_match_keyword(wptr,wlen,"dir")) { | ||
417 | dir_fl = !0; | ||
418 | } else if (!debugifc_match_keyword(wptr,wlen,"out")) { | ||
419 | return -EINVAL; | ||
420 | } | ||
421 | scnt = debugifc_isolate_word(buf,count,&wptr,&wlen); | ||
422 | if (!scnt) return -EINVAL; | ||
423 | count -= scnt; buf += scnt; | ||
424 | if (!wptr) return -EINVAL; | ||
425 | ret = debugifc_parse_unsigned_number(wptr,wlen,&msk); | ||
426 | if (ret) return ret; | ||
427 | scnt = debugifc_isolate_word(buf,count,&wptr,&wlen); | ||
428 | if (wptr) { | ||
429 | ret = debugifc_parse_unsigned_number(wptr,wlen,&val); | ||
430 | if (ret) return ret; | ||
431 | } else { | ||
432 | val = msk; | ||
433 | msk = 0xffffffff; | ||
434 | } | ||
435 | if (dir_fl) { | ||
436 | ret = pvr2_hdw_gpio_chg_dir(hdw,msk,val); | ||
437 | } else { | ||
438 | ret = pvr2_hdw_gpio_chg_out(hdw,msk,val); | ||
439 | } | ||
440 | return ret; | ||
441 | } | ||
442 | pvr2_trace(PVR2_TRACE_DEBUGIFC, | ||
443 | "debugifc failed to recognize cmd: \"%.*s\"",wlen,wptr); | ||
444 | return -EINVAL; | ||
445 | } | ||
446 | |||
447 | |||
448 | int pvr2_debugifc_docmd(struct pvr2_hdw *hdw,const char *buf, | ||
449 | unsigned int count) | ||
450 | { | ||
451 | unsigned int bcnt = 0; | ||
452 | int ret; | ||
453 | |||
454 | while (count) { | ||
455 | for (bcnt = 0; bcnt < count; bcnt++) { | ||
456 | if (buf[bcnt] == '\n') break; | ||
457 | } | ||
458 | |||
459 | ret = pvr2_debugifc_do1cmd(hdw,buf,bcnt); | ||
460 | if (ret < 0) return ret; | ||
461 | if (bcnt < count) bcnt++; | ||
462 | buf += bcnt; | ||
463 | count -= bcnt; | ||
464 | } | ||
465 | |||
466 | return 0; | ||
467 | } | ||
468 | |||
469 | |||
470 | /* | ||
471 | Stuff for Emacs to see, in order to encourage consistent editing style: | ||
472 | *** Local Variables: *** | ||
473 | *** mode: c *** | ||
474 | *** fill-column: 75 *** | ||
475 | *** tab-width: 8 *** | ||
476 | *** c-basic-offset: 8 *** | ||
477 | *** End: *** | ||
478 | */ | ||
diff --git a/drivers/media/video/pvrusb2/pvrusb2-debugifc.h b/drivers/media/video/pvrusb2/pvrusb2-debugifc.h new file mode 100644 index 000000000000..990b02d35d36 --- /dev/null +++ b/drivers/media/video/pvrusb2/pvrusb2-debugifc.h | |||
@@ -0,0 +1,53 @@ | |||
1 | /* | ||
2 | * | ||
3 | * $Id$ | ||
4 | * | ||
5 | * Copyright (C) 2005 Mike Isely <isely@pobox.com> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License as published by | ||
9 | * the Free Software Foundation; either version 2 of the License | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
19 | * | ||
20 | */ | ||
21 | #ifndef __PVRUSB2_DEBUGIFC_H | ||
22 | #define __PVRUSB2_DEBUGIFC_H | ||
23 | |||
24 | struct pvr2_hdw; | ||
25 | |||
26 | /* Non-intrusively print some useful debugging info from inside the | ||
27 | driver. This should work even if the driver appears to be | ||
28 | wedged. */ | ||
29 | int pvr2_debugifc_print_info(struct pvr2_hdw *, | ||
30 | char *buf_ptr,unsigned int buf_size); | ||
31 | |||
32 | /* Print general status of driver. This will also trigger a probe of | ||
33 | the USB link. Unlike print_info(), this one synchronizes with the | ||
34 | driver so the information should be self-consistent (but it will | ||
35 | hang if the driver is wedged). */ | ||
36 | int pvr2_debugifc_print_status(struct pvr2_hdw *, | ||
37 | char *buf_ptr,unsigned int buf_size); | ||
38 | |||
39 | /* Parse a string command into a driver action. */ | ||
40 | int pvr2_debugifc_docmd(struct pvr2_hdw *, | ||
41 | const char *buf_ptr,unsigned int buf_size); | ||
42 | |||
43 | #endif /* __PVRUSB2_DEBUGIFC_H */ | ||
44 | |||
45 | /* | ||
46 | Stuff for Emacs to see, in order to encourage consistent editing style: | ||
47 | *** Local Variables: *** | ||
48 | *** mode: c *** | ||
49 | *** fill-column: 75 *** | ||
50 | *** tab-width: 8 *** | ||
51 | *** c-basic-offset: 8 *** | ||
52 | *** End: *** | ||
53 | */ | ||
diff --git a/drivers/media/video/pvrusb2/pvrusb2-demod.c b/drivers/media/video/pvrusb2/pvrusb2-demod.c new file mode 100644 index 000000000000..9686569a11f6 --- /dev/null +++ b/drivers/media/video/pvrusb2/pvrusb2-demod.c | |||
@@ -0,0 +1,126 @@ | |||
1 | /* | ||
2 | * | ||
3 | * $Id$ | ||
4 | * | ||
5 | * Copyright (C) 2005 Mike Isely <isely@pobox.com> | ||
6 | * Copyright (C) 2004 Aurelien Alleaume <slts@free.fr> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License as published by | ||
10 | * the Free Software Foundation; either version 2 of the License | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | * GNU General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU General Public License | ||
18 | * along with this program; if not, write to the Free Software | ||
19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
20 | * | ||
21 | */ | ||
22 | |||
23 | #include "pvrusb2.h" | ||
24 | #include "pvrusb2-util.h" | ||
25 | #include "pvrusb2-demod.h" | ||
26 | #include "pvrusb2-hdw-internal.h" | ||
27 | #include "pvrusb2-debug.h" | ||
28 | #include <linux/videodev2.h> | ||
29 | #include <media/tuner.h> | ||
30 | #include <media/v4l2-common.h> | ||
31 | |||
32 | |||
33 | struct pvr2_demod_handler { | ||
34 | struct pvr2_hdw *hdw; | ||
35 | struct pvr2_i2c_client *client; | ||
36 | struct pvr2_i2c_handler i2c_handler; | ||
37 | int type_update_fl; | ||
38 | }; | ||
39 | |||
40 | |||
41 | static void set_config(struct pvr2_demod_handler *ctxt) | ||
42 | { | ||
43 | struct pvr2_hdw *hdw = ctxt->hdw; | ||
44 | int cfg = 0; | ||
45 | |||
46 | switch (hdw->tuner_type) { | ||
47 | case TUNER_PHILIPS_FM1216ME_MK3: | ||
48 | case TUNER_PHILIPS_FM1236_MK3: | ||
49 | cfg = TDA9887_PORT1_ACTIVE|TDA9887_PORT2_ACTIVE; | ||
50 | break; | ||
51 | default: | ||
52 | break; | ||
53 | } | ||
54 | pvr2_trace(PVR2_TRACE_CHIPS,"i2c demod set_config(0x%x)",cfg); | ||
55 | pvr2_i2c_client_cmd(ctxt->client,TDA9887_SET_CONFIG,&cfg); | ||
56 | ctxt->type_update_fl = 0; | ||
57 | } | ||
58 | |||
59 | |||
60 | static int demod_check(struct pvr2_demod_handler *ctxt) | ||
61 | { | ||
62 | struct pvr2_hdw *hdw = ctxt->hdw; | ||
63 | if (hdw->tuner_updated) ctxt->type_update_fl = !0; | ||
64 | return ctxt->type_update_fl != 0; | ||
65 | } | ||
66 | |||
67 | |||
68 | static void demod_update(struct pvr2_demod_handler *ctxt) | ||
69 | { | ||
70 | if (ctxt->type_update_fl) set_config(ctxt); | ||
71 | } | ||
72 | |||
73 | |||
74 | static void demod_detach(struct pvr2_demod_handler *ctxt) | ||
75 | { | ||
76 | ctxt->client->handler = 0; | ||
77 | kfree(ctxt); | ||
78 | } | ||
79 | |||
80 | |||
81 | static unsigned int demod_describe(struct pvr2_demod_handler *ctxt,char *buf,unsigned int cnt) | ||
82 | { | ||
83 | return scnprintf(buf,cnt,"handler: pvrusb2-demod"); | ||
84 | } | ||
85 | |||
86 | |||
87 | const static struct pvr2_i2c_handler_functions tuner_funcs = { | ||
88 | .detach = (void (*)(void *))demod_detach, | ||
89 | .check = (int (*)(void *))demod_check, | ||
90 | .update = (void (*)(void *))demod_update, | ||
91 | .describe = (unsigned int (*)(void *,char *,unsigned int))demod_describe, | ||
92 | }; | ||
93 | |||
94 | |||
95 | int pvr2_i2c_demod_setup(struct pvr2_hdw *hdw,struct pvr2_i2c_client *cp) | ||
96 | { | ||
97 | struct pvr2_demod_handler *ctxt; | ||
98 | if (cp->handler) return 0; | ||
99 | |||
100 | ctxt = kmalloc(sizeof(*ctxt),GFP_KERNEL); | ||
101 | if (!ctxt) return 0; | ||
102 | memset(ctxt,0,sizeof(*ctxt)); | ||
103 | |||
104 | ctxt->i2c_handler.func_data = ctxt; | ||
105 | ctxt->i2c_handler.func_table = &tuner_funcs; | ||
106 | ctxt->type_update_fl = !0; | ||
107 | ctxt->client = cp; | ||
108 | ctxt->hdw = hdw; | ||
109 | cp->handler = &ctxt->i2c_handler; | ||
110 | pvr2_trace(PVR2_TRACE_CHIPS,"i2c 0x%x tda9887 V4L2 handler set up", | ||
111 | cp->client->addr); | ||
112 | return !0; | ||
113 | } | ||
114 | |||
115 | |||
116 | |||
117 | |||
118 | /* | ||
119 | Stuff for Emacs to see, in order to encourage consistent editing style: | ||
120 | *** Local Variables: *** | ||
121 | *** mode: c *** | ||
122 | *** fill-column: 70 *** | ||
123 | *** tab-width: 8 *** | ||
124 | *** c-basic-offset: 8 *** | ||
125 | *** End: *** | ||
126 | */ | ||
diff --git a/drivers/media/video/pvrusb2/pvrusb2-demod.h b/drivers/media/video/pvrusb2/pvrusb2-demod.h new file mode 100644 index 000000000000..4c4e40ffbf03 --- /dev/null +++ b/drivers/media/video/pvrusb2/pvrusb2-demod.h | |||
@@ -0,0 +1,38 @@ | |||
1 | /* | ||
2 | * | ||
3 | * $Id$ | ||
4 | * | ||
5 | * Copyright (C) 2005 Mike Isely <isely@pobox.com> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License as published by | ||
9 | * the Free Software Foundation; either version 2 of the License | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
19 | * | ||
20 | */ | ||
21 | #ifndef __PVRUSB2_DEMOD_H | ||
22 | #define __PVRUSB2_DEMOD_H | ||
23 | |||
24 | #include "pvrusb2-i2c-core.h" | ||
25 | |||
26 | int pvr2_i2c_demod_setup(struct pvr2_hdw *,struct pvr2_i2c_client *); | ||
27 | |||
28 | #endif /* __PVRUSB2_DEMOD_H */ | ||
29 | |||
30 | /* | ||
31 | Stuff for Emacs to see, in order to encourage consistent editing style: | ||
32 | *** Local Variables: *** | ||
33 | *** mode: c *** | ||
34 | *** fill-column: 70 *** | ||
35 | *** tab-width: 8 *** | ||
36 | *** c-basic-offset: 8 *** | ||
37 | *** End: *** | ||
38 | */ | ||
diff --git a/drivers/media/video/pvrusb2/pvrusb2-eeprom.c b/drivers/media/video/pvrusb2/pvrusb2-eeprom.c new file mode 100644 index 000000000000..94d383ff9889 --- /dev/null +++ b/drivers/media/video/pvrusb2/pvrusb2-eeprom.c | |||
@@ -0,0 +1,164 @@ | |||
1 | /* | ||
2 | * | ||
3 | * $Id$ | ||
4 | * | ||
5 | * Copyright (C) 2005 Mike Isely <isely@pobox.com> | ||
6 | * Copyright (C) 2004 Aurelien Alleaume <slts@free.fr> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License as published by | ||
10 | * the Free Software Foundation; either version 2 of the License | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | * GNU General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU General Public License | ||
18 | * along with this program; if not, write to the Free Software | ||
19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
20 | * | ||
21 | */ | ||
22 | |||
23 | #include "pvrusb2-eeprom.h" | ||
24 | #include "pvrusb2-hdw-internal.h" | ||
25 | #include "pvrusb2-debug.h" | ||
26 | |||
27 | #define trace_eeprom(...) pvr2_trace(PVR2_TRACE_EEPROM,__VA_ARGS__) | ||
28 | |||
29 | |||
30 | |||
31 | /* | ||
32 | |||
33 | Read and analyze data in the eeprom. Use tveeprom to figure out | ||
34 | the packet structure, since this is another Hauppauge device and | ||
35 | internally it has a family resemblence to ivtv-type devices | ||
36 | |||
37 | */ | ||
38 | |||
39 | #include <media/tveeprom.h> | ||
40 | |||
41 | /* We seem to only be interested in the last 128 bytes of the EEPROM */ | ||
42 | #define EEPROM_SIZE 128 | ||
43 | |||
44 | /* Grab EEPROM contents, needed for direct method. */ | ||
45 | static u8 *pvr2_eeprom_fetch(struct pvr2_hdw *hdw) | ||
46 | { | ||
47 | struct i2c_msg msg[2]; | ||
48 | u8 *eeprom; | ||
49 | u8 iadd[2]; | ||
50 | u8 addr; | ||
51 | u16 eepromSize; | ||
52 | unsigned int offs; | ||
53 | int ret; | ||
54 | int mode16 = 0; | ||
55 | unsigned pcnt,tcnt; | ||
56 | eeprom = kmalloc(EEPROM_SIZE,GFP_KERNEL); | ||
57 | if (!eeprom) { | ||
58 | pvr2_trace(PVR2_TRACE_ERROR_LEGS, | ||
59 | "Failed to allocate memory" | ||
60 | " required to read eeprom"); | ||
61 | return 0; | ||
62 | } | ||
63 | |||
64 | trace_eeprom("Value for eeprom addr from controller was 0x%x", | ||
65 | hdw->eeprom_addr); | ||
66 | addr = hdw->eeprom_addr; | ||
67 | /* Seems that if the high bit is set, then the *real* eeprom | ||
68 | address is shifted right now bit position (noticed this in | ||
69 | newer PVR USB2 hardware) */ | ||
70 | if (addr & 0x80) addr >>= 1; | ||
71 | |||
72 | /* FX2 documentation states that a 16bit-addressed eeprom is | ||
73 | expected if the I2C address is an odd number (yeah, this is | ||
74 | strange but it's what they do) */ | ||
75 | mode16 = (addr & 1); | ||
76 | eepromSize = (mode16 ? 4096 : 256); | ||
77 | trace_eeprom("Examining %d byte eeprom at location 0x%x" | ||
78 | " using %d bit addressing",eepromSize,addr, | ||
79 | mode16 ? 16 : 8); | ||
80 | |||
81 | msg[0].addr = addr; | ||
82 | msg[0].flags = 0; | ||
83 | msg[0].len = mode16 ? 2 : 1; | ||
84 | msg[0].buf = iadd; | ||
85 | msg[1].addr = addr; | ||
86 | msg[1].flags = I2C_M_RD; | ||
87 | |||
88 | /* We have to do the actual eeprom data fetch ourselves, because | ||
89 | (1) we're only fetching part of the eeprom, and (2) if we were | ||
90 | getting the whole thing our I2C driver can't grab it in one | ||
91 | pass - which is what tveeprom is otherwise going to attempt */ | ||
92 | memset(eeprom,0,EEPROM_SIZE); | ||
93 | for (tcnt = 0; tcnt < EEPROM_SIZE; tcnt += pcnt) { | ||
94 | pcnt = 16; | ||
95 | if (pcnt + tcnt > EEPROM_SIZE) pcnt = EEPROM_SIZE-tcnt; | ||
96 | offs = tcnt + (eepromSize - EEPROM_SIZE); | ||
97 | if (mode16) { | ||
98 | iadd[0] = offs >> 8; | ||
99 | iadd[1] = offs; | ||
100 | } else { | ||
101 | iadd[0] = offs; | ||
102 | } | ||
103 | msg[1].len = pcnt; | ||
104 | msg[1].buf = eeprom+tcnt; | ||
105 | if ((ret = i2c_transfer( | ||
106 | &hdw->i2c_adap, | ||
107 | msg,sizeof(msg)/sizeof(msg[0]))) != 2) { | ||
108 | pvr2_trace(PVR2_TRACE_ERROR_LEGS, | ||
109 | "eeprom fetch set offs err=%d",ret); | ||
110 | kfree(eeprom); | ||
111 | return 0; | ||
112 | } | ||
113 | } | ||
114 | return eeprom; | ||
115 | } | ||
116 | |||
117 | |||
118 | /* Directly call eeprom analysis function within tveeprom. */ | ||
119 | int pvr2_eeprom_analyze(struct pvr2_hdw *hdw) | ||
120 | { | ||
121 | u8 *eeprom; | ||
122 | struct tveeprom tvdata; | ||
123 | |||
124 | memset(&tvdata,0,sizeof(tvdata)); | ||
125 | |||
126 | eeprom = pvr2_eeprom_fetch(hdw); | ||
127 | if (!eeprom) return -EINVAL; | ||
128 | |||
129 | { | ||
130 | struct i2c_client fake_client; | ||
131 | /* Newer version expects a useless client interface */ | ||
132 | fake_client.addr = hdw->eeprom_addr; | ||
133 | fake_client.adapter = &hdw->i2c_adap; | ||
134 | tveeprom_hauppauge_analog(&fake_client,&tvdata,eeprom); | ||
135 | } | ||
136 | |||
137 | trace_eeprom("eeprom assumed v4l tveeprom module"); | ||
138 | trace_eeprom("eeprom direct call results:"); | ||
139 | trace_eeprom("has_radio=%d",tvdata.has_radio); | ||
140 | trace_eeprom("tuner_type=%d",tvdata.tuner_type); | ||
141 | trace_eeprom("tuner_formats=0x%x",tvdata.tuner_formats); | ||
142 | trace_eeprom("audio_processor=%d",tvdata.audio_processor); | ||
143 | trace_eeprom("model=%d",tvdata.model); | ||
144 | trace_eeprom("revision=%d",tvdata.revision); | ||
145 | trace_eeprom("serial_number=%d",tvdata.serial_number); | ||
146 | trace_eeprom("rev_str=%s",tvdata.rev_str); | ||
147 | hdw->tuner_type = tvdata.tuner_type; | ||
148 | hdw->serial_number = tvdata.serial_number; | ||
149 | hdw->std_mask_eeprom = tvdata.tuner_formats; | ||
150 | |||
151 | kfree(eeprom); | ||
152 | |||
153 | return 0; | ||
154 | } | ||
155 | |||
156 | /* | ||
157 | Stuff for Emacs to see, in order to encourage consistent editing style: | ||
158 | *** Local Variables: *** | ||
159 | *** mode: c *** | ||
160 | *** fill-column: 70 *** | ||
161 | *** tab-width: 8 *** | ||
162 | *** c-basic-offset: 8 *** | ||
163 | *** End: *** | ||
164 | */ | ||
diff --git a/drivers/media/video/pvrusb2/pvrusb2-eeprom.h b/drivers/media/video/pvrusb2/pvrusb2-eeprom.h new file mode 100644 index 000000000000..84242975dea7 --- /dev/null +++ b/drivers/media/video/pvrusb2/pvrusb2-eeprom.h | |||
@@ -0,0 +1,40 @@ | |||
1 | /* | ||
2 | * | ||
3 | * $Id$ | ||
4 | * | ||
5 | * Copyright (C) 2005 Mike Isely <isely@pobox.com> | ||
6 | * Copyright (C) 2004 Aurelien Alleaume <slts@free.fr> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License as published by | ||
10 | * the Free Software Foundation; either version 2 of the License | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | * GNU General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU General Public License | ||
18 | * along with this program; if not, write to the Free Software | ||
19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
20 | * | ||
21 | */ | ||
22 | |||
23 | #ifndef __PVRUSB2_EEPROM_H | ||
24 | #define __PVRUSB2_EEPROM_H | ||
25 | |||
26 | struct pvr2_hdw; | ||
27 | |||
28 | int pvr2_eeprom_analyze(struct pvr2_hdw *); | ||
29 | |||
30 | #endif /* __PVRUSB2_EEPROM_H */ | ||
31 | |||
32 | /* | ||
33 | Stuff for Emacs to see, in order to encourage consistent editing style: | ||
34 | *** Local Variables: *** | ||
35 | *** mode: c *** | ||
36 | *** fill-column: 70 *** | ||
37 | *** tab-width: 8 *** | ||
38 | *** c-basic-offset: 8 *** | ||
39 | *** End: *** | ||
40 | */ | ||
diff --git a/drivers/media/video/pvrusb2/pvrusb2-encoder.c b/drivers/media/video/pvrusb2/pvrusb2-encoder.c new file mode 100644 index 000000000000..2cc31695b435 --- /dev/null +++ b/drivers/media/video/pvrusb2/pvrusb2-encoder.c | |||
@@ -0,0 +1,418 @@ | |||
1 | /* | ||
2 | * | ||
3 | * $Id$ | ||
4 | * | ||
5 | * Copyright (C) 2005 Mike Isely <isely@pobox.com> | ||
6 | * Copyright (C) 2004 Aurelien Alleaume <slts@free.fr> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License as published by | ||
10 | * the Free Software Foundation; either version 2 of the License | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | * GNU General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU General Public License | ||
18 | * along with this program; if not, write to the Free Software | ||
19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
20 | * | ||
21 | */ | ||
22 | |||
23 | #include <linux/device.h> // for linux/firmware.h | ||
24 | #include <linux/firmware.h> | ||
25 | #include "pvrusb2-util.h" | ||
26 | #include "pvrusb2-encoder.h" | ||
27 | #include "pvrusb2-hdw-internal.h" | ||
28 | #include "pvrusb2-debug.h" | ||
29 | |||
30 | |||
31 | |||
32 | /* Firmware mailbox flags - definitions found from ivtv */ | ||
33 | #define IVTV_MBOX_FIRMWARE_DONE 0x00000004 | ||
34 | #define IVTV_MBOX_DRIVER_DONE 0x00000002 | ||
35 | #define IVTV_MBOX_DRIVER_BUSY 0x00000001 | ||
36 | |||
37 | |||
38 | static int pvr2_encoder_write_words(struct pvr2_hdw *hdw, | ||
39 | const u32 *data, unsigned int dlen) | ||
40 | { | ||
41 | unsigned int idx; | ||
42 | int ret; | ||
43 | unsigned int offs = 0; | ||
44 | unsigned int chunkCnt; | ||
45 | |||
46 | /* | ||
47 | |||
48 | Format: First byte must be 0x01. Remaining 32 bit words are | ||
49 | spread out into chunks of 7 bytes each, little-endian ordered, | ||
50 | offset at zero within each 2 blank bytes following and a | ||
51 | single byte that is 0x44 plus the offset of the word. Repeat | ||
52 | request for additional words, with offset adjusted | ||
53 | accordingly. | ||
54 | |||
55 | */ | ||
56 | while (dlen) { | ||
57 | chunkCnt = 8; | ||
58 | if (chunkCnt > dlen) chunkCnt = dlen; | ||
59 | memset(hdw->cmd_buffer,0,sizeof(hdw->cmd_buffer)); | ||
60 | hdw->cmd_buffer[0] = 0x01; | ||
61 | for (idx = 0; idx < chunkCnt; idx++) { | ||
62 | hdw->cmd_buffer[1+(idx*7)+6] = 0x44 + idx + offs; | ||
63 | PVR2_DECOMPOSE_LE(hdw->cmd_buffer, 1+(idx*7), | ||
64 | data[idx]); | ||
65 | } | ||
66 | ret = pvr2_send_request(hdw, | ||
67 | hdw->cmd_buffer,1+(chunkCnt*7), | ||
68 | 0,0); | ||
69 | if (ret) return ret; | ||
70 | data += chunkCnt; | ||
71 | dlen -= chunkCnt; | ||
72 | offs += chunkCnt; | ||
73 | } | ||
74 | |||
75 | return 0; | ||
76 | } | ||
77 | |||
78 | |||
79 | static int pvr2_encoder_read_words(struct pvr2_hdw *hdw,int statusFl, | ||
80 | u32 *data, unsigned int dlen) | ||
81 | { | ||
82 | unsigned int idx; | ||
83 | int ret; | ||
84 | unsigned int offs = 0; | ||
85 | unsigned int chunkCnt; | ||
86 | |||
87 | /* | ||
88 | |||
89 | Format: First byte must be 0x02 (status check) or 0x28 (read | ||
90 | back block of 32 bit words). Next 6 bytes must be zero, | ||
91 | followed by a single byte of 0x44+offset for portion to be | ||
92 | read. Returned data is packed set of 32 bits words that were | ||
93 | read. | ||
94 | |||
95 | */ | ||
96 | |||
97 | while (dlen) { | ||
98 | chunkCnt = 16; | ||
99 | if (chunkCnt > dlen) chunkCnt = dlen; | ||
100 | memset(hdw->cmd_buffer,0,sizeof(hdw->cmd_buffer)); | ||
101 | hdw->cmd_buffer[0] = statusFl ? 0x02 : 0x28; | ||
102 | hdw->cmd_buffer[7] = 0x44 + offs; | ||
103 | ret = pvr2_send_request(hdw, | ||
104 | hdw->cmd_buffer,8, | ||
105 | hdw->cmd_buffer,chunkCnt * 4); | ||
106 | if (ret) return ret; | ||
107 | |||
108 | for (idx = 0; idx < chunkCnt; idx++) { | ||
109 | data[idx] = PVR2_COMPOSE_LE(hdw->cmd_buffer,idx*4); | ||
110 | } | ||
111 | data += chunkCnt; | ||
112 | dlen -= chunkCnt; | ||
113 | offs += chunkCnt; | ||
114 | } | ||
115 | |||
116 | return 0; | ||
117 | } | ||
118 | |||
119 | |||
120 | /* This prototype is set up to be compatible with the | ||
121 | cx2341x_mbox_func prototype in cx2341x.h, which should be in | ||
122 | kernels 2.6.18 or later. We do this so that we can enable | ||
123 | cx2341x.ko to write to our encoder (by handing it a pointer to this | ||
124 | function). For earlier kernels this doesn't really matter. */ | ||
125 | static int pvr2_encoder_cmd(void *ctxt, | ||
126 | int cmd, | ||
127 | int arg_cnt_send, | ||
128 | int arg_cnt_recv, | ||
129 | u32 *argp) | ||
130 | { | ||
131 | unsigned int poll_count; | ||
132 | int ret = 0; | ||
133 | unsigned int idx; | ||
134 | /* These sizes look to be limited by the FX2 firmware implementation */ | ||
135 | u32 wrData[16]; | ||
136 | u32 rdData[16]; | ||
137 | struct pvr2_hdw *hdw = (struct pvr2_hdw *)ctxt; | ||
138 | |||
139 | |||
140 | /* | ||
141 | |||
142 | The encoder seems to speak entirely using blocks 32 bit words. | ||
143 | In ivtv driver terms, this is a mailbox which we populate with | ||
144 | data and watch what the hardware does with it. The first word | ||
145 | is a set of flags used to control the transaction, the second | ||
146 | word is the command to execute, the third byte is zero (ivtv | ||
147 | driver suggests that this is some kind of return value), and | ||
148 | the fourth byte is a specified timeout (windows driver always | ||
149 | uses 0x00060000 except for one case when it is zero). All | ||
150 | successive words are the argument words for the command. | ||
151 | |||
152 | First, write out the entire set of words, with the first word | ||
153 | being zero. | ||
154 | |||
155 | Next, write out just the first word again, but set it to | ||
156 | IVTV_MBOX_DRIVER_DONE | IVTV_DRIVER_BUSY this time (which | ||
157 | probably means "go"). | ||
158 | |||
159 | Next, read back 16 words as status. Check the first word, | ||
160 | which should have IVTV_MBOX_FIRMWARE_DONE set. If however | ||
161 | that bit is not set, then the command isn't done so repeat the | ||
162 | read. | ||
163 | |||
164 | Next, read back 32 words and compare with the original | ||
165 | arugments. Hopefully they will match. | ||
166 | |||
167 | Finally, write out just the first word again, but set it to | ||
168 | 0x0 this time (which probably means "idle"). | ||
169 | |||
170 | */ | ||
171 | |||
172 | if (arg_cnt_send > (sizeof(wrData)/sizeof(wrData[0]))-4) { | ||
173 | pvr2_trace( | ||
174 | PVR2_TRACE_ERROR_LEGS, | ||
175 | "Failed to write cx23416 command" | ||
176 | " - too many input arguments" | ||
177 | " (was given %u limit %u)", | ||
178 | arg_cnt_send, | ||
179 | (unsigned int)(sizeof(wrData)/sizeof(wrData[0])) - 4); | ||
180 | return -EINVAL; | ||
181 | } | ||
182 | |||
183 | if (arg_cnt_recv > (sizeof(rdData)/sizeof(rdData[0]))-4) { | ||
184 | pvr2_trace( | ||
185 | PVR2_TRACE_ERROR_LEGS, | ||
186 | "Failed to write cx23416 command" | ||
187 | " - too many return arguments" | ||
188 | " (was given %u limit %u)", | ||
189 | arg_cnt_recv, | ||
190 | (unsigned int)(sizeof(rdData)/sizeof(rdData[0])) - 4); | ||
191 | return -EINVAL; | ||
192 | } | ||
193 | |||
194 | |||
195 | LOCK_TAKE(hdw->ctl_lock); do { | ||
196 | |||
197 | wrData[0] = 0; | ||
198 | wrData[1] = cmd; | ||
199 | wrData[2] = 0; | ||
200 | wrData[3] = 0x00060000; | ||
201 | for (idx = 0; idx < arg_cnt_send; idx++) { | ||
202 | wrData[idx+4] = argp[idx]; | ||
203 | } | ||
204 | for (; idx < (sizeof(wrData)/sizeof(wrData[0]))-4; idx++) { | ||
205 | wrData[idx+4] = 0; | ||
206 | } | ||
207 | |||
208 | ret = pvr2_encoder_write_words(hdw,wrData,idx); | ||
209 | if (ret) break; | ||
210 | wrData[0] = IVTV_MBOX_DRIVER_DONE|IVTV_MBOX_DRIVER_BUSY; | ||
211 | ret = pvr2_encoder_write_words(hdw,wrData,1); | ||
212 | if (ret) break; | ||
213 | poll_count = 0; | ||
214 | while (1) { | ||
215 | if (poll_count < 10000000) poll_count++; | ||
216 | ret = pvr2_encoder_read_words(hdw,!0,rdData,1); | ||
217 | if (ret) break; | ||
218 | if (rdData[0] & IVTV_MBOX_FIRMWARE_DONE) { | ||
219 | break; | ||
220 | } | ||
221 | if (poll_count == 100) { | ||
222 | pvr2_trace( | ||
223 | PVR2_TRACE_ERROR_LEGS, | ||
224 | "***WARNING*** device's encoder" | ||
225 | " appears to be stuck" | ||
226 | " (status=0%08x)",rdData[0]); | ||
227 | pvr2_trace( | ||
228 | PVR2_TRACE_ERROR_LEGS, | ||
229 | "Encoder command: 0x%02x",cmd); | ||
230 | for (idx = 4; idx < arg_cnt_send; idx++) { | ||
231 | pvr2_trace( | ||
232 | PVR2_TRACE_ERROR_LEGS, | ||
233 | "Encoder arg%d: 0x%08x", | ||
234 | idx-3,wrData[idx]); | ||
235 | } | ||
236 | pvr2_trace( | ||
237 | PVR2_TRACE_ERROR_LEGS, | ||
238 | "Giving up waiting." | ||
239 | " It is likely that" | ||
240 | " this is a bad idea..."); | ||
241 | ret = -EBUSY; | ||
242 | break; | ||
243 | } | ||
244 | } | ||
245 | if (ret) break; | ||
246 | wrData[0] = 0x7; | ||
247 | ret = pvr2_encoder_read_words( | ||
248 | hdw,0,rdData, | ||
249 | sizeof(rdData)/sizeof(rdData[0])); | ||
250 | if (ret) break; | ||
251 | for (idx = 0; idx < arg_cnt_recv; idx++) { | ||
252 | argp[idx] = rdData[idx+4]; | ||
253 | } | ||
254 | |||
255 | wrData[0] = 0x0; | ||
256 | ret = pvr2_encoder_write_words(hdw,wrData,1); | ||
257 | if (ret) break; | ||
258 | |||
259 | } while(0); LOCK_GIVE(hdw->ctl_lock); | ||
260 | |||
261 | return ret; | ||
262 | } | ||
263 | |||
264 | |||
265 | static int pvr2_encoder_vcmd(struct pvr2_hdw *hdw, int cmd, | ||
266 | int args, ...) | ||
267 | { | ||
268 | va_list vl; | ||
269 | unsigned int idx; | ||
270 | u32 data[12]; | ||
271 | |||
272 | if (args > sizeof(data)/sizeof(data[0])) { | ||
273 | pvr2_trace( | ||
274 | PVR2_TRACE_ERROR_LEGS, | ||
275 | "Failed to write cx23416 command" | ||
276 | " - too many arguments" | ||
277 | " (was given %u limit %u)", | ||
278 | args,(unsigned int)(sizeof(data)/sizeof(data[0]))); | ||
279 | return -EINVAL; | ||
280 | } | ||
281 | |||
282 | va_start(vl, args); | ||
283 | for (idx = 0; idx < args; idx++) { | ||
284 | data[idx] = va_arg(vl, u32); | ||
285 | } | ||
286 | va_end(vl); | ||
287 | |||
288 | return pvr2_encoder_cmd(hdw,cmd,args,0,data); | ||
289 | } | ||
290 | |||
291 | int pvr2_encoder_configure(struct pvr2_hdw *hdw) | ||
292 | { | ||
293 | int ret; | ||
294 | pvr2_trace(PVR2_TRACE_ENCODER,"pvr2_encoder_configure" | ||
295 | " (cx2341x module)"); | ||
296 | hdw->enc_ctl_state.port = CX2341X_PORT_STREAMING; | ||
297 | hdw->enc_ctl_state.width = hdw->res_hor_val; | ||
298 | hdw->enc_ctl_state.height = hdw->res_ver_val; | ||
299 | hdw->enc_ctl_state.is_50hz = ((hdw->std_mask_cur & | ||
300 | (V4L2_STD_NTSC|V4L2_STD_PAL_M)) ? | ||
301 | 0 : 1); | ||
302 | |||
303 | ret = 0; | ||
304 | |||
305 | if (!ret) ret = pvr2_encoder_vcmd( | ||
306 | hdw,CX2341X_ENC_SET_NUM_VSYNC_LINES, 2, | ||
307 | 0xf0, 0xf0); | ||
308 | |||
309 | /* setup firmware to notify us about some events (don't know why...) */ | ||
310 | if (!ret) ret = pvr2_encoder_vcmd( | ||
311 | hdw,CX2341X_ENC_SET_EVENT_NOTIFICATION, 4, | ||
312 | 0, 0, 0x10000000, 0xffffffff); | ||
313 | |||
314 | if (!ret) ret = pvr2_encoder_vcmd( | ||
315 | hdw,CX2341X_ENC_SET_VBI_LINE, 5, | ||
316 | 0xffffffff,0,0,0,0); | ||
317 | |||
318 | if (ret) { | ||
319 | pvr2_trace(PVR2_TRACE_ERROR_LEGS, | ||
320 | "Failed to configure cx32416"); | ||
321 | return ret; | ||
322 | } | ||
323 | |||
324 | ret = cx2341x_update(hdw,pvr2_encoder_cmd, | ||
325 | (hdw->enc_cur_valid ? &hdw->enc_cur_state : 0), | ||
326 | &hdw->enc_ctl_state); | ||
327 | if (ret) { | ||
328 | pvr2_trace(PVR2_TRACE_ERROR_LEGS, | ||
329 | "Error from cx2341x module code=%d",ret); | ||
330 | return ret; | ||
331 | } | ||
332 | |||
333 | ret = 0; | ||
334 | |||
335 | if (!ret) ret = pvr2_encoder_vcmd( | ||
336 | hdw, CX2341X_ENC_INITIALIZE_INPUT, 0); | ||
337 | |||
338 | if (ret) { | ||
339 | pvr2_trace(PVR2_TRACE_ERROR_LEGS, | ||
340 | "Failed to initialize cx32416 video input"); | ||
341 | return ret; | ||
342 | } | ||
343 | |||
344 | hdw->subsys_enabled_mask |= (1<<PVR2_SUBSYS_B_ENC_CFG); | ||
345 | memcpy(&hdw->enc_cur_state,&hdw->enc_ctl_state, | ||
346 | sizeof(struct cx2341x_mpeg_params)); | ||
347 | hdw->enc_cur_valid = !0; | ||
348 | return 0; | ||
349 | } | ||
350 | |||
351 | |||
352 | int pvr2_encoder_start(struct pvr2_hdw *hdw) | ||
353 | { | ||
354 | int status; | ||
355 | |||
356 | /* unmask some interrupts */ | ||
357 | pvr2_write_register(hdw, 0x0048, 0xbfffffff); | ||
358 | |||
359 | /* change some GPIO data */ | ||
360 | pvr2_hdw_gpio_chg_dir(hdw,0xffffffff,0x00000481); | ||
361 | pvr2_hdw_gpio_chg_out(hdw,0xffffffff,0x00000000); | ||
362 | |||
363 | if (hdw->config == pvr2_config_vbi) { | ||
364 | status = pvr2_encoder_vcmd(hdw,CX2341X_ENC_START_CAPTURE,2, | ||
365 | 0x01,0x14); | ||
366 | } else if (hdw->config == pvr2_config_mpeg) { | ||
367 | status = pvr2_encoder_vcmd(hdw,CX2341X_ENC_START_CAPTURE,2, | ||
368 | 0,0x13); | ||
369 | } else { | ||
370 | status = pvr2_encoder_vcmd(hdw,CX2341X_ENC_START_CAPTURE,2, | ||
371 | 0,0x13); | ||
372 | } | ||
373 | if (!status) { | ||
374 | hdw->subsys_enabled_mask |= (1<<PVR2_SUBSYS_B_ENC_RUN); | ||
375 | } | ||
376 | return status; | ||
377 | } | ||
378 | |||
379 | int pvr2_encoder_stop(struct pvr2_hdw *hdw) | ||
380 | { | ||
381 | int status; | ||
382 | |||
383 | /* mask all interrupts */ | ||
384 | pvr2_write_register(hdw, 0x0048, 0xffffffff); | ||
385 | |||
386 | if (hdw->config == pvr2_config_vbi) { | ||
387 | status = pvr2_encoder_vcmd(hdw,CX2341X_ENC_STOP_CAPTURE,3, | ||
388 | 0x01,0x01,0x14); | ||
389 | } else if (hdw->config == pvr2_config_mpeg) { | ||
390 | status = pvr2_encoder_vcmd(hdw,CX2341X_ENC_STOP_CAPTURE,3, | ||
391 | 0x01,0,0x13); | ||
392 | } else { | ||
393 | status = pvr2_encoder_vcmd(hdw,CX2341X_ENC_STOP_CAPTURE,3, | ||
394 | 0x01,0,0x13); | ||
395 | } | ||
396 | |||
397 | /* change some GPIO data */ | ||
398 | /* Note: Bit d7 of dir appears to control the LED. So we shut it | ||
399 | off here. */ | ||
400 | pvr2_hdw_gpio_chg_dir(hdw,0xffffffff,0x00000401); | ||
401 | pvr2_hdw_gpio_chg_out(hdw,0xffffffff,0x00000000); | ||
402 | |||
403 | if (!status) { | ||
404 | hdw->subsys_enabled_mask &= ~(1<<PVR2_SUBSYS_B_ENC_RUN); | ||
405 | } | ||
406 | return status; | ||
407 | } | ||
408 | |||
409 | |||
410 | /* | ||
411 | Stuff for Emacs to see, in order to encourage consistent editing style: | ||
412 | *** Local Variables: *** | ||
413 | *** mode: c *** | ||
414 | *** fill-column: 70 *** | ||
415 | *** tab-width: 8 *** | ||
416 | *** c-basic-offset: 8 *** | ||
417 | *** End: *** | ||
418 | */ | ||
diff --git a/drivers/media/video/pvrusb2/pvrusb2-encoder.h b/drivers/media/video/pvrusb2/pvrusb2-encoder.h new file mode 100644 index 000000000000..01b5a0b89c03 --- /dev/null +++ b/drivers/media/video/pvrusb2/pvrusb2-encoder.h | |||
@@ -0,0 +1,42 @@ | |||
1 | /* | ||
2 | * | ||
3 | * $Id$ | ||
4 | * | ||
5 | * Copyright (C) 2005 Mike Isely <isely@pobox.com> | ||
6 | * Copyright (C) 2004 Aurelien Alleaume <slts@free.fr> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License as published by | ||
10 | * the Free Software Foundation; either version 2 of the License | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | * GNU General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU General Public License | ||
18 | * along with this program; if not, write to the Free Software | ||
19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
20 | * | ||
21 | */ | ||
22 | |||
23 | #ifndef __PVRUSB2_ENCODER_H | ||
24 | #define __PVRUSB2_ENCODER_H | ||
25 | |||
26 | struct pvr2_hdw; | ||
27 | |||
28 | int pvr2_encoder_configure(struct pvr2_hdw *); | ||
29 | int pvr2_encoder_start(struct pvr2_hdw *); | ||
30 | int pvr2_encoder_stop(struct pvr2_hdw *); | ||
31 | |||
32 | #endif /* __PVRUSB2_ENCODER_H */ | ||
33 | |||
34 | /* | ||
35 | Stuff for Emacs to see, in order to encourage consistent editing style: | ||
36 | *** Local Variables: *** | ||
37 | *** mode: c *** | ||
38 | *** fill-column: 70 *** | ||
39 | *** tab-width: 8 *** | ||
40 | *** c-basic-offset: 8 *** | ||
41 | *** End: *** | ||
42 | */ | ||
diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h b/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h new file mode 100644 index 000000000000..ba2afbfe32c5 --- /dev/null +++ b/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h | |||
@@ -0,0 +1,384 @@ | |||
1 | /* | ||
2 | * | ||
3 | * $Id$ | ||
4 | * | ||
5 | * Copyright (C) 2005 Mike Isely <isely@pobox.com> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License as published by | ||
9 | * the Free Software Foundation; either version 2 of the License | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
19 | * | ||
20 | */ | ||
21 | #ifndef __PVRUSB2_HDW_INTERNAL_H | ||
22 | #define __PVRUSB2_HDW_INTERNAL_H | ||
23 | |||
24 | /* | ||
25 | |||
26 | This header sets up all the internal structures and definitions needed to | ||
27 | track and coordinate the driver's interaction with the hardware. ONLY | ||
28 | source files which actually implement part of that whole circus should be | ||
29 | including this header. Higher levels, like the external layers to the | ||
30 | various public APIs (V4L, sysfs, etc) should NOT ever include this | ||
31 | private, internal header. This means that pvrusb2-hdw, pvrusb2-encoder, | ||
32 | etc will include this, but pvrusb2-v4l should not. | ||
33 | |||
34 | */ | ||
35 | |||
36 | #include <linux/config.h> | ||
37 | #include <linux/videodev2.h> | ||
38 | #include <linux/i2c.h> | ||
39 | #include <linux/mutex.h> | ||
40 | #include "pvrusb2-hdw.h" | ||
41 | #include "pvrusb2-io.h" | ||
42 | #include <media/cx2341x.h> | ||
43 | |||
44 | /* Legal values for the SRATE state variable */ | ||
45 | #define PVR2_CVAL_SRATE_48 0 | ||
46 | #define PVR2_CVAL_SRATE_44_1 1 | ||
47 | |||
48 | /* Legal values for the AUDIOBITRATE state variable */ | ||
49 | #define PVR2_CVAL_AUDIOBITRATE_384 0 | ||
50 | #define PVR2_CVAL_AUDIOBITRATE_320 1 | ||
51 | #define PVR2_CVAL_AUDIOBITRATE_256 2 | ||
52 | #define PVR2_CVAL_AUDIOBITRATE_224 3 | ||
53 | #define PVR2_CVAL_AUDIOBITRATE_192 4 | ||
54 | #define PVR2_CVAL_AUDIOBITRATE_160 5 | ||
55 | #define PVR2_CVAL_AUDIOBITRATE_128 6 | ||
56 | #define PVR2_CVAL_AUDIOBITRATE_112 7 | ||
57 | #define PVR2_CVAL_AUDIOBITRATE_96 8 | ||
58 | #define PVR2_CVAL_AUDIOBITRATE_80 9 | ||
59 | #define PVR2_CVAL_AUDIOBITRATE_64 10 | ||
60 | #define PVR2_CVAL_AUDIOBITRATE_56 11 | ||
61 | #define PVR2_CVAL_AUDIOBITRATE_48 12 | ||
62 | #define PVR2_CVAL_AUDIOBITRATE_32 13 | ||
63 | #define PVR2_CVAL_AUDIOBITRATE_VBR 14 | ||
64 | |||
65 | /* Legal values for the AUDIOEMPHASIS state variable */ | ||
66 | #define PVR2_CVAL_AUDIOEMPHASIS_NONE 0 | ||
67 | #define PVR2_CVAL_AUDIOEMPHASIS_50_15 1 | ||
68 | #define PVR2_CVAL_AUDIOEMPHASIS_CCITT 2 | ||
69 | |||
70 | /* Legal values for PVR2_CID_HSM */ | ||
71 | #define PVR2_CVAL_HSM_FAIL 0 | ||
72 | #define PVR2_CVAL_HSM_FULL 1 | ||
73 | #define PVR2_CVAL_HSM_HIGH 2 | ||
74 | |||
75 | #define PVR2_VID_ENDPOINT 0x84 | ||
76 | #define PVR2_UNK_ENDPOINT 0x86 /* maybe raw yuv ? */ | ||
77 | #define PVR2_VBI_ENDPOINT 0x88 | ||
78 | |||
79 | #define PVR2_CTL_BUFFSIZE 64 | ||
80 | |||
81 | #define FREQTABLE_SIZE 500 | ||
82 | |||
83 | #define LOCK_TAKE(x) do { mutex_lock(&x##_mutex); x##_held = !0; } while (0) | ||
84 | #define LOCK_GIVE(x) do { x##_held = 0; mutex_unlock(&x##_mutex); } while (0) | ||
85 | |||
86 | struct pvr2_decoder; | ||
87 | |||
88 | typedef int (*pvr2_ctlf_is_dirty)(struct pvr2_ctrl *); | ||
89 | typedef void (*pvr2_ctlf_clear_dirty)(struct pvr2_ctrl *); | ||
90 | typedef int (*pvr2_ctlf_get_value)(struct pvr2_ctrl *,int *); | ||
91 | typedef int (*pvr2_ctlf_set_value)(struct pvr2_ctrl *,int msk,int val); | ||
92 | typedef int (*pvr2_ctlf_val_to_sym)(struct pvr2_ctrl *,int msk,int val, | ||
93 | char *,unsigned int,unsigned int *); | ||
94 | typedef int (*pvr2_ctlf_sym_to_val)(struct pvr2_ctrl *, | ||
95 | const char *,unsigned int, | ||
96 | int *mskp,int *valp); | ||
97 | typedef unsigned int (*pvr2_ctlf_get_v4lflags)(struct pvr2_ctrl *); | ||
98 | |||
99 | /* This structure describes a specific control. A table of these is set up | ||
100 | in pvrusb2-hdw.c. */ | ||
101 | struct pvr2_ctl_info { | ||
102 | /* Control's name suitable for use as an identifier */ | ||
103 | const char *name; | ||
104 | |||
105 | /* Short description of control */ | ||
106 | const char *desc; | ||
107 | |||
108 | /* Control's implementation */ | ||
109 | pvr2_ctlf_get_value get_value; /* Get its value */ | ||
110 | pvr2_ctlf_set_value set_value; /* Set its value */ | ||
111 | pvr2_ctlf_val_to_sym val_to_sym; /* Custom convert value->symbol */ | ||
112 | pvr2_ctlf_sym_to_val sym_to_val; /* Custom convert symbol->value */ | ||
113 | pvr2_ctlf_is_dirty is_dirty; /* Return true if dirty */ | ||
114 | pvr2_ctlf_clear_dirty clear_dirty; /* Clear dirty state */ | ||
115 | pvr2_ctlf_get_v4lflags get_v4lflags;/* Retrieve v4l flags */ | ||
116 | |||
117 | /* Control's type (int, enum, bitmask) */ | ||
118 | enum pvr2_ctl_type type; | ||
119 | |||
120 | /* Associated V4L control ID, if any */ | ||
121 | int v4l_id; | ||
122 | |||
123 | /* Associated driver internal ID, if any */ | ||
124 | int internal_id; | ||
125 | |||
126 | /* Don't implicitly initialize this control's value */ | ||
127 | int skip_init; | ||
128 | |||
129 | /* Starting value for this control */ | ||
130 | int default_value; | ||
131 | |||
132 | /* Type-specific control information */ | ||
133 | union { | ||
134 | struct { /* Integer control */ | ||
135 | long min_value; /* lower limit */ | ||
136 | long max_value; /* upper limit */ | ||
137 | } type_int; | ||
138 | struct { /* enumerated control */ | ||
139 | unsigned int count; /* enum value count */ | ||
140 | const char **value_names; /* symbol names */ | ||
141 | } type_enum; | ||
142 | struct { /* bitmask control */ | ||
143 | unsigned int valid_bits; /* bits in use */ | ||
144 | const char **bit_names; /* symbol name/bit */ | ||
145 | } type_bitmask; | ||
146 | } def; | ||
147 | }; | ||
148 | |||
149 | |||
150 | /* Same as pvr2_ctl_info, but includes storage for the control description */ | ||
151 | #define PVR2_CTLD_INFO_DESC_SIZE 32 | ||
152 | struct pvr2_ctld_info { | ||
153 | struct pvr2_ctl_info info; | ||
154 | char desc[PVR2_CTLD_INFO_DESC_SIZE]; | ||
155 | }; | ||
156 | |||
157 | struct pvr2_ctrl { | ||
158 | const struct pvr2_ctl_info *info; | ||
159 | struct pvr2_hdw *hdw; | ||
160 | }; | ||
161 | |||
162 | |||
163 | struct pvr2_audio_stat { | ||
164 | void *ctxt; | ||
165 | void (*detach)(void *); | ||
166 | int (*status)(void *); | ||
167 | }; | ||
168 | |||
169 | struct pvr2_decoder_ctrl { | ||
170 | void *ctxt; | ||
171 | void (*detach)(void *); | ||
172 | void (*enable)(void *,int); | ||
173 | int (*tuned)(void *); | ||
174 | void (*force_reset)(void *); | ||
175 | }; | ||
176 | |||
177 | #define PVR2_I2C_PEND_DETECT 0x01 /* Need to detect a client type */ | ||
178 | #define PVR2_I2C_PEND_CLIENT 0x02 /* Client needs a specific update */ | ||
179 | #define PVR2_I2C_PEND_REFRESH 0x04 /* Client has specific pending bits */ | ||
180 | #define PVR2_I2C_PEND_STALE 0x08 /* Broadcast pending bits */ | ||
181 | |||
182 | #define PVR2_I2C_PEND_ALL (PVR2_I2C_PEND_DETECT |\ | ||
183 | PVR2_I2C_PEND_CLIENT |\ | ||
184 | PVR2_I2C_PEND_REFRESH |\ | ||
185 | PVR2_I2C_PEND_STALE) | ||
186 | |||
187 | /* Disposition of firmware1 loading situation */ | ||
188 | #define FW1_STATE_UNKNOWN 0 | ||
189 | #define FW1_STATE_MISSING 1 | ||
190 | #define FW1_STATE_FAILED 2 | ||
191 | #define FW1_STATE_RELOAD 3 | ||
192 | #define FW1_STATE_OK 4 | ||
193 | |||
194 | /* Known major hardware variants, keyed from device ID */ | ||
195 | #define PVR2_HDW_TYPE_29XXX 0 | ||
196 | #ifdef CONFIG_VIDEO_PVRUSB2_24XXX | ||
197 | #define PVR2_HDW_TYPE_24XXX 1 | ||
198 | #endif | ||
199 | |||
200 | typedef int (*pvr2_i2c_func)(struct pvr2_hdw *,u8,u8 *,u16,u8 *, u16); | ||
201 | #define PVR2_I2C_FUNC_CNT 128 | ||
202 | |||
203 | /* This structure contains all state data directly needed to | ||
204 | manipulate the hardware (as opposed to complying with a kernel | ||
205 | interface) */ | ||
206 | struct pvr2_hdw { | ||
207 | /* Underlying USB device handle */ | ||
208 | struct usb_device *usb_dev; | ||
209 | struct usb_interface *usb_intf; | ||
210 | |||
211 | /* Device type, one of PVR2_HDW_TYPE_xxxxx */ | ||
212 | unsigned int hdw_type; | ||
213 | |||
214 | /* Video spigot */ | ||
215 | struct pvr2_stream *vid_stream; | ||
216 | |||
217 | /* Mutex for all hardware state control */ | ||
218 | struct mutex big_lock_mutex; | ||
219 | int big_lock_held; /* For debugging */ | ||
220 | |||
221 | void (*poll_trigger_func)(void *); | ||
222 | void *poll_trigger_data; | ||
223 | |||
224 | char name[32]; | ||
225 | |||
226 | /* I2C stuff */ | ||
227 | struct i2c_adapter i2c_adap; | ||
228 | struct i2c_algorithm i2c_algo; | ||
229 | pvr2_i2c_func i2c_func[PVR2_I2C_FUNC_CNT]; | ||
230 | int i2c_cx25840_hack_state; | ||
231 | int i2c_linked; | ||
232 | unsigned int i2c_pend_types; /* Which types of update are needed */ | ||
233 | unsigned long i2c_pend_mask; /* Change bits we need to scan */ | ||
234 | unsigned long i2c_stale_mask; /* Pending broadcast change bits */ | ||
235 | unsigned long i2c_active_mask; /* All change bits currently in use */ | ||
236 | struct list_head i2c_clients; | ||
237 | struct mutex i2c_list_lock; | ||
238 | |||
239 | /* Frequency table */ | ||
240 | unsigned int freqTable[FREQTABLE_SIZE]; | ||
241 | unsigned int freqProgSlot; | ||
242 | unsigned int freqSlot; | ||
243 | |||
244 | /* Stuff for handling low level control interaction with device */ | ||
245 | struct mutex ctl_lock_mutex; | ||
246 | int ctl_lock_held; /* For debugging */ | ||
247 | struct urb *ctl_write_urb; | ||
248 | struct urb *ctl_read_urb; | ||
249 | unsigned char *ctl_write_buffer; | ||
250 | unsigned char *ctl_read_buffer; | ||
251 | volatile int ctl_write_pend_flag; | ||
252 | volatile int ctl_read_pend_flag; | ||
253 | volatile int ctl_timeout_flag; | ||
254 | struct completion ctl_done; | ||
255 | unsigned char cmd_buffer[PVR2_CTL_BUFFSIZE]; | ||
256 | int cmd_debug_state; // Low level command debugging info | ||
257 | unsigned char cmd_debug_code; // | ||
258 | unsigned int cmd_debug_write_len; // | ||
259 | unsigned int cmd_debug_read_len; // | ||
260 | |||
261 | int flag_ok; // device in known good state | ||
262 | int flag_disconnected; // flag_ok == 0 due to disconnect | ||
263 | int flag_init_ok; // true if structure is fully initialized | ||
264 | int flag_streaming_enabled; // true if streaming should be on | ||
265 | int fw1_state; // current situation with fw1 | ||
266 | |||
267 | int flag_decoder_is_tuned; | ||
268 | |||
269 | struct pvr2_decoder_ctrl *decoder_ctrl; | ||
270 | |||
271 | // CPU firmware info (used to help find / save firmware data) | ||
272 | char *fw_buffer; | ||
273 | unsigned int fw_size; | ||
274 | |||
275 | // Which subsystem pieces have been enabled / configured | ||
276 | unsigned long subsys_enabled_mask; | ||
277 | |||
278 | // Which subsystems are manipulated to enable streaming | ||
279 | unsigned long subsys_stream_mask; | ||
280 | |||
281 | // True if there is a request to trigger logging of state in each | ||
282 | // module. | ||
283 | int log_requested; | ||
284 | |||
285 | /* Tuner / frequency control stuff */ | ||
286 | unsigned int tuner_type; | ||
287 | int tuner_updated; | ||
288 | unsigned int freqVal; | ||
289 | int freqDirty; | ||
290 | |||
291 | /* Video standard handling */ | ||
292 | v4l2_std_id std_mask_eeprom; // Hardware supported selections | ||
293 | v4l2_std_id std_mask_avail; // Which standards we may select from | ||
294 | v4l2_std_id std_mask_cur; // Currently selected standard(s) | ||
295 | unsigned int std_enum_cnt; // # of enumerated standards | ||
296 | int std_enum_cur; // selected standard enumeration value | ||
297 | int std_dirty; // True if std_mask_cur has changed | ||
298 | struct pvr2_ctl_info std_info_enum; | ||
299 | struct pvr2_ctl_info std_info_avail; | ||
300 | struct pvr2_ctl_info std_info_cur; | ||
301 | struct v4l2_standard *std_defs; | ||
302 | const char **std_enum_names; | ||
303 | |||
304 | // Generated string names, one per actual V4L2 standard | ||
305 | const char *std_mask_ptrs[32]; | ||
306 | char std_mask_names[32][10]; | ||
307 | |||
308 | int unit_number; /* ID for driver instance */ | ||
309 | unsigned long serial_number; /* ID for hardware itself */ | ||
310 | |||
311 | /* Minor number used by v4l logic (yes, this is a hack, as there should | ||
312 | be no v4l junk here). Probably a better way to do this. */ | ||
313 | int v4l_minor_number; | ||
314 | |||
315 | /* Location of eeprom or a negative number if none */ | ||
316 | int eeprom_addr; | ||
317 | |||
318 | enum pvr2_config config; | ||
319 | |||
320 | /* Information about what audio signal we're hearing */ | ||
321 | int flag_stereo; | ||
322 | int flag_bilingual; | ||
323 | struct pvr2_audio_stat *audio_stat; | ||
324 | |||
325 | /* Control state needed for cx2341x module */ | ||
326 | struct cx2341x_mpeg_params enc_cur_state; | ||
327 | struct cx2341x_mpeg_params enc_ctl_state; | ||
328 | /* True if an encoder attribute has changed */ | ||
329 | int enc_stale; | ||
330 | /* True if enc_cur_state is valid */ | ||
331 | int enc_cur_valid; | ||
332 | |||
333 | /* Control state */ | ||
334 | #define VCREATE_DATA(lab) int lab##_val; int lab##_dirty | ||
335 | VCREATE_DATA(brightness); | ||
336 | VCREATE_DATA(contrast); | ||
337 | VCREATE_DATA(saturation); | ||
338 | VCREATE_DATA(hue); | ||
339 | VCREATE_DATA(volume); | ||
340 | VCREATE_DATA(balance); | ||
341 | VCREATE_DATA(bass); | ||
342 | VCREATE_DATA(treble); | ||
343 | VCREATE_DATA(mute); | ||
344 | VCREATE_DATA(input); | ||
345 | VCREATE_DATA(audiomode); | ||
346 | VCREATE_DATA(res_hor); | ||
347 | VCREATE_DATA(res_ver); | ||
348 | VCREATE_DATA(srate); | ||
349 | #undef VCREATE_DATA | ||
350 | |||
351 | struct pvr2_ctld_info *mpeg_ctrl_info; | ||
352 | |||
353 | struct pvr2_ctrl *controls; | ||
354 | unsigned int control_cnt; | ||
355 | }; | ||
356 | |||
357 | int pvr2_hdw_commit_ctl_internal(struct pvr2_hdw *hdw); | ||
358 | |||
359 | unsigned int pvr2_hdw_get_signal_status_internal(struct pvr2_hdw *); | ||
360 | |||
361 | void pvr2_hdw_subsys_bit_chg_no_lock(struct pvr2_hdw *hdw, | ||
362 | unsigned long msk,unsigned long val); | ||
363 | void pvr2_hdw_subsys_stream_bit_chg_no_lock(struct pvr2_hdw *hdw, | ||
364 | unsigned long msk, | ||
365 | unsigned long val); | ||
366 | |||
367 | void pvr2_hdw_internal_find_stdenum(struct pvr2_hdw *hdw); | ||
368 | void pvr2_hdw_internal_set_std_avail(struct pvr2_hdw *hdw); | ||
369 | |||
370 | int pvr2_i2c_basic_op(struct pvr2_hdw *,u8 i2c_addr, | ||
371 | u8 *wdata,u16 wlen, | ||
372 | u8 *rdata,u16 rlen); | ||
373 | |||
374 | #endif /* __PVRUSB2_HDW_INTERNAL_H */ | ||
375 | |||
376 | /* | ||
377 | Stuff for Emacs to see, in order to encourage consistent editing style: | ||
378 | *** Local Variables: *** | ||
379 | *** mode: c *** | ||
380 | *** fill-column: 75 *** | ||
381 | *** tab-width: 8 *** | ||
382 | *** c-basic-offset: 8 *** | ||
383 | *** End: *** | ||
384 | */ | ||
diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw.c b/drivers/media/video/pvrusb2/pvrusb2-hdw.c new file mode 100644 index 000000000000..643c471375da --- /dev/null +++ b/drivers/media/video/pvrusb2/pvrusb2-hdw.c | |||
@@ -0,0 +1,3120 @@ | |||
1 | /* | ||
2 | * | ||
3 | * $Id$ | ||
4 | * | ||
5 | * Copyright (C) 2005 Mike Isely <isely@pobox.com> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License as published by | ||
9 | * the Free Software Foundation; either version 2 of the License | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
19 | * | ||
20 | */ | ||
21 | |||
22 | #include <linux/errno.h> | ||
23 | #include <linux/string.h> | ||
24 | #include <linux/slab.h> | ||
25 | #include <linux/firmware.h> | ||
26 | #include <linux/videodev2.h> | ||
27 | #include <asm/semaphore.h> | ||
28 | #include "pvrusb2.h" | ||
29 | #include "pvrusb2-std.h" | ||
30 | #include "pvrusb2-util.h" | ||
31 | #include "pvrusb2-hdw.h" | ||
32 | #include "pvrusb2-i2c-core.h" | ||
33 | #include "pvrusb2-tuner.h" | ||
34 | #include "pvrusb2-eeprom.h" | ||
35 | #include "pvrusb2-hdw-internal.h" | ||
36 | #include "pvrusb2-encoder.h" | ||
37 | #include "pvrusb2-debug.h" | ||
38 | |||
39 | struct usb_device_id pvr2_device_table[] = { | ||
40 | [PVR2_HDW_TYPE_29XXX] = { USB_DEVICE(0x2040, 0x2900) }, | ||
41 | #ifdef CONFIG_VIDEO_PVRUSB2_24XXX | ||
42 | [PVR2_HDW_TYPE_24XXX] = { USB_DEVICE(0x2040, 0x2400) }, | ||
43 | #endif | ||
44 | { } | ||
45 | }; | ||
46 | |||
47 | MODULE_DEVICE_TABLE(usb, pvr2_device_table); | ||
48 | |||
49 | static const char *pvr2_device_names[] = { | ||
50 | [PVR2_HDW_TYPE_29XXX] = "WinTV PVR USB2 Model Category 29xxxx", | ||
51 | #ifdef CONFIG_VIDEO_PVRUSB2_24XXX | ||
52 | [PVR2_HDW_TYPE_24XXX] = "WinTV PVR USB2 Model Category 24xxxx", | ||
53 | #endif | ||
54 | }; | ||
55 | |||
56 | struct pvr2_string_table { | ||
57 | const char **lst; | ||
58 | unsigned int cnt; | ||
59 | }; | ||
60 | |||
61 | #ifdef CONFIG_VIDEO_PVRUSB2_24XXX | ||
62 | // Names of other client modules to request for 24xxx model hardware | ||
63 | static const char *pvr2_client_24xxx[] = { | ||
64 | "cx25840", | ||
65 | "tuner", | ||
66 | "tda9887", | ||
67 | "wm8775", | ||
68 | }; | ||
69 | #endif | ||
70 | |||
71 | // Names of other client modules to request for 29xxx model hardware | ||
72 | static const char *pvr2_client_29xxx[] = { | ||
73 | "msp3400", | ||
74 | "saa7115", | ||
75 | "tuner", | ||
76 | "tda9887", | ||
77 | }; | ||
78 | |||
79 | static struct pvr2_string_table pvr2_client_lists[] = { | ||
80 | [PVR2_HDW_TYPE_29XXX] = { | ||
81 | pvr2_client_29xxx, | ||
82 | sizeof(pvr2_client_29xxx)/sizeof(pvr2_client_29xxx[0]), | ||
83 | }, | ||
84 | #ifdef CONFIG_VIDEO_PVRUSB2_24XXX | ||
85 | [PVR2_HDW_TYPE_24XXX] = { | ||
86 | pvr2_client_24xxx, | ||
87 | sizeof(pvr2_client_24xxx)/sizeof(pvr2_client_24xxx[0]), | ||
88 | }, | ||
89 | #endif | ||
90 | }; | ||
91 | |||
92 | static struct pvr2_hdw *unit_pointers[PVR_NUM] = {[ 0 ... PVR_NUM-1 ] = 0}; | ||
93 | DECLARE_MUTEX(pvr2_unit_sem); | ||
94 | |||
95 | static int ctlchg = 0; | ||
96 | static int initusbreset = 1; | ||
97 | static int procreload = 0; | ||
98 | static int tuner[PVR_NUM] = { [0 ... PVR_NUM-1] = -1 }; | ||
99 | static int tolerance[PVR_NUM] = { [0 ... PVR_NUM-1] = 0 }; | ||
100 | static int video_std[PVR_NUM] = { [0 ... PVR_NUM-1] = 0 }; | ||
101 | static int init_pause_msec = 0; | ||
102 | |||
103 | module_param(ctlchg, int, S_IRUGO|S_IWUSR); | ||
104 | MODULE_PARM_DESC(ctlchg, "0=optimize ctl change 1=always accept new ctl value"); | ||
105 | module_param(init_pause_msec, int, S_IRUGO|S_IWUSR); | ||
106 | MODULE_PARM_DESC(init_pause_msec, "hardware initialization settling delay"); | ||
107 | module_param(initusbreset, int, S_IRUGO|S_IWUSR); | ||
108 | MODULE_PARM_DESC(initusbreset, "Do USB reset device on probe"); | ||
109 | module_param(procreload, int, S_IRUGO|S_IWUSR); | ||
110 | MODULE_PARM_DESC(procreload, | ||
111 | "Attempt init failure recovery with firmware reload"); | ||
112 | module_param_array(tuner, int, NULL, 0444); | ||
113 | MODULE_PARM_DESC(tuner,"specify installed tuner type"); | ||
114 | module_param_array(video_std, int, NULL, 0444); | ||
115 | MODULE_PARM_DESC(video_std,"specify initial video standard"); | ||
116 | module_param_array(tolerance, int, NULL, 0444); | ||
117 | MODULE_PARM_DESC(tolerance,"specify stream error tolerance"); | ||
118 | |||
119 | #define PVR2_CTL_WRITE_ENDPOINT 0x01 | ||
120 | #define PVR2_CTL_READ_ENDPOINT 0x81 | ||
121 | |||
122 | #define PVR2_GPIO_IN 0x9008 | ||
123 | #define PVR2_GPIO_OUT 0x900c | ||
124 | #define PVR2_GPIO_DIR 0x9020 | ||
125 | |||
126 | #define trace_firmware(...) pvr2_trace(PVR2_TRACE_FIRMWARE,__VA_ARGS__) | ||
127 | |||
128 | #define PVR2_FIRMWARE_ENDPOINT 0x02 | ||
129 | |||
130 | /* size of a firmware chunk */ | ||
131 | #define FIRMWARE_CHUNK_SIZE 0x2000 | ||
132 | |||
133 | /* Define the list of additional controls we'll dynamically construct based | ||
134 | on query of the cx2341x module. */ | ||
135 | struct pvr2_mpeg_ids { | ||
136 | const char *strid; | ||
137 | int id; | ||
138 | }; | ||
139 | static const struct pvr2_mpeg_ids mpeg_ids[] = { | ||
140 | { | ||
141 | .strid = "audio_layer", | ||
142 | .id = V4L2_CID_MPEG_AUDIO_ENCODING, | ||
143 | },{ | ||
144 | .strid = "audio_bitrate", | ||
145 | .id = V4L2_CID_MPEG_AUDIO_L2_BITRATE, | ||
146 | },{ | ||
147 | /* Already using audio_mode elsewhere :-( */ | ||
148 | .strid = "mpeg_audio_mode", | ||
149 | .id = V4L2_CID_MPEG_AUDIO_MODE, | ||
150 | },{ | ||
151 | .strid = "mpeg_audio_mode_extension", | ||
152 | .id = V4L2_CID_MPEG_AUDIO_MODE_EXTENSION, | ||
153 | },{ | ||
154 | .strid = "audio_emphasis", | ||
155 | .id = V4L2_CID_MPEG_AUDIO_EMPHASIS, | ||
156 | },{ | ||
157 | .strid = "audio_crc", | ||
158 | .id = V4L2_CID_MPEG_AUDIO_CRC, | ||
159 | },{ | ||
160 | .strid = "video_aspect", | ||
161 | .id = V4L2_CID_MPEG_VIDEO_ASPECT, | ||
162 | },{ | ||
163 | .strid = "video_b_frames", | ||
164 | .id = V4L2_CID_MPEG_VIDEO_B_FRAMES, | ||
165 | },{ | ||
166 | .strid = "video_gop_size", | ||
167 | .id = V4L2_CID_MPEG_VIDEO_GOP_SIZE, | ||
168 | },{ | ||
169 | .strid = "video_gop_closure", | ||
170 | .id = V4L2_CID_MPEG_VIDEO_GOP_CLOSURE, | ||
171 | },{ | ||
172 | .strid = "video_pulldown", | ||
173 | .id = V4L2_CID_MPEG_VIDEO_PULLDOWN, | ||
174 | },{ | ||
175 | .strid = "video_bitrate_mode", | ||
176 | .id = V4L2_CID_MPEG_VIDEO_BITRATE_MODE, | ||
177 | },{ | ||
178 | .strid = "video_bitrate", | ||
179 | .id = V4L2_CID_MPEG_VIDEO_BITRATE, | ||
180 | },{ | ||
181 | .strid = "video_bitrate_peak", | ||
182 | .id = V4L2_CID_MPEG_VIDEO_BITRATE_PEAK, | ||
183 | },{ | ||
184 | .strid = "video_temporal_decimation", | ||
185 | .id = V4L2_CID_MPEG_VIDEO_TEMPORAL_DECIMATION, | ||
186 | },{ | ||
187 | .strid = "stream_type", | ||
188 | .id = V4L2_CID_MPEG_STREAM_TYPE, | ||
189 | },{ | ||
190 | .strid = "video_spatial_filter_mode", | ||
191 | .id = V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE, | ||
192 | },{ | ||
193 | .strid = "video_spatial_filter", | ||
194 | .id = V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER, | ||
195 | },{ | ||
196 | .strid = "video_luma_spatial_filter_type", | ||
197 | .id = V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE, | ||
198 | },{ | ||
199 | .strid = "video_chroma_spatial_filter_type", | ||
200 | .id = V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE, | ||
201 | },{ | ||
202 | .strid = "video_temporal_filter_mode", | ||
203 | .id = V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE, | ||
204 | },{ | ||
205 | .strid = "video_temporal_filter", | ||
206 | .id = V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER, | ||
207 | },{ | ||
208 | .strid = "video_median_filter_type", | ||
209 | .id = V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE, | ||
210 | },{ | ||
211 | .strid = "video_luma_median_filter_top", | ||
212 | .id = V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_TOP, | ||
213 | },{ | ||
214 | .strid = "video_luma_median_filter_bottom", | ||
215 | .id = V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_BOTTOM, | ||
216 | },{ | ||
217 | .strid = "video_chroma_median_filter_top", | ||
218 | .id = V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_TOP, | ||
219 | },{ | ||
220 | .strid = "video_chroma_median_filter_bottom", | ||
221 | .id = V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_BOTTOM, | ||
222 | } | ||
223 | }; | ||
224 | #define MPEGDEF_COUNT (sizeof(mpeg_ids)/sizeof(mpeg_ids[0])) | ||
225 | |||
226 | static const char *control_values_srate[] = { | ||
227 | [PVR2_CVAL_SRATE_48] = "48KHz", | ||
228 | [PVR2_CVAL_SRATE_44_1] = "44.1KHz", | ||
229 | }; | ||
230 | |||
231 | |||
232 | |||
233 | |||
234 | static const char *control_values_input[] = { | ||
235 | [PVR2_CVAL_INPUT_TV] = "television", /*xawtv needs this name*/ | ||
236 | [PVR2_CVAL_INPUT_RADIO] = "radio", | ||
237 | [PVR2_CVAL_INPUT_SVIDEO] = "s-video", | ||
238 | [PVR2_CVAL_INPUT_COMPOSITE] = "composite", | ||
239 | }; | ||
240 | |||
241 | |||
242 | static const char *control_values_audiomode[] = { | ||
243 | [V4L2_TUNER_MODE_MONO] = "Mono", | ||
244 | [V4L2_TUNER_MODE_STEREO] = "Stereo", | ||
245 | [V4L2_TUNER_MODE_LANG1] = "Lang1", | ||
246 | [V4L2_TUNER_MODE_LANG2] = "Lang2", | ||
247 | [V4L2_TUNER_MODE_LANG1_LANG2] = "Lang1+Lang2", | ||
248 | }; | ||
249 | |||
250 | |||
251 | static const char *control_values_hsm[] = { | ||
252 | [PVR2_CVAL_HSM_FAIL] = "Fail", | ||
253 | [PVR2_CVAL_HSM_HIGH] = "High", | ||
254 | [PVR2_CVAL_HSM_FULL] = "Full", | ||
255 | }; | ||
256 | |||
257 | |||
258 | static const char *control_values_subsystem[] = { | ||
259 | [PVR2_SUBSYS_B_ENC_FIRMWARE] = "enc_firmware", | ||
260 | [PVR2_SUBSYS_B_ENC_CFG] = "enc_config", | ||
261 | [PVR2_SUBSYS_B_DIGITIZER_RUN] = "digitizer_run", | ||
262 | [PVR2_SUBSYS_B_USBSTREAM_RUN] = "usbstream_run", | ||
263 | [PVR2_SUBSYS_B_ENC_RUN] = "enc_run", | ||
264 | }; | ||
265 | |||
266 | |||
267 | static int ctrl_channelfreq_get(struct pvr2_ctrl *cptr,int *vp) | ||
268 | { | ||
269 | struct pvr2_hdw *hdw = cptr->hdw; | ||
270 | if ((hdw->freqProgSlot > 0) && (hdw->freqProgSlot <= FREQTABLE_SIZE)) { | ||
271 | *vp = hdw->freqTable[hdw->freqProgSlot-1]; | ||
272 | } else { | ||
273 | *vp = 0; | ||
274 | } | ||
275 | return 0; | ||
276 | } | ||
277 | |||
278 | static int ctrl_channelfreq_set(struct pvr2_ctrl *cptr,int m,int v) | ||
279 | { | ||
280 | struct pvr2_hdw *hdw = cptr->hdw; | ||
281 | if ((hdw->freqProgSlot > 0) && (hdw->freqProgSlot <= FREQTABLE_SIZE)) { | ||
282 | hdw->freqTable[hdw->freqProgSlot-1] = v; | ||
283 | } | ||
284 | return 0; | ||
285 | } | ||
286 | |||
287 | static int ctrl_channelprog_get(struct pvr2_ctrl *cptr,int *vp) | ||
288 | { | ||
289 | *vp = cptr->hdw->freqProgSlot; | ||
290 | return 0; | ||
291 | } | ||
292 | |||
293 | static int ctrl_channelprog_set(struct pvr2_ctrl *cptr,int m,int v) | ||
294 | { | ||
295 | struct pvr2_hdw *hdw = cptr->hdw; | ||
296 | if ((v >= 0) && (v <= FREQTABLE_SIZE)) { | ||
297 | hdw->freqProgSlot = v; | ||
298 | } | ||
299 | return 0; | ||
300 | } | ||
301 | |||
302 | static int ctrl_channel_get(struct pvr2_ctrl *cptr,int *vp) | ||
303 | { | ||
304 | *vp = cptr->hdw->freqSlot; | ||
305 | return 0; | ||
306 | } | ||
307 | |||
308 | static int ctrl_channel_set(struct pvr2_ctrl *cptr,int m,int v) | ||
309 | { | ||
310 | unsigned freq = 0; | ||
311 | struct pvr2_hdw *hdw = cptr->hdw; | ||
312 | hdw->freqSlot = v; | ||
313 | if ((hdw->freqSlot > 0) && (hdw->freqSlot <= FREQTABLE_SIZE)) { | ||
314 | freq = hdw->freqTable[hdw->freqSlot-1]; | ||
315 | } | ||
316 | if (freq && (freq != hdw->freqVal)) { | ||
317 | hdw->freqVal = freq; | ||
318 | hdw->freqDirty = !0; | ||
319 | } | ||
320 | return 0; | ||
321 | } | ||
322 | |||
323 | static int ctrl_freq_get(struct pvr2_ctrl *cptr,int *vp) | ||
324 | { | ||
325 | *vp = cptr->hdw->freqVal; | ||
326 | return 0; | ||
327 | } | ||
328 | |||
329 | static int ctrl_freq_is_dirty(struct pvr2_ctrl *cptr) | ||
330 | { | ||
331 | return cptr->hdw->freqDirty != 0; | ||
332 | } | ||
333 | |||
334 | static void ctrl_freq_clear_dirty(struct pvr2_ctrl *cptr) | ||
335 | { | ||
336 | cptr->hdw->freqDirty = 0; | ||
337 | } | ||
338 | |||
339 | static int ctrl_freq_set(struct pvr2_ctrl *cptr,int m,int v) | ||
340 | { | ||
341 | struct pvr2_hdw *hdw = cptr->hdw; | ||
342 | hdw->freqVal = v; | ||
343 | hdw->freqDirty = !0; | ||
344 | hdw->freqSlot = 0; | ||
345 | return 0; | ||
346 | } | ||
347 | |||
348 | static int ctrl_cx2341x_is_dirty(struct pvr2_ctrl *cptr) | ||
349 | { | ||
350 | return cptr->hdw->enc_stale != 0; | ||
351 | } | ||
352 | |||
353 | static void ctrl_cx2341x_clear_dirty(struct pvr2_ctrl *cptr) | ||
354 | { | ||
355 | cptr->hdw->enc_stale = 0; | ||
356 | } | ||
357 | |||
358 | static int ctrl_cx2341x_get(struct pvr2_ctrl *cptr,int *vp) | ||
359 | { | ||
360 | int ret; | ||
361 | struct v4l2_ext_controls cs; | ||
362 | struct v4l2_ext_control c1; | ||
363 | memset(&cs,0,sizeof(cs)); | ||
364 | memset(&c1,0,sizeof(c1)); | ||
365 | cs.controls = &c1; | ||
366 | cs.count = 1; | ||
367 | c1.id = cptr->info->v4l_id; | ||
368 | ret = cx2341x_ext_ctrls(&cptr->hdw->enc_ctl_state,&cs, | ||
369 | VIDIOC_G_EXT_CTRLS); | ||
370 | if (ret) return ret; | ||
371 | *vp = c1.value; | ||
372 | return 0; | ||
373 | } | ||
374 | |||
375 | static int ctrl_cx2341x_set(struct pvr2_ctrl *cptr,int m,int v) | ||
376 | { | ||
377 | int ret; | ||
378 | struct v4l2_ext_controls cs; | ||
379 | struct v4l2_ext_control c1; | ||
380 | memset(&cs,0,sizeof(cs)); | ||
381 | memset(&c1,0,sizeof(c1)); | ||
382 | cs.controls = &c1; | ||
383 | cs.count = 1; | ||
384 | c1.id = cptr->info->v4l_id; | ||
385 | c1.value = v; | ||
386 | ret = cx2341x_ext_ctrls(&cptr->hdw->enc_ctl_state,&cs, | ||
387 | VIDIOC_S_EXT_CTRLS); | ||
388 | if (ret) return ret; | ||
389 | cptr->hdw->enc_stale = !0; | ||
390 | return 0; | ||
391 | } | ||
392 | |||
393 | static unsigned int ctrl_cx2341x_getv4lflags(struct pvr2_ctrl *cptr) | ||
394 | { | ||
395 | struct v4l2_queryctrl qctrl; | ||
396 | struct pvr2_ctl_info *info; | ||
397 | qctrl.id = cptr->info->v4l_id; | ||
398 | cx2341x_ctrl_query(&cptr->hdw->enc_ctl_state,&qctrl); | ||
399 | /* Strip out the const so we can adjust a function pointer. It's | ||
400 | OK to do this here because we know this is a dynamically created | ||
401 | control, so the underlying storage for the info pointer is (a) | ||
402 | private to us, and (b) not in read-only storage. Either we do | ||
403 | this or we significantly complicate the underlying control | ||
404 | implementation. */ | ||
405 | info = (struct pvr2_ctl_info *)(cptr->info); | ||
406 | if (qctrl.flags & V4L2_CTRL_FLAG_READ_ONLY) { | ||
407 | if (info->set_value) { | ||
408 | info->set_value = 0; | ||
409 | } | ||
410 | } else { | ||
411 | if (!(info->set_value)) { | ||
412 | info->set_value = ctrl_cx2341x_set; | ||
413 | } | ||
414 | } | ||
415 | return qctrl.flags; | ||
416 | } | ||
417 | |||
418 | static int ctrl_streamingenabled_get(struct pvr2_ctrl *cptr,int *vp) | ||
419 | { | ||
420 | *vp = cptr->hdw->flag_streaming_enabled; | ||
421 | return 0; | ||
422 | } | ||
423 | |||
424 | static int ctrl_hsm_get(struct pvr2_ctrl *cptr,int *vp) | ||
425 | { | ||
426 | int result = pvr2_hdw_is_hsm(cptr->hdw); | ||
427 | *vp = PVR2_CVAL_HSM_FULL; | ||
428 | if (result < 0) *vp = PVR2_CVAL_HSM_FAIL; | ||
429 | if (result) *vp = PVR2_CVAL_HSM_HIGH; | ||
430 | return 0; | ||
431 | } | ||
432 | |||
433 | static int ctrl_stdavail_get(struct pvr2_ctrl *cptr,int *vp) | ||
434 | { | ||
435 | *vp = cptr->hdw->std_mask_avail; | ||
436 | return 0; | ||
437 | } | ||
438 | |||
439 | static int ctrl_stdavail_set(struct pvr2_ctrl *cptr,int m,int v) | ||
440 | { | ||
441 | struct pvr2_hdw *hdw = cptr->hdw; | ||
442 | v4l2_std_id ns; | ||
443 | ns = hdw->std_mask_avail; | ||
444 | ns = (ns & ~m) | (v & m); | ||
445 | if (ns == hdw->std_mask_avail) return 0; | ||
446 | hdw->std_mask_avail = ns; | ||
447 | pvr2_hdw_internal_set_std_avail(hdw); | ||
448 | pvr2_hdw_internal_find_stdenum(hdw); | ||
449 | return 0; | ||
450 | } | ||
451 | |||
452 | static int ctrl_std_val_to_sym(struct pvr2_ctrl *cptr,int msk,int val, | ||
453 | char *bufPtr,unsigned int bufSize, | ||
454 | unsigned int *len) | ||
455 | { | ||
456 | *len = pvr2_std_id_to_str(bufPtr,bufSize,msk & val); | ||
457 | return 0; | ||
458 | } | ||
459 | |||
460 | static int ctrl_std_sym_to_val(struct pvr2_ctrl *cptr, | ||
461 | const char *bufPtr,unsigned int bufSize, | ||
462 | int *mskp,int *valp) | ||
463 | { | ||
464 | int ret; | ||
465 | v4l2_std_id id; | ||
466 | ret = pvr2_std_str_to_id(&id,bufPtr,bufSize); | ||
467 | if (ret < 0) return ret; | ||
468 | if (mskp) *mskp = id; | ||
469 | if (valp) *valp = id; | ||
470 | return 0; | ||
471 | } | ||
472 | |||
473 | static int ctrl_stdcur_get(struct pvr2_ctrl *cptr,int *vp) | ||
474 | { | ||
475 | *vp = cptr->hdw->std_mask_cur; | ||
476 | return 0; | ||
477 | } | ||
478 | |||
479 | static int ctrl_stdcur_set(struct pvr2_ctrl *cptr,int m,int v) | ||
480 | { | ||
481 | struct pvr2_hdw *hdw = cptr->hdw; | ||
482 | v4l2_std_id ns; | ||
483 | ns = hdw->std_mask_cur; | ||
484 | ns = (ns & ~m) | (v & m); | ||
485 | if (ns == hdw->std_mask_cur) return 0; | ||
486 | hdw->std_mask_cur = ns; | ||
487 | hdw->std_dirty = !0; | ||
488 | pvr2_hdw_internal_find_stdenum(hdw); | ||
489 | return 0; | ||
490 | } | ||
491 | |||
492 | static int ctrl_stdcur_is_dirty(struct pvr2_ctrl *cptr) | ||
493 | { | ||
494 | return cptr->hdw->std_dirty != 0; | ||
495 | } | ||
496 | |||
497 | static void ctrl_stdcur_clear_dirty(struct pvr2_ctrl *cptr) | ||
498 | { | ||
499 | cptr->hdw->std_dirty = 0; | ||
500 | } | ||
501 | |||
502 | static int ctrl_signal_get(struct pvr2_ctrl *cptr,int *vp) | ||
503 | { | ||
504 | *vp = ((pvr2_hdw_get_signal_status_internal(cptr->hdw) & | ||
505 | PVR2_SIGNAL_OK) ? 1 : 0); | ||
506 | return 0; | ||
507 | } | ||
508 | |||
509 | static int ctrl_subsys_get(struct pvr2_ctrl *cptr,int *vp) | ||
510 | { | ||
511 | *vp = cptr->hdw->subsys_enabled_mask; | ||
512 | return 0; | ||
513 | } | ||
514 | |||
515 | static int ctrl_subsys_set(struct pvr2_ctrl *cptr,int m,int v) | ||
516 | { | ||
517 | pvr2_hdw_subsys_bit_chg_no_lock(cptr->hdw,m,v); | ||
518 | return 0; | ||
519 | } | ||
520 | |||
521 | static int ctrl_subsys_stream_get(struct pvr2_ctrl *cptr,int *vp) | ||
522 | { | ||
523 | *vp = cptr->hdw->subsys_stream_mask; | ||
524 | return 0; | ||
525 | } | ||
526 | |||
527 | static int ctrl_subsys_stream_set(struct pvr2_ctrl *cptr,int m,int v) | ||
528 | { | ||
529 | pvr2_hdw_subsys_stream_bit_chg_no_lock(cptr->hdw,m,v); | ||
530 | return 0; | ||
531 | } | ||
532 | |||
533 | static int ctrl_stdenumcur_set(struct pvr2_ctrl *cptr,int m,int v) | ||
534 | { | ||
535 | struct pvr2_hdw *hdw = cptr->hdw; | ||
536 | if (v < 0) return -EINVAL; | ||
537 | if (v > hdw->std_enum_cnt) return -EINVAL; | ||
538 | hdw->std_enum_cur = v; | ||
539 | if (!v) return 0; | ||
540 | v--; | ||
541 | if (hdw->std_mask_cur == hdw->std_defs[v].id) return 0; | ||
542 | hdw->std_mask_cur = hdw->std_defs[v].id; | ||
543 | hdw->std_dirty = !0; | ||
544 | return 0; | ||
545 | } | ||
546 | |||
547 | |||
548 | static int ctrl_stdenumcur_get(struct pvr2_ctrl *cptr,int *vp) | ||
549 | { | ||
550 | *vp = cptr->hdw->std_enum_cur; | ||
551 | return 0; | ||
552 | } | ||
553 | |||
554 | |||
555 | static int ctrl_stdenumcur_is_dirty(struct pvr2_ctrl *cptr) | ||
556 | { | ||
557 | return cptr->hdw->std_dirty != 0; | ||
558 | } | ||
559 | |||
560 | |||
561 | static void ctrl_stdenumcur_clear_dirty(struct pvr2_ctrl *cptr) | ||
562 | { | ||
563 | cptr->hdw->std_dirty = 0; | ||
564 | } | ||
565 | |||
566 | |||
567 | #define DEFINT(vmin,vmax) \ | ||
568 | .type = pvr2_ctl_int, \ | ||
569 | .def.type_int.min_value = vmin, \ | ||
570 | .def.type_int.max_value = vmax | ||
571 | |||
572 | #define DEFENUM(tab) \ | ||
573 | .type = pvr2_ctl_enum, \ | ||
574 | .def.type_enum.count = (sizeof(tab)/sizeof((tab)[0])), \ | ||
575 | .def.type_enum.value_names = tab | ||
576 | |||
577 | #define DEFBOOL \ | ||
578 | .type = pvr2_ctl_bool | ||
579 | |||
580 | #define DEFMASK(msk,tab) \ | ||
581 | .type = pvr2_ctl_bitmask, \ | ||
582 | .def.type_bitmask.valid_bits = msk, \ | ||
583 | .def.type_bitmask.bit_names = tab | ||
584 | |||
585 | #define DEFREF(vname) \ | ||
586 | .set_value = ctrl_set_##vname, \ | ||
587 | .get_value = ctrl_get_##vname, \ | ||
588 | .is_dirty = ctrl_isdirty_##vname, \ | ||
589 | .clear_dirty = ctrl_cleardirty_##vname | ||
590 | |||
591 | |||
592 | #define VCREATE_FUNCS(vname) \ | ||
593 | static int ctrl_get_##vname(struct pvr2_ctrl *cptr,int *vp) \ | ||
594 | {*vp = cptr->hdw->vname##_val; return 0;} \ | ||
595 | static int ctrl_set_##vname(struct pvr2_ctrl *cptr,int m,int v) \ | ||
596 | {cptr->hdw->vname##_val = v; cptr->hdw->vname##_dirty = !0; return 0;} \ | ||
597 | static int ctrl_isdirty_##vname(struct pvr2_ctrl *cptr) \ | ||
598 | {return cptr->hdw->vname##_dirty != 0;} \ | ||
599 | static void ctrl_cleardirty_##vname(struct pvr2_ctrl *cptr) \ | ||
600 | {cptr->hdw->vname##_dirty = 0;} | ||
601 | |||
602 | VCREATE_FUNCS(brightness) | ||
603 | VCREATE_FUNCS(contrast) | ||
604 | VCREATE_FUNCS(saturation) | ||
605 | VCREATE_FUNCS(hue) | ||
606 | VCREATE_FUNCS(volume) | ||
607 | VCREATE_FUNCS(balance) | ||
608 | VCREATE_FUNCS(bass) | ||
609 | VCREATE_FUNCS(treble) | ||
610 | VCREATE_FUNCS(mute) | ||
611 | VCREATE_FUNCS(input) | ||
612 | VCREATE_FUNCS(audiomode) | ||
613 | VCREATE_FUNCS(res_hor) | ||
614 | VCREATE_FUNCS(res_ver) | ||
615 | VCREATE_FUNCS(srate) | ||
616 | |||
617 | #define MIN_FREQ 55250000L | ||
618 | #define MAX_FREQ 850000000L | ||
619 | |||
620 | /* Table definition of all controls which can be manipulated */ | ||
621 | static const struct pvr2_ctl_info control_defs[] = { | ||
622 | { | ||
623 | .v4l_id = V4L2_CID_BRIGHTNESS, | ||
624 | .desc = "Brightness", | ||
625 | .name = "brightness", | ||
626 | .default_value = 128, | ||
627 | DEFREF(brightness), | ||
628 | DEFINT(0,255), | ||
629 | },{ | ||
630 | .v4l_id = V4L2_CID_CONTRAST, | ||
631 | .desc = "Contrast", | ||
632 | .name = "contrast", | ||
633 | .default_value = 68, | ||
634 | DEFREF(contrast), | ||
635 | DEFINT(0,127), | ||
636 | },{ | ||
637 | .v4l_id = V4L2_CID_SATURATION, | ||
638 | .desc = "Saturation", | ||
639 | .name = "saturation", | ||
640 | .default_value = 64, | ||
641 | DEFREF(saturation), | ||
642 | DEFINT(0,127), | ||
643 | },{ | ||
644 | .v4l_id = V4L2_CID_HUE, | ||
645 | .desc = "Hue", | ||
646 | .name = "hue", | ||
647 | .default_value = 0, | ||
648 | DEFREF(hue), | ||
649 | DEFINT(-128,127), | ||
650 | },{ | ||
651 | .v4l_id = V4L2_CID_AUDIO_VOLUME, | ||
652 | .desc = "Volume", | ||
653 | .name = "volume", | ||
654 | .default_value = 65535, | ||
655 | DEFREF(volume), | ||
656 | DEFINT(0,65535), | ||
657 | },{ | ||
658 | .v4l_id = V4L2_CID_AUDIO_BALANCE, | ||
659 | .desc = "Balance", | ||
660 | .name = "balance", | ||
661 | .default_value = 0, | ||
662 | DEFREF(balance), | ||
663 | DEFINT(-32768,32767), | ||
664 | },{ | ||
665 | .v4l_id = V4L2_CID_AUDIO_BASS, | ||
666 | .desc = "Bass", | ||
667 | .name = "bass", | ||
668 | .default_value = 0, | ||
669 | DEFREF(bass), | ||
670 | DEFINT(-32768,32767), | ||
671 | },{ | ||
672 | .v4l_id = V4L2_CID_AUDIO_TREBLE, | ||
673 | .desc = "Treble", | ||
674 | .name = "treble", | ||
675 | .default_value = 0, | ||
676 | DEFREF(treble), | ||
677 | DEFINT(-32768,32767), | ||
678 | },{ | ||
679 | .v4l_id = V4L2_CID_AUDIO_MUTE, | ||
680 | .desc = "Mute", | ||
681 | .name = "mute", | ||
682 | .default_value = 0, | ||
683 | DEFREF(mute), | ||
684 | DEFBOOL, | ||
685 | },{ | ||
686 | .desc = "Video Source", | ||
687 | .name = "input", | ||
688 | .internal_id = PVR2_CID_INPUT, | ||
689 | .default_value = PVR2_CVAL_INPUT_TV, | ||
690 | DEFREF(input), | ||
691 | DEFENUM(control_values_input), | ||
692 | },{ | ||
693 | .desc = "Audio Mode", | ||
694 | .name = "audio_mode", | ||
695 | .internal_id = PVR2_CID_AUDIOMODE, | ||
696 | .default_value = V4L2_TUNER_MODE_STEREO, | ||
697 | DEFREF(audiomode), | ||
698 | DEFENUM(control_values_audiomode), | ||
699 | },{ | ||
700 | .desc = "Horizontal capture resolution", | ||
701 | .name = "resolution_hor", | ||
702 | .internal_id = PVR2_CID_HRES, | ||
703 | .default_value = 720, | ||
704 | DEFREF(res_hor), | ||
705 | DEFINT(320,720), | ||
706 | },{ | ||
707 | .desc = "Vertical capture resolution", | ||
708 | .name = "resolution_ver", | ||
709 | .internal_id = PVR2_CID_VRES, | ||
710 | .default_value = 480, | ||
711 | DEFREF(res_ver), | ||
712 | DEFINT(200,625), | ||
713 | },{ | ||
714 | .v4l_id = V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ, | ||
715 | .desc = "Sample rate", | ||
716 | .name = "srate", | ||
717 | .default_value = PVR2_CVAL_SRATE_48, | ||
718 | DEFREF(srate), | ||
719 | DEFENUM(control_values_srate), | ||
720 | },{ | ||
721 | .desc = "Tuner Frequency (Hz)", | ||
722 | .name = "frequency", | ||
723 | .internal_id = PVR2_CID_FREQUENCY, | ||
724 | .default_value = 175250000L, | ||
725 | .set_value = ctrl_freq_set, | ||
726 | .get_value = ctrl_freq_get, | ||
727 | .is_dirty = ctrl_freq_is_dirty, | ||
728 | .clear_dirty = ctrl_freq_clear_dirty, | ||
729 | DEFINT(MIN_FREQ,MAX_FREQ), | ||
730 | },{ | ||
731 | .desc = "Channel", | ||
732 | .name = "channel", | ||
733 | .set_value = ctrl_channel_set, | ||
734 | .get_value = ctrl_channel_get, | ||
735 | DEFINT(0,FREQTABLE_SIZE), | ||
736 | },{ | ||
737 | .desc = "Channel Program Frequency", | ||
738 | .name = "freq_table_value", | ||
739 | .set_value = ctrl_channelfreq_set, | ||
740 | .get_value = ctrl_channelfreq_get, | ||
741 | DEFINT(MIN_FREQ,MAX_FREQ), | ||
742 | },{ | ||
743 | .desc = "Channel Program ID", | ||
744 | .name = "freq_table_channel", | ||
745 | .set_value = ctrl_channelprog_set, | ||
746 | .get_value = ctrl_channelprog_get, | ||
747 | DEFINT(0,FREQTABLE_SIZE), | ||
748 | },{ | ||
749 | .desc = "Streaming Enabled", | ||
750 | .name = "streaming_enabled", | ||
751 | .get_value = ctrl_streamingenabled_get, | ||
752 | DEFBOOL, | ||
753 | },{ | ||
754 | .desc = "USB Speed", | ||
755 | .name = "usb_speed", | ||
756 | .get_value = ctrl_hsm_get, | ||
757 | DEFENUM(control_values_hsm), | ||
758 | },{ | ||
759 | .desc = "Signal Present", | ||
760 | .name = "signal_present", | ||
761 | .get_value = ctrl_signal_get, | ||
762 | DEFBOOL, | ||
763 | },{ | ||
764 | .desc = "Video Standards Available Mask", | ||
765 | .name = "video_standard_mask_available", | ||
766 | .internal_id = PVR2_CID_STDAVAIL, | ||
767 | .skip_init = !0, | ||
768 | .get_value = ctrl_stdavail_get, | ||
769 | .set_value = ctrl_stdavail_set, | ||
770 | .val_to_sym = ctrl_std_val_to_sym, | ||
771 | .sym_to_val = ctrl_std_sym_to_val, | ||
772 | .type = pvr2_ctl_bitmask, | ||
773 | },{ | ||
774 | .desc = "Video Standards In Use Mask", | ||
775 | .name = "video_standard_mask_active", | ||
776 | .internal_id = PVR2_CID_STDCUR, | ||
777 | .skip_init = !0, | ||
778 | .get_value = ctrl_stdcur_get, | ||
779 | .set_value = ctrl_stdcur_set, | ||
780 | .is_dirty = ctrl_stdcur_is_dirty, | ||
781 | .clear_dirty = ctrl_stdcur_clear_dirty, | ||
782 | .val_to_sym = ctrl_std_val_to_sym, | ||
783 | .sym_to_val = ctrl_std_sym_to_val, | ||
784 | .type = pvr2_ctl_bitmask, | ||
785 | },{ | ||
786 | .desc = "Subsystem enabled mask", | ||
787 | .name = "debug_subsys_mask", | ||
788 | .skip_init = !0, | ||
789 | .get_value = ctrl_subsys_get, | ||
790 | .set_value = ctrl_subsys_set, | ||
791 | DEFMASK(PVR2_SUBSYS_ALL,control_values_subsystem), | ||
792 | },{ | ||
793 | .desc = "Subsystem stream mask", | ||
794 | .name = "debug_subsys_stream_mask", | ||
795 | .skip_init = !0, | ||
796 | .get_value = ctrl_subsys_stream_get, | ||
797 | .set_value = ctrl_subsys_stream_set, | ||
798 | DEFMASK(PVR2_SUBSYS_ALL,control_values_subsystem), | ||
799 | },{ | ||
800 | .desc = "Video Standard Name", | ||
801 | .name = "video_standard", | ||
802 | .internal_id = PVR2_CID_STDENUM, | ||
803 | .skip_init = !0, | ||
804 | .get_value = ctrl_stdenumcur_get, | ||
805 | .set_value = ctrl_stdenumcur_set, | ||
806 | .is_dirty = ctrl_stdenumcur_is_dirty, | ||
807 | .clear_dirty = ctrl_stdenumcur_clear_dirty, | ||
808 | .type = pvr2_ctl_enum, | ||
809 | } | ||
810 | }; | ||
811 | |||
812 | #define CTRLDEF_COUNT (sizeof(control_defs)/sizeof(control_defs[0])) | ||
813 | |||
814 | |||
815 | const char *pvr2_config_get_name(enum pvr2_config cfg) | ||
816 | { | ||
817 | switch (cfg) { | ||
818 | case pvr2_config_empty: return "empty"; | ||
819 | case pvr2_config_mpeg: return "mpeg"; | ||
820 | case pvr2_config_vbi: return "vbi"; | ||
821 | case pvr2_config_radio: return "radio"; | ||
822 | } | ||
823 | return "<unknown>"; | ||
824 | } | ||
825 | |||
826 | |||
827 | struct usb_device *pvr2_hdw_get_dev(struct pvr2_hdw *hdw) | ||
828 | { | ||
829 | return hdw->usb_dev; | ||
830 | } | ||
831 | |||
832 | |||
833 | unsigned long pvr2_hdw_get_sn(struct pvr2_hdw *hdw) | ||
834 | { | ||
835 | return hdw->serial_number; | ||
836 | } | ||
837 | |||
838 | |||
839 | struct pvr2_hdw *pvr2_hdw_find(int unit_number) | ||
840 | { | ||
841 | if (unit_number < 0) return 0; | ||
842 | if (unit_number >= PVR_NUM) return 0; | ||
843 | return unit_pointers[unit_number]; | ||
844 | } | ||
845 | |||
846 | |||
847 | int pvr2_hdw_get_unit_number(struct pvr2_hdw *hdw) | ||
848 | { | ||
849 | return hdw->unit_number; | ||
850 | } | ||
851 | |||
852 | |||
853 | /* Attempt to locate one of the given set of files. Messages are logged | ||
854 | appropriate to what has been found. The return value will be 0 or | ||
855 | greater on success (it will be the index of the file name found) and | ||
856 | fw_entry will be filled in. Otherwise a negative error is returned on | ||
857 | failure. If the return value is -ENOENT then no viable firmware file | ||
858 | could be located. */ | ||
859 | static int pvr2_locate_firmware(struct pvr2_hdw *hdw, | ||
860 | const struct firmware **fw_entry, | ||
861 | const char *fwtypename, | ||
862 | unsigned int fwcount, | ||
863 | const char *fwnames[]) | ||
864 | { | ||
865 | unsigned int idx; | ||
866 | int ret = -EINVAL; | ||
867 | for (idx = 0; idx < fwcount; idx++) { | ||
868 | ret = request_firmware(fw_entry, | ||
869 | fwnames[idx], | ||
870 | &hdw->usb_dev->dev); | ||
871 | if (!ret) { | ||
872 | trace_firmware("Located %s firmware: %s;" | ||
873 | " uploading...", | ||
874 | fwtypename, | ||
875 | fwnames[idx]); | ||
876 | return idx; | ||
877 | } | ||
878 | if (ret == -ENOENT) continue; | ||
879 | pvr2_trace(PVR2_TRACE_ERROR_LEGS, | ||
880 | "request_firmware fatal error with code=%d",ret); | ||
881 | return ret; | ||
882 | } | ||
883 | pvr2_trace(PVR2_TRACE_ERROR_LEGS, | ||
884 | "***WARNING***" | ||
885 | " Device %s firmware" | ||
886 | " seems to be missing.", | ||
887 | fwtypename); | ||
888 | pvr2_trace(PVR2_TRACE_ERROR_LEGS, | ||
889 | "Did you install the pvrusb2 firmware files" | ||
890 | " in their proper location?"); | ||
891 | if (fwcount == 1) { | ||
892 | pvr2_trace(PVR2_TRACE_ERROR_LEGS, | ||
893 | "request_firmware unable to locate %s file %s", | ||
894 | fwtypename,fwnames[0]); | ||
895 | } else { | ||
896 | pvr2_trace(PVR2_TRACE_ERROR_LEGS, | ||
897 | "request_firmware unable to locate" | ||
898 | " one of the following %s files:", | ||
899 | fwtypename); | ||
900 | for (idx = 0; idx < fwcount; idx++) { | ||
901 | pvr2_trace(PVR2_TRACE_ERROR_LEGS, | ||
902 | "request_firmware: Failed to find %s", | ||
903 | fwnames[idx]); | ||
904 | } | ||
905 | } | ||
906 | return ret; | ||
907 | } | ||
908 | |||
909 | |||
910 | /* | ||
911 | * pvr2_upload_firmware1(). | ||
912 | * | ||
913 | * Send the 8051 firmware to the device. After the upload, arrange for | ||
914 | * device to re-enumerate. | ||
915 | * | ||
916 | * NOTE : the pointer to the firmware data given by request_firmware() | ||
917 | * is not suitable for an usb transaction. | ||
918 | * | ||
919 | */ | ||
920 | int pvr2_upload_firmware1(struct pvr2_hdw *hdw) | ||
921 | { | ||
922 | const struct firmware *fw_entry = 0; | ||
923 | void *fw_ptr; | ||
924 | unsigned int pipe; | ||
925 | int ret; | ||
926 | u16 address; | ||
927 | static const char *fw_files_29xxx[] = { | ||
928 | "v4l-pvrusb2-29xxx-01.fw", | ||
929 | }; | ||
930 | #ifdef CONFIG_VIDEO_PVRUSB2_24XXX | ||
931 | static const char *fw_files_24xxx[] = { | ||
932 | "v4l-pvrusb2-24xxx-01.fw", | ||
933 | }; | ||
934 | #endif | ||
935 | static const struct pvr2_string_table fw_file_defs[] = { | ||
936 | [PVR2_HDW_TYPE_29XXX] = { | ||
937 | fw_files_29xxx, | ||
938 | sizeof(fw_files_29xxx)/sizeof(fw_files_29xxx[0]), | ||
939 | }, | ||
940 | #ifdef CONFIG_VIDEO_PVRUSB2_24XXX | ||
941 | [PVR2_HDW_TYPE_24XXX] = { | ||
942 | fw_files_24xxx, | ||
943 | sizeof(fw_files_24xxx)/sizeof(fw_files_24xxx[0]), | ||
944 | }, | ||
945 | #endif | ||
946 | }; | ||
947 | hdw->fw1_state = FW1_STATE_FAILED; // default result | ||
948 | |||
949 | trace_firmware("pvr2_upload_firmware1"); | ||
950 | |||
951 | ret = pvr2_locate_firmware(hdw,&fw_entry,"fx2 controller", | ||
952 | fw_file_defs[hdw->hdw_type].cnt, | ||
953 | fw_file_defs[hdw->hdw_type].lst); | ||
954 | if (ret < 0) { | ||
955 | if (ret == -ENOENT) hdw->fw1_state = FW1_STATE_MISSING; | ||
956 | return ret; | ||
957 | } | ||
958 | |||
959 | usb_settoggle(hdw->usb_dev, 0 & 0xf, !(0 & USB_DIR_IN), 0); | ||
960 | usb_clear_halt(hdw->usb_dev, usb_sndbulkpipe(hdw->usb_dev, 0 & 0x7f)); | ||
961 | |||
962 | pipe = usb_sndctrlpipe(hdw->usb_dev, 0); | ||
963 | |||
964 | if (fw_entry->size != 0x2000){ | ||
965 | pvr2_trace(PVR2_TRACE_ERROR_LEGS,"wrong fx2 firmware size"); | ||
966 | release_firmware(fw_entry); | ||
967 | return -ENOMEM; | ||
968 | } | ||
969 | |||
970 | fw_ptr = kmalloc(0x800, GFP_KERNEL); | ||
971 | if (fw_ptr == NULL){ | ||
972 | release_firmware(fw_entry); | ||
973 | return -ENOMEM; | ||
974 | } | ||
975 | |||
976 | /* We have to hold the CPU during firmware upload. */ | ||
977 | pvr2_hdw_cpureset_assert(hdw,1); | ||
978 | |||
979 | /* upload the firmware to address 0000-1fff in 2048 (=0x800) bytes | ||
980 | chunk. */ | ||
981 | |||
982 | ret = 0; | ||
983 | for(address = 0; address < fw_entry->size; address += 0x800) { | ||
984 | memcpy(fw_ptr, fw_entry->data + address, 0x800); | ||
985 | ret += usb_control_msg(hdw->usb_dev, pipe, 0xa0, 0x40, address, | ||
986 | 0, fw_ptr, 0x800, HZ); | ||
987 | } | ||
988 | |||
989 | trace_firmware("Upload done, releasing device's CPU"); | ||
990 | |||
991 | /* Now release the CPU. It will disconnect and reconnect later. */ | ||
992 | pvr2_hdw_cpureset_assert(hdw,0); | ||
993 | |||
994 | kfree(fw_ptr); | ||
995 | release_firmware(fw_entry); | ||
996 | |||
997 | trace_firmware("Upload done (%d bytes sent)",ret); | ||
998 | |||
999 | /* We should have written 8192 bytes */ | ||
1000 | if (ret == 8192) { | ||
1001 | hdw->fw1_state = FW1_STATE_RELOAD; | ||
1002 | return 0; | ||
1003 | } | ||
1004 | |||
1005 | return -EIO; | ||
1006 | } | ||
1007 | |||
1008 | |||
1009 | /* | ||
1010 | * pvr2_upload_firmware2() | ||
1011 | * | ||
1012 | * This uploads encoder firmware on endpoint 2. | ||
1013 | * | ||
1014 | */ | ||
1015 | |||
1016 | int pvr2_upload_firmware2(struct pvr2_hdw *hdw) | ||
1017 | { | ||
1018 | const struct firmware *fw_entry = 0; | ||
1019 | void *fw_ptr; | ||
1020 | unsigned int pipe, fw_len, fw_done; | ||
1021 | int actual_length; | ||
1022 | int ret = 0; | ||
1023 | int fwidx; | ||
1024 | static const char *fw_files[] = { | ||
1025 | CX2341X_FIRM_ENC_FILENAME, | ||
1026 | }; | ||
1027 | |||
1028 | trace_firmware("pvr2_upload_firmware2"); | ||
1029 | |||
1030 | ret = pvr2_locate_firmware(hdw,&fw_entry,"encoder", | ||
1031 | sizeof(fw_files)/sizeof(fw_files[0]), | ||
1032 | fw_files); | ||
1033 | if (ret < 0) return ret; | ||
1034 | fwidx = ret; | ||
1035 | ret = 0; | ||
1036 | /* Since we're about to completely reinitialize the encoder, | ||
1037 | invalidate our cached copy of its configuration state. Next | ||
1038 | time we configure the encoder, then we'll fully configure it. */ | ||
1039 | hdw->enc_cur_valid = 0; | ||
1040 | |||
1041 | /* First prepare firmware loading */ | ||
1042 | ret |= pvr2_write_register(hdw, 0x0048, 0xffffffff); /*interrupt mask*/ | ||
1043 | ret |= pvr2_hdw_gpio_chg_dir(hdw,0xffffffff,0x00000088); /*gpio dir*/ | ||
1044 | ret |= pvr2_hdw_gpio_chg_out(hdw,0xffffffff,0x00000008); /*gpio output state*/ | ||
1045 | ret |= pvr2_hdw_cmd_deep_reset(hdw); | ||
1046 | ret |= pvr2_write_register(hdw, 0xa064, 0x00000000); /*APU command*/ | ||
1047 | ret |= pvr2_hdw_gpio_chg_dir(hdw,0xffffffff,0x00000408); /*gpio dir*/ | ||
1048 | ret |= pvr2_hdw_gpio_chg_out(hdw,0xffffffff,0x00000008); /*gpio output state*/ | ||
1049 | ret |= pvr2_write_register(hdw, 0x9058, 0xffffffed); /*VPU ctrl*/ | ||
1050 | ret |= pvr2_write_register(hdw, 0x9054, 0xfffffffd); /*reset hw blocks*/ | ||
1051 | ret |= pvr2_write_register(hdw, 0x07f8, 0x80000800); /*encoder SDRAM refresh*/ | ||
1052 | ret |= pvr2_write_register(hdw, 0x07fc, 0x0000001a); /*encoder SDRAM pre-charge*/ | ||
1053 | ret |= pvr2_write_register(hdw, 0x0700, 0x00000000); /*I2C clock*/ | ||
1054 | ret |= pvr2_write_register(hdw, 0xaa00, 0x00000000); /*unknown*/ | ||
1055 | ret |= pvr2_write_register(hdw, 0xaa04, 0x00057810); /*unknown*/ | ||
1056 | ret |= pvr2_write_register(hdw, 0xaa10, 0x00148500); /*unknown*/ | ||
1057 | ret |= pvr2_write_register(hdw, 0xaa18, 0x00840000); /*unknown*/ | ||
1058 | ret |= pvr2_write_u8(hdw, 0x52, 0); | ||
1059 | ret |= pvr2_write_u16(hdw, 0x0600, 0); | ||
1060 | |||
1061 | if (ret) { | ||
1062 | pvr2_trace(PVR2_TRACE_ERROR_LEGS, | ||
1063 | "firmware2 upload prep failed, ret=%d",ret); | ||
1064 | release_firmware(fw_entry); | ||
1065 | return ret; | ||
1066 | } | ||
1067 | |||
1068 | /* Now send firmware */ | ||
1069 | |||
1070 | fw_len = fw_entry->size; | ||
1071 | |||
1072 | if (fw_len % FIRMWARE_CHUNK_SIZE) { | ||
1073 | pvr2_trace(PVR2_TRACE_ERROR_LEGS, | ||
1074 | "size of %s firmware" | ||
1075 | " must be a multiple of 8192B", | ||
1076 | fw_files[fwidx]); | ||
1077 | release_firmware(fw_entry); | ||
1078 | return -1; | ||
1079 | } | ||
1080 | |||
1081 | fw_ptr = kmalloc(FIRMWARE_CHUNK_SIZE, GFP_KERNEL); | ||
1082 | if (fw_ptr == NULL){ | ||
1083 | release_firmware(fw_entry); | ||
1084 | pvr2_trace(PVR2_TRACE_ERROR_LEGS, | ||
1085 | "failed to allocate memory for firmware2 upload"); | ||
1086 | return -ENOMEM; | ||
1087 | } | ||
1088 | |||
1089 | pipe = usb_sndbulkpipe(hdw->usb_dev, PVR2_FIRMWARE_ENDPOINT); | ||
1090 | |||
1091 | for (fw_done = 0 ; (fw_done < fw_len) && !ret ; | ||
1092 | fw_done += FIRMWARE_CHUNK_SIZE ) { | ||
1093 | int i; | ||
1094 | memcpy(fw_ptr, fw_entry->data + fw_done, FIRMWARE_CHUNK_SIZE); | ||
1095 | /* Usbsnoop log shows that we must swap bytes... */ | ||
1096 | for (i = 0; i < FIRMWARE_CHUNK_SIZE/4 ; i++) | ||
1097 | ((u32 *)fw_ptr)[i] = ___swab32(((u32 *)fw_ptr)[i]); | ||
1098 | |||
1099 | ret |= usb_bulk_msg(hdw->usb_dev, pipe, fw_ptr, | ||
1100 | FIRMWARE_CHUNK_SIZE, | ||
1101 | &actual_length, HZ); | ||
1102 | ret |= (actual_length != FIRMWARE_CHUNK_SIZE); | ||
1103 | } | ||
1104 | |||
1105 | trace_firmware("upload of %s : %i / %i ", | ||
1106 | fw_files[fwidx],fw_done,fw_len); | ||
1107 | |||
1108 | kfree(fw_ptr); | ||
1109 | release_firmware(fw_entry); | ||
1110 | |||
1111 | if (ret) { | ||
1112 | pvr2_trace(PVR2_TRACE_ERROR_LEGS, | ||
1113 | "firmware2 upload transfer failure"); | ||
1114 | return ret; | ||
1115 | } | ||
1116 | |||
1117 | /* Finish upload */ | ||
1118 | |||
1119 | ret |= pvr2_write_register(hdw, 0x9054, 0xffffffff); /*reset hw blocks*/ | ||
1120 | ret |= pvr2_write_register(hdw, 0x9058, 0xffffffe8); /*VPU ctrl*/ | ||
1121 | ret |= pvr2_write_u16(hdw, 0x0600, 0); | ||
1122 | |||
1123 | if (ret) { | ||
1124 | pvr2_trace(PVR2_TRACE_ERROR_LEGS, | ||
1125 | "firmware2 upload post-proc failure"); | ||
1126 | } else { | ||
1127 | hdw->subsys_enabled_mask |= (1<<PVR2_SUBSYS_B_ENC_FIRMWARE); | ||
1128 | } | ||
1129 | return ret; | ||
1130 | } | ||
1131 | |||
1132 | |||
1133 | #define FIRMWARE_RECOVERY_BITS \ | ||
1134 | ((1<<PVR2_SUBSYS_B_ENC_CFG) | \ | ||
1135 | (1<<PVR2_SUBSYS_B_ENC_RUN) | \ | ||
1136 | (1<<PVR2_SUBSYS_B_ENC_FIRMWARE) | \ | ||
1137 | (1<<PVR2_SUBSYS_B_USBSTREAM_RUN)) | ||
1138 | |||
1139 | /* | ||
1140 | |||
1141 | This single function is key to pretty much everything. The pvrusb2 | ||
1142 | device can logically be viewed as a series of subsystems which can be | ||
1143 | stopped / started or unconfigured / configured. To get things streaming, | ||
1144 | one must configure everything and start everything, but there may be | ||
1145 | various reasons over time to deconfigure something or stop something. | ||
1146 | This function handles all of this activity. Everything EVERYWHERE that | ||
1147 | must affect a subsystem eventually comes here to do the work. | ||
1148 | |||
1149 | The current state of all subsystems is represented by a single bit mask, | ||
1150 | known as subsys_enabled_mask. The bit positions are defined by the | ||
1151 | PVR2_SUBSYS_xxxx macros, with one subsystem per bit position. At any | ||
1152 | time the set of configured or active subsystems can be queried just by | ||
1153 | looking at that mask. To change bits in that mask, this function here | ||
1154 | must be called. The "msk" argument indicates which bit positions to | ||
1155 | change, and the "val" argument defines the new values for the positions | ||
1156 | defined by "msk". | ||
1157 | |||
1158 | There is a priority ordering of starting / stopping things, and for | ||
1159 | multiple requested changes, this function implements that ordering. | ||
1160 | (Thus we will act on a request to load encoder firmware before we | ||
1161 | configure the encoder.) In addition to priority ordering, there is a | ||
1162 | recovery strategy implemented here. If a particular step fails and we | ||
1163 | detect that failure, this function will clear the affected subsystem bits | ||
1164 | and restart. Thus we have a means for recovering from a dead encoder: | ||
1165 | Clear all bits that correspond to subsystems that we need to restart / | ||
1166 | reconfigure and start over. | ||
1167 | |||
1168 | */ | ||
1169 | void pvr2_hdw_subsys_bit_chg_no_lock(struct pvr2_hdw *hdw, | ||
1170 | unsigned long msk,unsigned long val) | ||
1171 | { | ||
1172 | unsigned long nmsk; | ||
1173 | unsigned long vmsk; | ||
1174 | int ret; | ||
1175 | unsigned int tryCount = 0; | ||
1176 | |||
1177 | if (!hdw->flag_ok) return; | ||
1178 | |||
1179 | msk &= PVR2_SUBSYS_ALL; | ||
1180 | nmsk = (hdw->subsys_enabled_mask & ~msk) | (val & msk); | ||
1181 | nmsk &= PVR2_SUBSYS_ALL; | ||
1182 | |||
1183 | for (;;) { | ||
1184 | tryCount++; | ||
1185 | if (!((nmsk ^ hdw->subsys_enabled_mask) & | ||
1186 | PVR2_SUBSYS_ALL)) break; | ||
1187 | if (tryCount > 4) { | ||
1188 | pvr2_trace(PVR2_TRACE_ERROR_LEGS, | ||
1189 | "Too many retries when configuring device;" | ||
1190 | " giving up"); | ||
1191 | pvr2_hdw_render_useless(hdw); | ||
1192 | break; | ||
1193 | } | ||
1194 | if (tryCount > 1) { | ||
1195 | pvr2_trace(PVR2_TRACE_ERROR_LEGS, | ||
1196 | "Retrying device reconfiguration"); | ||
1197 | } | ||
1198 | pvr2_trace(PVR2_TRACE_INIT, | ||
1199 | "subsys mask changing 0x%lx:0x%lx" | ||
1200 | " from 0x%lx to 0x%lx", | ||
1201 | msk,val,hdw->subsys_enabled_mask,nmsk); | ||
1202 | |||
1203 | vmsk = (nmsk ^ hdw->subsys_enabled_mask) & | ||
1204 | hdw->subsys_enabled_mask; | ||
1205 | if (vmsk) { | ||
1206 | if (vmsk & (1<<PVR2_SUBSYS_B_ENC_RUN)) { | ||
1207 | pvr2_trace(PVR2_TRACE_CTL, | ||
1208 | "/*---TRACE_CTL----*/" | ||
1209 | " pvr2_encoder_stop"); | ||
1210 | ret = pvr2_encoder_stop(hdw); | ||
1211 | if (ret) { | ||
1212 | pvr2_trace(PVR2_TRACE_ERROR_LEGS, | ||
1213 | "Error recovery initiated"); | ||
1214 | hdw->subsys_enabled_mask &= | ||
1215 | ~FIRMWARE_RECOVERY_BITS; | ||
1216 | continue; | ||
1217 | } | ||
1218 | } | ||
1219 | if (vmsk & (1<<PVR2_SUBSYS_B_USBSTREAM_RUN)) { | ||
1220 | pvr2_trace(PVR2_TRACE_CTL, | ||
1221 | "/*---TRACE_CTL----*/" | ||
1222 | " pvr2_hdw_cmd_usbstream(0)"); | ||
1223 | pvr2_hdw_cmd_usbstream(hdw,0); | ||
1224 | } | ||
1225 | if (vmsk & (1<<PVR2_SUBSYS_B_DIGITIZER_RUN)) { | ||
1226 | pvr2_trace(PVR2_TRACE_CTL, | ||
1227 | "/*---TRACE_CTL----*/" | ||
1228 | " decoder disable"); | ||
1229 | if (hdw->decoder_ctrl) { | ||
1230 | hdw->decoder_ctrl->enable( | ||
1231 | hdw->decoder_ctrl->ctxt,0); | ||
1232 | } else { | ||
1233 | pvr2_trace(PVR2_TRACE_ERROR_LEGS, | ||
1234 | "WARNING:" | ||
1235 | " No decoder present"); | ||
1236 | } | ||
1237 | hdw->subsys_enabled_mask &= | ||
1238 | ~(1<<PVR2_SUBSYS_B_DIGITIZER_RUN); | ||
1239 | } | ||
1240 | if (vmsk & PVR2_SUBSYS_CFG_ALL) { | ||
1241 | hdw->subsys_enabled_mask &= | ||
1242 | ~(vmsk & PVR2_SUBSYS_CFG_ALL); | ||
1243 | } | ||
1244 | } | ||
1245 | vmsk = (nmsk ^ hdw->subsys_enabled_mask) & nmsk; | ||
1246 | if (vmsk) { | ||
1247 | if (vmsk & (1<<PVR2_SUBSYS_B_ENC_FIRMWARE)) { | ||
1248 | pvr2_trace(PVR2_TRACE_CTL, | ||
1249 | "/*---TRACE_CTL----*/" | ||
1250 | " pvr2_upload_firmware2"); | ||
1251 | ret = pvr2_upload_firmware2(hdw); | ||
1252 | if (ret) { | ||
1253 | pvr2_trace(PVR2_TRACE_ERROR_LEGS, | ||
1254 | "Failure uploading encoder" | ||
1255 | " firmware"); | ||
1256 | pvr2_hdw_render_useless(hdw); | ||
1257 | break; | ||
1258 | } | ||
1259 | } | ||
1260 | if (vmsk & (1<<PVR2_SUBSYS_B_ENC_CFG)) { | ||
1261 | pvr2_trace(PVR2_TRACE_CTL, | ||
1262 | "/*---TRACE_CTL----*/" | ||
1263 | " pvr2_encoder_configure"); | ||
1264 | ret = pvr2_encoder_configure(hdw); | ||
1265 | if (ret) { | ||
1266 | pvr2_trace(PVR2_TRACE_ERROR_LEGS, | ||
1267 | "Error recovery initiated"); | ||
1268 | hdw->subsys_enabled_mask &= | ||
1269 | ~FIRMWARE_RECOVERY_BITS; | ||
1270 | continue; | ||
1271 | } | ||
1272 | } | ||
1273 | if (vmsk & (1<<PVR2_SUBSYS_B_DIGITIZER_RUN)) { | ||
1274 | pvr2_trace(PVR2_TRACE_CTL, | ||
1275 | "/*---TRACE_CTL----*/" | ||
1276 | " decoder enable"); | ||
1277 | if (hdw->decoder_ctrl) { | ||
1278 | hdw->decoder_ctrl->enable( | ||
1279 | hdw->decoder_ctrl->ctxt,!0); | ||
1280 | } else { | ||
1281 | pvr2_trace(PVR2_TRACE_ERROR_LEGS, | ||
1282 | "WARNING:" | ||
1283 | " No decoder present"); | ||
1284 | } | ||
1285 | hdw->subsys_enabled_mask |= | ||
1286 | (1<<PVR2_SUBSYS_B_DIGITIZER_RUN); | ||
1287 | } | ||
1288 | if (vmsk & (1<<PVR2_SUBSYS_B_USBSTREAM_RUN)) { | ||
1289 | pvr2_trace(PVR2_TRACE_CTL, | ||
1290 | "/*---TRACE_CTL----*/" | ||
1291 | " pvr2_hdw_cmd_usbstream(1)"); | ||
1292 | pvr2_hdw_cmd_usbstream(hdw,!0); | ||
1293 | } | ||
1294 | if (vmsk & (1<<PVR2_SUBSYS_B_ENC_RUN)) { | ||
1295 | pvr2_trace(PVR2_TRACE_CTL, | ||
1296 | "/*---TRACE_CTL----*/" | ||
1297 | " pvr2_encoder_start"); | ||
1298 | ret = pvr2_encoder_start(hdw); | ||
1299 | if (ret) { | ||
1300 | pvr2_trace(PVR2_TRACE_ERROR_LEGS, | ||
1301 | "Error recovery initiated"); | ||
1302 | hdw->subsys_enabled_mask &= | ||
1303 | ~FIRMWARE_RECOVERY_BITS; | ||
1304 | continue; | ||
1305 | } | ||
1306 | } | ||
1307 | } | ||
1308 | } | ||
1309 | } | ||
1310 | |||
1311 | |||
1312 | void pvr2_hdw_subsys_bit_chg(struct pvr2_hdw *hdw, | ||
1313 | unsigned long msk,unsigned long val) | ||
1314 | { | ||
1315 | LOCK_TAKE(hdw->big_lock); do { | ||
1316 | pvr2_hdw_subsys_bit_chg_no_lock(hdw,msk,val); | ||
1317 | } while (0); LOCK_GIVE(hdw->big_lock); | ||
1318 | } | ||
1319 | |||
1320 | |||
1321 | void pvr2_hdw_subsys_bit_set(struct pvr2_hdw *hdw,unsigned long msk) | ||
1322 | { | ||
1323 | pvr2_hdw_subsys_bit_chg(hdw,msk,msk); | ||
1324 | } | ||
1325 | |||
1326 | |||
1327 | void pvr2_hdw_subsys_bit_clr(struct pvr2_hdw *hdw,unsigned long msk) | ||
1328 | { | ||
1329 | pvr2_hdw_subsys_bit_chg(hdw,msk,0); | ||
1330 | } | ||
1331 | |||
1332 | |||
1333 | unsigned long pvr2_hdw_subsys_get(struct pvr2_hdw *hdw) | ||
1334 | { | ||
1335 | return hdw->subsys_enabled_mask; | ||
1336 | } | ||
1337 | |||
1338 | |||
1339 | unsigned long pvr2_hdw_subsys_stream_get(struct pvr2_hdw *hdw) | ||
1340 | { | ||
1341 | return hdw->subsys_stream_mask; | ||
1342 | } | ||
1343 | |||
1344 | |||
1345 | void pvr2_hdw_subsys_stream_bit_chg_no_lock(struct pvr2_hdw *hdw, | ||
1346 | unsigned long msk, | ||
1347 | unsigned long val) | ||
1348 | { | ||
1349 | unsigned long val2; | ||
1350 | msk &= PVR2_SUBSYS_ALL; | ||
1351 | val2 = ((hdw->subsys_stream_mask & ~msk) | (val & msk)); | ||
1352 | pvr2_trace(PVR2_TRACE_INIT, | ||
1353 | "stream mask changing 0x%lx:0x%lx from 0x%lx to 0x%lx", | ||
1354 | msk,val,hdw->subsys_stream_mask,val2); | ||
1355 | hdw->subsys_stream_mask = val2; | ||
1356 | } | ||
1357 | |||
1358 | |||
1359 | void pvr2_hdw_subsys_stream_bit_chg(struct pvr2_hdw *hdw, | ||
1360 | unsigned long msk, | ||
1361 | unsigned long val) | ||
1362 | { | ||
1363 | LOCK_TAKE(hdw->big_lock); do { | ||
1364 | pvr2_hdw_subsys_stream_bit_chg_no_lock(hdw,msk,val); | ||
1365 | } while (0); LOCK_GIVE(hdw->big_lock); | ||
1366 | } | ||
1367 | |||
1368 | |||
1369 | int pvr2_hdw_set_streaming_no_lock(struct pvr2_hdw *hdw,int enableFl) | ||
1370 | { | ||
1371 | if ((!enableFl) == !(hdw->flag_streaming_enabled)) return 0; | ||
1372 | if (enableFl) { | ||
1373 | pvr2_trace(PVR2_TRACE_START_STOP, | ||
1374 | "/*--TRACE_STREAM--*/ enable"); | ||
1375 | pvr2_hdw_subsys_bit_chg_no_lock(hdw,~0,~0); | ||
1376 | } else { | ||
1377 | pvr2_trace(PVR2_TRACE_START_STOP, | ||
1378 | "/*--TRACE_STREAM--*/ disable"); | ||
1379 | pvr2_hdw_subsys_bit_chg_no_lock(hdw,hdw->subsys_stream_mask,0); | ||
1380 | } | ||
1381 | if (!hdw->flag_ok) return -EIO; | ||
1382 | hdw->flag_streaming_enabled = enableFl != 0; | ||
1383 | return 0; | ||
1384 | } | ||
1385 | |||
1386 | |||
1387 | int pvr2_hdw_get_streaming(struct pvr2_hdw *hdw) | ||
1388 | { | ||
1389 | return hdw->flag_streaming_enabled != 0; | ||
1390 | } | ||
1391 | |||
1392 | |||
1393 | int pvr2_hdw_set_streaming(struct pvr2_hdw *hdw,int enable_flag) | ||
1394 | { | ||
1395 | int ret; | ||
1396 | LOCK_TAKE(hdw->big_lock); do { | ||
1397 | ret = pvr2_hdw_set_streaming_no_lock(hdw,enable_flag); | ||
1398 | } while (0); LOCK_GIVE(hdw->big_lock); | ||
1399 | return ret; | ||
1400 | } | ||
1401 | |||
1402 | |||
1403 | int pvr2_hdw_set_stream_type_no_lock(struct pvr2_hdw *hdw, | ||
1404 | enum pvr2_config config) | ||
1405 | { | ||
1406 | unsigned long sm = hdw->subsys_enabled_mask; | ||
1407 | if (!hdw->flag_ok) return -EIO; | ||
1408 | pvr2_hdw_subsys_bit_chg_no_lock(hdw,hdw->subsys_stream_mask,0); | ||
1409 | hdw->config = config; | ||
1410 | pvr2_hdw_subsys_bit_chg_no_lock(hdw,~0,sm); | ||
1411 | return 0; | ||
1412 | } | ||
1413 | |||
1414 | |||
1415 | int pvr2_hdw_set_stream_type(struct pvr2_hdw *hdw,enum pvr2_config config) | ||
1416 | { | ||
1417 | int ret; | ||
1418 | if (!hdw->flag_ok) return -EIO; | ||
1419 | LOCK_TAKE(hdw->big_lock); | ||
1420 | ret = pvr2_hdw_set_stream_type_no_lock(hdw,config); | ||
1421 | LOCK_GIVE(hdw->big_lock); | ||
1422 | return ret; | ||
1423 | } | ||
1424 | |||
1425 | |||
1426 | static int get_default_tuner_type(struct pvr2_hdw *hdw) | ||
1427 | { | ||
1428 | int unit_number = hdw->unit_number; | ||
1429 | int tp = -1; | ||
1430 | if ((unit_number >= 0) && (unit_number < PVR_NUM)) { | ||
1431 | tp = tuner[unit_number]; | ||
1432 | } | ||
1433 | if (tp < 0) return -EINVAL; | ||
1434 | hdw->tuner_type = tp; | ||
1435 | return 0; | ||
1436 | } | ||
1437 | |||
1438 | |||
1439 | static v4l2_std_id get_default_standard(struct pvr2_hdw *hdw) | ||
1440 | { | ||
1441 | int unit_number = hdw->unit_number; | ||
1442 | int tp = 0; | ||
1443 | if ((unit_number >= 0) && (unit_number < PVR_NUM)) { | ||
1444 | tp = video_std[unit_number]; | ||
1445 | } | ||
1446 | return tp; | ||
1447 | } | ||
1448 | |||
1449 | |||
1450 | static unsigned int get_default_error_tolerance(struct pvr2_hdw *hdw) | ||
1451 | { | ||
1452 | int unit_number = hdw->unit_number; | ||
1453 | int tp = 0; | ||
1454 | if ((unit_number >= 0) && (unit_number < PVR_NUM)) { | ||
1455 | tp = tolerance[unit_number]; | ||
1456 | } | ||
1457 | return tp; | ||
1458 | } | ||
1459 | |||
1460 | |||
1461 | static int pvr2_hdw_check_firmware(struct pvr2_hdw *hdw) | ||
1462 | { | ||
1463 | /* Try a harmless request to fetch the eeprom's address over | ||
1464 | endpoint 1. See what happens. Only the full FX2 image can | ||
1465 | respond to this. If this probe fails then likely the FX2 | ||
1466 | firmware needs be loaded. */ | ||
1467 | int result; | ||
1468 | LOCK_TAKE(hdw->ctl_lock); do { | ||
1469 | hdw->cmd_buffer[0] = 0xeb; | ||
1470 | result = pvr2_send_request_ex(hdw,HZ*1,!0, | ||
1471 | hdw->cmd_buffer,1, | ||
1472 | hdw->cmd_buffer,1); | ||
1473 | if (result < 0) break; | ||
1474 | } while(0); LOCK_GIVE(hdw->ctl_lock); | ||
1475 | if (result) { | ||
1476 | pvr2_trace(PVR2_TRACE_INIT, | ||
1477 | "Probe of device endpoint 1 result status %d", | ||
1478 | result); | ||
1479 | } else { | ||
1480 | pvr2_trace(PVR2_TRACE_INIT, | ||
1481 | "Probe of device endpoint 1 succeeded"); | ||
1482 | } | ||
1483 | return result == 0; | ||
1484 | } | ||
1485 | |||
1486 | static void pvr2_hdw_setup_std(struct pvr2_hdw *hdw) | ||
1487 | { | ||
1488 | char buf[40]; | ||
1489 | unsigned int bcnt; | ||
1490 | v4l2_std_id std1,std2; | ||
1491 | |||
1492 | std1 = get_default_standard(hdw); | ||
1493 | |||
1494 | bcnt = pvr2_std_id_to_str(buf,sizeof(buf),hdw->std_mask_eeprom); | ||
1495 | pvr2_trace(PVR2_TRACE_INIT, | ||
1496 | "Supported video standard(s) reported by eeprom: %.*s", | ||
1497 | bcnt,buf); | ||
1498 | |||
1499 | hdw->std_mask_avail = hdw->std_mask_eeprom; | ||
1500 | |||
1501 | std2 = std1 & ~hdw->std_mask_avail; | ||
1502 | if (std2) { | ||
1503 | bcnt = pvr2_std_id_to_str(buf,sizeof(buf),std2); | ||
1504 | pvr2_trace(PVR2_TRACE_INIT, | ||
1505 | "Expanding supported video standards" | ||
1506 | " to include: %.*s", | ||
1507 | bcnt,buf); | ||
1508 | hdw->std_mask_avail |= std2; | ||
1509 | } | ||
1510 | |||
1511 | pvr2_hdw_internal_set_std_avail(hdw); | ||
1512 | |||
1513 | if (std1) { | ||
1514 | bcnt = pvr2_std_id_to_str(buf,sizeof(buf),std1); | ||
1515 | pvr2_trace(PVR2_TRACE_INIT, | ||
1516 | "Initial video standard forced to %.*s", | ||
1517 | bcnt,buf); | ||
1518 | hdw->std_mask_cur = std1; | ||
1519 | hdw->std_dirty = !0; | ||
1520 | pvr2_hdw_internal_find_stdenum(hdw); | ||
1521 | return; | ||
1522 | } | ||
1523 | |||
1524 | if (hdw->std_enum_cnt > 1) { | ||
1525 | // Autoselect the first listed standard | ||
1526 | hdw->std_enum_cur = 1; | ||
1527 | hdw->std_mask_cur = hdw->std_defs[hdw->std_enum_cur-1].id; | ||
1528 | hdw->std_dirty = !0; | ||
1529 | pvr2_trace(PVR2_TRACE_INIT, | ||
1530 | "Initial video standard auto-selected to %s", | ||
1531 | hdw->std_defs[hdw->std_enum_cur-1].name); | ||
1532 | return; | ||
1533 | } | ||
1534 | |||
1535 | pvr2_trace(PVR2_TRACE_ERROR_LEGS, | ||
1536 | "Unable to select a viable initial video standard"); | ||
1537 | } | ||
1538 | |||
1539 | |||
1540 | static void pvr2_hdw_setup_low(struct pvr2_hdw *hdw) | ||
1541 | { | ||
1542 | int ret; | ||
1543 | unsigned int idx; | ||
1544 | struct pvr2_ctrl *cptr; | ||
1545 | int reloadFl = 0; | ||
1546 | if (!reloadFl) { | ||
1547 | reloadFl = (hdw->usb_intf->cur_altsetting->desc.bNumEndpoints | ||
1548 | == 0); | ||
1549 | if (reloadFl) { | ||
1550 | pvr2_trace(PVR2_TRACE_INIT, | ||
1551 | "USB endpoint config looks strange" | ||
1552 | "; possibly firmware needs to be loaded"); | ||
1553 | } | ||
1554 | } | ||
1555 | if (!reloadFl) { | ||
1556 | reloadFl = !pvr2_hdw_check_firmware(hdw); | ||
1557 | if (reloadFl) { | ||
1558 | pvr2_trace(PVR2_TRACE_INIT, | ||
1559 | "Check for FX2 firmware failed" | ||
1560 | "; possibly firmware needs to be loaded"); | ||
1561 | } | ||
1562 | } | ||
1563 | if (reloadFl) { | ||
1564 | if (pvr2_upload_firmware1(hdw) != 0) { | ||
1565 | pvr2_trace(PVR2_TRACE_ERROR_LEGS, | ||
1566 | "Failure uploading firmware1"); | ||
1567 | } | ||
1568 | return; | ||
1569 | } | ||
1570 | hdw->fw1_state = FW1_STATE_OK; | ||
1571 | |||
1572 | if (initusbreset) { | ||
1573 | pvr2_hdw_device_reset(hdw); | ||
1574 | } | ||
1575 | if (!pvr2_hdw_dev_ok(hdw)) return; | ||
1576 | |||
1577 | for (idx = 0; idx < pvr2_client_lists[hdw->hdw_type].cnt; idx++) { | ||
1578 | request_module(pvr2_client_lists[hdw->hdw_type].lst[idx]); | ||
1579 | } | ||
1580 | |||
1581 | pvr2_hdw_cmd_powerup(hdw); | ||
1582 | if (!pvr2_hdw_dev_ok(hdw)) return; | ||
1583 | |||
1584 | if (pvr2_upload_firmware2(hdw)){ | ||
1585 | pvr2_trace(PVR2_TRACE_ERROR_LEGS,"device unstable!!"); | ||
1586 | pvr2_hdw_render_useless(hdw); | ||
1587 | return; | ||
1588 | } | ||
1589 | |||
1590 | // This step MUST happen after the earlier powerup step. | ||
1591 | pvr2_i2c_core_init(hdw); | ||
1592 | if (!pvr2_hdw_dev_ok(hdw)) return; | ||
1593 | |||
1594 | for (idx = 0; idx < CTRLDEF_COUNT; idx++) { | ||
1595 | cptr = hdw->controls + idx; | ||
1596 | if (cptr->info->skip_init) continue; | ||
1597 | if (!cptr->info->set_value) continue; | ||
1598 | cptr->info->set_value(cptr,~0,cptr->info->default_value); | ||
1599 | } | ||
1600 | |||
1601 | // Do not use pvr2_reset_ctl_endpoints() here. It is not | ||
1602 | // thread-safe against the normal pvr2_send_request() mechanism. | ||
1603 | // (We should make it thread safe). | ||
1604 | |||
1605 | ret = pvr2_hdw_get_eeprom_addr(hdw); | ||
1606 | if (!pvr2_hdw_dev_ok(hdw)) return; | ||
1607 | if (ret < 0) { | ||
1608 | pvr2_trace(PVR2_TRACE_ERROR_LEGS, | ||
1609 | "Unable to determine location of eeprom, skipping"); | ||
1610 | } else { | ||
1611 | hdw->eeprom_addr = ret; | ||
1612 | pvr2_eeprom_analyze(hdw); | ||
1613 | if (!pvr2_hdw_dev_ok(hdw)) return; | ||
1614 | } | ||
1615 | |||
1616 | pvr2_hdw_setup_std(hdw); | ||
1617 | |||
1618 | if (!get_default_tuner_type(hdw)) { | ||
1619 | pvr2_trace(PVR2_TRACE_INIT, | ||
1620 | "pvr2_hdw_setup: Tuner type overridden to %d", | ||
1621 | hdw->tuner_type); | ||
1622 | } | ||
1623 | |||
1624 | hdw->tuner_updated = !0; | ||
1625 | pvr2_i2c_core_check_stale(hdw); | ||
1626 | hdw->tuner_updated = 0; | ||
1627 | |||
1628 | if (!pvr2_hdw_dev_ok(hdw)) return; | ||
1629 | |||
1630 | pvr2_hdw_commit_ctl_internal(hdw); | ||
1631 | if (!pvr2_hdw_dev_ok(hdw)) return; | ||
1632 | |||
1633 | hdw->vid_stream = pvr2_stream_create(); | ||
1634 | if (!pvr2_hdw_dev_ok(hdw)) return; | ||
1635 | pvr2_trace(PVR2_TRACE_INIT, | ||
1636 | "pvr2_hdw_setup: video stream is %p",hdw->vid_stream); | ||
1637 | if (hdw->vid_stream) { | ||
1638 | idx = get_default_error_tolerance(hdw); | ||
1639 | if (idx) { | ||
1640 | pvr2_trace(PVR2_TRACE_INIT, | ||
1641 | "pvr2_hdw_setup: video stream %p" | ||
1642 | " setting tolerance %u", | ||
1643 | hdw->vid_stream,idx); | ||
1644 | } | ||
1645 | pvr2_stream_setup(hdw->vid_stream,hdw->usb_dev, | ||
1646 | PVR2_VID_ENDPOINT,idx); | ||
1647 | } | ||
1648 | |||
1649 | if (!pvr2_hdw_dev_ok(hdw)) return; | ||
1650 | |||
1651 | /* Make sure everything is up to date */ | ||
1652 | pvr2_i2c_core_sync(hdw); | ||
1653 | |||
1654 | if (!pvr2_hdw_dev_ok(hdw)) return; | ||
1655 | |||
1656 | hdw->flag_init_ok = !0; | ||
1657 | } | ||
1658 | |||
1659 | |||
1660 | int pvr2_hdw_setup(struct pvr2_hdw *hdw) | ||
1661 | { | ||
1662 | pvr2_trace(PVR2_TRACE_INIT,"pvr2_hdw_setup(hdw=%p) begin",hdw); | ||
1663 | LOCK_TAKE(hdw->big_lock); do { | ||
1664 | pvr2_hdw_setup_low(hdw); | ||
1665 | pvr2_trace(PVR2_TRACE_INIT, | ||
1666 | "pvr2_hdw_setup(hdw=%p) done, ok=%d init_ok=%d", | ||
1667 | hdw,hdw->flag_ok,hdw->flag_init_ok); | ||
1668 | if (pvr2_hdw_dev_ok(hdw)) { | ||
1669 | if (pvr2_hdw_init_ok(hdw)) { | ||
1670 | pvr2_trace( | ||
1671 | PVR2_TRACE_INFO, | ||
1672 | "Device initialization" | ||
1673 | " completed successfully."); | ||
1674 | break; | ||
1675 | } | ||
1676 | if (hdw->fw1_state == FW1_STATE_RELOAD) { | ||
1677 | pvr2_trace( | ||
1678 | PVR2_TRACE_INFO, | ||
1679 | "Device microcontroller firmware" | ||
1680 | " (re)loaded; it should now reset" | ||
1681 | " and reconnect."); | ||
1682 | break; | ||
1683 | } | ||
1684 | pvr2_trace( | ||
1685 | PVR2_TRACE_ERROR_LEGS, | ||
1686 | "Device initialization was not successful."); | ||
1687 | if (hdw->fw1_state == FW1_STATE_MISSING) { | ||
1688 | pvr2_trace( | ||
1689 | PVR2_TRACE_ERROR_LEGS, | ||
1690 | "Giving up since device" | ||
1691 | " microcontroller firmware" | ||
1692 | " appears to be missing."); | ||
1693 | break; | ||
1694 | } | ||
1695 | } | ||
1696 | if (procreload) { | ||
1697 | pvr2_trace( | ||
1698 | PVR2_TRACE_ERROR_LEGS, | ||
1699 | "Attempting pvrusb2 recovery by reloading" | ||
1700 | " primary firmware."); | ||
1701 | pvr2_trace( | ||
1702 | PVR2_TRACE_ERROR_LEGS, | ||
1703 | "If this works, device should disconnect" | ||
1704 | " and reconnect in a sane state."); | ||
1705 | hdw->fw1_state = FW1_STATE_UNKNOWN; | ||
1706 | pvr2_upload_firmware1(hdw); | ||
1707 | } else { | ||
1708 | pvr2_trace( | ||
1709 | PVR2_TRACE_ERROR_LEGS, | ||
1710 | "***WARNING*** pvrusb2 device hardware" | ||
1711 | " appears to be jammed" | ||
1712 | " and I can't clear it."); | ||
1713 | pvr2_trace( | ||
1714 | PVR2_TRACE_ERROR_LEGS, | ||
1715 | "You might need to power cycle" | ||
1716 | " the pvrusb2 device" | ||
1717 | " in order to recover."); | ||
1718 | } | ||
1719 | } while (0); LOCK_GIVE(hdw->big_lock); | ||
1720 | pvr2_trace(PVR2_TRACE_INIT,"pvr2_hdw_setup(hdw=%p) end",hdw); | ||
1721 | return hdw->flag_init_ok; | ||
1722 | } | ||
1723 | |||
1724 | |||
1725 | /* Create and return a structure for interacting with the underlying | ||
1726 | hardware */ | ||
1727 | struct pvr2_hdw *pvr2_hdw_create(struct usb_interface *intf, | ||
1728 | const struct usb_device_id *devid) | ||
1729 | { | ||
1730 | unsigned int idx,cnt1,cnt2; | ||
1731 | struct pvr2_hdw *hdw; | ||
1732 | unsigned int hdw_type; | ||
1733 | int valid_std_mask; | ||
1734 | struct pvr2_ctrl *cptr; | ||
1735 | __u8 ifnum; | ||
1736 | struct v4l2_queryctrl qctrl; | ||
1737 | struct pvr2_ctl_info *ciptr; | ||
1738 | |||
1739 | hdw_type = devid - pvr2_device_table; | ||
1740 | if (hdw_type >= | ||
1741 | sizeof(pvr2_device_names)/sizeof(pvr2_device_names[0])) { | ||
1742 | pvr2_trace(PVR2_TRACE_ERROR_LEGS, | ||
1743 | "Bogus device type of %u reported",hdw_type); | ||
1744 | return 0; | ||
1745 | } | ||
1746 | |||
1747 | hdw = kmalloc(sizeof(*hdw),GFP_KERNEL); | ||
1748 | pvr2_trace(PVR2_TRACE_INIT,"pvr2_hdw_create: hdw=%p, type \"%s\"", | ||
1749 | hdw,pvr2_device_names[hdw_type]); | ||
1750 | if (!hdw) goto fail; | ||
1751 | memset(hdw,0,sizeof(*hdw)); | ||
1752 | cx2341x_fill_defaults(&hdw->enc_ctl_state); | ||
1753 | |||
1754 | hdw->control_cnt = CTRLDEF_COUNT; | ||
1755 | hdw->control_cnt += MPEGDEF_COUNT; | ||
1756 | hdw->controls = kmalloc(sizeof(struct pvr2_ctrl) * hdw->control_cnt, | ||
1757 | GFP_KERNEL); | ||
1758 | if (!hdw->controls) goto fail; | ||
1759 | memset(hdw->controls,0,sizeof(struct pvr2_ctrl) * hdw->control_cnt); | ||
1760 | hdw->hdw_type = hdw_type; | ||
1761 | for (idx = 0; idx < hdw->control_cnt; idx++) { | ||
1762 | cptr = hdw->controls + idx; | ||
1763 | cptr->hdw = hdw; | ||
1764 | } | ||
1765 | for (idx = 0; idx < 32; idx++) { | ||
1766 | hdw->std_mask_ptrs[idx] = hdw->std_mask_names[idx]; | ||
1767 | } | ||
1768 | for (idx = 0; idx < CTRLDEF_COUNT; idx++) { | ||
1769 | cptr = hdw->controls + idx; | ||
1770 | cptr->info = control_defs+idx; | ||
1771 | } | ||
1772 | /* Define and configure additional controls from cx2341x module. */ | ||
1773 | hdw->mpeg_ctrl_info = kmalloc( | ||
1774 | sizeof(*(hdw->mpeg_ctrl_info)) * MPEGDEF_COUNT, GFP_KERNEL); | ||
1775 | if (!hdw->mpeg_ctrl_info) goto fail; | ||
1776 | memset(hdw->mpeg_ctrl_info,0, | ||
1777 | sizeof(*(hdw->mpeg_ctrl_info)) * MPEGDEF_COUNT); | ||
1778 | for (idx = 0; idx < MPEGDEF_COUNT; idx++) { | ||
1779 | cptr = hdw->controls + idx + CTRLDEF_COUNT; | ||
1780 | ciptr = &(hdw->mpeg_ctrl_info[idx].info); | ||
1781 | ciptr->desc = hdw->mpeg_ctrl_info[idx].desc; | ||
1782 | ciptr->name = mpeg_ids[idx].strid; | ||
1783 | ciptr->v4l_id = mpeg_ids[idx].id; | ||
1784 | ciptr->skip_init = !0; | ||
1785 | ciptr->get_value = ctrl_cx2341x_get; | ||
1786 | ciptr->get_v4lflags = ctrl_cx2341x_getv4lflags; | ||
1787 | ciptr->is_dirty = ctrl_cx2341x_is_dirty; | ||
1788 | if (!idx) ciptr->clear_dirty = ctrl_cx2341x_clear_dirty; | ||
1789 | qctrl.id = ciptr->v4l_id; | ||
1790 | cx2341x_ctrl_query(&hdw->enc_ctl_state,&qctrl); | ||
1791 | if (!(qctrl.flags & V4L2_CTRL_FLAG_READ_ONLY)) { | ||
1792 | ciptr->set_value = ctrl_cx2341x_set; | ||
1793 | } | ||
1794 | strncpy(hdw->mpeg_ctrl_info[idx].desc,qctrl.name, | ||
1795 | PVR2_CTLD_INFO_DESC_SIZE); | ||
1796 | hdw->mpeg_ctrl_info[idx].desc[PVR2_CTLD_INFO_DESC_SIZE-1] = 0; | ||
1797 | ciptr->default_value = qctrl.default_value; | ||
1798 | switch (qctrl.type) { | ||
1799 | default: | ||
1800 | case V4L2_CTRL_TYPE_INTEGER: | ||
1801 | ciptr->type = pvr2_ctl_int; | ||
1802 | ciptr->def.type_int.min_value = qctrl.minimum; | ||
1803 | ciptr->def.type_int.max_value = qctrl.maximum; | ||
1804 | break; | ||
1805 | case V4L2_CTRL_TYPE_BOOLEAN: | ||
1806 | ciptr->type = pvr2_ctl_bool; | ||
1807 | break; | ||
1808 | case V4L2_CTRL_TYPE_MENU: | ||
1809 | ciptr->type = pvr2_ctl_enum; | ||
1810 | ciptr->def.type_enum.value_names = | ||
1811 | cx2341x_ctrl_get_menu(ciptr->v4l_id); | ||
1812 | for (cnt1 = 0; | ||
1813 | ciptr->def.type_enum.value_names[cnt1] != NULL; | ||
1814 | cnt1++) { } | ||
1815 | ciptr->def.type_enum.count = cnt1; | ||
1816 | break; | ||
1817 | } | ||
1818 | cptr->info = ciptr; | ||
1819 | } | ||
1820 | |||
1821 | // Initialize video standard enum dynamic control | ||
1822 | cptr = pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_STDENUM); | ||
1823 | if (cptr) { | ||
1824 | memcpy(&hdw->std_info_enum,cptr->info, | ||
1825 | sizeof(hdw->std_info_enum)); | ||
1826 | cptr->info = &hdw->std_info_enum; | ||
1827 | |||
1828 | } | ||
1829 | // Initialize control data regarding video standard masks | ||
1830 | valid_std_mask = pvr2_std_get_usable(); | ||
1831 | for (idx = 0; idx < 32; idx++) { | ||
1832 | if (!(valid_std_mask & (1 << idx))) continue; | ||
1833 | cnt1 = pvr2_std_id_to_str( | ||
1834 | hdw->std_mask_names[idx], | ||
1835 | sizeof(hdw->std_mask_names[idx])-1, | ||
1836 | 1 << idx); | ||
1837 | hdw->std_mask_names[idx][cnt1] = 0; | ||
1838 | } | ||
1839 | cptr = pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_STDAVAIL); | ||
1840 | if (cptr) { | ||
1841 | memcpy(&hdw->std_info_avail,cptr->info, | ||
1842 | sizeof(hdw->std_info_avail)); | ||
1843 | cptr->info = &hdw->std_info_avail; | ||
1844 | hdw->std_info_avail.def.type_bitmask.bit_names = | ||
1845 | hdw->std_mask_ptrs; | ||
1846 | hdw->std_info_avail.def.type_bitmask.valid_bits = | ||
1847 | valid_std_mask; | ||
1848 | } | ||
1849 | cptr = pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_STDCUR); | ||
1850 | if (cptr) { | ||
1851 | memcpy(&hdw->std_info_cur,cptr->info, | ||
1852 | sizeof(hdw->std_info_cur)); | ||
1853 | cptr->info = &hdw->std_info_cur; | ||
1854 | hdw->std_info_cur.def.type_bitmask.bit_names = | ||
1855 | hdw->std_mask_ptrs; | ||
1856 | hdw->std_info_avail.def.type_bitmask.valid_bits = | ||
1857 | valid_std_mask; | ||
1858 | } | ||
1859 | |||
1860 | hdw->eeprom_addr = -1; | ||
1861 | hdw->unit_number = -1; | ||
1862 | hdw->v4l_minor_number = -1; | ||
1863 | hdw->ctl_write_buffer = kmalloc(PVR2_CTL_BUFFSIZE,GFP_KERNEL); | ||
1864 | if (!hdw->ctl_write_buffer) goto fail; | ||
1865 | hdw->ctl_read_buffer = kmalloc(PVR2_CTL_BUFFSIZE,GFP_KERNEL); | ||
1866 | if (!hdw->ctl_read_buffer) goto fail; | ||
1867 | hdw->ctl_write_urb = usb_alloc_urb(0,GFP_KERNEL); | ||
1868 | if (!hdw->ctl_write_urb) goto fail; | ||
1869 | hdw->ctl_read_urb = usb_alloc_urb(0,GFP_KERNEL); | ||
1870 | if (!hdw->ctl_read_urb) goto fail; | ||
1871 | |||
1872 | down(&pvr2_unit_sem); do { | ||
1873 | for (idx = 0; idx < PVR_NUM; idx++) { | ||
1874 | if (unit_pointers[idx]) continue; | ||
1875 | hdw->unit_number = idx; | ||
1876 | unit_pointers[idx] = hdw; | ||
1877 | break; | ||
1878 | } | ||
1879 | } while (0); up(&pvr2_unit_sem); | ||
1880 | |||
1881 | cnt1 = 0; | ||
1882 | cnt2 = scnprintf(hdw->name+cnt1,sizeof(hdw->name)-cnt1,"pvrusb2"); | ||
1883 | cnt1 += cnt2; | ||
1884 | if (hdw->unit_number >= 0) { | ||
1885 | cnt2 = scnprintf(hdw->name+cnt1,sizeof(hdw->name)-cnt1,"_%c", | ||
1886 | ('a' + hdw->unit_number)); | ||
1887 | cnt1 += cnt2; | ||
1888 | } | ||
1889 | if (cnt1 >= sizeof(hdw->name)) cnt1 = sizeof(hdw->name)-1; | ||
1890 | hdw->name[cnt1] = 0; | ||
1891 | |||
1892 | pvr2_trace(PVR2_TRACE_INIT,"Driver unit number is %d, name is %s", | ||
1893 | hdw->unit_number,hdw->name); | ||
1894 | |||
1895 | hdw->tuner_type = -1; | ||
1896 | hdw->flag_ok = !0; | ||
1897 | /* Initialize the mask of subsystems that we will shut down when we | ||
1898 | stop streaming. */ | ||
1899 | hdw->subsys_stream_mask = PVR2_SUBSYS_RUN_ALL; | ||
1900 | hdw->subsys_stream_mask |= (1<<PVR2_SUBSYS_B_ENC_CFG); | ||
1901 | |||
1902 | pvr2_trace(PVR2_TRACE_INIT,"subsys_stream_mask: 0x%lx", | ||
1903 | hdw->subsys_stream_mask); | ||
1904 | |||
1905 | hdw->usb_intf = intf; | ||
1906 | hdw->usb_dev = interface_to_usbdev(intf); | ||
1907 | |||
1908 | ifnum = hdw->usb_intf->cur_altsetting->desc.bInterfaceNumber; | ||
1909 | usb_set_interface(hdw->usb_dev,ifnum,0); | ||
1910 | |||
1911 | mutex_init(&hdw->ctl_lock_mutex); | ||
1912 | mutex_init(&hdw->big_lock_mutex); | ||
1913 | |||
1914 | return hdw; | ||
1915 | fail: | ||
1916 | if (hdw) { | ||
1917 | if (hdw->ctl_read_urb) usb_free_urb(hdw->ctl_read_urb); | ||
1918 | if (hdw->ctl_write_urb) usb_free_urb(hdw->ctl_write_urb); | ||
1919 | if (hdw->ctl_read_buffer) kfree(hdw->ctl_read_buffer); | ||
1920 | if (hdw->ctl_write_buffer) kfree(hdw->ctl_write_buffer); | ||
1921 | if (hdw->controls) kfree(hdw->controls); | ||
1922 | if (hdw->mpeg_ctrl_info) kfree(hdw->mpeg_ctrl_info); | ||
1923 | kfree(hdw); | ||
1924 | } | ||
1925 | return 0; | ||
1926 | } | ||
1927 | |||
1928 | |||
1929 | /* Remove _all_ associations between this driver and the underlying USB | ||
1930 | layer. */ | ||
1931 | void pvr2_hdw_remove_usb_stuff(struct pvr2_hdw *hdw) | ||
1932 | { | ||
1933 | if (hdw->flag_disconnected) return; | ||
1934 | pvr2_trace(PVR2_TRACE_INIT,"pvr2_hdw_remove_usb_stuff: hdw=%p",hdw); | ||
1935 | if (hdw->ctl_read_urb) { | ||
1936 | usb_kill_urb(hdw->ctl_read_urb); | ||
1937 | usb_free_urb(hdw->ctl_read_urb); | ||
1938 | hdw->ctl_read_urb = 0; | ||
1939 | } | ||
1940 | if (hdw->ctl_write_urb) { | ||
1941 | usb_kill_urb(hdw->ctl_write_urb); | ||
1942 | usb_free_urb(hdw->ctl_write_urb); | ||
1943 | hdw->ctl_write_urb = 0; | ||
1944 | } | ||
1945 | if (hdw->ctl_read_buffer) { | ||
1946 | kfree(hdw->ctl_read_buffer); | ||
1947 | hdw->ctl_read_buffer = 0; | ||
1948 | } | ||
1949 | if (hdw->ctl_write_buffer) { | ||
1950 | kfree(hdw->ctl_write_buffer); | ||
1951 | hdw->ctl_write_buffer = 0; | ||
1952 | } | ||
1953 | pvr2_hdw_render_useless_unlocked(hdw); | ||
1954 | hdw->flag_disconnected = !0; | ||
1955 | hdw->usb_dev = 0; | ||
1956 | hdw->usb_intf = 0; | ||
1957 | } | ||
1958 | |||
1959 | |||
1960 | /* Destroy hardware interaction structure */ | ||
1961 | void pvr2_hdw_destroy(struct pvr2_hdw *hdw) | ||
1962 | { | ||
1963 | pvr2_trace(PVR2_TRACE_INIT,"pvr2_hdw_destroy: hdw=%p",hdw); | ||
1964 | if (hdw->fw_buffer) { | ||
1965 | kfree(hdw->fw_buffer); | ||
1966 | hdw->fw_buffer = 0; | ||
1967 | } | ||
1968 | if (hdw->vid_stream) { | ||
1969 | pvr2_stream_destroy(hdw->vid_stream); | ||
1970 | hdw->vid_stream = 0; | ||
1971 | } | ||
1972 | if (hdw->audio_stat) { | ||
1973 | hdw->audio_stat->detach(hdw->audio_stat->ctxt); | ||
1974 | } | ||
1975 | if (hdw->decoder_ctrl) { | ||
1976 | hdw->decoder_ctrl->detach(hdw->decoder_ctrl->ctxt); | ||
1977 | } | ||
1978 | pvr2_i2c_core_done(hdw); | ||
1979 | pvr2_hdw_remove_usb_stuff(hdw); | ||
1980 | down(&pvr2_unit_sem); do { | ||
1981 | if ((hdw->unit_number >= 0) && | ||
1982 | (hdw->unit_number < PVR_NUM) && | ||
1983 | (unit_pointers[hdw->unit_number] == hdw)) { | ||
1984 | unit_pointers[hdw->unit_number] = 0; | ||
1985 | } | ||
1986 | } while (0); up(&pvr2_unit_sem); | ||
1987 | if (hdw->controls) kfree(hdw->controls); | ||
1988 | if (hdw->mpeg_ctrl_info) kfree(hdw->mpeg_ctrl_info); | ||
1989 | if (hdw->std_defs) kfree(hdw->std_defs); | ||
1990 | if (hdw->std_enum_names) kfree(hdw->std_enum_names); | ||
1991 | kfree(hdw); | ||
1992 | } | ||
1993 | |||
1994 | |||
1995 | int pvr2_hdw_init_ok(struct pvr2_hdw *hdw) | ||
1996 | { | ||
1997 | return hdw->flag_init_ok; | ||
1998 | } | ||
1999 | |||
2000 | |||
2001 | int pvr2_hdw_dev_ok(struct pvr2_hdw *hdw) | ||
2002 | { | ||
2003 | return (hdw && hdw->flag_ok); | ||
2004 | } | ||
2005 | |||
2006 | |||
2007 | /* Called when hardware has been unplugged */ | ||
2008 | void pvr2_hdw_disconnect(struct pvr2_hdw *hdw) | ||
2009 | { | ||
2010 | pvr2_trace(PVR2_TRACE_INIT,"pvr2_hdw_disconnect(hdw=%p)",hdw); | ||
2011 | LOCK_TAKE(hdw->big_lock); | ||
2012 | LOCK_TAKE(hdw->ctl_lock); | ||
2013 | pvr2_hdw_remove_usb_stuff(hdw); | ||
2014 | LOCK_GIVE(hdw->ctl_lock); | ||
2015 | LOCK_GIVE(hdw->big_lock); | ||
2016 | } | ||
2017 | |||
2018 | |||
2019 | // Attempt to autoselect an appropriate value for std_enum_cur given | ||
2020 | // whatever is currently in std_mask_cur | ||
2021 | void pvr2_hdw_internal_find_stdenum(struct pvr2_hdw *hdw) | ||
2022 | { | ||
2023 | unsigned int idx; | ||
2024 | for (idx = 1; idx < hdw->std_enum_cnt; idx++) { | ||
2025 | if (hdw->std_defs[idx-1].id == hdw->std_mask_cur) { | ||
2026 | hdw->std_enum_cur = idx; | ||
2027 | return; | ||
2028 | } | ||
2029 | } | ||
2030 | hdw->std_enum_cur = 0; | ||
2031 | } | ||
2032 | |||
2033 | |||
2034 | // Calculate correct set of enumerated standards based on currently known | ||
2035 | // set of available standards bits. | ||
2036 | void pvr2_hdw_internal_set_std_avail(struct pvr2_hdw *hdw) | ||
2037 | { | ||
2038 | struct v4l2_standard *newstd; | ||
2039 | unsigned int std_cnt; | ||
2040 | unsigned int idx; | ||
2041 | |||
2042 | newstd = pvr2_std_create_enum(&std_cnt,hdw->std_mask_avail); | ||
2043 | |||
2044 | if (hdw->std_defs) { | ||
2045 | kfree(hdw->std_defs); | ||
2046 | hdw->std_defs = 0; | ||
2047 | } | ||
2048 | hdw->std_enum_cnt = 0; | ||
2049 | if (hdw->std_enum_names) { | ||
2050 | kfree(hdw->std_enum_names); | ||
2051 | hdw->std_enum_names = 0; | ||
2052 | } | ||
2053 | |||
2054 | if (!std_cnt) { | ||
2055 | pvr2_trace( | ||
2056 | PVR2_TRACE_ERROR_LEGS, | ||
2057 | "WARNING: Failed to identify any viable standards"); | ||
2058 | } | ||
2059 | hdw->std_enum_names = kmalloc(sizeof(char *)*(std_cnt+1),GFP_KERNEL); | ||
2060 | hdw->std_enum_names[0] = "none"; | ||
2061 | for (idx = 0; idx < std_cnt; idx++) { | ||
2062 | hdw->std_enum_names[idx+1] = | ||
2063 | newstd[idx].name; | ||
2064 | } | ||
2065 | // Set up the dynamic control for this standard | ||
2066 | hdw->std_info_enum.def.type_enum.value_names = hdw->std_enum_names; | ||
2067 | hdw->std_info_enum.def.type_enum.count = std_cnt+1; | ||
2068 | hdw->std_defs = newstd; | ||
2069 | hdw->std_enum_cnt = std_cnt+1; | ||
2070 | hdw->std_enum_cur = 0; | ||
2071 | hdw->std_info_cur.def.type_bitmask.valid_bits = hdw->std_mask_avail; | ||
2072 | } | ||
2073 | |||
2074 | |||
2075 | int pvr2_hdw_get_stdenum_value(struct pvr2_hdw *hdw, | ||
2076 | struct v4l2_standard *std, | ||
2077 | unsigned int idx) | ||
2078 | { | ||
2079 | int ret = -EINVAL; | ||
2080 | if (!idx) return ret; | ||
2081 | LOCK_TAKE(hdw->big_lock); do { | ||
2082 | if (idx >= hdw->std_enum_cnt) break; | ||
2083 | idx--; | ||
2084 | memcpy(std,hdw->std_defs+idx,sizeof(*std)); | ||
2085 | ret = 0; | ||
2086 | } while (0); LOCK_GIVE(hdw->big_lock); | ||
2087 | return ret; | ||
2088 | } | ||
2089 | |||
2090 | |||
2091 | /* Get the number of defined controls */ | ||
2092 | unsigned int pvr2_hdw_get_ctrl_count(struct pvr2_hdw *hdw) | ||
2093 | { | ||
2094 | return hdw->control_cnt; | ||
2095 | } | ||
2096 | |||
2097 | |||
2098 | /* Retrieve a control handle given its index (0..count-1) */ | ||
2099 | struct pvr2_ctrl *pvr2_hdw_get_ctrl_by_index(struct pvr2_hdw *hdw, | ||
2100 | unsigned int idx) | ||
2101 | { | ||
2102 | if (idx >= hdw->control_cnt) return 0; | ||
2103 | return hdw->controls + idx; | ||
2104 | } | ||
2105 | |||
2106 | |||
2107 | /* Retrieve a control handle given its index (0..count-1) */ | ||
2108 | struct pvr2_ctrl *pvr2_hdw_get_ctrl_by_id(struct pvr2_hdw *hdw, | ||
2109 | unsigned int ctl_id) | ||
2110 | { | ||
2111 | struct pvr2_ctrl *cptr; | ||
2112 | unsigned int idx; | ||
2113 | int i; | ||
2114 | |||
2115 | /* This could be made a lot more efficient, but for now... */ | ||
2116 | for (idx = 0; idx < hdw->control_cnt; idx++) { | ||
2117 | cptr = hdw->controls + idx; | ||
2118 | i = cptr->info->internal_id; | ||
2119 | if (i && (i == ctl_id)) return cptr; | ||
2120 | } | ||
2121 | return 0; | ||
2122 | } | ||
2123 | |||
2124 | |||
2125 | /* Given a V4L ID, retrieve the control structure associated with it. */ | ||
2126 | struct pvr2_ctrl *pvr2_hdw_get_ctrl_v4l(struct pvr2_hdw *hdw,unsigned int ctl_id) | ||
2127 | { | ||
2128 | struct pvr2_ctrl *cptr; | ||
2129 | unsigned int idx; | ||
2130 | int i; | ||
2131 | |||
2132 | /* This could be made a lot more efficient, but for now... */ | ||
2133 | for (idx = 0; idx < hdw->control_cnt; idx++) { | ||
2134 | cptr = hdw->controls + idx; | ||
2135 | i = cptr->info->v4l_id; | ||
2136 | if (i && (i == ctl_id)) return cptr; | ||
2137 | } | ||
2138 | return 0; | ||
2139 | } | ||
2140 | |||
2141 | |||
2142 | /* Given a V4L ID for its immediate predecessor, retrieve the control | ||
2143 | structure associated with it. */ | ||
2144 | struct pvr2_ctrl *pvr2_hdw_get_ctrl_nextv4l(struct pvr2_hdw *hdw, | ||
2145 | unsigned int ctl_id) | ||
2146 | { | ||
2147 | struct pvr2_ctrl *cptr,*cp2; | ||
2148 | unsigned int idx; | ||
2149 | int i; | ||
2150 | |||
2151 | /* This could be made a lot more efficient, but for now... */ | ||
2152 | cp2 = 0; | ||
2153 | for (idx = 0; idx < hdw->control_cnt; idx++) { | ||
2154 | cptr = hdw->controls + idx; | ||
2155 | i = cptr->info->v4l_id; | ||
2156 | if (!i) continue; | ||
2157 | if (i <= ctl_id) continue; | ||
2158 | if (cp2 && (cp2->info->v4l_id < i)) continue; | ||
2159 | cp2 = cptr; | ||
2160 | } | ||
2161 | return cp2; | ||
2162 | return 0; | ||
2163 | } | ||
2164 | |||
2165 | |||
2166 | static const char *get_ctrl_typename(enum pvr2_ctl_type tp) | ||
2167 | { | ||
2168 | switch (tp) { | ||
2169 | case pvr2_ctl_int: return "integer"; | ||
2170 | case pvr2_ctl_enum: return "enum"; | ||
2171 | case pvr2_ctl_bool: return "boolean"; | ||
2172 | case pvr2_ctl_bitmask: return "bitmask"; | ||
2173 | } | ||
2174 | return ""; | ||
2175 | } | ||
2176 | |||
2177 | |||
2178 | /* Commit all control changes made up to this point. Subsystems can be | ||
2179 | indirectly affected by these changes. For a given set of things being | ||
2180 | committed, we'll clear the affected subsystem bits and then once we're | ||
2181 | done committing everything we'll make a request to restore the subsystem | ||
2182 | state(s) back to their previous value before this function was called. | ||
2183 | Thus we can automatically reconfigure affected pieces of the driver as | ||
2184 | controls are changed. */ | ||
2185 | int pvr2_hdw_commit_ctl_internal(struct pvr2_hdw *hdw) | ||
2186 | { | ||
2187 | unsigned long saved_subsys_mask = hdw->subsys_enabled_mask; | ||
2188 | unsigned long stale_subsys_mask = 0; | ||
2189 | unsigned int idx; | ||
2190 | struct pvr2_ctrl *cptr; | ||
2191 | int value; | ||
2192 | int commit_flag = 0; | ||
2193 | char buf[100]; | ||
2194 | unsigned int bcnt,ccnt; | ||
2195 | |||
2196 | for (idx = 0; idx < hdw->control_cnt; idx++) { | ||
2197 | cptr = hdw->controls + idx; | ||
2198 | if (cptr->info->is_dirty == 0) continue; | ||
2199 | if (!cptr->info->is_dirty(cptr)) continue; | ||
2200 | if (!commit_flag) { | ||
2201 | commit_flag = !0; | ||
2202 | } | ||
2203 | |||
2204 | bcnt = scnprintf(buf,sizeof(buf),"\"%s\" <-- ", | ||
2205 | cptr->info->name); | ||
2206 | value = 0; | ||
2207 | cptr->info->get_value(cptr,&value); | ||
2208 | pvr2_ctrl_value_to_sym_internal(cptr,~0,value, | ||
2209 | buf+bcnt, | ||
2210 | sizeof(buf)-bcnt,&ccnt); | ||
2211 | bcnt += ccnt; | ||
2212 | bcnt += scnprintf(buf+bcnt,sizeof(buf)-bcnt," <%s>", | ||
2213 | get_ctrl_typename(cptr->info->type)); | ||
2214 | pvr2_trace(PVR2_TRACE_CTL, | ||
2215 | "/*--TRACE_COMMIT--*/ %.*s", | ||
2216 | bcnt,buf); | ||
2217 | } | ||
2218 | |||
2219 | if (!commit_flag) { | ||
2220 | /* Nothing has changed */ | ||
2221 | return 0; | ||
2222 | } | ||
2223 | |||
2224 | /* When video standard changes, reset the hres and vres values - | ||
2225 | but if the user has pending changes there, then let the changes | ||
2226 | take priority. */ | ||
2227 | if (hdw->std_dirty) { | ||
2228 | /* Rewrite the vertical resolution to be appropriate to the | ||
2229 | video standard that has been selected. */ | ||
2230 | int nvres; | ||
2231 | if (hdw->std_mask_cur & V4L2_STD_525_60) { | ||
2232 | nvres = 480; | ||
2233 | } else { | ||
2234 | nvres = 576; | ||
2235 | } | ||
2236 | if (nvres != hdw->res_ver_val) { | ||
2237 | hdw->res_ver_val = nvres; | ||
2238 | hdw->res_ver_dirty = !0; | ||
2239 | } | ||
2240 | } | ||
2241 | |||
2242 | if (hdw->std_dirty || | ||
2243 | 0) { | ||
2244 | /* If any of this changes, then the encoder needs to be | ||
2245 | reconfigured, and we need to reset the stream. */ | ||
2246 | stale_subsys_mask |= (1<<PVR2_SUBSYS_B_ENC_CFG); | ||
2247 | stale_subsys_mask |= hdw->subsys_stream_mask; | ||
2248 | } | ||
2249 | |||
2250 | if (hdw->srate_dirty) { | ||
2251 | /* Write new sample rate into control structure since | ||
2252 | * the master copy is stale. We must track srate | ||
2253 | * separate from the mpeg control structure because | ||
2254 | * other logic also uses this value. */ | ||
2255 | struct v4l2_ext_controls cs; | ||
2256 | struct v4l2_ext_control c1; | ||
2257 | memset(&cs,0,sizeof(cs)); | ||
2258 | memset(&c1,0,sizeof(c1)); | ||
2259 | cs.controls = &c1; | ||
2260 | cs.count = 1; | ||
2261 | c1.id = V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ; | ||
2262 | c1.value = hdw->srate_val; | ||
2263 | cx2341x_ext_ctrls(&hdw->enc_ctl_state,&cs,VIDIOC_S_EXT_CTRLS); | ||
2264 | } | ||
2265 | |||
2266 | /* Scan i2c core at this point - before we clear all the dirty | ||
2267 | bits. Various parts of the i2c core will notice dirty bits as | ||
2268 | appropriate and arrange to broadcast or directly send updates to | ||
2269 | the client drivers in order to keep everything in sync */ | ||
2270 | pvr2_i2c_core_check_stale(hdw); | ||
2271 | |||
2272 | for (idx = 0; idx < hdw->control_cnt; idx++) { | ||
2273 | cptr = hdw->controls + idx; | ||
2274 | if (!cptr->info->clear_dirty) continue; | ||
2275 | cptr->info->clear_dirty(cptr); | ||
2276 | } | ||
2277 | |||
2278 | /* Now execute i2c core update */ | ||
2279 | pvr2_i2c_core_sync(hdw); | ||
2280 | |||
2281 | pvr2_hdw_subsys_bit_chg_no_lock(hdw,stale_subsys_mask,0); | ||
2282 | pvr2_hdw_subsys_bit_chg_no_lock(hdw,~0,saved_subsys_mask); | ||
2283 | |||
2284 | return 0; | ||
2285 | } | ||
2286 | |||
2287 | |||
2288 | int pvr2_hdw_commit_ctl(struct pvr2_hdw *hdw) | ||
2289 | { | ||
2290 | LOCK_TAKE(hdw->big_lock); do { | ||
2291 | pvr2_hdw_commit_ctl_internal(hdw); | ||
2292 | } while (0); LOCK_GIVE(hdw->big_lock); | ||
2293 | return 0; | ||
2294 | } | ||
2295 | |||
2296 | |||
2297 | void pvr2_hdw_poll(struct pvr2_hdw *hdw) | ||
2298 | { | ||
2299 | LOCK_TAKE(hdw->big_lock); do { | ||
2300 | pvr2_i2c_core_sync(hdw); | ||
2301 | } while (0); LOCK_GIVE(hdw->big_lock); | ||
2302 | } | ||
2303 | |||
2304 | |||
2305 | void pvr2_hdw_setup_poll_trigger(struct pvr2_hdw *hdw, | ||
2306 | void (*func)(void *), | ||
2307 | void *data) | ||
2308 | { | ||
2309 | LOCK_TAKE(hdw->big_lock); do { | ||
2310 | hdw->poll_trigger_func = func; | ||
2311 | hdw->poll_trigger_data = data; | ||
2312 | } while (0); LOCK_GIVE(hdw->big_lock); | ||
2313 | } | ||
2314 | |||
2315 | |||
2316 | void pvr2_hdw_poll_trigger_unlocked(struct pvr2_hdw *hdw) | ||
2317 | { | ||
2318 | if (hdw->poll_trigger_func) { | ||
2319 | hdw->poll_trigger_func(hdw->poll_trigger_data); | ||
2320 | } | ||
2321 | } | ||
2322 | |||
2323 | |||
2324 | void pvr2_hdw_poll_trigger(struct pvr2_hdw *hdw) | ||
2325 | { | ||
2326 | LOCK_TAKE(hdw->big_lock); do { | ||
2327 | pvr2_hdw_poll_trigger_unlocked(hdw); | ||
2328 | } while (0); LOCK_GIVE(hdw->big_lock); | ||
2329 | } | ||
2330 | |||
2331 | |||
2332 | /* Return name for this driver instance */ | ||
2333 | const char *pvr2_hdw_get_driver_name(struct pvr2_hdw *hdw) | ||
2334 | { | ||
2335 | return hdw->name; | ||
2336 | } | ||
2337 | |||
2338 | |||
2339 | /* Return bit mask indicating signal status */ | ||
2340 | unsigned int pvr2_hdw_get_signal_status_internal(struct pvr2_hdw *hdw) | ||
2341 | { | ||
2342 | unsigned int msk = 0; | ||
2343 | switch (hdw->input_val) { | ||
2344 | case PVR2_CVAL_INPUT_TV: | ||
2345 | case PVR2_CVAL_INPUT_RADIO: | ||
2346 | if (hdw->decoder_ctrl && | ||
2347 | hdw->decoder_ctrl->tuned(hdw->decoder_ctrl->ctxt)) { | ||
2348 | msk |= PVR2_SIGNAL_OK; | ||
2349 | if (hdw->audio_stat && | ||
2350 | hdw->audio_stat->status(hdw->audio_stat->ctxt)) { | ||
2351 | if (hdw->flag_stereo) { | ||
2352 | msk |= PVR2_SIGNAL_STEREO; | ||
2353 | } | ||
2354 | if (hdw->flag_bilingual) { | ||
2355 | msk |= PVR2_SIGNAL_SAP; | ||
2356 | } | ||
2357 | } | ||
2358 | } | ||
2359 | break; | ||
2360 | default: | ||
2361 | msk |= PVR2_SIGNAL_OK | PVR2_SIGNAL_STEREO; | ||
2362 | } | ||
2363 | return msk; | ||
2364 | } | ||
2365 | |||
2366 | |||
2367 | int pvr2_hdw_is_hsm(struct pvr2_hdw *hdw) | ||
2368 | { | ||
2369 | int result; | ||
2370 | LOCK_TAKE(hdw->ctl_lock); do { | ||
2371 | hdw->cmd_buffer[0] = 0x0b; | ||
2372 | result = pvr2_send_request(hdw, | ||
2373 | hdw->cmd_buffer,1, | ||
2374 | hdw->cmd_buffer,1); | ||
2375 | if (result < 0) break; | ||
2376 | result = (hdw->cmd_buffer[0] != 0); | ||
2377 | } while(0); LOCK_GIVE(hdw->ctl_lock); | ||
2378 | return result; | ||
2379 | } | ||
2380 | |||
2381 | |||
2382 | /* Return bit mask indicating signal status */ | ||
2383 | unsigned int pvr2_hdw_get_signal_status(struct pvr2_hdw *hdw) | ||
2384 | { | ||
2385 | unsigned int msk = 0; | ||
2386 | LOCK_TAKE(hdw->big_lock); do { | ||
2387 | msk = pvr2_hdw_get_signal_status_internal(hdw); | ||
2388 | } while (0); LOCK_GIVE(hdw->big_lock); | ||
2389 | return msk; | ||
2390 | } | ||
2391 | |||
2392 | |||
2393 | /* Get handle to video output stream */ | ||
2394 | struct pvr2_stream *pvr2_hdw_get_video_stream(struct pvr2_hdw *hp) | ||
2395 | { | ||
2396 | return hp->vid_stream; | ||
2397 | } | ||
2398 | |||
2399 | |||
2400 | void pvr2_hdw_trigger_module_log(struct pvr2_hdw *hdw) | ||
2401 | { | ||
2402 | int nr = pvr2_hdw_get_unit_number(hdw); | ||
2403 | LOCK_TAKE(hdw->big_lock); do { | ||
2404 | hdw->log_requested = !0; | ||
2405 | printk(KERN_INFO "pvrusb2: ================= START STATUS CARD #%d =================\n", nr); | ||
2406 | pvr2_i2c_core_check_stale(hdw); | ||
2407 | hdw->log_requested = 0; | ||
2408 | pvr2_i2c_core_sync(hdw); | ||
2409 | pvr2_trace(PVR2_TRACE_INFO,"cx2341x config:"); | ||
2410 | cx2341x_log_status(&hdw->enc_ctl_state, "pvrusb2"); | ||
2411 | printk(KERN_INFO "pvrusb2: ================== END STATUS CARD #%d ==================\n", nr); | ||
2412 | } while (0); LOCK_GIVE(hdw->big_lock); | ||
2413 | } | ||
2414 | |||
2415 | void pvr2_hdw_cpufw_set_enabled(struct pvr2_hdw *hdw, int enable_flag) | ||
2416 | { | ||
2417 | int ret; | ||
2418 | u16 address; | ||
2419 | unsigned int pipe; | ||
2420 | LOCK_TAKE(hdw->big_lock); do { | ||
2421 | if ((hdw->fw_buffer == 0) == !enable_flag) break; | ||
2422 | |||
2423 | if (!enable_flag) { | ||
2424 | pvr2_trace(PVR2_TRACE_FIRMWARE, | ||
2425 | "Cleaning up after CPU firmware fetch"); | ||
2426 | kfree(hdw->fw_buffer); | ||
2427 | hdw->fw_buffer = 0; | ||
2428 | hdw->fw_size = 0; | ||
2429 | /* Now release the CPU. It will disconnect and | ||
2430 | reconnect later. */ | ||
2431 | pvr2_hdw_cpureset_assert(hdw,0); | ||
2432 | break; | ||
2433 | } | ||
2434 | |||
2435 | pvr2_trace(PVR2_TRACE_FIRMWARE, | ||
2436 | "Preparing to suck out CPU firmware"); | ||
2437 | hdw->fw_size = 0x2000; | ||
2438 | hdw->fw_buffer = kmalloc(hdw->fw_size,GFP_KERNEL); | ||
2439 | if (!hdw->fw_buffer) { | ||
2440 | hdw->fw_size = 0; | ||
2441 | break; | ||
2442 | } | ||
2443 | |||
2444 | memset(hdw->fw_buffer,0,hdw->fw_size); | ||
2445 | |||
2446 | /* We have to hold the CPU during firmware upload. */ | ||
2447 | pvr2_hdw_cpureset_assert(hdw,1); | ||
2448 | |||
2449 | /* download the firmware from address 0000-1fff in 2048 | ||
2450 | (=0x800) bytes chunk. */ | ||
2451 | |||
2452 | pvr2_trace(PVR2_TRACE_FIRMWARE,"Grabbing CPU firmware"); | ||
2453 | pipe = usb_rcvctrlpipe(hdw->usb_dev, 0); | ||
2454 | for(address = 0; address < hdw->fw_size; address += 0x800) { | ||
2455 | ret = usb_control_msg(hdw->usb_dev,pipe,0xa0,0xc0, | ||
2456 | address,0, | ||
2457 | hdw->fw_buffer+address,0x800,HZ); | ||
2458 | if (ret < 0) break; | ||
2459 | } | ||
2460 | |||
2461 | pvr2_trace(PVR2_TRACE_FIRMWARE,"Done grabbing CPU firmware"); | ||
2462 | |||
2463 | } while (0); LOCK_GIVE(hdw->big_lock); | ||
2464 | } | ||
2465 | |||
2466 | |||
2467 | /* Return true if we're in a mode for retrieval CPU firmware */ | ||
2468 | int pvr2_hdw_cpufw_get_enabled(struct pvr2_hdw *hdw) | ||
2469 | { | ||
2470 | return hdw->fw_buffer != 0; | ||
2471 | } | ||
2472 | |||
2473 | |||
2474 | int pvr2_hdw_cpufw_get(struct pvr2_hdw *hdw,unsigned int offs, | ||
2475 | char *buf,unsigned int cnt) | ||
2476 | { | ||
2477 | int ret = -EINVAL; | ||
2478 | LOCK_TAKE(hdw->big_lock); do { | ||
2479 | if (!buf) break; | ||
2480 | if (!cnt) break; | ||
2481 | |||
2482 | if (!hdw->fw_buffer) { | ||
2483 | ret = -EIO; | ||
2484 | break; | ||
2485 | } | ||
2486 | |||
2487 | if (offs >= hdw->fw_size) { | ||
2488 | pvr2_trace(PVR2_TRACE_FIRMWARE, | ||
2489 | "Read firmware data offs=%d EOF", | ||
2490 | offs); | ||
2491 | ret = 0; | ||
2492 | break; | ||
2493 | } | ||
2494 | |||
2495 | if (offs + cnt > hdw->fw_size) cnt = hdw->fw_size - offs; | ||
2496 | |||
2497 | memcpy(buf,hdw->fw_buffer+offs,cnt); | ||
2498 | |||
2499 | pvr2_trace(PVR2_TRACE_FIRMWARE, | ||
2500 | "Read firmware data offs=%d cnt=%d", | ||
2501 | offs,cnt); | ||
2502 | ret = cnt; | ||
2503 | } while (0); LOCK_GIVE(hdw->big_lock); | ||
2504 | |||
2505 | return ret; | ||
2506 | } | ||
2507 | |||
2508 | |||
2509 | int pvr2_hdw_v4l_get_minor_number(struct pvr2_hdw *hdw) | ||
2510 | { | ||
2511 | return hdw->v4l_minor_number; | ||
2512 | } | ||
2513 | |||
2514 | |||
2515 | /* Store the v4l minor device number */ | ||
2516 | void pvr2_hdw_v4l_store_minor_number(struct pvr2_hdw *hdw,int v) | ||
2517 | { | ||
2518 | hdw->v4l_minor_number = v; | ||
2519 | } | ||
2520 | |||
2521 | |||
2522 | void pvr2_reset_ctl_endpoints(struct pvr2_hdw *hdw) | ||
2523 | { | ||
2524 | if (!hdw->usb_dev) return; | ||
2525 | usb_settoggle(hdw->usb_dev, PVR2_CTL_WRITE_ENDPOINT & 0xf, | ||
2526 | !(PVR2_CTL_WRITE_ENDPOINT & USB_DIR_IN), 0); | ||
2527 | usb_settoggle(hdw->usb_dev, PVR2_CTL_READ_ENDPOINT & 0xf, | ||
2528 | !(PVR2_CTL_READ_ENDPOINT & USB_DIR_IN), 0); | ||
2529 | usb_clear_halt(hdw->usb_dev, | ||
2530 | usb_rcvbulkpipe(hdw->usb_dev, | ||
2531 | PVR2_CTL_READ_ENDPOINT & 0x7f)); | ||
2532 | usb_clear_halt(hdw->usb_dev, | ||
2533 | usb_sndbulkpipe(hdw->usb_dev, | ||
2534 | PVR2_CTL_WRITE_ENDPOINT & 0x7f)); | ||
2535 | } | ||
2536 | |||
2537 | |||
2538 | static void pvr2_ctl_write_complete(struct urb *urb, struct pt_regs *regs) | ||
2539 | { | ||
2540 | struct pvr2_hdw *hdw = urb->context; | ||
2541 | hdw->ctl_write_pend_flag = 0; | ||
2542 | if (hdw->ctl_read_pend_flag) return; | ||
2543 | complete(&hdw->ctl_done); | ||
2544 | } | ||
2545 | |||
2546 | |||
2547 | static void pvr2_ctl_read_complete(struct urb *urb, struct pt_regs *regs) | ||
2548 | { | ||
2549 | struct pvr2_hdw *hdw = urb->context; | ||
2550 | hdw->ctl_read_pend_flag = 0; | ||
2551 | if (hdw->ctl_write_pend_flag) return; | ||
2552 | complete(&hdw->ctl_done); | ||
2553 | } | ||
2554 | |||
2555 | |||
2556 | static void pvr2_ctl_timeout(unsigned long data) | ||
2557 | { | ||
2558 | struct pvr2_hdw *hdw = (struct pvr2_hdw *)data; | ||
2559 | if (hdw->ctl_write_pend_flag || hdw->ctl_read_pend_flag) { | ||
2560 | hdw->ctl_timeout_flag = !0; | ||
2561 | if (hdw->ctl_write_pend_flag && hdw->ctl_write_urb) { | ||
2562 | usb_unlink_urb(hdw->ctl_write_urb); | ||
2563 | } | ||
2564 | if (hdw->ctl_read_pend_flag && hdw->ctl_read_urb) { | ||
2565 | usb_unlink_urb(hdw->ctl_read_urb); | ||
2566 | } | ||
2567 | } | ||
2568 | } | ||
2569 | |||
2570 | |||
2571 | int pvr2_send_request_ex(struct pvr2_hdw *hdw, | ||
2572 | unsigned int timeout,int probe_fl, | ||
2573 | void *write_data,unsigned int write_len, | ||
2574 | void *read_data,unsigned int read_len) | ||
2575 | { | ||
2576 | unsigned int idx; | ||
2577 | int status = 0; | ||
2578 | struct timer_list timer; | ||
2579 | if (!hdw->ctl_lock_held) { | ||
2580 | pvr2_trace(PVR2_TRACE_ERROR_LEGS, | ||
2581 | "Attempted to execute control transfer" | ||
2582 | " without lock!!"); | ||
2583 | return -EDEADLK; | ||
2584 | } | ||
2585 | if ((!hdw->flag_ok) && !probe_fl) { | ||
2586 | pvr2_trace(PVR2_TRACE_ERROR_LEGS, | ||
2587 | "Attempted to execute control transfer" | ||
2588 | " when device not ok"); | ||
2589 | return -EIO; | ||
2590 | } | ||
2591 | if (!(hdw->ctl_read_urb && hdw->ctl_write_urb)) { | ||
2592 | if (!probe_fl) { | ||
2593 | pvr2_trace(PVR2_TRACE_ERROR_LEGS, | ||
2594 | "Attempted to execute control transfer" | ||
2595 | " when USB is disconnected"); | ||
2596 | } | ||
2597 | return -ENOTTY; | ||
2598 | } | ||
2599 | |||
2600 | /* Ensure that we have sane parameters */ | ||
2601 | if (!write_data) write_len = 0; | ||
2602 | if (!read_data) read_len = 0; | ||
2603 | if (write_len > PVR2_CTL_BUFFSIZE) { | ||
2604 | pvr2_trace( | ||
2605 | PVR2_TRACE_ERROR_LEGS, | ||
2606 | "Attempted to execute %d byte" | ||
2607 | " control-write transfer (limit=%d)", | ||
2608 | write_len,PVR2_CTL_BUFFSIZE); | ||
2609 | return -EINVAL; | ||
2610 | } | ||
2611 | if (read_len > PVR2_CTL_BUFFSIZE) { | ||
2612 | pvr2_trace( | ||
2613 | PVR2_TRACE_ERROR_LEGS, | ||
2614 | "Attempted to execute %d byte" | ||
2615 | " control-read transfer (limit=%d)", | ||
2616 | write_len,PVR2_CTL_BUFFSIZE); | ||
2617 | return -EINVAL; | ||
2618 | } | ||
2619 | if ((!write_len) && (!read_len)) { | ||
2620 | pvr2_trace( | ||
2621 | PVR2_TRACE_ERROR_LEGS, | ||
2622 | "Attempted to execute null control transfer?"); | ||
2623 | return -EINVAL; | ||
2624 | } | ||
2625 | |||
2626 | |||
2627 | hdw->cmd_debug_state = 1; | ||
2628 | if (write_len) { | ||
2629 | hdw->cmd_debug_code = ((unsigned char *)write_data)[0]; | ||
2630 | } else { | ||
2631 | hdw->cmd_debug_code = 0; | ||
2632 | } | ||
2633 | hdw->cmd_debug_write_len = write_len; | ||
2634 | hdw->cmd_debug_read_len = read_len; | ||
2635 | |||
2636 | /* Initialize common stuff */ | ||
2637 | init_completion(&hdw->ctl_done); | ||
2638 | hdw->ctl_timeout_flag = 0; | ||
2639 | hdw->ctl_write_pend_flag = 0; | ||
2640 | hdw->ctl_read_pend_flag = 0; | ||
2641 | init_timer(&timer); | ||
2642 | timer.expires = jiffies + timeout; | ||
2643 | timer.data = (unsigned long)hdw; | ||
2644 | timer.function = pvr2_ctl_timeout; | ||
2645 | |||
2646 | if (write_len) { | ||
2647 | hdw->cmd_debug_state = 2; | ||
2648 | /* Transfer write data to internal buffer */ | ||
2649 | for (idx = 0; idx < write_len; idx++) { | ||
2650 | hdw->ctl_write_buffer[idx] = | ||
2651 | ((unsigned char *)write_data)[idx]; | ||
2652 | } | ||
2653 | /* Initiate a write request */ | ||
2654 | usb_fill_bulk_urb(hdw->ctl_write_urb, | ||
2655 | hdw->usb_dev, | ||
2656 | usb_sndbulkpipe(hdw->usb_dev, | ||
2657 | PVR2_CTL_WRITE_ENDPOINT), | ||
2658 | hdw->ctl_write_buffer, | ||
2659 | write_len, | ||
2660 | pvr2_ctl_write_complete, | ||
2661 | hdw); | ||
2662 | hdw->ctl_write_urb->actual_length = 0; | ||
2663 | hdw->ctl_write_pend_flag = !0; | ||
2664 | status = usb_submit_urb(hdw->ctl_write_urb,GFP_KERNEL); | ||
2665 | if (status < 0) { | ||
2666 | pvr2_trace(PVR2_TRACE_ERROR_LEGS, | ||
2667 | "Failed to submit write-control" | ||
2668 | " URB status=%d",status); | ||
2669 | hdw->ctl_write_pend_flag = 0; | ||
2670 | goto done; | ||
2671 | } | ||
2672 | } | ||
2673 | |||
2674 | if (read_len) { | ||
2675 | hdw->cmd_debug_state = 3; | ||
2676 | memset(hdw->ctl_read_buffer,0x43,read_len); | ||
2677 | /* Initiate a read request */ | ||
2678 | usb_fill_bulk_urb(hdw->ctl_read_urb, | ||
2679 | hdw->usb_dev, | ||
2680 | usb_rcvbulkpipe(hdw->usb_dev, | ||
2681 | PVR2_CTL_READ_ENDPOINT), | ||
2682 | hdw->ctl_read_buffer, | ||
2683 | read_len, | ||
2684 | pvr2_ctl_read_complete, | ||
2685 | hdw); | ||
2686 | hdw->ctl_read_urb->actual_length = 0; | ||
2687 | hdw->ctl_read_pend_flag = !0; | ||
2688 | status = usb_submit_urb(hdw->ctl_read_urb,GFP_KERNEL); | ||
2689 | if (status < 0) { | ||
2690 | pvr2_trace(PVR2_TRACE_ERROR_LEGS, | ||
2691 | "Failed to submit read-control" | ||
2692 | " URB status=%d",status); | ||
2693 | hdw->ctl_read_pend_flag = 0; | ||
2694 | goto done; | ||
2695 | } | ||
2696 | } | ||
2697 | |||
2698 | /* Start timer */ | ||
2699 | add_timer(&timer); | ||
2700 | |||
2701 | /* Now wait for all I/O to complete */ | ||
2702 | hdw->cmd_debug_state = 4; | ||
2703 | while (hdw->ctl_write_pend_flag || hdw->ctl_read_pend_flag) { | ||
2704 | wait_for_completion(&hdw->ctl_done); | ||
2705 | } | ||
2706 | hdw->cmd_debug_state = 5; | ||
2707 | |||
2708 | /* Stop timer */ | ||
2709 | del_timer_sync(&timer); | ||
2710 | |||
2711 | hdw->cmd_debug_state = 6; | ||
2712 | status = 0; | ||
2713 | |||
2714 | if (hdw->ctl_timeout_flag) { | ||
2715 | status = -ETIMEDOUT; | ||
2716 | if (!probe_fl) { | ||
2717 | pvr2_trace(PVR2_TRACE_ERROR_LEGS, | ||
2718 | "Timed out control-write"); | ||
2719 | } | ||
2720 | goto done; | ||
2721 | } | ||
2722 | |||
2723 | if (write_len) { | ||
2724 | /* Validate results of write request */ | ||
2725 | if ((hdw->ctl_write_urb->status != 0) && | ||
2726 | (hdw->ctl_write_urb->status != -ENOENT) && | ||
2727 | (hdw->ctl_write_urb->status != -ESHUTDOWN) && | ||
2728 | (hdw->ctl_write_urb->status != -ECONNRESET)) { | ||
2729 | /* USB subsystem is reporting some kind of failure | ||
2730 | on the write */ | ||
2731 | status = hdw->ctl_write_urb->status; | ||
2732 | if (!probe_fl) { | ||
2733 | pvr2_trace(PVR2_TRACE_ERROR_LEGS, | ||
2734 | "control-write URB failure," | ||
2735 | " status=%d", | ||
2736 | status); | ||
2737 | } | ||
2738 | goto done; | ||
2739 | } | ||
2740 | if (hdw->ctl_write_urb->actual_length < write_len) { | ||
2741 | /* Failed to write enough data */ | ||
2742 | status = -EIO; | ||
2743 | if (!probe_fl) { | ||
2744 | pvr2_trace(PVR2_TRACE_ERROR_LEGS, | ||
2745 | "control-write URB short," | ||
2746 | " expected=%d got=%d", | ||
2747 | write_len, | ||
2748 | hdw->ctl_write_urb->actual_length); | ||
2749 | } | ||
2750 | goto done; | ||
2751 | } | ||
2752 | } | ||
2753 | if (read_len) { | ||
2754 | /* Validate results of read request */ | ||
2755 | if ((hdw->ctl_read_urb->status != 0) && | ||
2756 | (hdw->ctl_read_urb->status != -ENOENT) && | ||
2757 | (hdw->ctl_read_urb->status != -ESHUTDOWN) && | ||
2758 | (hdw->ctl_read_urb->status != -ECONNRESET)) { | ||
2759 | /* USB subsystem is reporting some kind of failure | ||
2760 | on the read */ | ||
2761 | status = hdw->ctl_read_urb->status; | ||
2762 | if (!probe_fl) { | ||
2763 | pvr2_trace(PVR2_TRACE_ERROR_LEGS, | ||
2764 | "control-read URB failure," | ||
2765 | " status=%d", | ||
2766 | status); | ||
2767 | } | ||
2768 | goto done; | ||
2769 | } | ||
2770 | if (hdw->ctl_read_urb->actual_length < read_len) { | ||
2771 | /* Failed to read enough data */ | ||
2772 | status = -EIO; | ||
2773 | if (!probe_fl) { | ||
2774 | pvr2_trace(PVR2_TRACE_ERROR_LEGS, | ||
2775 | "control-read URB short," | ||
2776 | " expected=%d got=%d", | ||
2777 | read_len, | ||
2778 | hdw->ctl_read_urb->actual_length); | ||
2779 | } | ||
2780 | goto done; | ||
2781 | } | ||
2782 | /* Transfer retrieved data out from internal buffer */ | ||
2783 | for (idx = 0; idx < read_len; idx++) { | ||
2784 | ((unsigned char *)read_data)[idx] = | ||
2785 | hdw->ctl_read_buffer[idx]; | ||
2786 | } | ||
2787 | } | ||
2788 | |||
2789 | done: | ||
2790 | |||
2791 | hdw->cmd_debug_state = 0; | ||
2792 | if ((status < 0) && (!probe_fl)) { | ||
2793 | pvr2_hdw_render_useless_unlocked(hdw); | ||
2794 | } | ||
2795 | return status; | ||
2796 | } | ||
2797 | |||
2798 | |||
2799 | int pvr2_send_request(struct pvr2_hdw *hdw, | ||
2800 | void *write_data,unsigned int write_len, | ||
2801 | void *read_data,unsigned int read_len) | ||
2802 | { | ||
2803 | return pvr2_send_request_ex(hdw,HZ*4,0, | ||
2804 | write_data,write_len, | ||
2805 | read_data,read_len); | ||
2806 | } | ||
2807 | |||
2808 | int pvr2_write_register(struct pvr2_hdw *hdw, u16 reg, u32 data) | ||
2809 | { | ||
2810 | int ret; | ||
2811 | |||
2812 | LOCK_TAKE(hdw->ctl_lock); | ||
2813 | |||
2814 | hdw->cmd_buffer[0] = 0x04; /* write register prefix */ | ||
2815 | PVR2_DECOMPOSE_LE(hdw->cmd_buffer,1,data); | ||
2816 | hdw->cmd_buffer[5] = 0; | ||
2817 | hdw->cmd_buffer[6] = (reg >> 8) & 0xff; | ||
2818 | hdw->cmd_buffer[7] = reg & 0xff; | ||
2819 | |||
2820 | |||
2821 | ret = pvr2_send_request(hdw, hdw->cmd_buffer, 8, hdw->cmd_buffer, 0); | ||
2822 | |||
2823 | LOCK_GIVE(hdw->ctl_lock); | ||
2824 | |||
2825 | return ret; | ||
2826 | } | ||
2827 | |||
2828 | |||
2829 | int pvr2_read_register(struct pvr2_hdw *hdw, u16 reg, u32 *data) | ||
2830 | { | ||
2831 | int ret = 0; | ||
2832 | |||
2833 | LOCK_TAKE(hdw->ctl_lock); | ||
2834 | |||
2835 | hdw->cmd_buffer[0] = 0x05; /* read register prefix */ | ||
2836 | hdw->cmd_buffer[1] = 0; | ||
2837 | hdw->cmd_buffer[2] = 0; | ||
2838 | hdw->cmd_buffer[3] = 0; | ||
2839 | hdw->cmd_buffer[4] = 0; | ||
2840 | hdw->cmd_buffer[5] = 0; | ||
2841 | hdw->cmd_buffer[6] = (reg >> 8) & 0xff; | ||
2842 | hdw->cmd_buffer[7] = reg & 0xff; | ||
2843 | |||
2844 | ret |= pvr2_send_request(hdw, hdw->cmd_buffer, 8, hdw->cmd_buffer, 4); | ||
2845 | *data = PVR2_COMPOSE_LE(hdw->cmd_buffer,0); | ||
2846 | |||
2847 | LOCK_GIVE(hdw->ctl_lock); | ||
2848 | |||
2849 | return ret; | ||
2850 | } | ||
2851 | |||
2852 | |||
2853 | int pvr2_write_u16(struct pvr2_hdw *hdw, u16 data, int res) | ||
2854 | { | ||
2855 | int ret; | ||
2856 | |||
2857 | LOCK_TAKE(hdw->ctl_lock); | ||
2858 | |||
2859 | hdw->cmd_buffer[0] = (data >> 8) & 0xff; | ||
2860 | hdw->cmd_buffer[1] = data & 0xff; | ||
2861 | |||
2862 | ret = pvr2_send_request(hdw, hdw->cmd_buffer, 2, hdw->cmd_buffer, res); | ||
2863 | |||
2864 | LOCK_GIVE(hdw->ctl_lock); | ||
2865 | |||
2866 | return ret; | ||
2867 | } | ||
2868 | |||
2869 | |||
2870 | int pvr2_write_u8(struct pvr2_hdw *hdw, u8 data, int res) | ||
2871 | { | ||
2872 | int ret; | ||
2873 | |||
2874 | LOCK_TAKE(hdw->ctl_lock); | ||
2875 | |||
2876 | hdw->cmd_buffer[0] = data; | ||
2877 | |||
2878 | ret = pvr2_send_request(hdw, hdw->cmd_buffer, 1, hdw->cmd_buffer, res); | ||
2879 | |||
2880 | LOCK_GIVE(hdw->ctl_lock); | ||
2881 | |||
2882 | return ret; | ||
2883 | } | ||
2884 | |||
2885 | |||
2886 | void pvr2_hdw_render_useless_unlocked(struct pvr2_hdw *hdw) | ||
2887 | { | ||
2888 | if (!hdw->flag_ok) return; | ||
2889 | pvr2_trace(PVR2_TRACE_INIT,"render_useless"); | ||
2890 | hdw->flag_ok = 0; | ||
2891 | if (hdw->vid_stream) { | ||
2892 | pvr2_stream_setup(hdw->vid_stream,0,0,0); | ||
2893 | } | ||
2894 | hdw->flag_streaming_enabled = 0; | ||
2895 | hdw->subsys_enabled_mask = 0; | ||
2896 | } | ||
2897 | |||
2898 | |||
2899 | void pvr2_hdw_render_useless(struct pvr2_hdw *hdw) | ||
2900 | { | ||
2901 | LOCK_TAKE(hdw->ctl_lock); | ||
2902 | pvr2_hdw_render_useless_unlocked(hdw); | ||
2903 | LOCK_GIVE(hdw->ctl_lock); | ||
2904 | } | ||
2905 | |||
2906 | |||
2907 | void pvr2_hdw_device_reset(struct pvr2_hdw *hdw) | ||
2908 | { | ||
2909 | int ret; | ||
2910 | pvr2_trace(PVR2_TRACE_INIT,"Performing a device reset..."); | ||
2911 | ret = usb_lock_device_for_reset(hdw->usb_dev,0); | ||
2912 | if (ret == 1) { | ||
2913 | ret = usb_reset_device(hdw->usb_dev); | ||
2914 | usb_unlock_device(hdw->usb_dev); | ||
2915 | } else { | ||
2916 | pvr2_trace(PVR2_TRACE_ERROR_LEGS, | ||
2917 | "Failed to lock USB device ret=%d",ret); | ||
2918 | } | ||
2919 | if (init_pause_msec) { | ||
2920 | pvr2_trace(PVR2_TRACE_INFO, | ||
2921 | "Waiting %u msec for hardware to settle", | ||
2922 | init_pause_msec); | ||
2923 | msleep(init_pause_msec); | ||
2924 | } | ||
2925 | |||
2926 | } | ||
2927 | |||
2928 | |||
2929 | void pvr2_hdw_cpureset_assert(struct pvr2_hdw *hdw,int val) | ||
2930 | { | ||
2931 | char da[1]; | ||
2932 | unsigned int pipe; | ||
2933 | int ret; | ||
2934 | |||
2935 | if (!hdw->usb_dev) return; | ||
2936 | |||
2937 | pvr2_trace(PVR2_TRACE_INIT,"cpureset_assert(%d)",val); | ||
2938 | |||
2939 | da[0] = val ? 0x01 : 0x00; | ||
2940 | |||
2941 | /* Write the CPUCS register on the 8051. The lsb of the register | ||
2942 | is the reset bit; a 1 asserts reset while a 0 clears it. */ | ||
2943 | pipe = usb_sndctrlpipe(hdw->usb_dev, 0); | ||
2944 | ret = usb_control_msg(hdw->usb_dev,pipe,0xa0,0x40,0xe600,0,da,1,HZ); | ||
2945 | if (ret < 0) { | ||
2946 | pvr2_trace(PVR2_TRACE_ERROR_LEGS, | ||
2947 | "cpureset_assert(%d) error=%d",val,ret); | ||
2948 | pvr2_hdw_render_useless(hdw); | ||
2949 | } | ||
2950 | } | ||
2951 | |||
2952 | |||
2953 | int pvr2_hdw_cmd_deep_reset(struct pvr2_hdw *hdw) | ||
2954 | { | ||
2955 | int status; | ||
2956 | LOCK_TAKE(hdw->ctl_lock); do { | ||
2957 | pvr2_trace(PVR2_TRACE_INIT,"Requesting uproc hard reset"); | ||
2958 | hdw->flag_ok = !0; | ||
2959 | hdw->cmd_buffer[0] = 0xdd; | ||
2960 | status = pvr2_send_request(hdw,hdw->cmd_buffer,1,0,0); | ||
2961 | } while (0); LOCK_GIVE(hdw->ctl_lock); | ||
2962 | return status; | ||
2963 | } | ||
2964 | |||
2965 | |||
2966 | int pvr2_hdw_cmd_powerup(struct pvr2_hdw *hdw) | ||
2967 | { | ||
2968 | int status; | ||
2969 | LOCK_TAKE(hdw->ctl_lock); do { | ||
2970 | pvr2_trace(PVR2_TRACE_INIT,"Requesting powerup"); | ||
2971 | hdw->cmd_buffer[0] = 0xde; | ||
2972 | status = pvr2_send_request(hdw,hdw->cmd_buffer,1,0,0); | ||
2973 | } while (0); LOCK_GIVE(hdw->ctl_lock); | ||
2974 | return status; | ||
2975 | } | ||
2976 | |||
2977 | |||
2978 | int pvr2_hdw_cmd_decoder_reset(struct pvr2_hdw *hdw) | ||
2979 | { | ||
2980 | if (!hdw->decoder_ctrl) { | ||
2981 | pvr2_trace(PVR2_TRACE_INIT, | ||
2982 | "Unable to reset decoder: nothing attached"); | ||
2983 | return -ENOTTY; | ||
2984 | } | ||
2985 | |||
2986 | if (!hdw->decoder_ctrl->force_reset) { | ||
2987 | pvr2_trace(PVR2_TRACE_INIT, | ||
2988 | "Unable to reset decoder: not implemented"); | ||
2989 | return -ENOTTY; | ||
2990 | } | ||
2991 | |||
2992 | pvr2_trace(PVR2_TRACE_INIT, | ||
2993 | "Requesting decoder reset"); | ||
2994 | hdw->decoder_ctrl->force_reset(hdw->decoder_ctrl->ctxt); | ||
2995 | return 0; | ||
2996 | } | ||
2997 | |||
2998 | |||
2999 | int pvr2_hdw_cmd_usbstream(struct pvr2_hdw *hdw,int runFl) | ||
3000 | { | ||
3001 | int status; | ||
3002 | LOCK_TAKE(hdw->ctl_lock); do { | ||
3003 | hdw->cmd_buffer[0] = (runFl ? 0x36 : 0x37); | ||
3004 | status = pvr2_send_request(hdw,hdw->cmd_buffer,1,0,0); | ||
3005 | } while (0); LOCK_GIVE(hdw->ctl_lock); | ||
3006 | if (!status) { | ||
3007 | hdw->subsys_enabled_mask = | ||
3008 | ((hdw->subsys_enabled_mask & | ||
3009 | ~(1<<PVR2_SUBSYS_B_USBSTREAM_RUN)) | | ||
3010 | (runFl ? (1<<PVR2_SUBSYS_B_USBSTREAM_RUN) : 0)); | ||
3011 | } | ||
3012 | return status; | ||
3013 | } | ||
3014 | |||
3015 | |||
3016 | void pvr2_hdw_get_debug_info(const struct pvr2_hdw *hdw, | ||
3017 | struct pvr2_hdw_debug_info *ptr) | ||
3018 | { | ||
3019 | ptr->big_lock_held = hdw->big_lock_held; | ||
3020 | ptr->ctl_lock_held = hdw->ctl_lock_held; | ||
3021 | ptr->flag_ok = hdw->flag_ok; | ||
3022 | ptr->flag_disconnected = hdw->flag_disconnected; | ||
3023 | ptr->flag_init_ok = hdw->flag_init_ok; | ||
3024 | ptr->flag_streaming_enabled = hdw->flag_streaming_enabled; | ||
3025 | ptr->subsys_flags = hdw->subsys_enabled_mask; | ||
3026 | ptr->cmd_debug_state = hdw->cmd_debug_state; | ||
3027 | ptr->cmd_code = hdw->cmd_debug_code; | ||
3028 | ptr->cmd_debug_write_len = hdw->cmd_debug_write_len; | ||
3029 | ptr->cmd_debug_read_len = hdw->cmd_debug_read_len; | ||
3030 | ptr->cmd_debug_timeout = hdw->ctl_timeout_flag; | ||
3031 | ptr->cmd_debug_write_pend = hdw->ctl_write_pend_flag; | ||
3032 | ptr->cmd_debug_read_pend = hdw->ctl_read_pend_flag; | ||
3033 | ptr->cmd_debug_rstatus = hdw->ctl_read_urb->status; | ||
3034 | ptr->cmd_debug_wstatus = hdw->ctl_read_urb->status; | ||
3035 | } | ||
3036 | |||
3037 | |||
3038 | int pvr2_hdw_gpio_get_dir(struct pvr2_hdw *hdw,u32 *dp) | ||
3039 | { | ||
3040 | return pvr2_read_register(hdw,PVR2_GPIO_DIR,dp); | ||
3041 | } | ||
3042 | |||
3043 | |||
3044 | int pvr2_hdw_gpio_get_out(struct pvr2_hdw *hdw,u32 *dp) | ||
3045 | { | ||
3046 | return pvr2_read_register(hdw,PVR2_GPIO_OUT,dp); | ||
3047 | } | ||
3048 | |||
3049 | |||
3050 | int pvr2_hdw_gpio_get_in(struct pvr2_hdw *hdw,u32 *dp) | ||
3051 | { | ||
3052 | return pvr2_read_register(hdw,PVR2_GPIO_IN,dp); | ||
3053 | } | ||
3054 | |||
3055 | |||
3056 | int pvr2_hdw_gpio_chg_dir(struct pvr2_hdw *hdw,u32 msk,u32 val) | ||
3057 | { | ||
3058 | u32 cval,nval; | ||
3059 | int ret; | ||
3060 | if (~msk) { | ||
3061 | ret = pvr2_read_register(hdw,PVR2_GPIO_DIR,&cval); | ||
3062 | if (ret) return ret; | ||
3063 | nval = (cval & ~msk) | (val & msk); | ||
3064 | pvr2_trace(PVR2_TRACE_GPIO, | ||
3065 | "GPIO direction changing 0x%x:0x%x" | ||
3066 | " from 0x%x to 0x%x", | ||
3067 | msk,val,cval,nval); | ||
3068 | } else { | ||
3069 | nval = val; | ||
3070 | pvr2_trace(PVR2_TRACE_GPIO, | ||
3071 | "GPIO direction changing to 0x%x",nval); | ||
3072 | } | ||
3073 | return pvr2_write_register(hdw,PVR2_GPIO_DIR,nval); | ||
3074 | } | ||
3075 | |||
3076 | |||
3077 | int pvr2_hdw_gpio_chg_out(struct pvr2_hdw *hdw,u32 msk,u32 val) | ||
3078 | { | ||
3079 | u32 cval,nval; | ||
3080 | int ret; | ||
3081 | if (~msk) { | ||
3082 | ret = pvr2_read_register(hdw,PVR2_GPIO_OUT,&cval); | ||
3083 | if (ret) return ret; | ||
3084 | nval = (cval & ~msk) | (val & msk); | ||
3085 | pvr2_trace(PVR2_TRACE_GPIO, | ||
3086 | "GPIO output changing 0x%x:0x%x from 0x%x to 0x%x", | ||
3087 | msk,val,cval,nval); | ||
3088 | } else { | ||
3089 | nval = val; | ||
3090 | pvr2_trace(PVR2_TRACE_GPIO, | ||
3091 | "GPIO output changing to 0x%x",nval); | ||
3092 | } | ||
3093 | return pvr2_write_register(hdw,PVR2_GPIO_OUT,nval); | ||
3094 | } | ||
3095 | |||
3096 | |||
3097 | int pvr2_hdw_get_eeprom_addr(struct pvr2_hdw *hdw) | ||
3098 | { | ||
3099 | int result; | ||
3100 | LOCK_TAKE(hdw->ctl_lock); do { | ||
3101 | hdw->cmd_buffer[0] = 0xeb; | ||
3102 | result = pvr2_send_request(hdw, | ||
3103 | hdw->cmd_buffer,1, | ||
3104 | hdw->cmd_buffer,1); | ||
3105 | if (result < 0) break; | ||
3106 | result = hdw->cmd_buffer[0]; | ||
3107 | } while(0); LOCK_GIVE(hdw->ctl_lock); | ||
3108 | return result; | ||
3109 | } | ||
3110 | |||
3111 | |||
3112 | /* | ||
3113 | Stuff for Emacs to see, in order to encourage consistent editing style: | ||
3114 | *** Local Variables: *** | ||
3115 | *** mode: c *** | ||
3116 | *** fill-column: 75 *** | ||
3117 | *** tab-width: 8 *** | ||
3118 | *** c-basic-offset: 8 *** | ||
3119 | *** End: *** | ||
3120 | */ | ||
diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw.h b/drivers/media/video/pvrusb2/pvrusb2-hdw.h new file mode 100644 index 000000000000..63f529154431 --- /dev/null +++ b/drivers/media/video/pvrusb2/pvrusb2-hdw.h | |||
@@ -0,0 +1,335 @@ | |||
1 | /* | ||
2 | * | ||
3 | * $Id$ | ||
4 | * | ||
5 | * Copyright (C) 2005 Mike Isely <isely@pobox.com> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License as published by | ||
9 | * the Free Software Foundation; either version 2 of the License | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
19 | * | ||
20 | */ | ||
21 | #ifndef __PVRUSB2_HDW_H | ||
22 | #define __PVRUSB2_HDW_H | ||
23 | |||
24 | #include <linux/usb.h> | ||
25 | #include <linux/videodev2.h> | ||
26 | #include "pvrusb2-io.h" | ||
27 | #include "pvrusb2-ctrl.h" | ||
28 | |||
29 | |||
30 | /* Private internal control ids, look these up with | ||
31 | pvr2_hdw_get_ctrl_by_id() - these are NOT visible in V4L */ | ||
32 | #define PVR2_CID_STDENUM 1 | ||
33 | #define PVR2_CID_STDCUR 2 | ||
34 | #define PVR2_CID_STDAVAIL 3 | ||
35 | #define PVR2_CID_INPUT 4 | ||
36 | #define PVR2_CID_AUDIOMODE 5 | ||
37 | #define PVR2_CID_FREQUENCY 6 | ||
38 | #define PVR2_CID_HRES 7 | ||
39 | #define PVR2_CID_VRES 8 | ||
40 | |||
41 | /* Legal values for the INPUT state variable */ | ||
42 | #define PVR2_CVAL_INPUT_TV 0 | ||
43 | #define PVR2_CVAL_INPUT_SVIDEO 1 | ||
44 | #define PVR2_CVAL_INPUT_COMPOSITE 2 | ||
45 | #define PVR2_CVAL_INPUT_RADIO 3 | ||
46 | |||
47 | /* Values that pvr2_hdw_get_signal_status() returns */ | ||
48 | #define PVR2_SIGNAL_OK 0x0001 | ||
49 | #define PVR2_SIGNAL_STEREO 0x0002 | ||
50 | #define PVR2_SIGNAL_SAP 0x0004 | ||
51 | |||
52 | |||
53 | /* Subsystem definitions - these are various pieces that can be | ||
54 | independently stopped / started. Usually you don't want to mess with | ||
55 | this directly (let the driver handle things itself), but it is useful | ||
56 | for debugging. */ | ||
57 | #define PVR2_SUBSYS_B_ENC_FIRMWARE 0 | ||
58 | #define PVR2_SUBSYS_B_ENC_CFG 1 | ||
59 | #define PVR2_SUBSYS_B_DIGITIZER_RUN 2 | ||
60 | #define PVR2_SUBSYS_B_USBSTREAM_RUN 3 | ||
61 | #define PVR2_SUBSYS_B_ENC_RUN 4 | ||
62 | |||
63 | #define PVR2_SUBSYS_CFG_ALL ( \ | ||
64 | (1 << PVR2_SUBSYS_B_ENC_FIRMWARE) | \ | ||
65 | (1 << PVR2_SUBSYS_B_ENC_CFG) ) | ||
66 | #define PVR2_SUBSYS_RUN_ALL ( \ | ||
67 | (1 << PVR2_SUBSYS_B_DIGITIZER_RUN) | \ | ||
68 | (1 << PVR2_SUBSYS_B_USBSTREAM_RUN) | \ | ||
69 | (1 << PVR2_SUBSYS_B_ENC_RUN) ) | ||
70 | #define PVR2_SUBSYS_ALL ( \ | ||
71 | PVR2_SUBSYS_CFG_ALL | \ | ||
72 | PVR2_SUBSYS_RUN_ALL ) | ||
73 | |||
74 | enum pvr2_config { | ||
75 | pvr2_config_empty, | ||
76 | pvr2_config_mpeg, | ||
77 | pvr2_config_vbi, | ||
78 | pvr2_config_radio, | ||
79 | }; | ||
80 | |||
81 | const char *pvr2_config_get_name(enum pvr2_config); | ||
82 | |||
83 | struct pvr2_hdw; | ||
84 | |||
85 | /* Create and return a structure for interacting with the underlying | ||
86 | hardware */ | ||
87 | struct pvr2_hdw *pvr2_hdw_create(struct usb_interface *intf, | ||
88 | const struct usb_device_id *devid); | ||
89 | |||
90 | /* Poll for background activity (if any) */ | ||
91 | void pvr2_hdw_poll(struct pvr2_hdw *); | ||
92 | |||
93 | /* Trigger a poll to take place later at a convenient time */ | ||
94 | void pvr2_hdw_poll_trigger(struct pvr2_hdw *); | ||
95 | void pvr2_hdw_poll_trigger_unlocked(struct pvr2_hdw *); | ||
96 | |||
97 | /* Register a callback used to trigger a future poll */ | ||
98 | void pvr2_hdw_setup_poll_trigger(struct pvr2_hdw *, | ||
99 | void (*func)(void *), | ||
100 | void *data); | ||
101 | |||
102 | /* Get pointer to structure given unit number */ | ||
103 | struct pvr2_hdw *pvr2_hdw_find(int unit_number); | ||
104 | |||
105 | /* Destroy hardware interaction structure */ | ||
106 | void pvr2_hdw_destroy(struct pvr2_hdw *); | ||
107 | |||
108 | /* Set up the structure and attempt to put the device into a usable state. | ||
109 | This can be a time-consuming operation, which is why it is not done | ||
110 | internally as part of the create() step. Return value is exactly the | ||
111 | same as pvr2_hdw_init_ok(). */ | ||
112 | int pvr2_hdw_setup(struct pvr2_hdw *); | ||
113 | |||
114 | /* Initialization succeeded */ | ||
115 | int pvr2_hdw_init_ok(struct pvr2_hdw *); | ||
116 | |||
117 | /* Return true if in the ready (normal) state */ | ||
118 | int pvr2_hdw_dev_ok(struct pvr2_hdw *); | ||
119 | |||
120 | /* Return small integer number [1..N] for logical instance number of this | ||
121 | device. This is useful for indexing array-valued module parameters. */ | ||
122 | int pvr2_hdw_get_unit_number(struct pvr2_hdw *); | ||
123 | |||
124 | /* Get pointer to underlying USB device */ | ||
125 | struct usb_device *pvr2_hdw_get_dev(struct pvr2_hdw *); | ||
126 | |||
127 | /* Retrieve serial number of device */ | ||
128 | unsigned long pvr2_hdw_get_sn(struct pvr2_hdw *); | ||
129 | |||
130 | /* Called when hardware has been unplugged */ | ||
131 | void pvr2_hdw_disconnect(struct pvr2_hdw *); | ||
132 | |||
133 | /* Get the number of defined controls */ | ||
134 | unsigned int pvr2_hdw_get_ctrl_count(struct pvr2_hdw *); | ||
135 | |||
136 | /* Retrieve a control handle given its index (0..count-1) */ | ||
137 | struct pvr2_ctrl *pvr2_hdw_get_ctrl_by_index(struct pvr2_hdw *,unsigned int); | ||
138 | |||
139 | /* Retrieve a control handle given its internal ID (if any) */ | ||
140 | struct pvr2_ctrl *pvr2_hdw_get_ctrl_by_id(struct pvr2_hdw *,unsigned int); | ||
141 | |||
142 | /* Retrieve a control handle given its V4L ID (if any) */ | ||
143 | struct pvr2_ctrl *pvr2_hdw_get_ctrl_v4l(struct pvr2_hdw *,unsigned int ctl_id); | ||
144 | |||
145 | /* Retrieve a control handle given its immediate predecessor V4L ID (if any) */ | ||
146 | struct pvr2_ctrl *pvr2_hdw_get_ctrl_nextv4l(struct pvr2_hdw *, | ||
147 | unsigned int ctl_id); | ||
148 | |||
149 | /* Commit all control changes made up to this point */ | ||
150 | int pvr2_hdw_commit_ctl(struct pvr2_hdw *); | ||
151 | |||
152 | /* Return name for this driver instance */ | ||
153 | const char *pvr2_hdw_get_driver_name(struct pvr2_hdw *); | ||
154 | |||
155 | /* Return PVR2_SIGNAL_XXXX bit mask indicating signal status */ | ||
156 | unsigned int pvr2_hdw_get_signal_status(struct pvr2_hdw *); | ||
157 | |||
158 | /* Query device and see if it thinks it is on a high-speed USB link */ | ||
159 | int pvr2_hdw_is_hsm(struct pvr2_hdw *); | ||
160 | |||
161 | /* Turn streaming on/off */ | ||
162 | int pvr2_hdw_set_streaming(struct pvr2_hdw *,int); | ||
163 | |||
164 | /* Find out if streaming is on */ | ||
165 | int pvr2_hdw_get_streaming(struct pvr2_hdw *); | ||
166 | |||
167 | /* Configure the type of stream to generate */ | ||
168 | int pvr2_hdw_set_stream_type(struct pvr2_hdw *, enum pvr2_config); | ||
169 | |||
170 | /* Get handle to video output stream */ | ||
171 | struct pvr2_stream *pvr2_hdw_get_video_stream(struct pvr2_hdw *); | ||
172 | |||
173 | /* Emit a video standard struct */ | ||
174 | int pvr2_hdw_get_stdenum_value(struct pvr2_hdw *hdw,struct v4l2_standard *std, | ||
175 | unsigned int idx); | ||
176 | |||
177 | /* Enable / disable various pieces of hardware. Items to change are | ||
178 | identified by bit positions within msk, and new state for each item is | ||
179 | identified by corresponding bit positions within val. */ | ||
180 | void pvr2_hdw_subsys_bit_chg(struct pvr2_hdw *hdw, | ||
181 | unsigned long msk,unsigned long val); | ||
182 | |||
183 | /* Shortcut for pvr2_hdw_subsys_bit_chg(hdw,msk,msk) */ | ||
184 | void pvr2_hdw_subsys_bit_set(struct pvr2_hdw *hdw,unsigned long msk); | ||
185 | |||
186 | /* Shortcut for pvr2_hdw_subsys_bit_chg(hdw,msk,0) */ | ||
187 | void pvr2_hdw_subsys_bit_clr(struct pvr2_hdw *hdw,unsigned long msk); | ||
188 | |||
189 | /* Retrieve mask indicating which pieces of hardware are currently enabled | ||
190 | / configured. */ | ||
191 | unsigned long pvr2_hdw_subsys_get(struct pvr2_hdw *); | ||
192 | |||
193 | /* Adjust mask of what get shut down when streaming is stopped. This is a | ||
194 | debugging aid. */ | ||
195 | void pvr2_hdw_subsys_stream_bit_chg(struct pvr2_hdw *hdw, | ||
196 | unsigned long msk,unsigned long val); | ||
197 | |||
198 | /* Retrieve mask indicating which pieces of hardware are disabled when | ||
199 | streaming is turned off. */ | ||
200 | unsigned long pvr2_hdw_subsys_stream_get(struct pvr2_hdw *); | ||
201 | |||
202 | |||
203 | /* Enable / disable retrieval of CPU firmware. This must be enabled before | ||
204 | pvr2_hdw_cpufw_get() will function. Note that doing this may prevent | ||
205 | the device from running (and leaving this mode may imply a device | ||
206 | reset). */ | ||
207 | void pvr2_hdw_cpufw_set_enabled(struct pvr2_hdw *, int enable_flag); | ||
208 | |||
209 | /* Return true if we're in a mode for retrieval CPU firmware */ | ||
210 | int pvr2_hdw_cpufw_get_enabled(struct pvr2_hdw *); | ||
211 | |||
212 | /* Retrieve a piece of the CPU's firmware at the given offset. Return | ||
213 | value is the number of bytes retrieved or zero if we're past the end or | ||
214 | an error otherwise (e.g. if firmware retrieval is not enabled). */ | ||
215 | int pvr2_hdw_cpufw_get(struct pvr2_hdw *,unsigned int offs, | ||
216 | char *buf,unsigned int cnt); | ||
217 | |||
218 | /* Retrieve previously stored v4l minor device number */ | ||
219 | int pvr2_hdw_v4l_get_minor_number(struct pvr2_hdw *); | ||
220 | |||
221 | /* Store the v4l minor device number */ | ||
222 | void pvr2_hdw_v4l_store_minor_number(struct pvr2_hdw *,int); | ||
223 | |||
224 | |||
225 | /* The following entry points are all lower level things you normally don't | ||
226 | want to worry about. */ | ||
227 | |||
228 | /* Attempt to recover from a USB foul-up (in practice I find that if you | ||
229 | have to do this, then it's already too late). */ | ||
230 | void pvr2_reset_ctl_endpoints(struct pvr2_hdw *hdw); | ||
231 | |||
232 | /* Issue a command and get a response from the device. LOTS of higher | ||
233 | level stuff is built on this. */ | ||
234 | int pvr2_send_request(struct pvr2_hdw *, | ||
235 | void *write_ptr,unsigned int write_len, | ||
236 | void *read_ptr,unsigned int read_len); | ||
237 | |||
238 | /* Issue a command and get a response from the device. This extended | ||
239 | version includes a probe flag (which if set means that device errors | ||
240 | should not be logged or treated as fatal) and a timeout in jiffies. | ||
241 | This can be used to non-lethally probe the health of endpoint 1. */ | ||
242 | int pvr2_send_request_ex(struct pvr2_hdw *,unsigned int timeout,int probe_fl, | ||
243 | void *write_ptr,unsigned int write_len, | ||
244 | void *read_ptr,unsigned int read_len); | ||
245 | |||
246 | /* Slightly higher level device communication functions. */ | ||
247 | int pvr2_write_register(struct pvr2_hdw *, u16, u32); | ||
248 | int pvr2_read_register(struct pvr2_hdw *, u16, u32 *); | ||
249 | int pvr2_write_u16(struct pvr2_hdw *, u16, int); | ||
250 | int pvr2_write_u8(struct pvr2_hdw *, u8, int); | ||
251 | |||
252 | /* Call if for any reason we can't talk to the hardware anymore - this will | ||
253 | cause the driver to stop flailing on the device. */ | ||
254 | void pvr2_hdw_render_useless(struct pvr2_hdw *); | ||
255 | void pvr2_hdw_render_useless_unlocked(struct pvr2_hdw *); | ||
256 | |||
257 | /* Set / clear 8051's reset bit */ | ||
258 | void pvr2_hdw_cpureset_assert(struct pvr2_hdw *,int); | ||
259 | |||
260 | /* Execute a USB-commanded device reset */ | ||
261 | void pvr2_hdw_device_reset(struct pvr2_hdw *); | ||
262 | |||
263 | /* Execute hard reset command (after this point it's likely that the | ||
264 | encoder will have to be reconfigured). This also clears the "useless" | ||
265 | state. */ | ||
266 | int pvr2_hdw_cmd_deep_reset(struct pvr2_hdw *); | ||
267 | |||
268 | /* Execute simple reset command */ | ||
269 | int pvr2_hdw_cmd_powerup(struct pvr2_hdw *); | ||
270 | |||
271 | /* Order decoder to reset */ | ||
272 | int pvr2_hdw_cmd_decoder_reset(struct pvr2_hdw *); | ||
273 | |||
274 | /* Stop / start video stream transport */ | ||
275 | int pvr2_hdw_cmd_usbstream(struct pvr2_hdw *hdw,int runFl); | ||
276 | |||
277 | /* Find I2C address of eeprom */ | ||
278 | int pvr2_hdw_get_eeprom_addr(struct pvr2_hdw *); | ||
279 | |||
280 | /* Direct manipulation of GPIO bits */ | ||
281 | int pvr2_hdw_gpio_get_dir(struct pvr2_hdw *hdw,u32 *); | ||
282 | int pvr2_hdw_gpio_get_out(struct pvr2_hdw *hdw,u32 *); | ||
283 | int pvr2_hdw_gpio_get_in(struct pvr2_hdw *hdw,u32 *); | ||
284 | int pvr2_hdw_gpio_chg_dir(struct pvr2_hdw *hdw,u32 msk,u32 val); | ||
285 | int pvr2_hdw_gpio_chg_out(struct pvr2_hdw *hdw,u32 msk,u32 val); | ||
286 | |||
287 | /* This data structure is specifically for the next function... */ | ||
288 | struct pvr2_hdw_debug_info { | ||
289 | int big_lock_held; | ||
290 | int ctl_lock_held; | ||
291 | int flag_ok; | ||
292 | int flag_disconnected; | ||
293 | int flag_init_ok; | ||
294 | int flag_streaming_enabled; | ||
295 | unsigned long subsys_flags; | ||
296 | int cmd_debug_state; | ||
297 | int cmd_debug_write_len; | ||
298 | int cmd_debug_read_len; | ||
299 | int cmd_debug_write_pend; | ||
300 | int cmd_debug_read_pend; | ||
301 | int cmd_debug_timeout; | ||
302 | int cmd_debug_rstatus; | ||
303 | int cmd_debug_wstatus; | ||
304 | unsigned char cmd_code; | ||
305 | }; | ||
306 | |||
307 | /* Non-intrusively retrieve internal state info - this is useful for | ||
308 | diagnosing lockups. Note that this operation is completed without any | ||
309 | kind of locking and so it is not atomic and may yield inconsistent | ||
310 | results. This is *purely* a debugging aid. */ | ||
311 | void pvr2_hdw_get_debug_info(const struct pvr2_hdw *hdw, | ||
312 | struct pvr2_hdw_debug_info *); | ||
313 | |||
314 | /* Cause modules to log their state once */ | ||
315 | void pvr2_hdw_trigger_module_log(struct pvr2_hdw *hdw); | ||
316 | |||
317 | /* Cause encoder firmware to be uploaded into the device. This is normally | ||
318 | done autonomously, but the interface is exported here because it is also | ||
319 | a debugging aid. */ | ||
320 | int pvr2_upload_firmware2(struct pvr2_hdw *hdw); | ||
321 | |||
322 | /* List of device types that we can match */ | ||
323 | extern struct usb_device_id pvr2_device_table[]; | ||
324 | |||
325 | #endif /* __PVRUSB2_HDW_H */ | ||
326 | |||
327 | /* | ||
328 | Stuff for Emacs to see, in order to encourage consistent editing style: | ||
329 | *** Local Variables: *** | ||
330 | *** mode: c *** | ||
331 | *** fill-column: 75 *** | ||
332 | *** tab-width: 8 *** | ||
333 | *** c-basic-offset: 8 *** | ||
334 | *** End: *** | ||
335 | */ | ||
diff --git a/drivers/media/video/pvrusb2/pvrusb2-i2c-chips-v4l2.c b/drivers/media/video/pvrusb2/pvrusb2-i2c-chips-v4l2.c new file mode 100644 index 000000000000..1dd4f6249b99 --- /dev/null +++ b/drivers/media/video/pvrusb2/pvrusb2-i2c-chips-v4l2.c | |||
@@ -0,0 +1,115 @@ | |||
1 | /* | ||
2 | * | ||
3 | * $Id$ | ||
4 | * | ||
5 | * Copyright (C) 2005 Mike Isely <isely@pobox.com> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License as published by | ||
9 | * the Free Software Foundation; either version 2 of the License | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
19 | * | ||
20 | */ | ||
21 | |||
22 | #include "pvrusb2-i2c-core.h" | ||
23 | #include "pvrusb2-hdw-internal.h" | ||
24 | #include "pvrusb2-debug.h" | ||
25 | #include "pvrusb2-i2c-cmd-v4l2.h" | ||
26 | #include "pvrusb2-audio.h" | ||
27 | #include "pvrusb2-tuner.h" | ||
28 | #include "pvrusb2-demod.h" | ||
29 | #include "pvrusb2-video-v4l.h" | ||
30 | #ifdef CONFIG_VIDEO_PVRUSB2_24XXX | ||
31 | #include "pvrusb2-cx2584x-v4l.h" | ||
32 | #include "pvrusb2-wm8775.h" | ||
33 | #endif | ||
34 | |||
35 | #define trace_i2c(...) pvr2_trace(PVR2_TRACE_I2C,__VA_ARGS__) | ||
36 | |||
37 | #define OP_STANDARD 0 | ||
38 | #define OP_BCSH 1 | ||
39 | #define OP_VOLUME 2 | ||
40 | #define OP_FREQ 3 | ||
41 | #define OP_AUDIORATE 4 | ||
42 | #define OP_SIZE 5 | ||
43 | #define OP_LOG 6 | ||
44 | |||
45 | static const struct pvr2_i2c_op * const ops[] = { | ||
46 | [OP_STANDARD] = &pvr2_i2c_op_v4l2_standard, | ||
47 | [OP_BCSH] = &pvr2_i2c_op_v4l2_bcsh, | ||
48 | [OP_VOLUME] = &pvr2_i2c_op_v4l2_volume, | ||
49 | [OP_FREQ] = &pvr2_i2c_op_v4l2_frequency, | ||
50 | [OP_SIZE] = &pvr2_i2c_op_v4l2_size, | ||
51 | [OP_LOG] = &pvr2_i2c_op_v4l2_log, | ||
52 | }; | ||
53 | |||
54 | void pvr2_i2c_probe(struct pvr2_hdw *hdw,struct pvr2_i2c_client *cp) | ||
55 | { | ||
56 | int id; | ||
57 | id = cp->client->driver->id; | ||
58 | cp->ctl_mask = ((1 << OP_STANDARD) | | ||
59 | (1 << OP_BCSH) | | ||
60 | (1 << OP_VOLUME) | | ||
61 | (1 << OP_FREQ) | | ||
62 | (1 << OP_SIZE) | | ||
63 | (1 << OP_LOG)); | ||
64 | |||
65 | if (id == I2C_DRIVERID_MSP3400) { | ||
66 | if (pvr2_i2c_msp3400_setup(hdw,cp)) { | ||
67 | return; | ||
68 | } | ||
69 | } | ||
70 | if (id == I2C_DRIVERID_TUNER) { | ||
71 | if (pvr2_i2c_tuner_setup(hdw,cp)) { | ||
72 | return; | ||
73 | } | ||
74 | } | ||
75 | #ifdef CONFIG_VIDEO_PVRUSB2_24XXX | ||
76 | if (id == I2C_DRIVERID_CX25840) { | ||
77 | if (pvr2_i2c_cx2584x_v4l_setup(hdw,cp)) { | ||
78 | return; | ||
79 | } | ||
80 | } | ||
81 | if (id == I2C_DRIVERID_WM8775) { | ||
82 | if (pvr2_i2c_wm8775_setup(hdw,cp)) { | ||
83 | return; | ||
84 | } | ||
85 | } | ||
86 | #endif | ||
87 | if (id == I2C_DRIVERID_SAA711X) { | ||
88 | if (pvr2_i2c_decoder_v4l_setup(hdw,cp)) { | ||
89 | return; | ||
90 | } | ||
91 | } | ||
92 | if (id == I2C_DRIVERID_TDA9887) { | ||
93 | if (pvr2_i2c_demod_setup(hdw,cp)) { | ||
94 | return; | ||
95 | } | ||
96 | } | ||
97 | } | ||
98 | |||
99 | |||
100 | const struct pvr2_i2c_op *pvr2_i2c_get_op(unsigned int idx) | ||
101 | { | ||
102 | if (idx >= sizeof(ops)/sizeof(ops[0])) return 0; | ||
103 | return ops[idx]; | ||
104 | } | ||
105 | |||
106 | |||
107 | /* | ||
108 | Stuff for Emacs to see, in order to encourage consistent editing style: | ||
109 | *** Local Variables: *** | ||
110 | *** mode: c *** | ||
111 | *** fill-column: 75 *** | ||
112 | *** tab-width: 8 *** | ||
113 | *** c-basic-offset: 8 *** | ||
114 | *** End: *** | ||
115 | */ | ||
diff --git a/drivers/media/video/pvrusb2/pvrusb2-i2c-cmd-v4l2.c b/drivers/media/video/pvrusb2/pvrusb2-i2c-cmd-v4l2.c new file mode 100644 index 000000000000..9f81aff2b38a --- /dev/null +++ b/drivers/media/video/pvrusb2/pvrusb2-i2c-cmd-v4l2.c | |||
@@ -0,0 +1,232 @@ | |||
1 | /* | ||
2 | * | ||
3 | * $Id$ | ||
4 | * | ||
5 | * Copyright (C) 2005 Mike Isely <isely@pobox.com> | ||
6 | * Copyright (C) 2004 Aurelien Alleaume <slts@free.fr> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License as published by | ||
10 | * the Free Software Foundation; either version 2 of the License | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | * GNU General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU General Public License | ||
18 | * along with this program; if not, write to the Free Software | ||
19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
20 | * | ||
21 | */ | ||
22 | |||
23 | #include "pvrusb2-i2c-cmd-v4l2.h" | ||
24 | #include "pvrusb2-hdw-internal.h" | ||
25 | #include "pvrusb2-debug.h" | ||
26 | #include <linux/videodev2.h> | ||
27 | |||
28 | |||
29 | static void set_standard(struct pvr2_hdw *hdw) | ||
30 | { | ||
31 | v4l2_std_id vs; | ||
32 | vs = hdw->std_mask_cur; | ||
33 | pvr2_trace(PVR2_TRACE_CHIPS, | ||
34 | "i2c v4l2 set_standard(0x%llx)",(__u64)vs); | ||
35 | |||
36 | pvr2_i2c_core_cmd(hdw,VIDIOC_S_STD,&vs); | ||
37 | } | ||
38 | |||
39 | |||
40 | static int check_standard(struct pvr2_hdw *hdw) | ||
41 | { | ||
42 | return hdw->std_dirty != 0; | ||
43 | } | ||
44 | |||
45 | |||
46 | const struct pvr2_i2c_op pvr2_i2c_op_v4l2_standard = { | ||
47 | .check = check_standard, | ||
48 | .update = set_standard, | ||
49 | .name = "v4l2_standard", | ||
50 | }; | ||
51 | |||
52 | |||
53 | static void set_bcsh(struct pvr2_hdw *hdw) | ||
54 | { | ||
55 | struct v4l2_control ctrl; | ||
56 | pvr2_trace(PVR2_TRACE_CHIPS,"i2c v4l2 set_bcsh" | ||
57 | " b=%d c=%d s=%d h=%d", | ||
58 | hdw->brightness_val,hdw->contrast_val, | ||
59 | hdw->saturation_val,hdw->hue_val); | ||
60 | memset(&ctrl,0,sizeof(ctrl)); | ||
61 | ctrl.id = V4L2_CID_BRIGHTNESS; | ||
62 | ctrl.value = hdw->brightness_val; | ||
63 | pvr2_i2c_core_cmd(hdw,VIDIOC_S_CTRL,&ctrl); | ||
64 | ctrl.id = V4L2_CID_CONTRAST; | ||
65 | ctrl.value = hdw->contrast_val; | ||
66 | pvr2_i2c_core_cmd(hdw,VIDIOC_S_CTRL,&ctrl); | ||
67 | ctrl.id = V4L2_CID_SATURATION; | ||
68 | ctrl.value = hdw->saturation_val; | ||
69 | pvr2_i2c_core_cmd(hdw,VIDIOC_S_CTRL,&ctrl); | ||
70 | ctrl.id = V4L2_CID_HUE; | ||
71 | ctrl.value = hdw->hue_val; | ||
72 | pvr2_i2c_core_cmd(hdw,VIDIOC_S_CTRL,&ctrl); | ||
73 | } | ||
74 | |||
75 | |||
76 | static int check_bcsh(struct pvr2_hdw *hdw) | ||
77 | { | ||
78 | return (hdw->brightness_dirty || | ||
79 | hdw->contrast_dirty || | ||
80 | hdw->saturation_dirty || | ||
81 | hdw->hue_dirty); | ||
82 | } | ||
83 | |||
84 | |||
85 | const struct pvr2_i2c_op pvr2_i2c_op_v4l2_bcsh = { | ||
86 | .check = check_bcsh, | ||
87 | .update = set_bcsh, | ||
88 | .name = "v4l2_bcsh", | ||
89 | }; | ||
90 | |||
91 | |||
92 | static void set_volume(struct pvr2_hdw *hdw) | ||
93 | { | ||
94 | struct v4l2_control ctrl; | ||
95 | pvr2_trace(PVR2_TRACE_CHIPS, | ||
96 | "i2c v4l2 set_volume" | ||
97 | "(vol=%d bal=%d bas=%d treb=%d mute=%d)", | ||
98 | hdw->volume_val, | ||
99 | hdw->balance_val, | ||
100 | hdw->bass_val, | ||
101 | hdw->treble_val, | ||
102 | hdw->mute_val); | ||
103 | memset(&ctrl,0,sizeof(ctrl)); | ||
104 | ctrl.id = V4L2_CID_AUDIO_MUTE; | ||
105 | ctrl.value = hdw->mute_val ? 1 : 0; | ||
106 | pvr2_i2c_core_cmd(hdw,VIDIOC_S_CTRL,&ctrl); | ||
107 | ctrl.id = V4L2_CID_AUDIO_VOLUME; | ||
108 | ctrl.value = hdw->volume_val; | ||
109 | pvr2_i2c_core_cmd(hdw,VIDIOC_S_CTRL,&ctrl); | ||
110 | ctrl.id = V4L2_CID_AUDIO_BALANCE; | ||
111 | ctrl.value = hdw->balance_val; | ||
112 | pvr2_i2c_core_cmd(hdw,VIDIOC_S_CTRL,&ctrl); | ||
113 | ctrl.id = V4L2_CID_AUDIO_BASS; | ||
114 | ctrl.value = hdw->bass_val; | ||
115 | pvr2_i2c_core_cmd(hdw,VIDIOC_S_CTRL,&ctrl); | ||
116 | ctrl.id = V4L2_CID_AUDIO_TREBLE; | ||
117 | ctrl.value = hdw->treble_val; | ||
118 | pvr2_i2c_core_cmd(hdw,VIDIOC_S_CTRL,&ctrl); | ||
119 | } | ||
120 | |||
121 | |||
122 | static int check_volume(struct pvr2_hdw *hdw) | ||
123 | { | ||
124 | return (hdw->volume_dirty || | ||
125 | hdw->balance_dirty || | ||
126 | hdw->bass_dirty || | ||
127 | hdw->treble_dirty || | ||
128 | hdw->mute_dirty); | ||
129 | } | ||
130 | |||
131 | |||
132 | const struct pvr2_i2c_op pvr2_i2c_op_v4l2_volume = { | ||
133 | .check = check_volume, | ||
134 | .update = set_volume, | ||
135 | .name = "v4l2_volume", | ||
136 | }; | ||
137 | |||
138 | |||
139 | static void set_frequency(struct pvr2_hdw *hdw) | ||
140 | { | ||
141 | unsigned long fv; | ||
142 | struct v4l2_frequency freq; | ||
143 | fv = hdw->freqVal; | ||
144 | pvr2_trace(PVR2_TRACE_CHIPS,"i2c v4l2 set_freq(%lu)",fv); | ||
145 | memset(&freq,0,sizeof(freq)); | ||
146 | freq.frequency = fv / 62500; | ||
147 | freq.tuner = 0; | ||
148 | freq.type = V4L2_TUNER_ANALOG_TV; | ||
149 | pvr2_i2c_core_cmd(hdw,VIDIOC_S_FREQUENCY,&freq); | ||
150 | } | ||
151 | |||
152 | |||
153 | static int check_frequency(struct pvr2_hdw *hdw) | ||
154 | { | ||
155 | return hdw->freqDirty != 0; | ||
156 | } | ||
157 | |||
158 | |||
159 | const struct pvr2_i2c_op pvr2_i2c_op_v4l2_frequency = { | ||
160 | .check = check_frequency, | ||
161 | .update = set_frequency, | ||
162 | .name = "v4l2_freq", | ||
163 | }; | ||
164 | |||
165 | |||
166 | static void set_size(struct pvr2_hdw *hdw) | ||
167 | { | ||
168 | struct v4l2_format fmt; | ||
169 | |||
170 | memset(&fmt,0,sizeof(fmt)); | ||
171 | |||
172 | fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | ||
173 | fmt.fmt.pix.width = hdw->res_hor_val; | ||
174 | fmt.fmt.pix.height = hdw->res_ver_val; | ||
175 | |||
176 | pvr2_trace(PVR2_TRACE_CHIPS,"i2c v4l2 set_size(%dx%d)", | ||
177 | fmt.fmt.pix.width,fmt.fmt.pix.height); | ||
178 | |||
179 | pvr2_i2c_core_cmd(hdw,VIDIOC_S_FMT,&fmt); | ||
180 | } | ||
181 | |||
182 | |||
183 | static int check_size(struct pvr2_hdw *hdw) | ||
184 | { | ||
185 | return (hdw->res_hor_dirty || hdw->res_ver_dirty); | ||
186 | } | ||
187 | |||
188 | |||
189 | const struct pvr2_i2c_op pvr2_i2c_op_v4l2_size = { | ||
190 | .check = check_size, | ||
191 | .update = set_size, | ||
192 | .name = "v4l2_size", | ||
193 | }; | ||
194 | |||
195 | |||
196 | static void do_log(struct pvr2_hdw *hdw) | ||
197 | { | ||
198 | pvr2_trace(PVR2_TRACE_CHIPS,"i2c v4l2 do_log()"); | ||
199 | pvr2_i2c_core_cmd(hdw,VIDIOC_LOG_STATUS,0); | ||
200 | |||
201 | } | ||
202 | |||
203 | |||
204 | static int check_log(struct pvr2_hdw *hdw) | ||
205 | { | ||
206 | return hdw->log_requested != 0; | ||
207 | } | ||
208 | |||
209 | |||
210 | const struct pvr2_i2c_op pvr2_i2c_op_v4l2_log = { | ||
211 | .check = check_log, | ||
212 | .update = do_log, | ||
213 | .name = "v4l2_log", | ||
214 | }; | ||
215 | |||
216 | |||
217 | void pvr2_v4l2_cmd_stream(struct pvr2_i2c_client *cp,int fl) | ||
218 | { | ||
219 | pvr2_i2c_client_cmd(cp, | ||
220 | (fl ? VIDIOC_STREAMON : VIDIOC_STREAMOFF),0); | ||
221 | } | ||
222 | |||
223 | |||
224 | /* | ||
225 | Stuff for Emacs to see, in order to encourage consistent editing style: | ||
226 | *** Local Variables: *** | ||
227 | *** mode: c *** | ||
228 | *** fill-column: 70 *** | ||
229 | *** tab-width: 8 *** | ||
230 | *** c-basic-offset: 8 *** | ||
231 | *** End: *** | ||
232 | */ | ||
diff --git a/drivers/media/video/pvrusb2/pvrusb2-i2c-cmd-v4l2.h b/drivers/media/video/pvrusb2/pvrusb2-i2c-cmd-v4l2.h new file mode 100644 index 000000000000..ecabddba1ec5 --- /dev/null +++ b/drivers/media/video/pvrusb2/pvrusb2-i2c-cmd-v4l2.h | |||
@@ -0,0 +1,47 @@ | |||
1 | /* | ||
2 | * | ||
3 | * $Id$ | ||
4 | * | ||
5 | * Copyright (C) 2005 Mike Isely <isely@pobox.com> | ||
6 | * Copyright (C) 2004 Aurelien Alleaume <slts@free.fr> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License as published by | ||
10 | * the Free Software Foundation; either version 2 of the License | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | * GNU General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU General Public License | ||
18 | * along with this program; if not, write to the Free Software | ||
19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
20 | * | ||
21 | */ | ||
22 | |||
23 | #ifndef __PVRUSB2_CMD_V4L2_H | ||
24 | #define __PVRUSB2_CMD_V4L2_H | ||
25 | |||
26 | #include "pvrusb2-i2c-core.h" | ||
27 | |||
28 | extern const struct pvr2_i2c_op pvr2_i2c_op_v4l2_standard; | ||
29 | extern const struct pvr2_i2c_op pvr2_i2c_op_v4l2_bcsh; | ||
30 | extern const struct pvr2_i2c_op pvr2_i2c_op_v4l2_volume; | ||
31 | extern const struct pvr2_i2c_op pvr2_i2c_op_v4l2_frequency; | ||
32 | extern const struct pvr2_i2c_op pvr2_i2c_op_v4l2_size; | ||
33 | extern const struct pvr2_i2c_op pvr2_i2c_op_v4l2_log; | ||
34 | |||
35 | void pvr2_v4l2_cmd_stream(struct pvr2_i2c_client *,int); | ||
36 | |||
37 | #endif /* __PVRUSB2_CMD_V4L2_H */ | ||
38 | |||
39 | /* | ||
40 | Stuff for Emacs to see, in order to encourage consistent editing style: | ||
41 | *** Local Variables: *** | ||
42 | *** mode: c *** | ||
43 | *** fill-column: 70 *** | ||
44 | *** tab-width: 8 *** | ||
45 | *** c-basic-offset: 8 *** | ||
46 | *** End: *** | ||
47 | */ | ||
diff --git a/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c b/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c new file mode 100644 index 000000000000..c8d0bdee3ff1 --- /dev/null +++ b/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c | |||
@@ -0,0 +1,937 @@ | |||
1 | /* | ||
2 | * | ||
3 | * $Id$ | ||
4 | * | ||
5 | * Copyright (C) 2005 Mike Isely <isely@pobox.com> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License as published by | ||
9 | * the Free Software Foundation; either version 2 of the License | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
19 | * | ||
20 | */ | ||
21 | |||
22 | #include "pvrusb2-i2c-core.h" | ||
23 | #include "pvrusb2-hdw-internal.h" | ||
24 | #include "pvrusb2-debug.h" | ||
25 | |||
26 | #define trace_i2c(...) pvr2_trace(PVR2_TRACE_I2C,__VA_ARGS__) | ||
27 | |||
28 | /* | ||
29 | |||
30 | This module attempts to implement a compliant I2C adapter for the pvrusb2 | ||
31 | device. By doing this we can then make use of existing functionality in | ||
32 | V4L (e.g. tuner.c) rather than rolling our own. | ||
33 | |||
34 | */ | ||
35 | |||
36 | static unsigned int i2c_scan = 0; | ||
37 | module_param(i2c_scan, int, S_IRUGO|S_IWUSR); | ||
38 | MODULE_PARM_DESC(i2c_scan,"scan i2c bus at insmod time"); | ||
39 | |||
40 | static int pvr2_i2c_write(struct pvr2_hdw *hdw, /* Context */ | ||
41 | u8 i2c_addr, /* I2C address we're talking to */ | ||
42 | u8 *data, /* Data to write */ | ||
43 | u16 length) /* Size of data to write */ | ||
44 | { | ||
45 | /* Return value - default 0 means success */ | ||
46 | int ret; | ||
47 | |||
48 | |||
49 | if (!data) length = 0; | ||
50 | if (length > (sizeof(hdw->cmd_buffer) - 3)) { | ||
51 | pvr2_trace(PVR2_TRACE_ERROR_LEGS, | ||
52 | "Killing an I2C write to %u that is too large" | ||
53 | " (desired=%u limit=%u)", | ||
54 | i2c_addr, | ||
55 | length,(unsigned int)(sizeof(hdw->cmd_buffer) - 3)); | ||
56 | return -ENOTSUPP; | ||
57 | } | ||
58 | |||
59 | LOCK_TAKE(hdw->ctl_lock); | ||
60 | |||
61 | /* Clear the command buffer (likely to be paranoia) */ | ||
62 | memset(hdw->cmd_buffer, 0, sizeof(hdw->cmd_buffer)); | ||
63 | |||
64 | /* Set up command buffer for an I2C write */ | ||
65 | hdw->cmd_buffer[0] = 0x08; /* write prefix */ | ||
66 | hdw->cmd_buffer[1] = i2c_addr; /* i2c addr of chip */ | ||
67 | hdw->cmd_buffer[2] = length; /* length of what follows */ | ||
68 | if (length) memcpy(hdw->cmd_buffer + 3, data, length); | ||
69 | |||
70 | /* Do the operation */ | ||
71 | ret = pvr2_send_request(hdw, | ||
72 | hdw->cmd_buffer, | ||
73 | length + 3, | ||
74 | hdw->cmd_buffer, | ||
75 | 1); | ||
76 | if (!ret) { | ||
77 | if (hdw->cmd_buffer[0] != 8) { | ||
78 | ret = -EIO; | ||
79 | if (hdw->cmd_buffer[0] != 7) { | ||
80 | trace_i2c("unexpected status" | ||
81 | " from i2_write[%d]: %d", | ||
82 | i2c_addr,hdw->cmd_buffer[0]); | ||
83 | } | ||
84 | } | ||
85 | } | ||
86 | |||
87 | LOCK_GIVE(hdw->ctl_lock); | ||
88 | |||
89 | return ret; | ||
90 | } | ||
91 | |||
92 | static int pvr2_i2c_read(struct pvr2_hdw *hdw, /* Context */ | ||
93 | u8 i2c_addr, /* I2C address we're talking to */ | ||
94 | u8 *data, /* Data to write */ | ||
95 | u16 dlen, /* Size of data to write */ | ||
96 | u8 *res, /* Where to put data we read */ | ||
97 | u16 rlen) /* Amount of data to read */ | ||
98 | { | ||
99 | /* Return value - default 0 means success */ | ||
100 | int ret; | ||
101 | |||
102 | |||
103 | if (!data) dlen = 0; | ||
104 | if (dlen > (sizeof(hdw->cmd_buffer) - 4)) { | ||
105 | pvr2_trace(PVR2_TRACE_ERROR_LEGS, | ||
106 | "Killing an I2C read to %u that has wlen too large" | ||
107 | " (desired=%u limit=%u)", | ||
108 | i2c_addr, | ||
109 | dlen,(unsigned int)(sizeof(hdw->cmd_buffer) - 4)); | ||
110 | return -ENOTSUPP; | ||
111 | } | ||
112 | if (res && (rlen > (sizeof(hdw->cmd_buffer) - 1))) { | ||
113 | pvr2_trace(PVR2_TRACE_ERROR_LEGS, | ||
114 | "Killing an I2C read to %u that has rlen too large" | ||
115 | " (desired=%u limit=%u)", | ||
116 | i2c_addr, | ||
117 | rlen,(unsigned int)(sizeof(hdw->cmd_buffer) - 1)); | ||
118 | return -ENOTSUPP; | ||
119 | } | ||
120 | |||
121 | LOCK_TAKE(hdw->ctl_lock); | ||
122 | |||
123 | /* Clear the command buffer (likely to be paranoia) */ | ||
124 | memset(hdw->cmd_buffer, 0, sizeof(hdw->cmd_buffer)); | ||
125 | |||
126 | /* Set up command buffer for an I2C write followed by a read */ | ||
127 | hdw->cmd_buffer[0] = 0x09; /* read prefix */ | ||
128 | hdw->cmd_buffer[1] = dlen; /* arg length */ | ||
129 | hdw->cmd_buffer[2] = rlen; /* answer length. Device will send one | ||
130 | more byte (status). */ | ||
131 | hdw->cmd_buffer[3] = i2c_addr; /* i2c addr of chip */ | ||
132 | if (dlen) memcpy(hdw->cmd_buffer + 4, data, dlen); | ||
133 | |||
134 | /* Do the operation */ | ||
135 | ret = pvr2_send_request(hdw, | ||
136 | hdw->cmd_buffer, | ||
137 | 4 + dlen, | ||
138 | hdw->cmd_buffer, | ||
139 | rlen + 1); | ||
140 | if (!ret) { | ||
141 | if (hdw->cmd_buffer[0] != 8) { | ||
142 | ret = -EIO; | ||
143 | if (hdw->cmd_buffer[0] != 7) { | ||
144 | trace_i2c("unexpected status" | ||
145 | " from i2_read[%d]: %d", | ||
146 | i2c_addr,hdw->cmd_buffer[0]); | ||
147 | } | ||
148 | } | ||
149 | } | ||
150 | |||
151 | /* Copy back the result */ | ||
152 | if (res && rlen) { | ||
153 | if (ret) { | ||
154 | /* Error, just blank out the return buffer */ | ||
155 | memset(res, 0, rlen); | ||
156 | } else { | ||
157 | memcpy(res, hdw->cmd_buffer + 1, rlen); | ||
158 | } | ||
159 | } | ||
160 | |||
161 | LOCK_GIVE(hdw->ctl_lock); | ||
162 | |||
163 | return ret; | ||
164 | } | ||
165 | |||
166 | /* This is the common low level entry point for doing I2C operations to the | ||
167 | hardware. */ | ||
168 | int pvr2_i2c_basic_op(struct pvr2_hdw *hdw, | ||
169 | u8 i2c_addr, | ||
170 | u8 *wdata, | ||
171 | u16 wlen, | ||
172 | u8 *rdata, | ||
173 | u16 rlen) | ||
174 | { | ||
175 | if (!rdata) rlen = 0; | ||
176 | if (!wdata) wlen = 0; | ||
177 | if (rlen || !wlen) { | ||
178 | return pvr2_i2c_read(hdw,i2c_addr,wdata,wlen,rdata,rlen); | ||
179 | } else { | ||
180 | return pvr2_i2c_write(hdw,i2c_addr,wdata,wlen); | ||
181 | } | ||
182 | } | ||
183 | |||
184 | #ifdef CONFIG_VIDEO_PVRUSB2_24XXX | ||
185 | |||
186 | /* This is a special entry point that is entered if an I2C operation is | ||
187 | attempted to a wm8775 chip on model 24xxx hardware. Autodetect of this | ||
188 | part doesn't work, but we know it is really there. So let's look for | ||
189 | the autodetect attempt and just return success if we see that. */ | ||
190 | static int i2c_hack_wm8775(struct pvr2_hdw *hdw, | ||
191 | u8 i2c_addr,u8 *wdata,u16 wlen,u8 *rdata,u16 rlen) | ||
192 | { | ||
193 | if (!(rlen || wlen)) { | ||
194 | // This is a probe attempt. Just let it succeed. | ||
195 | return 0; | ||
196 | } | ||
197 | return pvr2_i2c_basic_op(hdw,i2c_addr,wdata,wlen,rdata,rlen); | ||
198 | } | ||
199 | |||
200 | /* This is a special entry point that is entered if an I2C operation is | ||
201 | attempted to a cx25840 chip on model 24xxx hardware. This chip can | ||
202 | sometimes wedge itself. Worse still, when this happens msp3400 can | ||
203 | falsely detect this part and then the system gets hosed up after msp3400 | ||
204 | gets confused and dies. What we want to do here is try to keep msp3400 | ||
205 | away and also try to notice if the chip is wedged and send a warning to | ||
206 | the system log. */ | ||
207 | static int i2c_hack_cx25840(struct pvr2_hdw *hdw, | ||
208 | u8 i2c_addr,u8 *wdata,u16 wlen,u8 *rdata,u16 rlen) | ||
209 | { | ||
210 | int ret; | ||
211 | unsigned int subaddr; | ||
212 | u8 wbuf[2]; | ||
213 | int state = hdw->i2c_cx25840_hack_state; | ||
214 | |||
215 | if (!(rlen || wlen)) { | ||
216 | // Probe attempt - always just succeed and don't bother the | ||
217 | // hardware (this helps to make the state machine further | ||
218 | // down somewhat easier). | ||
219 | return 0; | ||
220 | } | ||
221 | |||
222 | if (state == 3) { | ||
223 | return pvr2_i2c_basic_op(hdw,i2c_addr,wdata,wlen,rdata,rlen); | ||
224 | } | ||
225 | |||
226 | /* We're looking for the exact pattern where the revision register | ||
227 | is being read. The cx25840 module will always look at the | ||
228 | revision register first. Any other pattern of access therefore | ||
229 | has to be a probe attempt from somebody else so we'll reject it. | ||
230 | Normally we could just let each client just probe the part | ||
231 | anyway, but when the cx25840 is wedged, msp3400 will get a false | ||
232 | positive and that just screws things up... */ | ||
233 | |||
234 | if (wlen == 0) { | ||
235 | switch (state) { | ||
236 | case 1: subaddr = 0x0100; break; | ||
237 | case 2: subaddr = 0x0101; break; | ||
238 | default: goto fail; | ||
239 | } | ||
240 | } else if (wlen == 2) { | ||
241 | subaddr = (wdata[0] << 8) | wdata[1]; | ||
242 | switch (subaddr) { | ||
243 | case 0x0100: state = 1; break; | ||
244 | case 0x0101: state = 2; break; | ||
245 | default: goto fail; | ||
246 | } | ||
247 | } else { | ||
248 | goto fail; | ||
249 | } | ||
250 | if (!rlen) goto success; | ||
251 | state = 0; | ||
252 | if (rlen != 1) goto fail; | ||
253 | |||
254 | /* If we get to here then we have a legitimate read for one of the | ||
255 | two revision bytes, so pass it through. */ | ||
256 | wbuf[0] = subaddr >> 8; | ||
257 | wbuf[1] = subaddr; | ||
258 | ret = pvr2_i2c_basic_op(hdw,i2c_addr,wbuf,2,rdata,rlen); | ||
259 | |||
260 | if ((ret != 0) || (*rdata == 0x04) || (*rdata == 0x0a)) { | ||
261 | pvr2_trace(PVR2_TRACE_ERROR_LEGS, | ||
262 | "WARNING: Detected a wedged cx25840 chip;" | ||
263 | " the device will not work."); | ||
264 | pvr2_trace(PVR2_TRACE_ERROR_LEGS, | ||
265 | "WARNING: Try power cycling the pvrusb2 device."); | ||
266 | pvr2_trace(PVR2_TRACE_ERROR_LEGS, | ||
267 | "WARNING: Disabling further access to the device" | ||
268 | " to prevent other foul-ups."); | ||
269 | // This blocks all further communication with the part. | ||
270 | hdw->i2c_func[0x44] = 0; | ||
271 | pvr2_hdw_render_useless(hdw); | ||
272 | goto fail; | ||
273 | } | ||
274 | |||
275 | /* Success! */ | ||
276 | pvr2_trace(PVR2_TRACE_CHIPS,"cx25840 appears to be OK."); | ||
277 | state = 3; | ||
278 | |||
279 | success: | ||
280 | hdw->i2c_cx25840_hack_state = state; | ||
281 | return 0; | ||
282 | |||
283 | fail: | ||
284 | hdw->i2c_cx25840_hack_state = state; | ||
285 | return -EIO; | ||
286 | } | ||
287 | |||
288 | #endif /* CONFIG_VIDEO_PVRUSB2_24XXX */ | ||
289 | |||
290 | /* This is a very, very limited I2C adapter implementation. We can only | ||
291 | support what we actually know will work on the device... */ | ||
292 | static int pvr2_i2c_xfer(struct i2c_adapter *i2c_adap, | ||
293 | struct i2c_msg msgs[], | ||
294 | int num) | ||
295 | { | ||
296 | int ret = -ENOTSUPP; | ||
297 | pvr2_i2c_func funcp = 0; | ||
298 | struct pvr2_hdw *hdw = (struct pvr2_hdw *)(i2c_adap->algo_data); | ||
299 | |||
300 | if (!num) { | ||
301 | ret = -EINVAL; | ||
302 | goto done; | ||
303 | } | ||
304 | if ((msgs[0].flags & I2C_M_NOSTART)) { | ||
305 | trace_i2c("i2c refusing I2C_M_NOSTART"); | ||
306 | goto done; | ||
307 | } | ||
308 | if (msgs[0].addr < PVR2_I2C_FUNC_CNT) { | ||
309 | funcp = hdw->i2c_func[msgs[0].addr]; | ||
310 | } | ||
311 | if (!funcp) { | ||
312 | ret = -EIO; | ||
313 | goto done; | ||
314 | } | ||
315 | |||
316 | if (num == 1) { | ||
317 | if (msgs[0].flags & I2C_M_RD) { | ||
318 | /* Simple read */ | ||
319 | u16 tcnt,bcnt,offs; | ||
320 | if (!msgs[0].len) { | ||
321 | /* Length == 0 read. This is a probe. */ | ||
322 | if (funcp(hdw,msgs[0].addr,0,0,0,0)) { | ||
323 | ret = -EIO; | ||
324 | goto done; | ||
325 | } | ||
326 | ret = 1; | ||
327 | goto done; | ||
328 | } | ||
329 | /* If the read is short enough we'll do the whole | ||
330 | thing atomically. Otherwise we have no choice | ||
331 | but to break apart the reads. */ | ||
332 | tcnt = msgs[0].len; | ||
333 | offs = 0; | ||
334 | while (tcnt) { | ||
335 | bcnt = tcnt; | ||
336 | if (bcnt > sizeof(hdw->cmd_buffer)-1) { | ||
337 | bcnt = sizeof(hdw->cmd_buffer)-1; | ||
338 | } | ||
339 | if (funcp(hdw,msgs[0].addr,0,0, | ||
340 | msgs[0].buf+offs,bcnt)) { | ||
341 | ret = -EIO; | ||
342 | goto done; | ||
343 | } | ||
344 | offs += bcnt; | ||
345 | tcnt -= bcnt; | ||
346 | } | ||
347 | ret = 1; | ||
348 | goto done; | ||
349 | } else { | ||
350 | /* Simple write */ | ||
351 | ret = 1; | ||
352 | if (funcp(hdw,msgs[0].addr, | ||
353 | msgs[0].buf,msgs[0].len,0,0)) { | ||
354 | ret = -EIO; | ||
355 | } | ||
356 | goto done; | ||
357 | } | ||
358 | } else if (num == 2) { | ||
359 | if (msgs[0].addr != msgs[1].addr) { | ||
360 | trace_i2c("i2c refusing 2 phase transfer with" | ||
361 | " conflicting target addresses"); | ||
362 | ret = -ENOTSUPP; | ||
363 | goto done; | ||
364 | } | ||
365 | if ((!((msgs[0].flags & I2C_M_RD))) && | ||
366 | (msgs[1].flags & I2C_M_RD)) { | ||
367 | u16 tcnt,bcnt,wcnt,offs; | ||
368 | /* Write followed by atomic read. If the read | ||
369 | portion is short enough we'll do the whole thing | ||
370 | atomically. Otherwise we have no choice but to | ||
371 | break apart the reads. */ | ||
372 | tcnt = msgs[1].len; | ||
373 | wcnt = msgs[0].len; | ||
374 | offs = 0; | ||
375 | while (tcnt || wcnt) { | ||
376 | bcnt = tcnt; | ||
377 | if (bcnt > sizeof(hdw->cmd_buffer)-1) { | ||
378 | bcnt = sizeof(hdw->cmd_buffer)-1; | ||
379 | } | ||
380 | if (funcp(hdw,msgs[0].addr, | ||
381 | msgs[0].buf,wcnt, | ||
382 | msgs[1].buf+offs,bcnt)) { | ||
383 | ret = -EIO; | ||
384 | goto done; | ||
385 | } | ||
386 | offs += bcnt; | ||
387 | tcnt -= bcnt; | ||
388 | wcnt = 0; | ||
389 | } | ||
390 | ret = 2; | ||
391 | goto done; | ||
392 | } else { | ||
393 | trace_i2c("i2c refusing complex transfer" | ||
394 | " read0=%d read1=%d", | ||
395 | (msgs[0].flags & I2C_M_RD), | ||
396 | (msgs[1].flags & I2C_M_RD)); | ||
397 | } | ||
398 | } else { | ||
399 | trace_i2c("i2c refusing %d phase transfer",num); | ||
400 | } | ||
401 | |||
402 | done: | ||
403 | if (pvrusb2_debug & PVR2_TRACE_I2C_TRAF) { | ||
404 | unsigned int idx,offs,cnt; | ||
405 | for (idx = 0; idx < num; idx++) { | ||
406 | cnt = msgs[idx].len; | ||
407 | printk(KERN_INFO | ||
408 | "pvrusb2 i2c xfer %u/%u:" | ||
409 | " addr=0x%x len=%d %s%s", | ||
410 | idx+1,num, | ||
411 | msgs[idx].addr, | ||
412 | cnt, | ||
413 | (msgs[idx].flags & I2C_M_RD ? | ||
414 | "read" : "write"), | ||
415 | (msgs[idx].flags & I2C_M_NOSTART ? | ||
416 | " nostart" : "")); | ||
417 | if ((ret > 0) || !(msgs[idx].flags & I2C_M_RD)) { | ||
418 | if (cnt > 8) cnt = 8; | ||
419 | printk(" ["); | ||
420 | for (offs = 0; offs < (cnt>8?8:cnt); offs++) { | ||
421 | if (offs) printk(" "); | ||
422 | printk("%02x",msgs[idx].buf[offs]); | ||
423 | } | ||
424 | if (offs < cnt) printk(" ..."); | ||
425 | printk("]"); | ||
426 | } | ||
427 | if (idx+1 == num) { | ||
428 | printk(" result=%d",ret); | ||
429 | } | ||
430 | printk("\n"); | ||
431 | } | ||
432 | if (!num) { | ||
433 | printk(KERN_INFO | ||
434 | "pvrusb2 i2c xfer null transfer result=%d\n", | ||
435 | ret); | ||
436 | } | ||
437 | } | ||
438 | return ret; | ||
439 | } | ||
440 | |||
441 | static int pvr2_i2c_control(struct i2c_adapter *adapter, | ||
442 | unsigned int cmd, unsigned long arg) | ||
443 | { | ||
444 | return 0; | ||
445 | } | ||
446 | |||
447 | static u32 pvr2_i2c_functionality(struct i2c_adapter *adap) | ||
448 | { | ||
449 | return I2C_FUNC_SMBUS_EMUL | I2C_FUNC_I2C | I2C_FUNC_SMBUS_BYTE_DATA; | ||
450 | } | ||
451 | |||
452 | static int pvr2_i2c_core_singleton(struct i2c_client *cp, | ||
453 | unsigned int cmd,void *arg) | ||
454 | { | ||
455 | int stat; | ||
456 | if (!cp) return -EINVAL; | ||
457 | if (!(cp->driver)) return -EINVAL; | ||
458 | if (!(cp->driver->command)) return -EINVAL; | ||
459 | if (!try_module_get(cp->driver->driver.owner)) return -EAGAIN; | ||
460 | stat = cp->driver->command(cp,cmd,arg); | ||
461 | module_put(cp->driver->driver.owner); | ||
462 | return stat; | ||
463 | } | ||
464 | |||
465 | int pvr2_i2c_client_cmd(struct pvr2_i2c_client *cp,unsigned int cmd,void *arg) | ||
466 | { | ||
467 | int stat; | ||
468 | if (pvrusb2_debug & PVR2_TRACE_I2C_CMD) { | ||
469 | char buf[100]; | ||
470 | unsigned int cnt; | ||
471 | cnt = pvr2_i2c_client_describe(cp,PVR2_I2C_DETAIL_DEBUG, | ||
472 | buf,sizeof(buf)); | ||
473 | pvr2_trace(PVR2_TRACE_I2C_CMD, | ||
474 | "i2c COMMAND (code=%u 0x%x) to %.*s", | ||
475 | cmd,cmd,cnt,buf); | ||
476 | } | ||
477 | stat = pvr2_i2c_core_singleton(cp->client,cmd,arg); | ||
478 | if (pvrusb2_debug & PVR2_TRACE_I2C_CMD) { | ||
479 | char buf[100]; | ||
480 | unsigned int cnt; | ||
481 | cnt = pvr2_i2c_client_describe(cp,PVR2_I2C_DETAIL_DEBUG, | ||
482 | buf,sizeof(buf)); | ||
483 | pvr2_trace(PVR2_TRACE_I2C_CMD, | ||
484 | "i2c COMMAND to %.*s (ret=%d)",cnt,buf,stat); | ||
485 | } | ||
486 | return stat; | ||
487 | } | ||
488 | |||
489 | int pvr2_i2c_core_cmd(struct pvr2_hdw *hdw,unsigned int cmd,void *arg) | ||
490 | { | ||
491 | struct list_head *item,*nc; | ||
492 | struct pvr2_i2c_client *cp; | ||
493 | int stat = -EINVAL; | ||
494 | |||
495 | if (!hdw) return stat; | ||
496 | |||
497 | mutex_lock(&hdw->i2c_list_lock); | ||
498 | list_for_each_safe(item,nc,&hdw->i2c_clients) { | ||
499 | cp = list_entry(item,struct pvr2_i2c_client,list); | ||
500 | if (!cp->recv_enable) continue; | ||
501 | mutex_unlock(&hdw->i2c_list_lock); | ||
502 | stat = pvr2_i2c_client_cmd(cp,cmd,arg); | ||
503 | mutex_lock(&hdw->i2c_list_lock); | ||
504 | } | ||
505 | mutex_unlock(&hdw->i2c_list_lock); | ||
506 | return stat; | ||
507 | } | ||
508 | |||
509 | |||
510 | static int handler_check(struct pvr2_i2c_client *cp) | ||
511 | { | ||
512 | struct pvr2_i2c_handler *hp = cp->handler; | ||
513 | if (!hp) return 0; | ||
514 | if (!hp->func_table->check) return 0; | ||
515 | return hp->func_table->check(hp->func_data) != 0; | ||
516 | } | ||
517 | |||
518 | #define BUFSIZE 500 | ||
519 | |||
520 | void pvr2_i2c_core_sync(struct pvr2_hdw *hdw) | ||
521 | { | ||
522 | unsigned long msk; | ||
523 | unsigned int idx; | ||
524 | struct list_head *item,*nc; | ||
525 | struct pvr2_i2c_client *cp; | ||
526 | |||
527 | if (!hdw->i2c_linked) return; | ||
528 | if (!(hdw->i2c_pend_types & PVR2_I2C_PEND_ALL)) { | ||
529 | return; | ||
530 | } | ||
531 | mutex_lock(&hdw->i2c_list_lock); do { | ||
532 | pvr2_trace(PVR2_TRACE_I2C_CORE,"i2c: core_sync BEGIN"); | ||
533 | if (hdw->i2c_pend_types & PVR2_I2C_PEND_DETECT) { | ||
534 | /* One or more I2C clients have attached since we | ||
535 | last synced. So scan the list and identify the | ||
536 | new clients. */ | ||
537 | char *buf; | ||
538 | unsigned int cnt; | ||
539 | unsigned long amask = 0; | ||
540 | buf = kmalloc(BUFSIZE,GFP_KERNEL); | ||
541 | pvr2_trace(PVR2_TRACE_I2C_CORE,"i2c: PEND_DETECT"); | ||
542 | hdw->i2c_pend_types &= ~PVR2_I2C_PEND_DETECT; | ||
543 | list_for_each(item,&hdw->i2c_clients) { | ||
544 | cp = list_entry(item,struct pvr2_i2c_client, | ||
545 | list); | ||
546 | if (!cp->detected_flag) { | ||
547 | cp->ctl_mask = 0; | ||
548 | pvr2_i2c_probe(hdw,cp); | ||
549 | cp->detected_flag = !0; | ||
550 | msk = cp->ctl_mask; | ||
551 | cnt = 0; | ||
552 | if (buf) { | ||
553 | cnt = pvr2_i2c_client_describe( | ||
554 | cp, | ||
555 | PVR2_I2C_DETAIL_ALL, | ||
556 | buf,BUFSIZE); | ||
557 | } | ||
558 | trace_i2c("Probed: %.*s",cnt,buf); | ||
559 | if (handler_check(cp)) { | ||
560 | hdw->i2c_pend_types |= | ||
561 | PVR2_I2C_PEND_CLIENT; | ||
562 | } | ||
563 | cp->pend_mask = msk; | ||
564 | hdw->i2c_pend_mask |= msk; | ||
565 | hdw->i2c_pend_types |= | ||
566 | PVR2_I2C_PEND_REFRESH; | ||
567 | } | ||
568 | amask |= cp->ctl_mask; | ||
569 | } | ||
570 | hdw->i2c_active_mask = amask; | ||
571 | if (buf) kfree(buf); | ||
572 | } | ||
573 | if (hdw->i2c_pend_types & PVR2_I2C_PEND_STALE) { | ||
574 | /* Need to do one or more global updates. Arrange | ||
575 | for this to happen. */ | ||
576 | unsigned long m2; | ||
577 | pvr2_trace(PVR2_TRACE_I2C_CORE, | ||
578 | "i2c: PEND_STALE (0x%lx)", | ||
579 | hdw->i2c_stale_mask); | ||
580 | hdw->i2c_pend_types &= ~PVR2_I2C_PEND_STALE; | ||
581 | list_for_each(item,&hdw->i2c_clients) { | ||
582 | cp = list_entry(item,struct pvr2_i2c_client, | ||
583 | list); | ||
584 | m2 = hdw->i2c_stale_mask; | ||
585 | m2 &= cp->ctl_mask; | ||
586 | m2 &= ~cp->pend_mask; | ||
587 | if (m2) { | ||
588 | pvr2_trace(PVR2_TRACE_I2C_CORE, | ||
589 | "i2c: cp=%p setting 0x%lx", | ||
590 | cp,m2); | ||
591 | cp->pend_mask |= m2; | ||
592 | } | ||
593 | } | ||
594 | hdw->i2c_pend_mask |= hdw->i2c_stale_mask; | ||
595 | hdw->i2c_stale_mask = 0; | ||
596 | hdw->i2c_pend_types |= PVR2_I2C_PEND_REFRESH; | ||
597 | } | ||
598 | if (hdw->i2c_pend_types & PVR2_I2C_PEND_CLIENT) { | ||
599 | /* One or more client handlers are asking for an | ||
600 | update. Run through the list of known clients | ||
601 | and update each one. */ | ||
602 | pvr2_trace(PVR2_TRACE_I2C_CORE,"i2c: PEND_CLIENT"); | ||
603 | hdw->i2c_pend_types &= ~PVR2_I2C_PEND_CLIENT; | ||
604 | list_for_each_safe(item,nc,&hdw->i2c_clients) { | ||
605 | cp = list_entry(item,struct pvr2_i2c_client, | ||
606 | list); | ||
607 | if (!cp->handler) continue; | ||
608 | if (!cp->handler->func_table->update) continue; | ||
609 | pvr2_trace(PVR2_TRACE_I2C_CORE, | ||
610 | "i2c: cp=%p update",cp); | ||
611 | mutex_unlock(&hdw->i2c_list_lock); | ||
612 | cp->handler->func_table->update( | ||
613 | cp->handler->func_data); | ||
614 | mutex_lock(&hdw->i2c_list_lock); | ||
615 | /* If client's update function set some | ||
616 | additional pending bits, account for that | ||
617 | here. */ | ||
618 | if (cp->pend_mask & ~hdw->i2c_pend_mask) { | ||
619 | hdw->i2c_pend_mask |= cp->pend_mask; | ||
620 | hdw->i2c_pend_types |= | ||
621 | PVR2_I2C_PEND_REFRESH; | ||
622 | } | ||
623 | } | ||
624 | } | ||
625 | if (hdw->i2c_pend_types & PVR2_I2C_PEND_REFRESH) { | ||
626 | const struct pvr2_i2c_op *opf; | ||
627 | unsigned long pm; | ||
628 | /* Some actual updates are pending. Walk through | ||
629 | each update type and perform it. */ | ||
630 | pvr2_trace(PVR2_TRACE_I2C_CORE,"i2c: PEND_REFRESH" | ||
631 | " (0x%lx)",hdw->i2c_pend_mask); | ||
632 | hdw->i2c_pend_types &= ~PVR2_I2C_PEND_REFRESH; | ||
633 | pm = hdw->i2c_pend_mask; | ||
634 | hdw->i2c_pend_mask = 0; | ||
635 | for (idx = 0, msk = 1; pm; idx++, msk <<= 1) { | ||
636 | if (!(pm & msk)) continue; | ||
637 | pm &= ~msk; | ||
638 | list_for_each(item,&hdw->i2c_clients) { | ||
639 | cp = list_entry(item, | ||
640 | struct pvr2_i2c_client, | ||
641 | list); | ||
642 | if (cp->pend_mask & msk) { | ||
643 | cp->pend_mask &= ~msk; | ||
644 | cp->recv_enable = !0; | ||
645 | } else { | ||
646 | cp->recv_enable = 0; | ||
647 | } | ||
648 | } | ||
649 | opf = pvr2_i2c_get_op(idx); | ||
650 | if (!opf) continue; | ||
651 | mutex_unlock(&hdw->i2c_list_lock); | ||
652 | opf->update(hdw); | ||
653 | mutex_lock(&hdw->i2c_list_lock); | ||
654 | } | ||
655 | } | ||
656 | pvr2_trace(PVR2_TRACE_I2C_CORE,"i2c: core_sync END"); | ||
657 | } while (0); mutex_unlock(&hdw->i2c_list_lock); | ||
658 | } | ||
659 | |||
660 | int pvr2_i2c_core_check_stale(struct pvr2_hdw *hdw) | ||
661 | { | ||
662 | unsigned long msk,sm,pm; | ||
663 | unsigned int idx; | ||
664 | const struct pvr2_i2c_op *opf; | ||
665 | struct list_head *item; | ||
666 | struct pvr2_i2c_client *cp; | ||
667 | unsigned int pt = 0; | ||
668 | |||
669 | pvr2_trace(PVR2_TRACE_I2C_CORE,"pvr2_i2c_core_check_stale BEGIN"); | ||
670 | |||
671 | pm = hdw->i2c_active_mask; | ||
672 | sm = 0; | ||
673 | for (idx = 0, msk = 1; pm; idx++, msk <<= 1) { | ||
674 | if (!(msk & pm)) continue; | ||
675 | pm &= ~msk; | ||
676 | opf = pvr2_i2c_get_op(idx); | ||
677 | if (!opf) continue; | ||
678 | if (opf->check(hdw)) { | ||
679 | sm |= msk; | ||
680 | } | ||
681 | } | ||
682 | if (sm) pt |= PVR2_I2C_PEND_STALE; | ||
683 | |||
684 | list_for_each(item,&hdw->i2c_clients) { | ||
685 | cp = list_entry(item,struct pvr2_i2c_client,list); | ||
686 | if (!handler_check(cp)) continue; | ||
687 | pt |= PVR2_I2C_PEND_CLIENT; | ||
688 | } | ||
689 | |||
690 | if (pt) { | ||
691 | mutex_lock(&hdw->i2c_list_lock); do { | ||
692 | hdw->i2c_pend_types |= pt; | ||
693 | hdw->i2c_stale_mask |= sm; | ||
694 | hdw->i2c_pend_mask |= hdw->i2c_stale_mask; | ||
695 | } while (0); mutex_unlock(&hdw->i2c_list_lock); | ||
696 | } | ||
697 | |||
698 | pvr2_trace(PVR2_TRACE_I2C_CORE, | ||
699 | "i2c: types=0x%x stale=0x%lx pend=0x%lx", | ||
700 | hdw->i2c_pend_types, | ||
701 | hdw->i2c_stale_mask, | ||
702 | hdw->i2c_pend_mask); | ||
703 | pvr2_trace(PVR2_TRACE_I2C_CORE,"pvr2_i2c_core_check_stale END"); | ||
704 | |||
705 | return (hdw->i2c_pend_types & PVR2_I2C_PEND_ALL) != 0; | ||
706 | } | ||
707 | |||
708 | unsigned int pvr2_i2c_client_describe(struct pvr2_i2c_client *cp, | ||
709 | unsigned int detail, | ||
710 | char *buf,unsigned int maxlen) | ||
711 | { | ||
712 | unsigned int ccnt,bcnt; | ||
713 | int spcfl = 0; | ||
714 | const struct pvr2_i2c_op *opf; | ||
715 | |||
716 | ccnt = 0; | ||
717 | if (detail & PVR2_I2C_DETAIL_DEBUG) { | ||
718 | bcnt = scnprintf(buf,maxlen, | ||
719 | "ctxt=%p ctl_mask=0x%lx", | ||
720 | cp,cp->ctl_mask); | ||
721 | ccnt += bcnt; buf += bcnt; maxlen -= bcnt; | ||
722 | spcfl = !0; | ||
723 | } | ||
724 | bcnt = scnprintf(buf,maxlen, | ||
725 | "%s%s @ 0x%x", | ||
726 | (spcfl ? " " : ""), | ||
727 | cp->client->name, | ||
728 | cp->client->addr); | ||
729 | ccnt += bcnt; buf += bcnt; maxlen -= bcnt; | ||
730 | if ((detail & PVR2_I2C_DETAIL_HANDLER) && | ||
731 | cp->handler && cp->handler->func_table->describe) { | ||
732 | bcnt = scnprintf(buf,maxlen," ("); | ||
733 | ccnt += bcnt; buf += bcnt; maxlen -= bcnt; | ||
734 | bcnt = cp->handler->func_table->describe( | ||
735 | cp->handler->func_data,buf,maxlen); | ||
736 | ccnt += bcnt; buf += bcnt; maxlen -= bcnt; | ||
737 | bcnt = scnprintf(buf,maxlen,")"); | ||
738 | ccnt += bcnt; buf += bcnt; maxlen -= bcnt; | ||
739 | } | ||
740 | if ((detail & PVR2_I2C_DETAIL_CTLMASK) && cp->ctl_mask) { | ||
741 | unsigned int idx; | ||
742 | unsigned long msk,sm; | ||
743 | int spcfl; | ||
744 | bcnt = scnprintf(buf,maxlen," ["); | ||
745 | ccnt += bcnt; buf += bcnt; maxlen -= bcnt; | ||
746 | sm = 0; | ||
747 | spcfl = 0; | ||
748 | for (idx = 0, msk = 1; msk; idx++, msk <<= 1) { | ||
749 | if (!(cp->ctl_mask & msk)) continue; | ||
750 | opf = pvr2_i2c_get_op(idx); | ||
751 | if (opf) { | ||
752 | bcnt = scnprintf(buf,maxlen,"%s%s", | ||
753 | spcfl ? " " : "", | ||
754 | opf->name); | ||
755 | ccnt += bcnt; buf += bcnt; maxlen -= bcnt; | ||
756 | spcfl = !0; | ||
757 | } else { | ||
758 | sm |= msk; | ||
759 | } | ||
760 | } | ||
761 | if (sm) { | ||
762 | bcnt = scnprintf(buf,maxlen,"%s%lx", | ||
763 | idx != 0 ? " " : "",sm); | ||
764 | ccnt += bcnt; buf += bcnt; maxlen -= bcnt; | ||
765 | } | ||
766 | bcnt = scnprintf(buf,maxlen,"]"); | ||
767 | ccnt += bcnt; buf += bcnt; maxlen -= bcnt; | ||
768 | } | ||
769 | return ccnt; | ||
770 | } | ||
771 | |||
772 | unsigned int pvr2_i2c_report(struct pvr2_hdw *hdw, | ||
773 | char *buf,unsigned int maxlen) | ||
774 | { | ||
775 | unsigned int ccnt,bcnt; | ||
776 | struct list_head *item; | ||
777 | struct pvr2_i2c_client *cp; | ||
778 | ccnt = 0; | ||
779 | mutex_lock(&hdw->i2c_list_lock); do { | ||
780 | list_for_each(item,&hdw->i2c_clients) { | ||
781 | cp = list_entry(item,struct pvr2_i2c_client,list); | ||
782 | bcnt = pvr2_i2c_client_describe( | ||
783 | cp, | ||
784 | (PVR2_I2C_DETAIL_HANDLER| | ||
785 | PVR2_I2C_DETAIL_CTLMASK), | ||
786 | buf,maxlen); | ||
787 | ccnt += bcnt; buf += bcnt; maxlen -= bcnt; | ||
788 | bcnt = scnprintf(buf,maxlen,"\n"); | ||
789 | ccnt += bcnt; buf += bcnt; maxlen -= bcnt; | ||
790 | } | ||
791 | } while (0); mutex_unlock(&hdw->i2c_list_lock); | ||
792 | return ccnt; | ||
793 | } | ||
794 | |||
795 | static int pvr2_i2c_attach_inform(struct i2c_client *client) | ||
796 | { | ||
797 | struct pvr2_hdw *hdw = (struct pvr2_hdw *)(client->adapter->algo_data); | ||
798 | struct pvr2_i2c_client *cp; | ||
799 | int fl = !(hdw->i2c_pend_types & PVR2_I2C_PEND_ALL); | ||
800 | cp = kmalloc(sizeof(*cp),GFP_KERNEL); | ||
801 | trace_i2c("i2c_attach [client=%s @ 0x%x ctxt=%p]", | ||
802 | client->name, | ||
803 | client->addr,cp); | ||
804 | if (!cp) return -ENOMEM; | ||
805 | memset(cp,0,sizeof(*cp)); | ||
806 | INIT_LIST_HEAD(&cp->list); | ||
807 | cp->client = client; | ||
808 | mutex_lock(&hdw->i2c_list_lock); do { | ||
809 | list_add_tail(&cp->list,&hdw->i2c_clients); | ||
810 | hdw->i2c_pend_types |= PVR2_I2C_PEND_DETECT; | ||
811 | } while (0); mutex_unlock(&hdw->i2c_list_lock); | ||
812 | if (fl) pvr2_hdw_poll_trigger_unlocked(hdw); | ||
813 | return 0; | ||
814 | } | ||
815 | |||
816 | static int pvr2_i2c_detach_inform(struct i2c_client *client) | ||
817 | { | ||
818 | struct pvr2_hdw *hdw = (struct pvr2_hdw *)(client->adapter->algo_data); | ||
819 | struct pvr2_i2c_client *cp; | ||
820 | struct list_head *item,*nc; | ||
821 | unsigned long amask = 0; | ||
822 | int foundfl = 0; | ||
823 | mutex_lock(&hdw->i2c_list_lock); do { | ||
824 | list_for_each_safe(item,nc,&hdw->i2c_clients) { | ||
825 | cp = list_entry(item,struct pvr2_i2c_client,list); | ||
826 | if (cp->client == client) { | ||
827 | trace_i2c("pvr2_i2c_detach" | ||
828 | " [client=%s @ 0x%x ctxt=%p]", | ||
829 | client->name, | ||
830 | client->addr,cp); | ||
831 | if (cp->handler && | ||
832 | cp->handler->func_table->detach) { | ||
833 | cp->handler->func_table->detach( | ||
834 | cp->handler->func_data); | ||
835 | } | ||
836 | list_del(&cp->list); | ||
837 | kfree(cp); | ||
838 | foundfl = !0; | ||
839 | continue; | ||
840 | } | ||
841 | amask |= cp->ctl_mask; | ||
842 | } | ||
843 | hdw->i2c_active_mask = amask; | ||
844 | } while (0); mutex_unlock(&hdw->i2c_list_lock); | ||
845 | if (!foundfl) { | ||
846 | trace_i2c("pvr2_i2c_detach [client=%s @ 0x%x ctxt=<unknown>]", | ||
847 | client->name, | ||
848 | client->addr); | ||
849 | } | ||
850 | return 0; | ||
851 | } | ||
852 | |||
853 | static struct i2c_algorithm pvr2_i2c_algo_template = { | ||
854 | .master_xfer = pvr2_i2c_xfer, | ||
855 | .algo_control = pvr2_i2c_control, | ||
856 | .functionality = pvr2_i2c_functionality, | ||
857 | }; | ||
858 | |||
859 | static struct i2c_adapter pvr2_i2c_adap_template = { | ||
860 | .owner = THIS_MODULE, | ||
861 | .class = I2C_CLASS_TV_ANALOG, | ||
862 | .id = I2C_HW_B_BT848, | ||
863 | .client_register = pvr2_i2c_attach_inform, | ||
864 | .client_unregister = pvr2_i2c_detach_inform, | ||
865 | }; | ||
866 | |||
867 | static void do_i2c_scan(struct pvr2_hdw *hdw) | ||
868 | { | ||
869 | struct i2c_msg msg[1]; | ||
870 | int i,rc; | ||
871 | msg[0].addr = 0; | ||
872 | msg[0].flags = I2C_M_RD; | ||
873 | msg[0].len = 0; | ||
874 | msg[0].buf = 0; | ||
875 | printk("%s: i2c scan beginning\n",hdw->name); | ||
876 | for (i = 0; i < 128; i++) { | ||
877 | msg[0].addr = i; | ||
878 | rc = i2c_transfer(&hdw->i2c_adap,msg, | ||
879 | sizeof(msg)/sizeof(msg[0])); | ||
880 | if (rc != 1) continue; | ||
881 | printk("%s: i2c scan: found device @ 0x%x\n",hdw->name,i); | ||
882 | } | ||
883 | printk("%s: i2c scan done.\n",hdw->name); | ||
884 | } | ||
885 | |||
886 | void pvr2_i2c_core_init(struct pvr2_hdw *hdw) | ||
887 | { | ||
888 | unsigned int idx; | ||
889 | |||
890 | // The default action for all possible I2C addresses is just to do | ||
891 | // the transfer normally. | ||
892 | for (idx = 0; idx < PVR2_I2C_FUNC_CNT; idx++) { | ||
893 | hdw->i2c_func[idx] = pvr2_i2c_basic_op; | ||
894 | } | ||
895 | |||
896 | #ifdef CONFIG_VIDEO_PVRUSB2_24XXX | ||
897 | // If however we're dealing with new hardware, insert some hacks in | ||
898 | // the I2C transfer stack to let things work better. | ||
899 | if (hdw->hdw_type == PVR2_HDW_TYPE_24XXX) { | ||
900 | hdw->i2c_func[0x1b] = i2c_hack_wm8775; | ||
901 | hdw->i2c_func[0x44] = i2c_hack_cx25840; | ||
902 | } | ||
903 | #endif | ||
904 | |||
905 | // Configure the adapter and set up everything else related to it. | ||
906 | memcpy(&hdw->i2c_adap,&pvr2_i2c_adap_template,sizeof(hdw->i2c_adap)); | ||
907 | memcpy(&hdw->i2c_algo,&pvr2_i2c_algo_template,sizeof(hdw->i2c_algo)); | ||
908 | strlcpy(hdw->i2c_adap.name,hdw->name,sizeof(hdw->i2c_adap.name)); | ||
909 | hdw->i2c_adap.algo = &hdw->i2c_algo; | ||
910 | hdw->i2c_adap.algo_data = hdw; | ||
911 | hdw->i2c_pend_mask = 0; | ||
912 | hdw->i2c_stale_mask = 0; | ||
913 | hdw->i2c_active_mask = 0; | ||
914 | INIT_LIST_HEAD(&hdw->i2c_clients); | ||
915 | mutex_init(&hdw->i2c_list_lock); | ||
916 | hdw->i2c_linked = !0; | ||
917 | i2c_add_adapter(&hdw->i2c_adap); | ||
918 | if (i2c_scan) do_i2c_scan(hdw); | ||
919 | } | ||
920 | |||
921 | void pvr2_i2c_core_done(struct pvr2_hdw *hdw) | ||
922 | { | ||
923 | if (hdw->i2c_linked) { | ||
924 | i2c_del_adapter(&hdw->i2c_adap); | ||
925 | hdw->i2c_linked = 0; | ||
926 | } | ||
927 | } | ||
928 | |||
929 | /* | ||
930 | Stuff for Emacs to see, in order to encourage consistent editing style: | ||
931 | *** Local Variables: *** | ||
932 | *** mode: c *** | ||
933 | *** fill-column: 75 *** | ||
934 | *** tab-width: 8 *** | ||
935 | *** c-basic-offset: 8 *** | ||
936 | *** End: *** | ||
937 | */ | ||
diff --git a/drivers/media/video/pvrusb2/pvrusb2-i2c-core.h b/drivers/media/video/pvrusb2/pvrusb2-i2c-core.h new file mode 100644 index 000000000000..e8af5b0ed3ce --- /dev/null +++ b/drivers/media/video/pvrusb2/pvrusb2-i2c-core.h | |||
@@ -0,0 +1,96 @@ | |||
1 | /* | ||
2 | * | ||
3 | * $Id$ | ||
4 | * | ||
5 | * Copyright (C) 2005 Mike Isely <isely@pobox.com> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License as published by | ||
9 | * the Free Software Foundation; either version 2 of the License | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
19 | * | ||
20 | */ | ||
21 | #ifndef __PVRUSB2_I2C_CORE_H | ||
22 | #define __PVRUSB2_I2C_CORE_H | ||
23 | |||
24 | #include <linux/list.h> | ||
25 | #include <linux/i2c.h> | ||
26 | |||
27 | struct pvr2_hdw; | ||
28 | struct pvr2_i2c_client; | ||
29 | struct pvr2_i2c_handler; | ||
30 | struct pvr2_i2c_handler_functions; | ||
31 | struct pvr2_i2c_op; | ||
32 | struct pvr2_i2c_op_functions; | ||
33 | |||
34 | struct pvr2_i2c_client { | ||
35 | struct i2c_client *client; | ||
36 | struct pvr2_i2c_handler *handler; | ||
37 | struct list_head list; | ||
38 | int detected_flag; | ||
39 | int recv_enable; | ||
40 | unsigned long pend_mask; | ||
41 | unsigned long ctl_mask; | ||
42 | }; | ||
43 | |||
44 | struct pvr2_i2c_handler { | ||
45 | void *func_data; | ||
46 | const struct pvr2_i2c_handler_functions *func_table; | ||
47 | }; | ||
48 | |||
49 | struct pvr2_i2c_handler_functions { | ||
50 | void (*detach)(void *); | ||
51 | int (*check)(void *); | ||
52 | void (*update)(void *); | ||
53 | unsigned int (*describe)(void *,char *,unsigned int); | ||
54 | }; | ||
55 | |||
56 | struct pvr2_i2c_op { | ||
57 | int (*check)(struct pvr2_hdw *); | ||
58 | void (*update)(struct pvr2_hdw *); | ||
59 | const char *name; | ||
60 | }; | ||
61 | |||
62 | void pvr2_i2c_core_init(struct pvr2_hdw *); | ||
63 | void pvr2_i2c_core_done(struct pvr2_hdw *); | ||
64 | |||
65 | int pvr2_i2c_client_cmd(struct pvr2_i2c_client *,unsigned int cmd,void *arg); | ||
66 | int pvr2_i2c_core_cmd(struct pvr2_hdw *,unsigned int cmd,void *arg); | ||
67 | |||
68 | int pvr2_i2c_core_check_stale(struct pvr2_hdw *); | ||
69 | void pvr2_i2c_core_sync(struct pvr2_hdw *); | ||
70 | unsigned int pvr2_i2c_report(struct pvr2_hdw *,char *buf,unsigned int maxlen); | ||
71 | #define PVR2_I2C_DETAIL_DEBUG 0x0001 | ||
72 | #define PVR2_I2C_DETAIL_HANDLER 0x0002 | ||
73 | #define PVR2_I2C_DETAIL_CTLMASK 0x0004 | ||
74 | #define PVR2_I2C_DETAIL_ALL (\ | ||
75 | PVR2_I2C_DETAIL_DEBUG |\ | ||
76 | PVR2_I2C_DETAIL_HANDLER |\ | ||
77 | PVR2_I2C_DETAIL_CTLMASK) | ||
78 | unsigned int pvr2_i2c_client_describe(struct pvr2_i2c_client *, | ||
79 | unsigned int detail_mask, | ||
80 | char *buf,unsigned int maxlen); | ||
81 | |||
82 | void pvr2_i2c_probe(struct pvr2_hdw *,struct pvr2_i2c_client *); | ||
83 | const struct pvr2_i2c_op *pvr2_i2c_get_op(unsigned int idx); | ||
84 | |||
85 | #endif /* __PVRUSB2_I2C_CORE_H */ | ||
86 | |||
87 | |||
88 | /* | ||
89 | Stuff for Emacs to see, in order to encourage consistent editing style: | ||
90 | *** Local Variables: *** | ||
91 | *** mode: c *** | ||
92 | *** fill-column: 75 *** | ||
93 | *** tab-width: 8 *** | ||
94 | *** c-basic-offset: 8 *** | ||
95 | *** End: *** | ||
96 | */ | ||
diff --git a/drivers/media/video/pvrusb2/pvrusb2-io.c b/drivers/media/video/pvrusb2/pvrusb2-io.c new file mode 100644 index 000000000000..a984c91f571c --- /dev/null +++ b/drivers/media/video/pvrusb2/pvrusb2-io.c | |||
@@ -0,0 +1,695 @@ | |||
1 | /* | ||
2 | * | ||
3 | * $Id$ | ||
4 | * | ||
5 | * Copyright (C) 2005 Mike Isely <isely@pobox.com> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License as published by | ||
9 | * the Free Software Foundation; either version 2 of the License | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
19 | * | ||
20 | */ | ||
21 | |||
22 | #include "pvrusb2-io.h" | ||
23 | #include "pvrusb2-debug.h" | ||
24 | #include <linux/errno.h> | ||
25 | #include <linux/string.h> | ||
26 | #include <linux/slab.h> | ||
27 | #include <linux/mutex.h> | ||
28 | |||
29 | #define BUFFER_SIG 0x47653271 | ||
30 | |||
31 | // #define SANITY_CHECK_BUFFERS | ||
32 | |||
33 | |||
34 | #ifdef SANITY_CHECK_BUFFERS | ||
35 | #define BUFFER_CHECK(bp) do { \ | ||
36 | if ((bp)->signature != BUFFER_SIG) { \ | ||
37 | pvr2_trace(PVR2_TRACE_ERROR_LEGS, \ | ||
38 | "Buffer %p is bad at %s:%d", \ | ||
39 | (bp),__FILE__,__LINE__); \ | ||
40 | pvr2_buffer_describe(bp,"BadSig"); \ | ||
41 | BUG(); \ | ||
42 | } \ | ||
43 | } while (0) | ||
44 | #else | ||
45 | #define BUFFER_CHECK(bp) do {} while(0) | ||
46 | #endif | ||
47 | |||
48 | struct pvr2_stream { | ||
49 | /* Buffers queued for reading */ | ||
50 | struct list_head queued_list; | ||
51 | unsigned int q_count; | ||
52 | unsigned int q_bcount; | ||
53 | /* Buffers with retrieved data */ | ||
54 | struct list_head ready_list; | ||
55 | unsigned int r_count; | ||
56 | unsigned int r_bcount; | ||
57 | /* Buffers available for use */ | ||
58 | struct list_head idle_list; | ||
59 | unsigned int i_count; | ||
60 | unsigned int i_bcount; | ||
61 | /* Pointers to all buffers */ | ||
62 | struct pvr2_buffer **buffers; | ||
63 | /* Array size of buffers */ | ||
64 | unsigned int buffer_slot_count; | ||
65 | /* Total buffers actually in circulation */ | ||
66 | unsigned int buffer_total_count; | ||
67 | /* Designed number of buffers to be in circulation */ | ||
68 | unsigned int buffer_target_count; | ||
69 | /* Executed when ready list become non-empty */ | ||
70 | pvr2_stream_callback callback_func; | ||
71 | void *callback_data; | ||
72 | /* Context for transfer endpoint */ | ||
73 | struct usb_device *dev; | ||
74 | int endpoint; | ||
75 | /* Overhead for mutex enforcement */ | ||
76 | spinlock_t list_lock; | ||
77 | struct mutex mutex; | ||
78 | /* Tracking state for tolerating errors */ | ||
79 | unsigned int fail_count; | ||
80 | unsigned int fail_tolerance; | ||
81 | }; | ||
82 | |||
83 | struct pvr2_buffer { | ||
84 | int id; | ||
85 | int signature; | ||
86 | enum pvr2_buffer_state state; | ||
87 | void *ptr; /* Pointer to storage area */ | ||
88 | unsigned int max_count; /* Size of storage area */ | ||
89 | unsigned int used_count; /* Amount of valid data in storage area */ | ||
90 | int status; /* Transfer result status */ | ||
91 | struct pvr2_stream *stream; | ||
92 | struct list_head list_overhead; | ||
93 | struct urb *purb; | ||
94 | }; | ||
95 | |||
96 | const char *pvr2_buffer_state_decode(enum pvr2_buffer_state st) | ||
97 | { | ||
98 | switch (st) { | ||
99 | case pvr2_buffer_state_none: return "none"; | ||
100 | case pvr2_buffer_state_idle: return "idle"; | ||
101 | case pvr2_buffer_state_queued: return "queued"; | ||
102 | case pvr2_buffer_state_ready: return "ready"; | ||
103 | } | ||
104 | return "unknown"; | ||
105 | } | ||
106 | |||
107 | void pvr2_buffer_describe(struct pvr2_buffer *bp,const char *msg) | ||
108 | { | ||
109 | pvr2_trace(PVR2_TRACE_INFO, | ||
110 | "buffer%s%s %p state=%s id=%d status=%d" | ||
111 | " stream=%p purb=%p sig=0x%x", | ||
112 | (msg ? " " : ""), | ||
113 | (msg ? msg : ""), | ||
114 | bp, | ||
115 | (bp ? pvr2_buffer_state_decode(bp->state) : "(invalid)"), | ||
116 | (bp ? bp->id : 0), | ||
117 | (bp ? bp->status : 0), | ||
118 | (bp ? bp->stream : 0), | ||
119 | (bp ? bp->purb : 0), | ||
120 | (bp ? bp->signature : 0)); | ||
121 | } | ||
122 | |||
123 | static void pvr2_buffer_remove(struct pvr2_buffer *bp) | ||
124 | { | ||
125 | unsigned int *cnt; | ||
126 | unsigned int *bcnt; | ||
127 | unsigned int ccnt; | ||
128 | struct pvr2_stream *sp = bp->stream; | ||
129 | switch (bp->state) { | ||
130 | case pvr2_buffer_state_idle: | ||
131 | cnt = &sp->i_count; | ||
132 | bcnt = &sp->i_bcount; | ||
133 | ccnt = bp->max_count; | ||
134 | break; | ||
135 | case pvr2_buffer_state_queued: | ||
136 | cnt = &sp->q_count; | ||
137 | bcnt = &sp->q_bcount; | ||
138 | ccnt = bp->max_count; | ||
139 | break; | ||
140 | case pvr2_buffer_state_ready: | ||
141 | cnt = &sp->r_count; | ||
142 | bcnt = &sp->r_bcount; | ||
143 | ccnt = bp->used_count; | ||
144 | break; | ||
145 | default: | ||
146 | return; | ||
147 | } | ||
148 | list_del_init(&bp->list_overhead); | ||
149 | (*cnt)--; | ||
150 | (*bcnt) -= ccnt; | ||
151 | pvr2_trace(PVR2_TRACE_BUF_FLOW, | ||
152 | "/*---TRACE_FLOW---*/" | ||
153 | " bufferPool %8s dec cap=%07d cnt=%02d", | ||
154 | pvr2_buffer_state_decode(bp->state),*bcnt,*cnt); | ||
155 | bp->state = pvr2_buffer_state_none; | ||
156 | } | ||
157 | |||
158 | static void pvr2_buffer_set_none(struct pvr2_buffer *bp) | ||
159 | { | ||
160 | unsigned long irq_flags; | ||
161 | struct pvr2_stream *sp; | ||
162 | BUFFER_CHECK(bp); | ||
163 | sp = bp->stream; | ||
164 | pvr2_trace(PVR2_TRACE_BUF_FLOW, | ||
165 | "/*---TRACE_FLOW---*/ bufferState %p %6s --> %6s", | ||
166 | bp, | ||
167 | pvr2_buffer_state_decode(bp->state), | ||
168 | pvr2_buffer_state_decode(pvr2_buffer_state_none)); | ||
169 | spin_lock_irqsave(&sp->list_lock,irq_flags); | ||
170 | pvr2_buffer_remove(bp); | ||
171 | spin_unlock_irqrestore(&sp->list_lock,irq_flags); | ||
172 | } | ||
173 | |||
174 | static int pvr2_buffer_set_ready(struct pvr2_buffer *bp) | ||
175 | { | ||
176 | int fl; | ||
177 | unsigned long irq_flags; | ||
178 | struct pvr2_stream *sp; | ||
179 | BUFFER_CHECK(bp); | ||
180 | sp = bp->stream; | ||
181 | pvr2_trace(PVR2_TRACE_BUF_FLOW, | ||
182 | "/*---TRACE_FLOW---*/ bufferState %p %6s --> %6s", | ||
183 | bp, | ||
184 | pvr2_buffer_state_decode(bp->state), | ||
185 | pvr2_buffer_state_decode(pvr2_buffer_state_ready)); | ||
186 | spin_lock_irqsave(&sp->list_lock,irq_flags); | ||
187 | fl = (sp->r_count == 0); | ||
188 | pvr2_buffer_remove(bp); | ||
189 | list_add_tail(&bp->list_overhead,&sp->ready_list); | ||
190 | bp->state = pvr2_buffer_state_ready; | ||
191 | (sp->r_count)++; | ||
192 | sp->r_bcount += bp->used_count; | ||
193 | pvr2_trace(PVR2_TRACE_BUF_FLOW, | ||
194 | "/*---TRACE_FLOW---*/" | ||
195 | " bufferPool %8s inc cap=%07d cnt=%02d", | ||
196 | pvr2_buffer_state_decode(bp->state), | ||
197 | sp->r_bcount,sp->r_count); | ||
198 | spin_unlock_irqrestore(&sp->list_lock,irq_flags); | ||
199 | return fl; | ||
200 | } | ||
201 | |||
202 | static void pvr2_buffer_set_idle(struct pvr2_buffer *bp) | ||
203 | { | ||
204 | unsigned long irq_flags; | ||
205 | struct pvr2_stream *sp; | ||
206 | BUFFER_CHECK(bp); | ||
207 | sp = bp->stream; | ||
208 | pvr2_trace(PVR2_TRACE_BUF_FLOW, | ||
209 | "/*---TRACE_FLOW---*/ bufferState %p %6s --> %6s", | ||
210 | bp, | ||
211 | pvr2_buffer_state_decode(bp->state), | ||
212 | pvr2_buffer_state_decode(pvr2_buffer_state_idle)); | ||
213 | spin_lock_irqsave(&sp->list_lock,irq_flags); | ||
214 | pvr2_buffer_remove(bp); | ||
215 | list_add_tail(&bp->list_overhead,&sp->idle_list); | ||
216 | bp->state = pvr2_buffer_state_idle; | ||
217 | (sp->i_count)++; | ||
218 | sp->i_bcount += bp->max_count; | ||
219 | pvr2_trace(PVR2_TRACE_BUF_FLOW, | ||
220 | "/*---TRACE_FLOW---*/" | ||
221 | " bufferPool %8s inc cap=%07d cnt=%02d", | ||
222 | pvr2_buffer_state_decode(bp->state), | ||
223 | sp->i_bcount,sp->i_count); | ||
224 | spin_unlock_irqrestore(&sp->list_lock,irq_flags); | ||
225 | } | ||
226 | |||
227 | static void pvr2_buffer_set_queued(struct pvr2_buffer *bp) | ||
228 | { | ||
229 | unsigned long irq_flags; | ||
230 | struct pvr2_stream *sp; | ||
231 | BUFFER_CHECK(bp); | ||
232 | sp = bp->stream; | ||
233 | pvr2_trace(PVR2_TRACE_BUF_FLOW, | ||
234 | "/*---TRACE_FLOW---*/ bufferState %p %6s --> %6s", | ||
235 | bp, | ||
236 | pvr2_buffer_state_decode(bp->state), | ||
237 | pvr2_buffer_state_decode(pvr2_buffer_state_queued)); | ||
238 | spin_lock_irqsave(&sp->list_lock,irq_flags); | ||
239 | pvr2_buffer_remove(bp); | ||
240 | list_add_tail(&bp->list_overhead,&sp->queued_list); | ||
241 | bp->state = pvr2_buffer_state_queued; | ||
242 | (sp->q_count)++; | ||
243 | sp->q_bcount += bp->max_count; | ||
244 | pvr2_trace(PVR2_TRACE_BUF_FLOW, | ||
245 | "/*---TRACE_FLOW---*/" | ||
246 | " bufferPool %8s inc cap=%07d cnt=%02d", | ||
247 | pvr2_buffer_state_decode(bp->state), | ||
248 | sp->q_bcount,sp->q_count); | ||
249 | spin_unlock_irqrestore(&sp->list_lock,irq_flags); | ||
250 | } | ||
251 | |||
252 | static void pvr2_buffer_wipe(struct pvr2_buffer *bp) | ||
253 | { | ||
254 | if (bp->state == pvr2_buffer_state_queued) { | ||
255 | usb_kill_urb(bp->purb); | ||
256 | } | ||
257 | } | ||
258 | |||
259 | static int pvr2_buffer_init(struct pvr2_buffer *bp, | ||
260 | struct pvr2_stream *sp, | ||
261 | unsigned int id) | ||
262 | { | ||
263 | memset(bp,0,sizeof(*bp)); | ||
264 | bp->signature = BUFFER_SIG; | ||
265 | bp->id = id; | ||
266 | pvr2_trace(PVR2_TRACE_BUF_POOL, | ||
267 | "/*---TRACE_FLOW---*/ bufferInit %p stream=%p",bp,sp); | ||
268 | bp->stream = sp; | ||
269 | bp->state = pvr2_buffer_state_none; | ||
270 | INIT_LIST_HEAD(&bp->list_overhead); | ||
271 | bp->purb = usb_alloc_urb(0,GFP_KERNEL); | ||
272 | if (! bp->purb) return -ENOMEM; | ||
273 | #ifdef SANITY_CHECK_BUFFERS | ||
274 | pvr2_buffer_describe(bp,"create"); | ||
275 | #endif | ||
276 | return 0; | ||
277 | } | ||
278 | |||
279 | static void pvr2_buffer_done(struct pvr2_buffer *bp) | ||
280 | { | ||
281 | #ifdef SANITY_CHECK_BUFFERS | ||
282 | pvr2_buffer_describe(bp,"delete"); | ||
283 | #endif | ||
284 | pvr2_buffer_wipe(bp); | ||
285 | pvr2_buffer_set_none(bp); | ||
286 | bp->signature = 0; | ||
287 | bp->stream = 0; | ||
288 | if (bp->purb) usb_free_urb(bp->purb); | ||
289 | pvr2_trace(PVR2_TRACE_BUF_POOL,"/*---TRACE_FLOW---*/" | ||
290 | " bufferDone %p",bp); | ||
291 | } | ||
292 | |||
293 | static int pvr2_stream_buffer_count(struct pvr2_stream *sp,unsigned int cnt) | ||
294 | { | ||
295 | int ret; | ||
296 | unsigned int scnt; | ||
297 | |||
298 | /* Allocate buffers pointer array in multiples of 32 entries */ | ||
299 | if (cnt == sp->buffer_total_count) return 0; | ||
300 | |||
301 | pvr2_trace(PVR2_TRACE_BUF_POOL, | ||
302 | "/*---TRACE_FLOW---*/ poolResize " | ||
303 | " stream=%p cur=%d adj=%+d", | ||
304 | sp, | ||
305 | sp->buffer_total_count, | ||
306 | cnt-sp->buffer_total_count); | ||
307 | |||
308 | scnt = cnt & ~0x1f; | ||
309 | if (cnt > scnt) scnt += 0x20; | ||
310 | |||
311 | if (cnt > sp->buffer_total_count) { | ||
312 | if (scnt > sp->buffer_slot_count) { | ||
313 | struct pvr2_buffer **nb; | ||
314 | nb = kmalloc(scnt * sizeof(*nb),GFP_KERNEL); | ||
315 | if (!nb) return -ENOMEM; | ||
316 | if (sp->buffer_slot_count) { | ||
317 | memcpy(nb,sp->buffers, | ||
318 | sp->buffer_slot_count * sizeof(*nb)); | ||
319 | kfree(sp->buffers); | ||
320 | } | ||
321 | sp->buffers = nb; | ||
322 | sp->buffer_slot_count = scnt; | ||
323 | } | ||
324 | while (sp->buffer_total_count < cnt) { | ||
325 | struct pvr2_buffer *bp; | ||
326 | bp = kmalloc(sizeof(*bp),GFP_KERNEL); | ||
327 | if (!bp) return -ENOMEM; | ||
328 | ret = pvr2_buffer_init(bp,sp,sp->buffer_total_count); | ||
329 | if (ret) { | ||
330 | kfree(bp); | ||
331 | return -ENOMEM; | ||
332 | } | ||
333 | sp->buffers[sp->buffer_total_count] = bp; | ||
334 | (sp->buffer_total_count)++; | ||
335 | pvr2_buffer_set_idle(bp); | ||
336 | } | ||
337 | } else { | ||
338 | while (sp->buffer_total_count > cnt) { | ||
339 | struct pvr2_buffer *bp; | ||
340 | bp = sp->buffers[sp->buffer_total_count - 1]; | ||
341 | /* Paranoia */ | ||
342 | sp->buffers[sp->buffer_total_count - 1] = 0; | ||
343 | (sp->buffer_total_count)--; | ||
344 | pvr2_buffer_done(bp); | ||
345 | kfree(bp); | ||
346 | } | ||
347 | if (scnt < sp->buffer_slot_count) { | ||
348 | struct pvr2_buffer **nb = 0; | ||
349 | if (scnt) { | ||
350 | nb = kmalloc(scnt * sizeof(*nb),GFP_KERNEL); | ||
351 | if (!nb) return -ENOMEM; | ||
352 | memcpy(nb,sp->buffers,scnt * sizeof(*nb)); | ||
353 | } | ||
354 | kfree(sp->buffers); | ||
355 | sp->buffers = nb; | ||
356 | sp->buffer_slot_count = scnt; | ||
357 | } | ||
358 | } | ||
359 | return 0; | ||
360 | } | ||
361 | |||
362 | static int pvr2_stream_achieve_buffer_count(struct pvr2_stream *sp) | ||
363 | { | ||
364 | struct pvr2_buffer *bp; | ||
365 | unsigned int cnt; | ||
366 | |||
367 | if (sp->buffer_total_count == sp->buffer_target_count) return 0; | ||
368 | |||
369 | pvr2_trace(PVR2_TRACE_BUF_POOL, | ||
370 | "/*---TRACE_FLOW---*/" | ||
371 | " poolCheck stream=%p cur=%d tgt=%d", | ||
372 | sp,sp->buffer_total_count,sp->buffer_target_count); | ||
373 | |||
374 | if (sp->buffer_total_count < sp->buffer_target_count) { | ||
375 | return pvr2_stream_buffer_count(sp,sp->buffer_target_count); | ||
376 | } | ||
377 | |||
378 | cnt = 0; | ||
379 | while ((sp->buffer_total_count - cnt) > sp->buffer_target_count) { | ||
380 | bp = sp->buffers[sp->buffer_total_count - (cnt + 1)]; | ||
381 | if (bp->state != pvr2_buffer_state_idle) break; | ||
382 | cnt++; | ||
383 | } | ||
384 | if (cnt) { | ||
385 | pvr2_stream_buffer_count(sp,sp->buffer_total_count - cnt); | ||
386 | } | ||
387 | |||
388 | return 0; | ||
389 | } | ||
390 | |||
391 | static void pvr2_stream_internal_flush(struct pvr2_stream *sp) | ||
392 | { | ||
393 | struct list_head *lp; | ||
394 | struct pvr2_buffer *bp1; | ||
395 | while ((lp = sp->queued_list.next) != &sp->queued_list) { | ||
396 | bp1 = list_entry(lp,struct pvr2_buffer,list_overhead); | ||
397 | pvr2_buffer_wipe(bp1); | ||
398 | /* At this point, we should be guaranteed that no | ||
399 | completion callback may happen on this buffer. But it's | ||
400 | possible that it might have completed after we noticed | ||
401 | it but before we wiped it. So double check its status | ||
402 | here first. */ | ||
403 | if (bp1->state != pvr2_buffer_state_queued) continue; | ||
404 | pvr2_buffer_set_idle(bp1); | ||
405 | } | ||
406 | if (sp->buffer_total_count != sp->buffer_target_count) { | ||
407 | pvr2_stream_achieve_buffer_count(sp); | ||
408 | } | ||
409 | } | ||
410 | |||
411 | static void pvr2_stream_init(struct pvr2_stream *sp) | ||
412 | { | ||
413 | spin_lock_init(&sp->list_lock); | ||
414 | mutex_init(&sp->mutex); | ||
415 | INIT_LIST_HEAD(&sp->queued_list); | ||
416 | INIT_LIST_HEAD(&sp->ready_list); | ||
417 | INIT_LIST_HEAD(&sp->idle_list); | ||
418 | } | ||
419 | |||
420 | static void pvr2_stream_done(struct pvr2_stream *sp) | ||
421 | { | ||
422 | mutex_lock(&sp->mutex); do { | ||
423 | pvr2_stream_internal_flush(sp); | ||
424 | pvr2_stream_buffer_count(sp,0); | ||
425 | } while (0); mutex_unlock(&sp->mutex); | ||
426 | } | ||
427 | |||
428 | static void buffer_complete(struct urb *urb, struct pt_regs *regs) | ||
429 | { | ||
430 | struct pvr2_buffer *bp = urb->context; | ||
431 | struct pvr2_stream *sp; | ||
432 | unsigned long irq_flags; | ||
433 | BUFFER_CHECK(bp); | ||
434 | sp = bp->stream; | ||
435 | bp->used_count = 0; | ||
436 | bp->status = 0; | ||
437 | pvr2_trace(PVR2_TRACE_BUF_FLOW, | ||
438 | "/*---TRACE_FLOW---*/ bufferComplete %p stat=%d cnt=%d", | ||
439 | bp,urb->status,urb->actual_length); | ||
440 | spin_lock_irqsave(&sp->list_lock,irq_flags); | ||
441 | if ((!(urb->status)) || | ||
442 | (urb->status == -ENOENT) || | ||
443 | (urb->status == -ECONNRESET) || | ||
444 | (urb->status == -ESHUTDOWN)) { | ||
445 | bp->used_count = urb->actual_length; | ||
446 | if (sp->fail_count) { | ||
447 | pvr2_trace(PVR2_TRACE_TOLERANCE, | ||
448 | "stream %p transfer ok" | ||
449 | " - fail count reset",sp); | ||
450 | sp->fail_count = 0; | ||
451 | } | ||
452 | } else if (sp->fail_count < sp->fail_tolerance) { | ||
453 | // We can tolerate this error, because we're below the | ||
454 | // threshold... | ||
455 | (sp->fail_count)++; | ||
456 | pvr2_trace(PVR2_TRACE_TOLERANCE, | ||
457 | "stream %p ignoring error %d" | ||
458 | " - fail count increased to %u", | ||
459 | sp,urb->status,sp->fail_count); | ||
460 | } else { | ||
461 | bp->status = urb->status; | ||
462 | } | ||
463 | spin_unlock_irqrestore(&sp->list_lock,irq_flags); | ||
464 | pvr2_buffer_set_ready(bp); | ||
465 | if (sp && sp->callback_func) { | ||
466 | sp->callback_func(sp->callback_data); | ||
467 | } | ||
468 | } | ||
469 | |||
470 | struct pvr2_stream *pvr2_stream_create(void) | ||
471 | { | ||
472 | struct pvr2_stream *sp; | ||
473 | sp = kmalloc(sizeof(*sp),GFP_KERNEL); | ||
474 | if (!sp) return sp; | ||
475 | memset(sp,0,sizeof(*sp)); | ||
476 | pvr2_trace(PVR2_TRACE_INIT,"pvr2_stream_create: sp=%p",sp); | ||
477 | pvr2_stream_init(sp); | ||
478 | return sp; | ||
479 | } | ||
480 | |||
481 | void pvr2_stream_destroy(struct pvr2_stream *sp) | ||
482 | { | ||
483 | if (!sp) return; | ||
484 | pvr2_trace(PVR2_TRACE_INIT,"pvr2_stream_destroy: sp=%p",sp); | ||
485 | pvr2_stream_done(sp); | ||
486 | kfree(sp); | ||
487 | } | ||
488 | |||
489 | void pvr2_stream_setup(struct pvr2_stream *sp, | ||
490 | struct usb_device *dev, | ||
491 | int endpoint, | ||
492 | unsigned int tolerance) | ||
493 | { | ||
494 | mutex_lock(&sp->mutex); do { | ||
495 | pvr2_stream_internal_flush(sp); | ||
496 | sp->dev = dev; | ||
497 | sp->endpoint = endpoint; | ||
498 | sp->fail_tolerance = tolerance; | ||
499 | } while(0); mutex_unlock(&sp->mutex); | ||
500 | } | ||
501 | |||
502 | void pvr2_stream_set_callback(struct pvr2_stream *sp, | ||
503 | pvr2_stream_callback func, | ||
504 | void *data) | ||
505 | { | ||
506 | unsigned long irq_flags; | ||
507 | mutex_lock(&sp->mutex); do { | ||
508 | spin_lock_irqsave(&sp->list_lock,irq_flags); | ||
509 | sp->callback_data = data; | ||
510 | sp->callback_func = func; | ||
511 | spin_unlock_irqrestore(&sp->list_lock,irq_flags); | ||
512 | } while(0); mutex_unlock(&sp->mutex); | ||
513 | } | ||
514 | |||
515 | /* Query / set the nominal buffer count */ | ||
516 | int pvr2_stream_get_buffer_count(struct pvr2_stream *sp) | ||
517 | { | ||
518 | return sp->buffer_target_count; | ||
519 | } | ||
520 | |||
521 | int pvr2_stream_set_buffer_count(struct pvr2_stream *sp,unsigned int cnt) | ||
522 | { | ||
523 | int ret; | ||
524 | if (sp->buffer_target_count == cnt) return 0; | ||
525 | mutex_lock(&sp->mutex); do { | ||
526 | sp->buffer_target_count = cnt; | ||
527 | ret = pvr2_stream_achieve_buffer_count(sp); | ||
528 | } while(0); mutex_unlock(&sp->mutex); | ||
529 | return ret; | ||
530 | } | ||
531 | |||
532 | struct pvr2_buffer *pvr2_stream_get_idle_buffer(struct pvr2_stream *sp) | ||
533 | { | ||
534 | struct list_head *lp = sp->idle_list.next; | ||
535 | if (lp == &sp->idle_list) return 0; | ||
536 | return list_entry(lp,struct pvr2_buffer,list_overhead); | ||
537 | } | ||
538 | |||
539 | struct pvr2_buffer *pvr2_stream_get_ready_buffer(struct pvr2_stream *sp) | ||
540 | { | ||
541 | struct list_head *lp = sp->ready_list.next; | ||
542 | if (lp == &sp->ready_list) return 0; | ||
543 | return list_entry(lp,struct pvr2_buffer,list_overhead); | ||
544 | } | ||
545 | |||
546 | struct pvr2_buffer *pvr2_stream_get_buffer(struct pvr2_stream *sp,int id) | ||
547 | { | ||
548 | if (id < 0) return 0; | ||
549 | if (id >= sp->buffer_total_count) return 0; | ||
550 | return sp->buffers[id]; | ||
551 | } | ||
552 | |||
553 | int pvr2_stream_get_ready_count(struct pvr2_stream *sp) | ||
554 | { | ||
555 | return sp->r_count; | ||
556 | } | ||
557 | |||
558 | int pvr2_stream_get_idle_count(struct pvr2_stream *sp) | ||
559 | { | ||
560 | return sp->i_count; | ||
561 | } | ||
562 | |||
563 | void pvr2_stream_flush(struct pvr2_stream *sp) | ||
564 | { | ||
565 | mutex_lock(&sp->mutex); do { | ||
566 | pvr2_stream_internal_flush(sp); | ||
567 | } while(0); mutex_unlock(&sp->mutex); | ||
568 | } | ||
569 | |||
570 | void pvr2_stream_kill(struct pvr2_stream *sp) | ||
571 | { | ||
572 | struct pvr2_buffer *bp; | ||
573 | mutex_lock(&sp->mutex); do { | ||
574 | pvr2_stream_internal_flush(sp); | ||
575 | while ((bp = pvr2_stream_get_ready_buffer(sp)) != 0) { | ||
576 | pvr2_buffer_set_idle(bp); | ||
577 | } | ||
578 | if (sp->buffer_total_count != sp->buffer_target_count) { | ||
579 | pvr2_stream_achieve_buffer_count(sp); | ||
580 | } | ||
581 | } while(0); mutex_unlock(&sp->mutex); | ||
582 | } | ||
583 | |||
584 | int pvr2_buffer_queue(struct pvr2_buffer *bp) | ||
585 | { | ||
586 | #undef SEED_BUFFER | ||
587 | #ifdef SEED_BUFFER | ||
588 | unsigned int idx; | ||
589 | unsigned int val; | ||
590 | #endif | ||
591 | int ret = 0; | ||
592 | struct pvr2_stream *sp; | ||
593 | if (!bp) return -EINVAL; | ||
594 | sp = bp->stream; | ||
595 | mutex_lock(&sp->mutex); do { | ||
596 | pvr2_buffer_wipe(bp); | ||
597 | if (!sp->dev) { | ||
598 | ret = -EIO; | ||
599 | break; | ||
600 | } | ||
601 | pvr2_buffer_set_queued(bp); | ||
602 | #ifdef SEED_BUFFER | ||
603 | for (idx = 0; idx < (bp->max_count) / 4; idx++) { | ||
604 | val = bp->id << 24; | ||
605 | val |= idx; | ||
606 | ((unsigned int *)(bp->ptr))[idx] = val; | ||
607 | } | ||
608 | #endif | ||
609 | bp->status = -EINPROGRESS; | ||
610 | usb_fill_bulk_urb(bp->purb, // struct urb *urb | ||
611 | sp->dev, // struct usb_device *dev | ||
612 | // endpoint (below) | ||
613 | usb_rcvbulkpipe(sp->dev,sp->endpoint), | ||
614 | bp->ptr, // void *transfer_buffer | ||
615 | bp->max_count, // int buffer_length | ||
616 | buffer_complete, | ||
617 | bp); | ||
618 | usb_submit_urb(bp->purb,GFP_KERNEL); | ||
619 | } while(0); mutex_unlock(&sp->mutex); | ||
620 | return ret; | ||
621 | } | ||
622 | |||
623 | int pvr2_buffer_idle(struct pvr2_buffer *bp) | ||
624 | { | ||
625 | struct pvr2_stream *sp; | ||
626 | if (!bp) return -EINVAL; | ||
627 | sp = bp->stream; | ||
628 | mutex_lock(&sp->mutex); do { | ||
629 | pvr2_buffer_wipe(bp); | ||
630 | pvr2_buffer_set_idle(bp); | ||
631 | if (sp->buffer_total_count != sp->buffer_target_count) { | ||
632 | pvr2_stream_achieve_buffer_count(sp); | ||
633 | } | ||
634 | } while(0); mutex_unlock(&sp->mutex); | ||
635 | return 0; | ||
636 | } | ||
637 | |||
638 | int pvr2_buffer_set_buffer(struct pvr2_buffer *bp,void *ptr,unsigned int cnt) | ||
639 | { | ||
640 | int ret = 0; | ||
641 | unsigned long irq_flags; | ||
642 | struct pvr2_stream *sp; | ||
643 | if (!bp) return -EINVAL; | ||
644 | sp = bp->stream; | ||
645 | mutex_lock(&sp->mutex); do { | ||
646 | spin_lock_irqsave(&sp->list_lock,irq_flags); | ||
647 | if (bp->state != pvr2_buffer_state_idle) { | ||
648 | ret = -EPERM; | ||
649 | } else { | ||
650 | bp->ptr = ptr; | ||
651 | bp->stream->i_bcount -= bp->max_count; | ||
652 | bp->max_count = cnt; | ||
653 | bp->stream->i_bcount += bp->max_count; | ||
654 | pvr2_trace(PVR2_TRACE_BUF_FLOW, | ||
655 | "/*---TRACE_FLOW---*/ bufferPool " | ||
656 | " %8s cap cap=%07d cnt=%02d", | ||
657 | pvr2_buffer_state_decode( | ||
658 | pvr2_buffer_state_idle), | ||
659 | bp->stream->i_bcount,bp->stream->i_count); | ||
660 | } | ||
661 | spin_unlock_irqrestore(&sp->list_lock,irq_flags); | ||
662 | } while(0); mutex_unlock(&sp->mutex); | ||
663 | return ret; | ||
664 | } | ||
665 | |||
666 | unsigned int pvr2_buffer_get_count(struct pvr2_buffer *bp) | ||
667 | { | ||
668 | return bp->used_count; | ||
669 | } | ||
670 | |||
671 | int pvr2_buffer_get_status(struct pvr2_buffer *bp) | ||
672 | { | ||
673 | return bp->status; | ||
674 | } | ||
675 | |||
676 | enum pvr2_buffer_state pvr2_buffer_get_state(struct pvr2_buffer *bp) | ||
677 | { | ||
678 | return bp->state; | ||
679 | } | ||
680 | |||
681 | int pvr2_buffer_get_id(struct pvr2_buffer *bp) | ||
682 | { | ||
683 | return bp->id; | ||
684 | } | ||
685 | |||
686 | |||
687 | /* | ||
688 | Stuff for Emacs to see, in order to encourage consistent editing style: | ||
689 | *** Local Variables: *** | ||
690 | *** mode: c *** | ||
691 | *** fill-column: 75 *** | ||
692 | *** tab-width: 8 *** | ||
693 | *** c-basic-offset: 8 *** | ||
694 | *** End: *** | ||
695 | */ | ||
diff --git a/drivers/media/video/pvrusb2/pvrusb2-io.h b/drivers/media/video/pvrusb2/pvrusb2-io.h new file mode 100644 index 000000000000..65e11385b2b3 --- /dev/null +++ b/drivers/media/video/pvrusb2/pvrusb2-io.h | |||
@@ -0,0 +1,102 @@ | |||
1 | /* | ||
2 | * | ||
3 | * $Id$ | ||
4 | * | ||
5 | * Copyright (C) 2005 Mike Isely <isely@pobox.com> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License as published by | ||
9 | * the Free Software Foundation; either version 2 of the License | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
19 | * | ||
20 | */ | ||
21 | #ifndef __PVRUSB2_IO_H | ||
22 | #define __PVRUSB2_IO_H | ||
23 | |||
24 | #include <linux/usb.h> | ||
25 | #include <linux/list.h> | ||
26 | |||
27 | typedef void (*pvr2_stream_callback)(void *); | ||
28 | |||
29 | enum pvr2_buffer_state { | ||
30 | pvr2_buffer_state_none = 0, // Not on any list | ||
31 | pvr2_buffer_state_idle = 1, // Buffer is ready to be used again | ||
32 | pvr2_buffer_state_queued = 2, // Buffer has been queued for filling | ||
33 | pvr2_buffer_state_ready = 3, // Buffer has data available | ||
34 | }; | ||
35 | |||
36 | struct pvr2_stream; | ||
37 | struct pvr2_buffer; | ||
38 | |||
39 | const char *pvr2_buffer_state_decode(enum pvr2_buffer_state); | ||
40 | |||
41 | /* Initialize / tear down stream structure */ | ||
42 | struct pvr2_stream *pvr2_stream_create(void); | ||
43 | void pvr2_stream_destroy(struct pvr2_stream *); | ||
44 | void pvr2_stream_setup(struct pvr2_stream *, | ||
45 | struct usb_device *dev,int endpoint, | ||
46 | unsigned int tolerance); | ||
47 | void pvr2_stream_set_callback(struct pvr2_stream *, | ||
48 | pvr2_stream_callback func, | ||
49 | void *data); | ||
50 | |||
51 | /* Query / set the nominal buffer count */ | ||
52 | int pvr2_stream_get_buffer_count(struct pvr2_stream *); | ||
53 | int pvr2_stream_set_buffer_count(struct pvr2_stream *,unsigned int); | ||
54 | |||
55 | /* Get a pointer to a buffer that is either idle, ready, or is specified | ||
56 | named. */ | ||
57 | struct pvr2_buffer *pvr2_stream_get_idle_buffer(struct pvr2_stream *); | ||
58 | struct pvr2_buffer *pvr2_stream_get_ready_buffer(struct pvr2_stream *); | ||
59 | struct pvr2_buffer *pvr2_stream_get_buffer(struct pvr2_stream *sp,int id); | ||
60 | |||
61 | /* Find out how many buffers are idle or ready */ | ||
62 | int pvr2_stream_get_idle_count(struct pvr2_stream *); | ||
63 | int pvr2_stream_get_ready_count(struct pvr2_stream *); | ||
64 | |||
65 | /* Kill all pending operations */ | ||
66 | void pvr2_stream_flush(struct pvr2_stream *); | ||
67 | |||
68 | /* Kill all pending buffers and throw away any ready buffers as well */ | ||
69 | void pvr2_stream_kill(struct pvr2_stream *); | ||
70 | |||
71 | /* Set up the actual storage for a buffer */ | ||
72 | int pvr2_buffer_set_buffer(struct pvr2_buffer *,void *ptr,unsigned int cnt); | ||
73 | |||
74 | /* Find out size of data in the given ready buffer */ | ||
75 | unsigned int pvr2_buffer_get_count(struct pvr2_buffer *); | ||
76 | |||
77 | /* Retrieve completion code for given ready buffer */ | ||
78 | int pvr2_buffer_get_status(struct pvr2_buffer *); | ||
79 | |||
80 | /* Retrieve state of given buffer */ | ||
81 | enum pvr2_buffer_state pvr2_buffer_get_state(struct pvr2_buffer *); | ||
82 | |||
83 | /* Retrieve ID of given buffer */ | ||
84 | int pvr2_buffer_get_id(struct pvr2_buffer *); | ||
85 | |||
86 | /* Start reading into given buffer (kill it if needed) */ | ||
87 | int pvr2_buffer_queue(struct pvr2_buffer *); | ||
88 | |||
89 | /* Move buffer back to idle pool (kill it if needed) */ | ||
90 | int pvr2_buffer_idle(struct pvr2_buffer *); | ||
91 | |||
92 | #endif /* __PVRUSB2_IO_H */ | ||
93 | |||
94 | /* | ||
95 | Stuff for Emacs to see, in order to encourage consistent editing style: | ||
96 | *** Local Variables: *** | ||
97 | *** mode: c *** | ||
98 | *** fill-column: 75 *** | ||
99 | *** tab-width: 8 *** | ||
100 | *** c-basic-offset: 8 *** | ||
101 | *** End: *** | ||
102 | */ | ||
diff --git a/drivers/media/video/pvrusb2/pvrusb2-ioread.c b/drivers/media/video/pvrusb2/pvrusb2-ioread.c new file mode 100644 index 000000000000..49da062e3271 --- /dev/null +++ b/drivers/media/video/pvrusb2/pvrusb2-ioread.c | |||
@@ -0,0 +1,513 @@ | |||
1 | /* | ||
2 | * | ||
3 | * $Id$ | ||
4 | * | ||
5 | * Copyright (C) 2005 Mike Isely <isely@pobox.com> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License as published by | ||
9 | * the Free Software Foundation; either version 2 of the License | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
19 | * | ||
20 | */ | ||
21 | |||
22 | #include "pvrusb2-ioread.h" | ||
23 | #include "pvrusb2-debug.h" | ||
24 | #include <linux/errno.h> | ||
25 | #include <linux/string.h> | ||
26 | #include <linux/slab.h> | ||
27 | #include <linux/mutex.h> | ||
28 | #include <asm/uaccess.h> | ||
29 | |||
30 | #define BUFFER_COUNT 32 | ||
31 | #define BUFFER_SIZE PAGE_ALIGN(0x4000) | ||
32 | |||
33 | struct pvr2_ioread { | ||
34 | struct pvr2_stream *stream; | ||
35 | char *buffer_storage[BUFFER_COUNT]; | ||
36 | char *sync_key_ptr; | ||
37 | unsigned int sync_key_len; | ||
38 | unsigned int sync_buf_offs; | ||
39 | unsigned int sync_state; | ||
40 | unsigned int sync_trashed_count; | ||
41 | int enabled; // Streaming is on | ||
42 | int spigot_open; // OK to pass data to client | ||
43 | int stream_running; // Passing data to client now | ||
44 | |||
45 | /* State relevant to current buffer being read */ | ||
46 | struct pvr2_buffer *c_buf; | ||
47 | char *c_data_ptr; | ||
48 | unsigned int c_data_len; | ||
49 | unsigned int c_data_offs; | ||
50 | struct mutex mutex; | ||
51 | }; | ||
52 | |||
53 | static int pvr2_ioread_init(struct pvr2_ioread *cp) | ||
54 | { | ||
55 | unsigned int idx; | ||
56 | |||
57 | cp->stream = 0; | ||
58 | mutex_init(&cp->mutex); | ||
59 | |||
60 | for (idx = 0; idx < BUFFER_COUNT; idx++) { | ||
61 | cp->buffer_storage[idx] = kmalloc(BUFFER_SIZE,GFP_KERNEL); | ||
62 | if (!(cp->buffer_storage[idx])) break; | ||
63 | } | ||
64 | |||
65 | if (idx < BUFFER_COUNT) { | ||
66 | // An allocation appears to have failed | ||
67 | for (idx = 0; idx < BUFFER_COUNT; idx++) { | ||
68 | if (!(cp->buffer_storage[idx])) continue; | ||
69 | kfree(cp->buffer_storage[idx]); | ||
70 | } | ||
71 | return -ENOMEM; | ||
72 | } | ||
73 | return 0; | ||
74 | } | ||
75 | |||
76 | static void pvr2_ioread_done(struct pvr2_ioread *cp) | ||
77 | { | ||
78 | unsigned int idx; | ||
79 | |||
80 | pvr2_ioread_setup(cp,0); | ||
81 | for (idx = 0; idx < BUFFER_COUNT; idx++) { | ||
82 | if (!(cp->buffer_storage[idx])) continue; | ||
83 | kfree(cp->buffer_storage[idx]); | ||
84 | } | ||
85 | } | ||
86 | |||
87 | struct pvr2_ioread *pvr2_ioread_create(void) | ||
88 | { | ||
89 | struct pvr2_ioread *cp; | ||
90 | cp = kmalloc(sizeof(*cp),GFP_KERNEL); | ||
91 | if (!cp) return 0; | ||
92 | pvr2_trace(PVR2_TRACE_STRUCT,"pvr2_ioread_create id=%p",cp); | ||
93 | memset(cp,0,sizeof(*cp)); | ||
94 | if (pvr2_ioread_init(cp) < 0) { | ||
95 | kfree(cp); | ||
96 | return 0; | ||
97 | } | ||
98 | return cp; | ||
99 | } | ||
100 | |||
101 | void pvr2_ioread_destroy(struct pvr2_ioread *cp) | ||
102 | { | ||
103 | if (!cp) return; | ||
104 | pvr2_ioread_done(cp); | ||
105 | pvr2_trace(PVR2_TRACE_STRUCT,"pvr2_ioread_destroy id=%p",cp); | ||
106 | if (cp->sync_key_ptr) { | ||
107 | kfree(cp->sync_key_ptr); | ||
108 | cp->sync_key_ptr = 0; | ||
109 | } | ||
110 | kfree(cp); | ||
111 | } | ||
112 | |||
113 | void pvr2_ioread_set_sync_key(struct pvr2_ioread *cp, | ||
114 | const char *sync_key_ptr, | ||
115 | unsigned int sync_key_len) | ||
116 | { | ||
117 | if (!cp) return; | ||
118 | |||
119 | if (!sync_key_ptr) sync_key_len = 0; | ||
120 | if ((sync_key_len == cp->sync_key_len) && | ||
121 | ((!sync_key_len) || | ||
122 | (!memcmp(sync_key_ptr,cp->sync_key_ptr,sync_key_len)))) return; | ||
123 | |||
124 | if (sync_key_len != cp->sync_key_len) { | ||
125 | if (cp->sync_key_ptr) { | ||
126 | kfree(cp->sync_key_ptr); | ||
127 | cp->sync_key_ptr = 0; | ||
128 | } | ||
129 | cp->sync_key_len = 0; | ||
130 | if (sync_key_len) { | ||
131 | cp->sync_key_ptr = kmalloc(sync_key_len,GFP_KERNEL); | ||
132 | if (cp->sync_key_ptr) { | ||
133 | cp->sync_key_len = sync_key_len; | ||
134 | } | ||
135 | } | ||
136 | } | ||
137 | if (!cp->sync_key_len) return; | ||
138 | memcpy(cp->sync_key_ptr,sync_key_ptr,cp->sync_key_len); | ||
139 | } | ||
140 | |||
141 | static void pvr2_ioread_stop(struct pvr2_ioread *cp) | ||
142 | { | ||
143 | if (!(cp->enabled)) return; | ||
144 | pvr2_trace(PVR2_TRACE_START_STOP, | ||
145 | "/*---TRACE_READ---*/ pvr2_ioread_stop id=%p",cp); | ||
146 | pvr2_stream_kill(cp->stream); | ||
147 | cp->c_buf = 0; | ||
148 | cp->c_data_ptr = 0; | ||
149 | cp->c_data_len = 0; | ||
150 | cp->c_data_offs = 0; | ||
151 | cp->enabled = 0; | ||
152 | cp->stream_running = 0; | ||
153 | cp->spigot_open = 0; | ||
154 | if (cp->sync_state) { | ||
155 | pvr2_trace(PVR2_TRACE_DATA_FLOW, | ||
156 | "/*---TRACE_READ---*/ sync_state <== 0"); | ||
157 | cp->sync_state = 0; | ||
158 | } | ||
159 | } | ||
160 | |||
161 | static int pvr2_ioread_start(struct pvr2_ioread *cp) | ||
162 | { | ||
163 | int stat; | ||
164 | struct pvr2_buffer *bp; | ||
165 | if (cp->enabled) return 0; | ||
166 | if (!(cp->stream)) return 0; | ||
167 | pvr2_trace(PVR2_TRACE_START_STOP, | ||
168 | "/*---TRACE_READ---*/ pvr2_ioread_start id=%p",cp); | ||
169 | while ((bp = pvr2_stream_get_idle_buffer(cp->stream)) != 0) { | ||
170 | stat = pvr2_buffer_queue(bp); | ||
171 | if (stat < 0) { | ||
172 | pvr2_trace(PVR2_TRACE_DATA_FLOW, | ||
173 | "/*---TRACE_READ---*/" | ||
174 | " pvr2_ioread_start id=%p" | ||
175 | " error=%d", | ||
176 | cp,stat); | ||
177 | pvr2_ioread_stop(cp); | ||
178 | return stat; | ||
179 | } | ||
180 | } | ||
181 | cp->enabled = !0; | ||
182 | cp->c_buf = 0; | ||
183 | cp->c_data_ptr = 0; | ||
184 | cp->c_data_len = 0; | ||
185 | cp->c_data_offs = 0; | ||
186 | cp->stream_running = 0; | ||
187 | if (cp->sync_key_len) { | ||
188 | pvr2_trace(PVR2_TRACE_DATA_FLOW, | ||
189 | "/*---TRACE_READ---*/ sync_state <== 1"); | ||
190 | cp->sync_state = 1; | ||
191 | cp->sync_trashed_count = 0; | ||
192 | cp->sync_buf_offs = 0; | ||
193 | } | ||
194 | cp->spigot_open = 0; | ||
195 | return 0; | ||
196 | } | ||
197 | |||
198 | struct pvr2_stream *pvr2_ioread_get_stream(struct pvr2_ioread *cp) | ||
199 | { | ||
200 | return cp->stream; | ||
201 | } | ||
202 | |||
203 | int pvr2_ioread_setup(struct pvr2_ioread *cp,struct pvr2_stream *sp) | ||
204 | { | ||
205 | int ret; | ||
206 | unsigned int idx; | ||
207 | struct pvr2_buffer *bp; | ||
208 | |||
209 | mutex_lock(&cp->mutex); do { | ||
210 | if (cp->stream) { | ||
211 | pvr2_trace(PVR2_TRACE_START_STOP, | ||
212 | "/*---TRACE_READ---*/" | ||
213 | " pvr2_ioread_setup (tear-down) id=%p",cp); | ||
214 | pvr2_ioread_stop(cp); | ||
215 | pvr2_stream_kill(cp->stream); | ||
216 | pvr2_stream_set_buffer_count(cp->stream,0); | ||
217 | cp->stream = 0; | ||
218 | } | ||
219 | if (sp) { | ||
220 | pvr2_trace(PVR2_TRACE_START_STOP, | ||
221 | "/*---TRACE_READ---*/" | ||
222 | " pvr2_ioread_setup (setup) id=%p",cp); | ||
223 | pvr2_stream_kill(sp); | ||
224 | ret = pvr2_stream_set_buffer_count(sp,BUFFER_COUNT); | ||
225 | if (ret < 0) return ret; | ||
226 | for (idx = 0; idx < BUFFER_COUNT; idx++) { | ||
227 | bp = pvr2_stream_get_buffer(sp,idx); | ||
228 | pvr2_buffer_set_buffer(bp, | ||
229 | cp->buffer_storage[idx], | ||
230 | BUFFER_SIZE); | ||
231 | } | ||
232 | cp->stream = sp; | ||
233 | } | ||
234 | } while (0); mutex_unlock(&cp->mutex); | ||
235 | |||
236 | return 0; | ||
237 | } | ||
238 | |||
239 | int pvr2_ioread_set_enabled(struct pvr2_ioread *cp,int fl) | ||
240 | { | ||
241 | int ret = 0; | ||
242 | if ((!fl) == (!(cp->enabled))) return ret; | ||
243 | |||
244 | mutex_lock(&cp->mutex); do { | ||
245 | if (fl) { | ||
246 | ret = pvr2_ioread_start(cp); | ||
247 | } else { | ||
248 | pvr2_ioread_stop(cp); | ||
249 | } | ||
250 | } while (0); mutex_unlock(&cp->mutex); | ||
251 | return ret; | ||
252 | } | ||
253 | |||
254 | int pvr2_ioread_get_enabled(struct pvr2_ioread *cp) | ||
255 | { | ||
256 | return cp->enabled != 0; | ||
257 | } | ||
258 | |||
259 | int pvr2_ioread_get_buffer(struct pvr2_ioread *cp) | ||
260 | { | ||
261 | int stat; | ||
262 | |||
263 | while (cp->c_data_len <= cp->c_data_offs) { | ||
264 | if (cp->c_buf) { | ||
265 | // Flush out current buffer first. | ||
266 | stat = pvr2_buffer_queue(cp->c_buf); | ||
267 | if (stat < 0) { | ||
268 | // Streaming error... | ||
269 | pvr2_trace(PVR2_TRACE_DATA_FLOW, | ||
270 | "/*---TRACE_READ---*/" | ||
271 | " pvr2_ioread_read id=%p" | ||
272 | " queue_error=%d", | ||
273 | cp,stat); | ||
274 | pvr2_ioread_stop(cp); | ||
275 | return 0; | ||
276 | } | ||
277 | cp->c_buf = 0; | ||
278 | cp->c_data_ptr = 0; | ||
279 | cp->c_data_len = 0; | ||
280 | cp->c_data_offs = 0; | ||
281 | } | ||
282 | // Now get a freshly filled buffer. | ||
283 | cp->c_buf = pvr2_stream_get_ready_buffer(cp->stream); | ||
284 | if (!cp->c_buf) break; // Nothing ready; done. | ||
285 | cp->c_data_len = pvr2_buffer_get_count(cp->c_buf); | ||
286 | if (!cp->c_data_len) { | ||
287 | // Nothing transferred. Was there an error? | ||
288 | stat = pvr2_buffer_get_status(cp->c_buf); | ||
289 | if (stat < 0) { | ||
290 | // Streaming error... | ||
291 | pvr2_trace(PVR2_TRACE_DATA_FLOW, | ||
292 | "/*---TRACE_READ---*/" | ||
293 | " pvr2_ioread_read id=%p" | ||
294 | " buffer_error=%d", | ||
295 | cp,stat); | ||
296 | pvr2_ioread_stop(cp); | ||
297 | // Give up. | ||
298 | return 0; | ||
299 | } | ||
300 | // Start over... | ||
301 | continue; | ||
302 | } | ||
303 | cp->c_data_offs = 0; | ||
304 | cp->c_data_ptr = cp->buffer_storage[ | ||
305 | pvr2_buffer_get_id(cp->c_buf)]; | ||
306 | } | ||
307 | return !0; | ||
308 | } | ||
309 | |||
310 | void pvr2_ioread_filter(struct pvr2_ioread *cp) | ||
311 | { | ||
312 | unsigned int idx; | ||
313 | if (!cp->enabled) return; | ||
314 | if (cp->sync_state != 1) return; | ||
315 | |||
316 | // Search the stream for our synchronization key. This is made | ||
317 | // complicated by the fact that in order to be honest with | ||
318 | // ourselves here we must search across buffer boundaries... | ||
319 | mutex_lock(&cp->mutex); while (1) { | ||
320 | // Ensure we have a buffer | ||
321 | if (!pvr2_ioread_get_buffer(cp)) break; | ||
322 | if (!cp->c_data_len) break; | ||
323 | |||
324 | // Now walk the buffer contents until we match the key or | ||
325 | // run out of buffer data. | ||
326 | for (idx = cp->c_data_offs; idx < cp->c_data_len; idx++) { | ||
327 | if (cp->sync_buf_offs >= cp->sync_key_len) break; | ||
328 | if (cp->c_data_ptr[idx] == | ||
329 | cp->sync_key_ptr[cp->sync_buf_offs]) { | ||
330 | // Found the next key byte | ||
331 | (cp->sync_buf_offs)++; | ||
332 | } else { | ||
333 | // Whoops, mismatched. Start key over... | ||
334 | cp->sync_buf_offs = 0; | ||
335 | } | ||
336 | } | ||
337 | |||
338 | // Consume what we've walked through | ||
339 | cp->c_data_offs += idx; | ||
340 | cp->sync_trashed_count += idx; | ||
341 | |||
342 | // If we've found the key, then update state and get out. | ||
343 | if (cp->sync_buf_offs >= cp->sync_key_len) { | ||
344 | cp->sync_trashed_count -= cp->sync_key_len; | ||
345 | pvr2_trace(PVR2_TRACE_DATA_FLOW, | ||
346 | "/*---TRACE_READ---*/" | ||
347 | " sync_state <== 2 (skipped %u bytes)", | ||
348 | cp->sync_trashed_count); | ||
349 | cp->sync_state = 2; | ||
350 | cp->sync_buf_offs = 0; | ||
351 | break; | ||
352 | } | ||
353 | |||
354 | if (cp->c_data_offs < cp->c_data_len) { | ||
355 | // Sanity check - should NEVER get here | ||
356 | pvr2_trace(PVR2_TRACE_ERROR_LEGS, | ||
357 | "ERROR: pvr2_ioread filter sync problem" | ||
358 | " len=%u offs=%u", | ||
359 | cp->c_data_len,cp->c_data_offs); | ||
360 | // Get out so we don't get stuck in an infinite | ||
361 | // loop. | ||
362 | break; | ||
363 | } | ||
364 | |||
365 | continue; // (for clarity) | ||
366 | } mutex_unlock(&cp->mutex); | ||
367 | } | ||
368 | |||
369 | int pvr2_ioread_avail(struct pvr2_ioread *cp) | ||
370 | { | ||
371 | int ret; | ||
372 | if (!(cp->enabled)) { | ||
373 | // Stream is not enabled; so this is an I/O error | ||
374 | return -EIO; | ||
375 | } | ||
376 | |||
377 | if (cp->sync_state == 1) { | ||
378 | pvr2_ioread_filter(cp); | ||
379 | if (cp->sync_state == 1) return -EAGAIN; | ||
380 | } | ||
381 | |||
382 | ret = 0; | ||
383 | if (cp->stream_running) { | ||
384 | if (!pvr2_stream_get_ready_count(cp->stream)) { | ||
385 | // No data available at all right now. | ||
386 | ret = -EAGAIN; | ||
387 | } | ||
388 | } else { | ||
389 | if (pvr2_stream_get_ready_count(cp->stream) < BUFFER_COUNT/2) { | ||
390 | // Haven't buffered up enough yet; try again later | ||
391 | ret = -EAGAIN; | ||
392 | } | ||
393 | } | ||
394 | |||
395 | if ((!(cp->spigot_open)) != (!(ret == 0))) { | ||
396 | cp->spigot_open = (ret == 0); | ||
397 | pvr2_trace(PVR2_TRACE_DATA_FLOW, | ||
398 | "/*---TRACE_READ---*/ data is %s", | ||
399 | cp->spigot_open ? "available" : "pending"); | ||
400 | } | ||
401 | |||
402 | return ret; | ||
403 | } | ||
404 | |||
405 | int pvr2_ioread_read(struct pvr2_ioread *cp,void __user *buf,unsigned int cnt) | ||
406 | { | ||
407 | unsigned int copied_cnt; | ||
408 | unsigned int bcnt; | ||
409 | const char *src; | ||
410 | int stat; | ||
411 | int ret = 0; | ||
412 | unsigned int req_cnt = cnt; | ||
413 | |||
414 | if (!cnt) { | ||
415 | pvr2_trace(PVR2_TRACE_TRAP, | ||
416 | "/*---TRACE_READ---*/ pvr2_ioread_read id=%p" | ||
417 | " ZERO Request? Returning zero.",cp); | ||
418 | return 0; | ||
419 | } | ||
420 | |||
421 | stat = pvr2_ioread_avail(cp); | ||
422 | if (stat < 0) return stat; | ||
423 | |||
424 | cp->stream_running = !0; | ||
425 | |||
426 | mutex_lock(&cp->mutex); do { | ||
427 | |||
428 | // Suck data out of the buffers and copy to the user | ||
429 | copied_cnt = 0; | ||
430 | if (!buf) cnt = 0; | ||
431 | while (1) { | ||
432 | if (!pvr2_ioread_get_buffer(cp)) { | ||
433 | ret = -EIO; | ||
434 | break; | ||
435 | } | ||
436 | |||
437 | if (!cnt) break; | ||
438 | |||
439 | if (cp->sync_state == 2) { | ||
440 | // We're repeating the sync key data into | ||
441 | // the stream. | ||
442 | src = cp->sync_key_ptr + cp->sync_buf_offs; | ||
443 | bcnt = cp->sync_key_len - cp->sync_buf_offs; | ||
444 | } else { | ||
445 | // Normal buffer copy | ||
446 | src = cp->c_data_ptr + cp->c_data_offs; | ||
447 | bcnt = cp->c_data_len - cp->c_data_offs; | ||
448 | } | ||
449 | |||
450 | if (!bcnt) break; | ||
451 | |||
452 | // Don't run past user's buffer | ||
453 | if (bcnt > cnt) bcnt = cnt; | ||
454 | |||
455 | if (copy_to_user(buf,src,bcnt)) { | ||
456 | // User supplied a bad pointer? | ||
457 | // Give up - this *will* cause data | ||
458 | // to be lost. | ||
459 | ret = -EFAULT; | ||
460 | break; | ||
461 | } | ||
462 | cnt -= bcnt; | ||
463 | buf += bcnt; | ||
464 | copied_cnt += bcnt; | ||
465 | |||
466 | if (cp->sync_state == 2) { | ||
467 | // Update offset inside sync key that we're | ||
468 | // repeating back out. | ||
469 | cp->sync_buf_offs += bcnt; | ||
470 | if (cp->sync_buf_offs >= cp->sync_key_len) { | ||
471 | // Consumed entire key; switch mode | ||
472 | // to normal. | ||
473 | pvr2_trace(PVR2_TRACE_DATA_FLOW, | ||
474 | "/*---TRACE_READ---*/" | ||
475 | " sync_state <== 0"); | ||
476 | cp->sync_state = 0; | ||
477 | } | ||
478 | } else { | ||
479 | // Update buffer offset. | ||
480 | cp->c_data_offs += bcnt; | ||
481 | } | ||
482 | } | ||
483 | |||
484 | } while (0); mutex_unlock(&cp->mutex); | ||
485 | |||
486 | if (!ret) { | ||
487 | if (copied_cnt) { | ||
488 | // If anything was copied, return that count | ||
489 | ret = copied_cnt; | ||
490 | } else { | ||
491 | // Nothing copied; suggest to caller that another | ||
492 | // attempt should be tried again later | ||
493 | ret = -EAGAIN; | ||
494 | } | ||
495 | } | ||
496 | |||
497 | pvr2_trace(PVR2_TRACE_DATA_FLOW, | ||
498 | "/*---TRACE_READ---*/ pvr2_ioread_read" | ||
499 | " id=%p request=%d result=%d", | ||
500 | cp,req_cnt,ret); | ||
501 | return ret; | ||
502 | } | ||
503 | |||
504 | |||
505 | /* | ||
506 | Stuff for Emacs to see, in order to encourage consistent editing style: | ||
507 | *** Local Variables: *** | ||
508 | *** mode: c *** | ||
509 | *** fill-column: 75 *** | ||
510 | *** tab-width: 8 *** | ||
511 | *** c-basic-offset: 8 *** | ||
512 | *** End: *** | ||
513 | */ | ||
diff --git a/drivers/media/video/pvrusb2/pvrusb2-ioread.h b/drivers/media/video/pvrusb2/pvrusb2-ioread.h new file mode 100644 index 000000000000..6b002597f5de --- /dev/null +++ b/drivers/media/video/pvrusb2/pvrusb2-ioread.h | |||
@@ -0,0 +1,50 @@ | |||
1 | /* | ||
2 | * | ||
3 | * $Id$ | ||
4 | * | ||
5 | * Copyright (C) 2005 Mike Isely <isely@pobox.com> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License as published by | ||
9 | * the Free Software Foundation; either version 2 of the License | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
19 | * | ||
20 | */ | ||
21 | #ifndef __PVRUSB2_IOREAD_H | ||
22 | #define __PVRUSB2_IOREAD_H | ||
23 | |||
24 | #include "pvrusb2-io.h" | ||
25 | |||
26 | struct pvr2_ioread; | ||
27 | |||
28 | struct pvr2_ioread *pvr2_ioread_create(void); | ||
29 | void pvr2_ioread_destroy(struct pvr2_ioread *); | ||
30 | int pvr2_ioread_setup(struct pvr2_ioread *,struct pvr2_stream *); | ||
31 | struct pvr2_stream *pvr2_ioread_get_stream(struct pvr2_ioread *); | ||
32 | void pvr2_ioread_set_sync_key(struct pvr2_ioread *, | ||
33 | const char *sync_key_ptr, | ||
34 | unsigned int sync_key_len); | ||
35 | int pvr2_ioread_set_enabled(struct pvr2_ioread *,int fl); | ||
36 | int pvr2_ioread_get_enabled(struct pvr2_ioread *); | ||
37 | int pvr2_ioread_read(struct pvr2_ioread *,void __user *buf,unsigned int cnt); | ||
38 | int pvr2_ioread_avail(struct pvr2_ioread *); | ||
39 | |||
40 | #endif /* __PVRUSB2_IOREAD_H */ | ||
41 | |||
42 | /* | ||
43 | Stuff for Emacs to see, in order to encourage consistent editing style: | ||
44 | *** Local Variables: *** | ||
45 | *** mode: c *** | ||
46 | *** fill-column: 75 *** | ||
47 | *** tab-width: 8 *** | ||
48 | *** c-basic-offset: 8 *** | ||
49 | *** End: *** | ||
50 | */ | ||
diff --git a/drivers/media/video/pvrusb2/pvrusb2-main.c b/drivers/media/video/pvrusb2/pvrusb2-main.c new file mode 100644 index 000000000000..b95248274ed0 --- /dev/null +++ b/drivers/media/video/pvrusb2/pvrusb2-main.c | |||
@@ -0,0 +1,172 @@ | |||
1 | /* | ||
2 | * | ||
3 | * $Id$ | ||
4 | * | ||
5 | * Copyright (C) 2005 Mike Isely <isely@pobox.com> | ||
6 | * Copyright (C) 2004 Aurelien Alleaume <slts@free.fr> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License as published by | ||
10 | * the Free Software Foundation; either version 2 of the License | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | * GNU General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU General Public License | ||
18 | * along with this program; if not, write to the Free Software | ||
19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
20 | * | ||
21 | */ | ||
22 | |||
23 | #include <linux/config.h> | ||
24 | #include <linux/kernel.h> | ||
25 | #include <linux/errno.h> | ||
26 | #include <linux/slab.h> | ||
27 | #include <linux/module.h> | ||
28 | #include <linux/moduleparam.h> | ||
29 | #include <linux/smp_lock.h> | ||
30 | #include <linux/usb.h> | ||
31 | #include <linux/videodev2.h> | ||
32 | |||
33 | #include "pvrusb2-hdw.h" | ||
34 | #include "pvrusb2-context.h" | ||
35 | #include "pvrusb2-debug.h" | ||
36 | #include "pvrusb2-v4l2.h" | ||
37 | #ifdef CONFIG_VIDEO_PVRUSB2_SYSFS | ||
38 | #include "pvrusb2-sysfs.h" | ||
39 | #endif /* CONFIG_VIDEO_PVRUSB2_SYSFS */ | ||
40 | |||
41 | #define DRIVER_AUTHOR "Mike Isely <isely@pobox.com>" | ||
42 | #define DRIVER_DESC "Hauppauge WinTV-PVR-USB2 MPEG2 Encoder/Tuner" | ||
43 | #define DRIVER_VERSION "V4L in-tree version" | ||
44 | |||
45 | #define DEFAULT_DEBUG_MASK (PVR2_TRACE_ERROR_LEGS| \ | ||
46 | PVR2_TRACE_INFO| \ | ||
47 | PVR2_TRACE_TOLERANCE| \ | ||
48 | PVR2_TRACE_TRAP| \ | ||
49 | 0) | ||
50 | |||
51 | int pvrusb2_debug = DEFAULT_DEBUG_MASK; | ||
52 | |||
53 | module_param_named(debug,pvrusb2_debug,int,S_IRUGO|S_IWUSR); | ||
54 | MODULE_PARM_DESC(debug, "Debug trace mask"); | ||
55 | |||
56 | #ifdef CONFIG_VIDEO_PVRUSB2_SYSFS | ||
57 | static struct pvr2_sysfs_class *class_ptr = 0; | ||
58 | #endif /* CONFIG_VIDEO_PVRUSB2_SYSFS */ | ||
59 | |||
60 | static void pvr_setup_attach(struct pvr2_context *pvr) | ||
61 | { | ||
62 | /* Create association with v4l layer */ | ||
63 | pvr2_v4l2_create(pvr); | ||
64 | #ifdef CONFIG_VIDEO_PVRUSB2_SYSFS | ||
65 | pvr2_sysfs_create(pvr,class_ptr); | ||
66 | #endif /* CONFIG_VIDEO_PVRUSB2_SYSFS */ | ||
67 | } | ||
68 | |||
69 | static int pvr_probe(struct usb_interface *intf, | ||
70 | const struct usb_device_id *devid) | ||
71 | { | ||
72 | struct pvr2_context *pvr; | ||
73 | |||
74 | /* Create underlying hardware interface */ | ||
75 | pvr = pvr2_context_create(intf,devid,pvr_setup_attach); | ||
76 | if (!pvr) { | ||
77 | pvr2_trace(PVR2_TRACE_ERROR_LEGS, | ||
78 | "Failed to create hdw handler"); | ||
79 | return -ENOMEM; | ||
80 | } | ||
81 | |||
82 | pvr2_trace(PVR2_TRACE_INIT,"pvr_probe(pvr=%p)",pvr); | ||
83 | |||
84 | usb_set_intfdata(intf, pvr); | ||
85 | |||
86 | return 0; | ||
87 | } | ||
88 | |||
89 | /* | ||
90 | * pvr_disconnect() | ||
91 | * | ||
92 | */ | ||
93 | static void pvr_disconnect(struct usb_interface *intf) | ||
94 | { | ||
95 | struct pvr2_context *pvr = usb_get_intfdata(intf); | ||
96 | |||
97 | pvr2_trace(PVR2_TRACE_INIT,"pvr_disconnect(pvr=%p) BEGIN",pvr); | ||
98 | |||
99 | usb_set_intfdata (intf, NULL); | ||
100 | pvr2_context_disconnect(pvr); | ||
101 | |||
102 | pvr2_trace(PVR2_TRACE_INIT,"pvr_disconnect(pvr=%p) DONE",pvr); | ||
103 | |||
104 | } | ||
105 | |||
106 | static struct usb_driver pvr_driver = { | ||
107 | name: "pvrusb2", | ||
108 | id_table: pvr2_device_table, | ||
109 | probe: pvr_probe, | ||
110 | disconnect: pvr_disconnect | ||
111 | }; | ||
112 | |||
113 | /* | ||
114 | * pvr_init() / pvr_exit() | ||
115 | * | ||
116 | * This code is run to initialize/exit the driver. | ||
117 | * | ||
118 | */ | ||
119 | static int __init pvr_init(void) | ||
120 | { | ||
121 | int ret; | ||
122 | |||
123 | pvr2_trace(PVR2_TRACE_INIT,"pvr_init"); | ||
124 | |||
125 | #ifdef CONFIG_VIDEO_PVRUSB2_SYSFS | ||
126 | class_ptr = pvr2_sysfs_class_create(); | ||
127 | #endif /* CONFIG_VIDEO_PVRUSB2_SYSFS */ | ||
128 | |||
129 | ret = usb_register(&pvr_driver); | ||
130 | |||
131 | if (ret == 0) | ||
132 | info(DRIVER_DESC " : " DRIVER_VERSION); | ||
133 | if (pvrusb2_debug) info("Debug mask is %d (0x%x)", | ||
134 | pvrusb2_debug,pvrusb2_debug); | ||
135 | |||
136 | return ret; | ||
137 | } | ||
138 | |||
139 | static void __exit pvr_exit(void) | ||
140 | { | ||
141 | |||
142 | pvr2_trace(PVR2_TRACE_INIT,"pvr_exit"); | ||
143 | |||
144 | #ifdef CONFIG_VIDEO_PVRUSB2_SYSFS | ||
145 | pvr2_sysfs_class_destroy(class_ptr); | ||
146 | #endif /* CONFIG_VIDEO_PVRUSB2_SYSFS */ | ||
147 | |||
148 | usb_deregister(&pvr_driver); | ||
149 | } | ||
150 | |||
151 | module_init(pvr_init); | ||
152 | module_exit(pvr_exit); | ||
153 | |||
154 | /* Mike Isely <mcisely@pobox.com> 11-Mar-2006: See pvrusb2-hdw.c for | ||
155 | MODULE_DEVICE_TABLE(). We have to declare that attribute there | ||
156 | because that's where the device table actually is now and it seems | ||
157 | that certain gcc configurations get angry if MODULE_DEVICE_TABLE() | ||
158 | is used on what ends up being an external symbol. */ | ||
159 | MODULE_AUTHOR(DRIVER_AUTHOR); | ||
160 | MODULE_DESCRIPTION(DRIVER_DESC); | ||
161 | MODULE_LICENSE("GPL"); | ||
162 | |||
163 | |||
164 | /* | ||
165 | Stuff for Emacs to see, in order to encourage consistent editing style: | ||
166 | *** Local Variables: *** | ||
167 | *** mode: c *** | ||
168 | *** fill-column: 70 *** | ||
169 | *** tab-width: 8 *** | ||
170 | *** c-basic-offset: 8 *** | ||
171 | *** End: *** | ||
172 | */ | ||
diff --git a/drivers/media/video/pvrusb2/pvrusb2-std.c b/drivers/media/video/pvrusb2/pvrusb2-std.c new file mode 100644 index 000000000000..134063693643 --- /dev/null +++ b/drivers/media/video/pvrusb2/pvrusb2-std.c | |||
@@ -0,0 +1,408 @@ | |||
1 | /* | ||
2 | * | ||
3 | * $Id$ | ||
4 | * | ||
5 | * Copyright (C) 2005 Mike Isely <isely@pobox.com> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License as published by | ||
9 | * the Free Software Foundation; either version 2 of the License | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
19 | * | ||
20 | */ | ||
21 | |||
22 | #include "pvrusb2-std.h" | ||
23 | #include "pvrusb2-debug.h" | ||
24 | #include <asm/string.h> | ||
25 | #include <linux/slab.h> | ||
26 | |||
27 | struct std_name { | ||
28 | const char *name; | ||
29 | v4l2_std_id id; | ||
30 | }; | ||
31 | |||
32 | |||
33 | #define CSTD_PAL \ | ||
34 | (V4L2_STD_PAL_B| \ | ||
35 | V4L2_STD_PAL_B1| \ | ||
36 | V4L2_STD_PAL_G| \ | ||
37 | V4L2_STD_PAL_H| \ | ||
38 | V4L2_STD_PAL_I| \ | ||
39 | V4L2_STD_PAL_D| \ | ||
40 | V4L2_STD_PAL_D1| \ | ||
41 | V4L2_STD_PAL_K| \ | ||
42 | V4L2_STD_PAL_M| \ | ||
43 | V4L2_STD_PAL_N| \ | ||
44 | V4L2_STD_PAL_Nc| \ | ||
45 | V4L2_STD_PAL_60) | ||
46 | |||
47 | #define CSTD_NTSC \ | ||
48 | (V4L2_STD_NTSC_M| \ | ||
49 | V4L2_STD_NTSC_M_JP| \ | ||
50 | V4L2_STD_NTSC_M_KR| \ | ||
51 | V4L2_STD_NTSC_443) | ||
52 | |||
53 | #define CSTD_SECAM \ | ||
54 | (V4L2_STD_SECAM_B| \ | ||
55 | V4L2_STD_SECAM_D| \ | ||
56 | V4L2_STD_SECAM_G| \ | ||
57 | V4L2_STD_SECAM_H| \ | ||
58 | V4L2_STD_SECAM_K| \ | ||
59 | V4L2_STD_SECAM_K1| \ | ||
60 | V4L2_STD_SECAM_L| \ | ||
61 | V4L2_STD_SECAM_LC) | ||
62 | |||
63 | #define TSTD_B (V4L2_STD_PAL_B|V4L2_STD_SECAM_B) | ||
64 | #define TSTD_B1 (V4L2_STD_PAL_B1) | ||
65 | #define TSTD_D (V4L2_STD_PAL_D|V4L2_STD_SECAM_D) | ||
66 | #define TSTD_D1 (V4L2_STD_PAL_D1) | ||
67 | #define TSTD_G (V4L2_STD_PAL_G|V4L2_STD_SECAM_G) | ||
68 | #define TSTD_H (V4L2_STD_PAL_H|V4L2_STD_SECAM_H) | ||
69 | #define TSTD_I (V4L2_STD_PAL_I) | ||
70 | #define TSTD_K (V4L2_STD_PAL_K|V4L2_STD_SECAM_K) | ||
71 | #define TSTD_K1 (V4L2_STD_SECAM_K1) | ||
72 | #define TSTD_L (V4L2_STD_SECAM_L) | ||
73 | #define TSTD_M (V4L2_STD_PAL_M|V4L2_STD_NTSC_M) | ||
74 | #define TSTD_N (V4L2_STD_PAL_N) | ||
75 | #define TSTD_Nc (V4L2_STD_PAL_Nc) | ||
76 | #define TSTD_60 (V4L2_STD_PAL_60) | ||
77 | |||
78 | #define CSTD_ALL (CSTD_PAL|CSTD_NTSC|CSTD_SECAM) | ||
79 | |||
80 | /* Mapping of standard bits to color system */ | ||
81 | const static struct std_name std_groups[] = { | ||
82 | {"PAL",CSTD_PAL}, | ||
83 | {"NTSC",CSTD_NTSC}, | ||
84 | {"SECAM",CSTD_SECAM}, | ||
85 | }; | ||
86 | |||
87 | /* Mapping of standard bits to modulation system */ | ||
88 | const static struct std_name std_items[] = { | ||
89 | {"B",TSTD_B}, | ||
90 | {"B1",TSTD_B1}, | ||
91 | {"D",TSTD_D}, | ||
92 | {"D1",TSTD_D1}, | ||
93 | {"G",TSTD_G}, | ||
94 | {"H",TSTD_H}, | ||
95 | {"I",TSTD_I}, | ||
96 | {"K",TSTD_K}, | ||
97 | {"K1",TSTD_K1}, | ||
98 | {"L",TSTD_L}, | ||
99 | {"LC",V4L2_STD_SECAM_LC}, | ||
100 | {"M",TSTD_M}, | ||
101 | {"Mj",V4L2_STD_NTSC_M_JP}, | ||
102 | {"443",V4L2_STD_NTSC_443}, | ||
103 | {"Mk",V4L2_STD_NTSC_M_KR}, | ||
104 | {"N",TSTD_N}, | ||
105 | {"Nc",TSTD_Nc}, | ||
106 | {"60",TSTD_60}, | ||
107 | }; | ||
108 | |||
109 | |||
110 | // Search an array of std_name structures and return a pointer to the | ||
111 | // element with the matching name. | ||
112 | static const struct std_name *find_std_name(const struct std_name *arrPtr, | ||
113 | unsigned int arrSize, | ||
114 | const char *bufPtr, | ||
115 | unsigned int bufSize) | ||
116 | { | ||
117 | unsigned int idx; | ||
118 | const struct std_name *p; | ||
119 | for (idx = 0; idx < arrSize; idx++) { | ||
120 | p = arrPtr + idx; | ||
121 | if (strlen(p->name) != bufSize) continue; | ||
122 | if (!memcmp(bufPtr,p->name,bufSize)) return p; | ||
123 | } | ||
124 | return 0; | ||
125 | } | ||
126 | |||
127 | |||
128 | int pvr2_std_str_to_id(v4l2_std_id *idPtr,const char *bufPtr, | ||
129 | unsigned int bufSize) | ||
130 | { | ||
131 | v4l2_std_id id = 0; | ||
132 | v4l2_std_id cmsk = 0; | ||
133 | v4l2_std_id t; | ||
134 | int mMode = 0; | ||
135 | unsigned int cnt; | ||
136 | char ch; | ||
137 | const struct std_name *sp; | ||
138 | |||
139 | while (bufSize) { | ||
140 | if (!mMode) { | ||
141 | cnt = 0; | ||
142 | while ((cnt < bufSize) && (bufPtr[cnt] != '-')) cnt++; | ||
143 | if (cnt >= bufSize) return 0; // No more characters | ||
144 | sp = find_std_name( | ||
145 | std_groups, | ||
146 | sizeof(std_groups)/sizeof(std_groups[0]), | ||
147 | bufPtr,cnt); | ||
148 | if (!sp) return 0; // Illegal color system name | ||
149 | cnt++; | ||
150 | bufPtr += cnt; | ||
151 | bufSize -= cnt; | ||
152 | mMode = !0; | ||
153 | cmsk = sp->id; | ||
154 | continue; | ||
155 | } | ||
156 | cnt = 0; | ||
157 | while (cnt < bufSize) { | ||
158 | ch = bufPtr[cnt]; | ||
159 | if (ch == ';') { | ||
160 | mMode = 0; | ||
161 | break; | ||
162 | } | ||
163 | if (ch == '/') break; | ||
164 | cnt++; | ||
165 | } | ||
166 | sp = find_std_name(std_items, | ||
167 | sizeof(std_items)/sizeof(std_items[0]), | ||
168 | bufPtr,cnt); | ||
169 | if (!sp) return 0; // Illegal modulation system ID | ||
170 | t = sp->id & cmsk; | ||
171 | if (!t) return 0; // Specific color + modulation system illegal | ||
172 | id |= t; | ||
173 | if (cnt < bufSize) cnt++; | ||
174 | bufPtr += cnt; | ||
175 | bufSize -= cnt; | ||
176 | } | ||
177 | |||
178 | if (idPtr) *idPtr = id; | ||
179 | return !0; | ||
180 | } | ||
181 | |||
182 | |||
183 | unsigned int pvr2_std_id_to_str(char *bufPtr, unsigned int bufSize, | ||
184 | v4l2_std_id id) | ||
185 | { | ||
186 | unsigned int idx1,idx2; | ||
187 | const struct std_name *ip,*gp; | ||
188 | int gfl,cfl; | ||
189 | unsigned int c1,c2; | ||
190 | cfl = 0; | ||
191 | c1 = 0; | ||
192 | for (idx1 = 0; | ||
193 | idx1 < sizeof(std_groups)/sizeof(std_groups[0]); | ||
194 | idx1++) { | ||
195 | gp = std_groups + idx1; | ||
196 | gfl = 0; | ||
197 | for (idx2 = 0; | ||
198 | idx2 < sizeof(std_items)/sizeof(std_items[0]); | ||
199 | idx2++) { | ||
200 | ip = std_items + idx2; | ||
201 | if (!(gp->id & ip->id & id)) continue; | ||
202 | if (!gfl) { | ||
203 | if (cfl) { | ||
204 | c2 = scnprintf(bufPtr,bufSize,";"); | ||
205 | c1 += c2; | ||
206 | bufSize -= c2; | ||
207 | bufPtr += c2; | ||
208 | } | ||
209 | cfl = !0; | ||
210 | c2 = scnprintf(bufPtr,bufSize, | ||
211 | "%s-",gp->name); | ||
212 | gfl = !0; | ||
213 | } else { | ||
214 | c2 = scnprintf(bufPtr,bufSize,"/"); | ||
215 | } | ||
216 | c1 += c2; | ||
217 | bufSize -= c2; | ||
218 | bufPtr += c2; | ||
219 | c2 = scnprintf(bufPtr,bufSize, | ||
220 | ip->name); | ||
221 | c1 += c2; | ||
222 | bufSize -= c2; | ||
223 | bufPtr += c2; | ||
224 | } | ||
225 | } | ||
226 | return c1; | ||
227 | } | ||
228 | |||
229 | |||
230 | // Template data for possible enumerated video standards. Here we group | ||
231 | // standards which share common frame rates and resolution. | ||
232 | static struct v4l2_standard generic_standards[] = { | ||
233 | { | ||
234 | .id = (TSTD_B|TSTD_B1| | ||
235 | TSTD_D|TSTD_D1| | ||
236 | TSTD_G| | ||
237 | TSTD_H| | ||
238 | TSTD_I| | ||
239 | TSTD_K|TSTD_K1| | ||
240 | TSTD_L| | ||
241 | V4L2_STD_SECAM_LC | | ||
242 | TSTD_N|TSTD_Nc), | ||
243 | .frameperiod = | ||
244 | { | ||
245 | .numerator = 1, | ||
246 | .denominator= 25 | ||
247 | }, | ||
248 | .framelines = 625, | ||
249 | .reserved = {0,0,0,0} | ||
250 | }, { | ||
251 | .id = (TSTD_M| | ||
252 | V4L2_STD_NTSC_M_JP| | ||
253 | V4L2_STD_NTSC_M_KR), | ||
254 | .frameperiod = | ||
255 | { | ||
256 | .numerator = 1001, | ||
257 | .denominator= 30000 | ||
258 | }, | ||
259 | .framelines = 525, | ||
260 | .reserved = {0,0,0,0} | ||
261 | }, { // This is a total wild guess | ||
262 | .id = (TSTD_60), | ||
263 | .frameperiod = | ||
264 | { | ||
265 | .numerator = 1001, | ||
266 | .denominator= 30000 | ||
267 | }, | ||
268 | .framelines = 525, | ||
269 | .reserved = {0,0,0,0} | ||
270 | }, { // This is total wild guess | ||
271 | .id = V4L2_STD_NTSC_443, | ||
272 | .frameperiod = | ||
273 | { | ||
274 | .numerator = 1001, | ||
275 | .denominator= 30000 | ||
276 | }, | ||
277 | .framelines = 525, | ||
278 | .reserved = {0,0,0,0} | ||
279 | } | ||
280 | }; | ||
281 | |||
282 | #define generic_standards_cnt (sizeof(generic_standards)/sizeof(generic_standards[0])) | ||
283 | |||
284 | static struct v4l2_standard *match_std(v4l2_std_id id) | ||
285 | { | ||
286 | unsigned int idx; | ||
287 | for (idx = 0; idx < generic_standards_cnt; idx++) { | ||
288 | if (generic_standards[idx].id & id) { | ||
289 | return generic_standards + idx; | ||
290 | } | ||
291 | } | ||
292 | return 0; | ||
293 | } | ||
294 | |||
295 | static int pvr2_std_fill(struct v4l2_standard *std,v4l2_std_id id) | ||
296 | { | ||
297 | struct v4l2_standard *template; | ||
298 | int idx; | ||
299 | unsigned int bcnt; | ||
300 | template = match_std(id); | ||
301 | if (!template) return 0; | ||
302 | idx = std->index; | ||
303 | memcpy(std,template,sizeof(*template)); | ||
304 | std->index = idx; | ||
305 | std->id = id; | ||
306 | bcnt = pvr2_std_id_to_str(std->name,sizeof(std->name)-1,id); | ||
307 | std->name[bcnt] = 0; | ||
308 | pvr2_trace(PVR2_TRACE_INIT,"Set up standard idx=%u name=%s", | ||
309 | std->index,std->name); | ||
310 | return !0; | ||
311 | } | ||
312 | |||
313 | /* These are special cases of combined standards that we should enumerate | ||
314 | separately if the component pieces are present. */ | ||
315 | static v4l2_std_id std_mixes[] = { | ||
316 | V4L2_STD_PAL_B | V4L2_STD_PAL_G, | ||
317 | V4L2_STD_PAL_D | V4L2_STD_PAL_K, | ||
318 | V4L2_STD_SECAM_B | V4L2_STD_SECAM_G, | ||
319 | V4L2_STD_SECAM_D | V4L2_STD_SECAM_K, | ||
320 | }; | ||
321 | |||
322 | struct v4l2_standard *pvr2_std_create_enum(unsigned int *countptr, | ||
323 | v4l2_std_id id) | ||
324 | { | ||
325 | unsigned int std_cnt = 0; | ||
326 | unsigned int idx,bcnt,idx2; | ||
327 | v4l2_std_id idmsk,cmsk,fmsk; | ||
328 | struct v4l2_standard *stddefs; | ||
329 | |||
330 | if (pvrusb2_debug & PVR2_TRACE_INIT) { | ||
331 | char buf[50]; | ||
332 | bcnt = pvr2_std_id_to_str(buf,sizeof(buf),id); | ||
333 | pvr2_trace( | ||
334 | PVR2_TRACE_INIT,"Mapping standards mask=0x%x (%.*s)", | ||
335 | (int)id,bcnt,buf); | ||
336 | } | ||
337 | |||
338 | *countptr = 0; | ||
339 | std_cnt = 0; | ||
340 | fmsk = 0; | ||
341 | for (idmsk = 1, cmsk = id; cmsk; idmsk <<= 1) { | ||
342 | if (!(idmsk & cmsk)) continue; | ||
343 | cmsk &= ~idmsk; | ||
344 | if (match_std(idmsk)) { | ||
345 | std_cnt++; | ||
346 | continue; | ||
347 | } | ||
348 | fmsk |= idmsk; | ||
349 | } | ||
350 | |||
351 | for (idx2 = 0; idx2 < sizeof(std_mixes)/sizeof(std_mixes[0]); idx2++) { | ||
352 | if ((id & std_mixes[idx2]) == std_mixes[idx2]) std_cnt++; | ||
353 | } | ||
354 | |||
355 | if (fmsk) { | ||
356 | char buf[50]; | ||
357 | bcnt = pvr2_std_id_to_str(buf,sizeof(buf),fmsk); | ||
358 | pvr2_trace( | ||
359 | PVR2_TRACE_ERROR_LEGS, | ||
360 | "WARNING:" | ||
361 | " Failed to classify the following standard(s): %.*s", | ||
362 | bcnt,buf); | ||
363 | } | ||
364 | |||
365 | pvr2_trace(PVR2_TRACE_INIT,"Setting up %u unique standard(s)", | ||
366 | std_cnt); | ||
367 | if (!std_cnt) return 0; // paranoia | ||
368 | |||
369 | stddefs = kmalloc(sizeof(struct v4l2_standard) * std_cnt, | ||
370 | GFP_KERNEL); | ||
371 | memset(stddefs,0,sizeof(struct v4l2_standard) * std_cnt); | ||
372 | for (idx = 0; idx < std_cnt; idx++) stddefs[idx].index = idx; | ||
373 | |||
374 | idx = 0; | ||
375 | |||
376 | /* Enumerate potential special cases */ | ||
377 | for (idx2 = 0; ((idx2 < sizeof(std_mixes)/sizeof(std_mixes[0])) && | ||
378 | (idx < std_cnt)); idx2++) { | ||
379 | if (!(id & std_mixes[idx2])) continue; | ||
380 | if (pvr2_std_fill(stddefs+idx,std_mixes[idx2])) idx++; | ||
381 | } | ||
382 | /* Now enumerate individual pieces */ | ||
383 | for (idmsk = 1, cmsk = id; cmsk && (idx < std_cnt); idmsk <<= 1) { | ||
384 | if (!(idmsk & cmsk)) continue; | ||
385 | cmsk &= ~idmsk; | ||
386 | if (!pvr2_std_fill(stddefs+idx,idmsk)) continue; | ||
387 | idx++; | ||
388 | } | ||
389 | |||
390 | *countptr = std_cnt; | ||
391 | return stddefs; | ||
392 | } | ||
393 | |||
394 | v4l2_std_id pvr2_std_get_usable(void) | ||
395 | { | ||
396 | return CSTD_ALL; | ||
397 | } | ||
398 | |||
399 | |||
400 | /* | ||
401 | Stuff for Emacs to see, in order to encourage consistent editing style: | ||
402 | *** Local Variables: *** | ||
403 | *** mode: c *** | ||
404 | *** fill-column: 75 *** | ||
405 | *** tab-width: 8 *** | ||
406 | *** c-basic-offset: 8 *** | ||
407 | *** End: *** | ||
408 | */ | ||
diff --git a/drivers/media/video/pvrusb2/pvrusb2-std.h b/drivers/media/video/pvrusb2/pvrusb2-std.h new file mode 100644 index 000000000000..07c399375341 --- /dev/null +++ b/drivers/media/video/pvrusb2/pvrusb2-std.h | |||
@@ -0,0 +1,60 @@ | |||
1 | /* | ||
2 | * | ||
3 | * $Id$ | ||
4 | * | ||
5 | * Copyright (C) 2005 Mike Isely <isely@pobox.com> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License as published by | ||
9 | * the Free Software Foundation; either version 2 of the License | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
19 | * | ||
20 | */ | ||
21 | #ifndef __PVRUSB2_STD_H | ||
22 | #define __PVRUSB2_STD_H | ||
23 | |||
24 | #include <linux/videodev2.h> | ||
25 | |||
26 | // Convert string describing one or more video standards into a mask of V4L | ||
27 | // standard bits. Return true if conversion succeeds otherwise return | ||
28 | // false. String is expected to be of the form: C1-x/y;C2-a/b where C1 and | ||
29 | // C2 are color system names (e.g. "PAL", "NTSC") and x, y, a, and b are | ||
30 | // modulation schemes (e.g. "M", "B", "G", etc). | ||
31 | int pvr2_std_str_to_id(v4l2_std_id *idPtr,const char *bufPtr, | ||
32 | unsigned int bufSize); | ||
33 | |||
34 | // Convert any arbitrary set of video standard bits into an unambiguous | ||
35 | // readable string. Return value is the number of bytes consumed in the | ||
36 | // buffer. The formatted string is of a form that can be parsed by our | ||
37 | // sibling std_std_to_id() function. | ||
38 | unsigned int pvr2_std_id_to_str(char *bufPtr, unsigned int bufSize, | ||
39 | v4l2_std_id id); | ||
40 | |||
41 | // Create an array of suitable v4l2_standard structures given a bit mask of | ||
42 | // video standards to support. The array is allocated from the heap, and | ||
43 | // the number of elements is returned in the first argument. | ||
44 | struct v4l2_standard *pvr2_std_create_enum(unsigned int *countptr, | ||
45 | v4l2_std_id id); | ||
46 | |||
47 | // Return mask of which video standard bits are valid | ||
48 | v4l2_std_id pvr2_std_get_usable(void); | ||
49 | |||
50 | #endif /* __PVRUSB2_STD_H */ | ||
51 | |||
52 | /* | ||
53 | Stuff for Emacs to see, in order to encourage consistent editing style: | ||
54 | *** Local Variables: *** | ||
55 | *** mode: c *** | ||
56 | *** fill-column: 75 *** | ||
57 | *** tab-width: 8 *** | ||
58 | *** c-basic-offset: 8 *** | ||
59 | *** End: *** | ||
60 | */ | ||
diff --git a/drivers/media/video/pvrusb2/pvrusb2-sysfs.c b/drivers/media/video/pvrusb2/pvrusb2-sysfs.c new file mode 100644 index 000000000000..c6e6523d74b4 --- /dev/null +++ b/drivers/media/video/pvrusb2/pvrusb2-sysfs.c | |||
@@ -0,0 +1,865 @@ | |||
1 | /* | ||
2 | * | ||
3 | * $Id$ | ||
4 | * | ||
5 | * Copyright (C) 2005 Mike Isely <isely@pobox.com> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License as published by | ||
9 | * the Free Software Foundation; either version 2 of the License | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
19 | * | ||
20 | */ | ||
21 | |||
22 | #include <linux/config.h> | ||
23 | #include <linux/string.h> | ||
24 | #include <linux/slab.h> | ||
25 | #include <asm/semaphore.h> | ||
26 | #include "pvrusb2-sysfs.h" | ||
27 | #include "pvrusb2-hdw.h" | ||
28 | #include "pvrusb2-debug.h" | ||
29 | #ifdef CONFIG_VIDEO_PVRUSB2_DEBUGIFC | ||
30 | #include "pvrusb2-debugifc.h" | ||
31 | #endif /* CONFIG_VIDEO_PVRUSB2_DEBUGIFC */ | ||
32 | |||
33 | #define pvr2_sysfs_trace(...) pvr2_trace(PVR2_TRACE_SYSFS,__VA_ARGS__) | ||
34 | |||
35 | struct pvr2_sysfs { | ||
36 | struct pvr2_channel channel; | ||
37 | struct class_device *class_dev; | ||
38 | #ifdef CONFIG_VIDEO_PVRUSB2_DEBUGIFC | ||
39 | struct pvr2_sysfs_debugifc *debugifc; | ||
40 | #endif /* CONFIG_VIDEO_PVRUSB2_DEBUGIFC */ | ||
41 | struct pvr2_sysfs_ctl_item *item_first; | ||
42 | struct pvr2_sysfs_ctl_item *item_last; | ||
43 | struct sysfs_ops kops; | ||
44 | struct kobj_type ktype; | ||
45 | struct class_device_attribute attr_v4l_minor_number; | ||
46 | struct class_device_attribute attr_unit_number; | ||
47 | }; | ||
48 | |||
49 | #ifdef CONFIG_VIDEO_PVRUSB2_DEBUGIFC | ||
50 | struct pvr2_sysfs_debugifc { | ||
51 | struct class_device_attribute attr_debugcmd; | ||
52 | struct class_device_attribute attr_debuginfo; | ||
53 | }; | ||
54 | #endif /* CONFIG_VIDEO_PVRUSB2_DEBUGIFC */ | ||
55 | |||
56 | struct pvr2_sysfs_ctl_item { | ||
57 | struct class_device_attribute attr_name; | ||
58 | struct class_device_attribute attr_type; | ||
59 | struct class_device_attribute attr_min; | ||
60 | struct class_device_attribute attr_max; | ||
61 | struct class_device_attribute attr_enum; | ||
62 | struct class_device_attribute attr_bits; | ||
63 | struct class_device_attribute attr_val; | ||
64 | struct class_device_attribute attr_custom; | ||
65 | struct pvr2_ctrl *cptr; | ||
66 | struct pvr2_sysfs *chptr; | ||
67 | struct pvr2_sysfs_ctl_item *item_next; | ||
68 | struct attribute *attr_gen[7]; | ||
69 | struct attribute_group grp; | ||
70 | char name[80]; | ||
71 | }; | ||
72 | |||
73 | struct pvr2_sysfs_class { | ||
74 | struct class class; | ||
75 | }; | ||
76 | |||
77 | static ssize_t show_name(int id,struct class_device *class_dev,char *buf) | ||
78 | { | ||
79 | struct pvr2_ctrl *cptr; | ||
80 | struct pvr2_sysfs *sfp; | ||
81 | const char *name; | ||
82 | |||
83 | sfp = (struct pvr2_sysfs *)class_dev->class_data; | ||
84 | if (!sfp) return -EINVAL; | ||
85 | cptr = pvr2_hdw_get_ctrl_by_index(sfp->channel.hdw,id); | ||
86 | if (!cptr) return -EINVAL; | ||
87 | |||
88 | name = pvr2_ctrl_get_desc(cptr); | ||
89 | pvr2_sysfs_trace("pvr2_sysfs(%p) show_name(cid=%d) is %s",sfp,id,name); | ||
90 | |||
91 | if (!name) return -EINVAL; | ||
92 | |||
93 | return scnprintf(buf,PAGE_SIZE,"%s\n",name); | ||
94 | } | ||
95 | |||
96 | static ssize_t show_type(int id,struct class_device *class_dev,char *buf) | ||
97 | { | ||
98 | struct pvr2_ctrl *cptr; | ||
99 | struct pvr2_sysfs *sfp; | ||
100 | const char *name; | ||
101 | enum pvr2_ctl_type tp; | ||
102 | |||
103 | sfp = (struct pvr2_sysfs *)class_dev->class_data; | ||
104 | if (!sfp) return -EINVAL; | ||
105 | cptr = pvr2_hdw_get_ctrl_by_index(sfp->channel.hdw,id); | ||
106 | if (!cptr) return -EINVAL; | ||
107 | |||
108 | tp = pvr2_ctrl_get_type(cptr); | ||
109 | switch (tp) { | ||
110 | case pvr2_ctl_int: name = "integer"; break; | ||
111 | case pvr2_ctl_enum: name = "enum"; break; | ||
112 | case pvr2_ctl_bitmask: name = "bitmask"; break; | ||
113 | case pvr2_ctl_bool: name = "boolean"; break; | ||
114 | default: name = "?"; break; | ||
115 | } | ||
116 | pvr2_sysfs_trace("pvr2_sysfs(%p) show_type(cid=%d) is %s",sfp,id,name); | ||
117 | |||
118 | if (!name) return -EINVAL; | ||
119 | |||
120 | return scnprintf(buf,PAGE_SIZE,"%s\n",name); | ||
121 | } | ||
122 | |||
123 | static ssize_t show_min(int id,struct class_device *class_dev,char *buf) | ||
124 | { | ||
125 | struct pvr2_ctrl *cptr; | ||
126 | struct pvr2_sysfs *sfp; | ||
127 | long val; | ||
128 | |||
129 | sfp = (struct pvr2_sysfs *)class_dev->class_data; | ||
130 | if (!sfp) return -EINVAL; | ||
131 | cptr = pvr2_hdw_get_ctrl_by_index(sfp->channel.hdw,id); | ||
132 | if (!cptr) return -EINVAL; | ||
133 | val = pvr2_ctrl_get_min(cptr); | ||
134 | |||
135 | pvr2_sysfs_trace("pvr2_sysfs(%p) show_min(cid=%d) is %ld",sfp,id,val); | ||
136 | |||
137 | return scnprintf(buf,PAGE_SIZE,"%ld\n",val); | ||
138 | } | ||
139 | |||
140 | static ssize_t show_max(int id,struct class_device *class_dev,char *buf) | ||
141 | { | ||
142 | struct pvr2_ctrl *cptr; | ||
143 | struct pvr2_sysfs *sfp; | ||
144 | long val; | ||
145 | |||
146 | sfp = (struct pvr2_sysfs *)class_dev->class_data; | ||
147 | if (!sfp) return -EINVAL; | ||
148 | cptr = pvr2_hdw_get_ctrl_by_index(sfp->channel.hdw,id); | ||
149 | if (!cptr) return -EINVAL; | ||
150 | val = pvr2_ctrl_get_max(cptr); | ||
151 | |||
152 | pvr2_sysfs_trace("pvr2_sysfs(%p) show_max(cid=%d) is %ld",sfp,id,val); | ||
153 | |||
154 | return scnprintf(buf,PAGE_SIZE,"%ld\n",val); | ||
155 | } | ||
156 | |||
157 | static ssize_t show_val_norm(int id,struct class_device *class_dev,char *buf) | ||
158 | { | ||
159 | struct pvr2_ctrl *cptr; | ||
160 | struct pvr2_sysfs *sfp; | ||
161 | int val,ret; | ||
162 | unsigned int cnt = 0; | ||
163 | |||
164 | sfp = (struct pvr2_sysfs *)class_dev->class_data; | ||
165 | if (!sfp) return -EINVAL; | ||
166 | cptr = pvr2_hdw_get_ctrl_by_index(sfp->channel.hdw,id); | ||
167 | if (!cptr) return -EINVAL; | ||
168 | |||
169 | ret = pvr2_ctrl_get_value(cptr,&val); | ||
170 | if (ret < 0) return ret; | ||
171 | |||
172 | ret = pvr2_ctrl_value_to_sym(cptr,~0,val, | ||
173 | buf,PAGE_SIZE-1,&cnt); | ||
174 | |||
175 | pvr2_sysfs_trace("pvr2_sysfs(%p) show_val_norm(cid=%d) is %.*s (%d)", | ||
176 | sfp,id,cnt,buf,val); | ||
177 | buf[cnt] = '\n'; | ||
178 | return cnt+1; | ||
179 | } | ||
180 | |||
181 | static ssize_t show_val_custom(int id,struct class_device *class_dev,char *buf) | ||
182 | { | ||
183 | struct pvr2_ctrl *cptr; | ||
184 | struct pvr2_sysfs *sfp; | ||
185 | int val,ret; | ||
186 | unsigned int cnt = 0; | ||
187 | |||
188 | sfp = (struct pvr2_sysfs *)class_dev->class_data; | ||
189 | if (!sfp) return -EINVAL; | ||
190 | cptr = pvr2_hdw_get_ctrl_by_index(sfp->channel.hdw,id); | ||
191 | if (!cptr) return -EINVAL; | ||
192 | |||
193 | ret = pvr2_ctrl_get_value(cptr,&val); | ||
194 | if (ret < 0) return ret; | ||
195 | |||
196 | ret = pvr2_ctrl_custom_value_to_sym(cptr,~0,val, | ||
197 | buf,PAGE_SIZE-1,&cnt); | ||
198 | |||
199 | pvr2_sysfs_trace("pvr2_sysfs(%p) show_val_custom(cid=%d) is %.*s (%d)", | ||
200 | sfp,id,cnt,buf,val); | ||
201 | buf[cnt] = '\n'; | ||
202 | return cnt+1; | ||
203 | } | ||
204 | |||
205 | static ssize_t show_enum(int id,struct class_device *class_dev,char *buf) | ||
206 | { | ||
207 | struct pvr2_ctrl *cptr; | ||
208 | struct pvr2_sysfs *sfp; | ||
209 | long val; | ||
210 | unsigned int bcnt,ccnt,ecnt; | ||
211 | |||
212 | sfp = (struct pvr2_sysfs *)class_dev->class_data; | ||
213 | if (!sfp) return -EINVAL; | ||
214 | cptr = pvr2_hdw_get_ctrl_by_index(sfp->channel.hdw,id); | ||
215 | if (!cptr) return -EINVAL; | ||
216 | ecnt = pvr2_ctrl_get_cnt(cptr); | ||
217 | bcnt = 0; | ||
218 | for (val = 0; val < ecnt; val++) { | ||
219 | pvr2_ctrl_get_valname(cptr,val,buf+bcnt,PAGE_SIZE-bcnt,&ccnt); | ||
220 | if (!ccnt) continue; | ||
221 | bcnt += ccnt; | ||
222 | if (bcnt >= PAGE_SIZE) break; | ||
223 | buf[bcnt] = '\n'; | ||
224 | bcnt++; | ||
225 | } | ||
226 | pvr2_sysfs_trace("pvr2_sysfs(%p) show_enum(cid=%d)",sfp,id); | ||
227 | return bcnt; | ||
228 | } | ||
229 | |||
230 | static ssize_t show_bits(int id,struct class_device *class_dev,char *buf) | ||
231 | { | ||
232 | struct pvr2_ctrl *cptr; | ||
233 | struct pvr2_sysfs *sfp; | ||
234 | int valid_bits,msk; | ||
235 | unsigned int bcnt,ccnt; | ||
236 | |||
237 | sfp = (struct pvr2_sysfs *)class_dev->class_data; | ||
238 | if (!sfp) return -EINVAL; | ||
239 | cptr = pvr2_hdw_get_ctrl_by_index(sfp->channel.hdw,id); | ||
240 | if (!cptr) return -EINVAL; | ||
241 | valid_bits = pvr2_ctrl_get_mask(cptr); | ||
242 | bcnt = 0; | ||
243 | for (msk = 1; valid_bits; msk <<= 1) { | ||
244 | if (!(msk & valid_bits)) continue; | ||
245 | valid_bits &= ~msk; | ||
246 | pvr2_ctrl_get_valname(cptr,msk,buf+bcnt,PAGE_SIZE-bcnt,&ccnt); | ||
247 | bcnt += ccnt; | ||
248 | if (bcnt >= PAGE_SIZE) break; | ||
249 | buf[bcnt] = '\n'; | ||
250 | bcnt++; | ||
251 | } | ||
252 | pvr2_sysfs_trace("pvr2_sysfs(%p) show_bits(cid=%d)",sfp,id); | ||
253 | return bcnt; | ||
254 | } | ||
255 | |||
256 | static int store_val_any(int id,int customfl,struct pvr2_sysfs *sfp, | ||
257 | const char *buf,unsigned int count) | ||
258 | { | ||
259 | struct pvr2_ctrl *cptr; | ||
260 | int ret; | ||
261 | int mask,val; | ||
262 | |||
263 | cptr = pvr2_hdw_get_ctrl_by_index(sfp->channel.hdw,id); | ||
264 | if (customfl) { | ||
265 | ret = pvr2_ctrl_custom_sym_to_value(cptr,buf,count,&mask,&val); | ||
266 | } else { | ||
267 | ret = pvr2_ctrl_sym_to_value(cptr,buf,count,&mask,&val); | ||
268 | } | ||
269 | if (ret < 0) return ret; | ||
270 | ret = pvr2_ctrl_set_mask_value(cptr,mask,val); | ||
271 | pvr2_hdw_commit_ctl(sfp->channel.hdw); | ||
272 | return ret; | ||
273 | } | ||
274 | |||
275 | static ssize_t store_val_norm(int id,struct class_device *class_dev, | ||
276 | const char *buf,size_t count) | ||
277 | { | ||
278 | struct pvr2_sysfs *sfp; | ||
279 | int ret; | ||
280 | sfp = (struct pvr2_sysfs *)class_dev->class_data; | ||
281 | ret = store_val_any(id,0,sfp,buf,count); | ||
282 | if (!ret) ret = count; | ||
283 | return ret; | ||
284 | } | ||
285 | |||
286 | static ssize_t store_val_custom(int id,struct class_device *class_dev, | ||
287 | const char *buf,size_t count) | ||
288 | { | ||
289 | struct pvr2_sysfs *sfp; | ||
290 | int ret; | ||
291 | sfp = (struct pvr2_sysfs *)class_dev->class_data; | ||
292 | ret = store_val_any(id,1,sfp,buf,count); | ||
293 | if (!ret) ret = count; | ||
294 | return ret; | ||
295 | } | ||
296 | |||
297 | /* | ||
298 | Mike Isely <isely@pobox.com> 30-April-2005 | ||
299 | |||
300 | This next batch of horrible preprocessor hackery is needed because the | ||
301 | kernel's class_device_attribute mechanism fails to pass the actual | ||
302 | attribute through to the show / store functions, which means we have no | ||
303 | way to package up any attribute-specific parameters, like for example the | ||
304 | control id. So we work around this brain-damage by encoding the control | ||
305 | id into the show / store functions themselves and pick the function based | ||
306 | on the control id we're setting up. These macros try to ease the pain. | ||
307 | Yuck. | ||
308 | */ | ||
309 | |||
310 | #define CREATE_SHOW_INSTANCE(sf_name,ctl_id) \ | ||
311 | static ssize_t sf_name##_##ctl_id(struct class_device *class_dev,char *buf) \ | ||
312 | { return sf_name(ctl_id,class_dev,buf); } | ||
313 | |||
314 | #define CREATE_STORE_INSTANCE(sf_name,ctl_id) \ | ||
315 | static ssize_t sf_name##_##ctl_id(struct class_device *class_dev,const char *buf,size_t count) \ | ||
316 | { return sf_name(ctl_id,class_dev,buf,count); } | ||
317 | |||
318 | #define CREATE_BATCH(ctl_id) \ | ||
319 | CREATE_SHOW_INSTANCE(show_name,ctl_id) \ | ||
320 | CREATE_SHOW_INSTANCE(show_type,ctl_id) \ | ||
321 | CREATE_SHOW_INSTANCE(show_min,ctl_id) \ | ||
322 | CREATE_SHOW_INSTANCE(show_max,ctl_id) \ | ||
323 | CREATE_SHOW_INSTANCE(show_val_norm,ctl_id) \ | ||
324 | CREATE_SHOW_INSTANCE(show_val_custom,ctl_id) \ | ||
325 | CREATE_SHOW_INSTANCE(show_enum,ctl_id) \ | ||
326 | CREATE_SHOW_INSTANCE(show_bits,ctl_id) \ | ||
327 | CREATE_STORE_INSTANCE(store_val_norm,ctl_id) \ | ||
328 | CREATE_STORE_INSTANCE(store_val_custom,ctl_id) \ | ||
329 | |||
330 | CREATE_BATCH(0) | ||
331 | CREATE_BATCH(1) | ||
332 | CREATE_BATCH(2) | ||
333 | CREATE_BATCH(3) | ||
334 | CREATE_BATCH(4) | ||
335 | CREATE_BATCH(5) | ||
336 | CREATE_BATCH(6) | ||
337 | CREATE_BATCH(7) | ||
338 | CREATE_BATCH(8) | ||
339 | CREATE_BATCH(9) | ||
340 | CREATE_BATCH(10) | ||
341 | CREATE_BATCH(11) | ||
342 | CREATE_BATCH(12) | ||
343 | CREATE_BATCH(13) | ||
344 | CREATE_BATCH(14) | ||
345 | CREATE_BATCH(15) | ||
346 | CREATE_BATCH(16) | ||
347 | CREATE_BATCH(17) | ||
348 | CREATE_BATCH(18) | ||
349 | CREATE_BATCH(19) | ||
350 | CREATE_BATCH(20) | ||
351 | CREATE_BATCH(21) | ||
352 | CREATE_BATCH(22) | ||
353 | CREATE_BATCH(23) | ||
354 | CREATE_BATCH(24) | ||
355 | CREATE_BATCH(25) | ||
356 | CREATE_BATCH(26) | ||
357 | CREATE_BATCH(27) | ||
358 | CREATE_BATCH(28) | ||
359 | CREATE_BATCH(29) | ||
360 | CREATE_BATCH(30) | ||
361 | CREATE_BATCH(31) | ||
362 | CREATE_BATCH(32) | ||
363 | CREATE_BATCH(33) | ||
364 | CREATE_BATCH(34) | ||
365 | CREATE_BATCH(35) | ||
366 | CREATE_BATCH(36) | ||
367 | CREATE_BATCH(37) | ||
368 | CREATE_BATCH(38) | ||
369 | CREATE_BATCH(39) | ||
370 | CREATE_BATCH(40) | ||
371 | CREATE_BATCH(41) | ||
372 | CREATE_BATCH(42) | ||
373 | CREATE_BATCH(43) | ||
374 | CREATE_BATCH(44) | ||
375 | CREATE_BATCH(45) | ||
376 | CREATE_BATCH(46) | ||
377 | CREATE_BATCH(47) | ||
378 | CREATE_BATCH(48) | ||
379 | CREATE_BATCH(49) | ||
380 | CREATE_BATCH(50) | ||
381 | CREATE_BATCH(51) | ||
382 | CREATE_BATCH(52) | ||
383 | CREATE_BATCH(53) | ||
384 | CREATE_BATCH(54) | ||
385 | CREATE_BATCH(55) | ||
386 | CREATE_BATCH(56) | ||
387 | CREATE_BATCH(57) | ||
388 | CREATE_BATCH(58) | ||
389 | CREATE_BATCH(59) | ||
390 | |||
391 | struct pvr2_sysfs_func_set { | ||
392 | ssize_t (*show_name)(struct class_device *,char *); | ||
393 | ssize_t (*show_type)(struct class_device *,char *); | ||
394 | ssize_t (*show_min)(struct class_device *,char *); | ||
395 | ssize_t (*show_max)(struct class_device *,char *); | ||
396 | ssize_t (*show_enum)(struct class_device *,char *); | ||
397 | ssize_t (*show_bits)(struct class_device *,char *); | ||
398 | ssize_t (*show_val_norm)(struct class_device *,char *); | ||
399 | ssize_t (*store_val_norm)(struct class_device *, | ||
400 | const char *,size_t); | ||
401 | ssize_t (*show_val_custom)(struct class_device *,char *); | ||
402 | ssize_t (*store_val_custom)(struct class_device *, | ||
403 | const char *,size_t); | ||
404 | }; | ||
405 | |||
406 | #define INIT_BATCH(ctl_id) \ | ||
407 | [ctl_id] = { \ | ||
408 | .show_name = show_name_##ctl_id, \ | ||
409 | .show_type = show_type_##ctl_id, \ | ||
410 | .show_min = show_min_##ctl_id, \ | ||
411 | .show_max = show_max_##ctl_id, \ | ||
412 | .show_enum = show_enum_##ctl_id, \ | ||
413 | .show_bits = show_bits_##ctl_id, \ | ||
414 | .show_val_norm = show_val_norm_##ctl_id, \ | ||
415 | .store_val_norm = store_val_norm_##ctl_id, \ | ||
416 | .show_val_custom = show_val_custom_##ctl_id, \ | ||
417 | .store_val_custom = store_val_custom_##ctl_id, \ | ||
418 | } \ | ||
419 | |||
420 | static struct pvr2_sysfs_func_set funcs[] = { | ||
421 | INIT_BATCH(0), | ||
422 | INIT_BATCH(1), | ||
423 | INIT_BATCH(2), | ||
424 | INIT_BATCH(3), | ||
425 | INIT_BATCH(4), | ||
426 | INIT_BATCH(5), | ||
427 | INIT_BATCH(6), | ||
428 | INIT_BATCH(7), | ||
429 | INIT_BATCH(8), | ||
430 | INIT_BATCH(9), | ||
431 | INIT_BATCH(10), | ||
432 | INIT_BATCH(11), | ||
433 | INIT_BATCH(12), | ||
434 | INIT_BATCH(13), | ||
435 | INIT_BATCH(14), | ||
436 | INIT_BATCH(15), | ||
437 | INIT_BATCH(16), | ||
438 | INIT_BATCH(17), | ||
439 | INIT_BATCH(18), | ||
440 | INIT_BATCH(19), | ||
441 | INIT_BATCH(20), | ||
442 | INIT_BATCH(21), | ||
443 | INIT_BATCH(22), | ||
444 | INIT_BATCH(23), | ||
445 | INIT_BATCH(24), | ||
446 | INIT_BATCH(25), | ||
447 | INIT_BATCH(26), | ||
448 | INIT_BATCH(27), | ||
449 | INIT_BATCH(28), | ||
450 | INIT_BATCH(29), | ||
451 | INIT_BATCH(30), | ||
452 | INIT_BATCH(31), | ||
453 | INIT_BATCH(32), | ||
454 | INIT_BATCH(33), | ||
455 | INIT_BATCH(34), | ||
456 | INIT_BATCH(35), | ||
457 | INIT_BATCH(36), | ||
458 | INIT_BATCH(37), | ||
459 | INIT_BATCH(38), | ||
460 | INIT_BATCH(39), | ||
461 | INIT_BATCH(40), | ||
462 | INIT_BATCH(41), | ||
463 | INIT_BATCH(42), | ||
464 | INIT_BATCH(43), | ||
465 | INIT_BATCH(44), | ||
466 | INIT_BATCH(45), | ||
467 | INIT_BATCH(46), | ||
468 | INIT_BATCH(47), | ||
469 | INIT_BATCH(48), | ||
470 | INIT_BATCH(49), | ||
471 | INIT_BATCH(50), | ||
472 | INIT_BATCH(51), | ||
473 | INIT_BATCH(52), | ||
474 | INIT_BATCH(53), | ||
475 | INIT_BATCH(54), | ||
476 | INIT_BATCH(55), | ||
477 | INIT_BATCH(56), | ||
478 | INIT_BATCH(57), | ||
479 | INIT_BATCH(58), | ||
480 | INIT_BATCH(59), | ||
481 | }; | ||
482 | |||
483 | |||
484 | static void pvr2_sysfs_add_control(struct pvr2_sysfs *sfp,int ctl_id) | ||
485 | { | ||
486 | struct pvr2_sysfs_ctl_item *cip; | ||
487 | struct pvr2_sysfs_func_set *fp; | ||
488 | struct pvr2_ctrl *cptr; | ||
489 | unsigned int cnt,acnt; | ||
490 | |||
491 | if ((ctl_id < 0) || (ctl_id >= (sizeof(funcs)/sizeof(funcs[0])))) { | ||
492 | return; | ||
493 | } | ||
494 | |||
495 | fp = funcs + ctl_id; | ||
496 | cptr = pvr2_hdw_get_ctrl_by_index(sfp->channel.hdw,ctl_id); | ||
497 | if (!cptr) return; | ||
498 | |||
499 | cip = kmalloc(sizeof(*cip),GFP_KERNEL); | ||
500 | if (!cip) return; | ||
501 | memset(cip,0,sizeof(*cip)); | ||
502 | pvr2_sysfs_trace("Creating pvr2_sysfs_ctl_item id=%p",cip); | ||
503 | |||
504 | cip->cptr = cptr; | ||
505 | |||
506 | cip->chptr = sfp; | ||
507 | cip->item_next = 0; | ||
508 | if (sfp->item_last) { | ||
509 | sfp->item_last->item_next = cip; | ||
510 | } else { | ||
511 | sfp->item_first = cip; | ||
512 | } | ||
513 | sfp->item_last = cip; | ||
514 | |||
515 | cip->attr_name.attr.owner = THIS_MODULE; | ||
516 | cip->attr_name.attr.name = "name"; | ||
517 | cip->attr_name.attr.mode = S_IRUGO; | ||
518 | cip->attr_name.show = fp->show_name; | ||
519 | |||
520 | cip->attr_type.attr.owner = THIS_MODULE; | ||
521 | cip->attr_type.attr.name = "type"; | ||
522 | cip->attr_type.attr.mode = S_IRUGO; | ||
523 | cip->attr_type.show = fp->show_type; | ||
524 | |||
525 | cip->attr_min.attr.owner = THIS_MODULE; | ||
526 | cip->attr_min.attr.name = "min_val"; | ||
527 | cip->attr_min.attr.mode = S_IRUGO; | ||
528 | cip->attr_min.show = fp->show_min; | ||
529 | |||
530 | cip->attr_max.attr.owner = THIS_MODULE; | ||
531 | cip->attr_max.attr.name = "max_val"; | ||
532 | cip->attr_max.attr.mode = S_IRUGO; | ||
533 | cip->attr_max.show = fp->show_max; | ||
534 | |||
535 | cip->attr_val.attr.owner = THIS_MODULE; | ||
536 | cip->attr_val.attr.name = "cur_val"; | ||
537 | cip->attr_val.attr.mode = S_IRUGO; | ||
538 | |||
539 | cip->attr_custom.attr.owner = THIS_MODULE; | ||
540 | cip->attr_custom.attr.name = "custom_val"; | ||
541 | cip->attr_custom.attr.mode = S_IRUGO; | ||
542 | |||
543 | cip->attr_enum.attr.owner = THIS_MODULE; | ||
544 | cip->attr_enum.attr.name = "enum_val"; | ||
545 | cip->attr_enum.attr.mode = S_IRUGO; | ||
546 | cip->attr_enum.show = fp->show_enum; | ||
547 | |||
548 | cip->attr_bits.attr.owner = THIS_MODULE; | ||
549 | cip->attr_bits.attr.name = "bit_val"; | ||
550 | cip->attr_bits.attr.mode = S_IRUGO; | ||
551 | cip->attr_bits.show = fp->show_bits; | ||
552 | |||
553 | if (pvr2_ctrl_is_writable(cptr)) { | ||
554 | cip->attr_val.attr.mode |= S_IWUSR|S_IWGRP; | ||
555 | cip->attr_custom.attr.mode |= S_IWUSR|S_IWGRP; | ||
556 | } | ||
557 | |||
558 | acnt = 0; | ||
559 | cip->attr_gen[acnt++] = &cip->attr_name.attr; | ||
560 | cip->attr_gen[acnt++] = &cip->attr_type.attr; | ||
561 | cip->attr_gen[acnt++] = &cip->attr_val.attr; | ||
562 | cip->attr_val.show = fp->show_val_norm; | ||
563 | cip->attr_val.store = fp->store_val_norm; | ||
564 | if (pvr2_ctrl_has_custom_symbols(cptr)) { | ||
565 | cip->attr_gen[acnt++] = &cip->attr_custom.attr; | ||
566 | cip->attr_custom.show = fp->show_val_custom; | ||
567 | cip->attr_custom.store = fp->store_val_custom; | ||
568 | } | ||
569 | switch (pvr2_ctrl_get_type(cptr)) { | ||
570 | case pvr2_ctl_enum: | ||
571 | // Control is an enumeration | ||
572 | cip->attr_gen[acnt++] = &cip->attr_enum.attr; | ||
573 | break; | ||
574 | case pvr2_ctl_int: | ||
575 | // Control is an integer | ||
576 | cip->attr_gen[acnt++] = &cip->attr_min.attr; | ||
577 | cip->attr_gen[acnt++] = &cip->attr_max.attr; | ||
578 | break; | ||
579 | case pvr2_ctl_bitmask: | ||
580 | // Control is an bitmask | ||
581 | cip->attr_gen[acnt++] = &cip->attr_bits.attr; | ||
582 | break; | ||
583 | default: break; | ||
584 | } | ||
585 | |||
586 | cnt = scnprintf(cip->name,sizeof(cip->name)-1,"ctl_%s", | ||
587 | pvr2_ctrl_get_name(cptr)); | ||
588 | cip->name[cnt] = 0; | ||
589 | cip->grp.name = cip->name; | ||
590 | cip->grp.attrs = cip->attr_gen; | ||
591 | |||
592 | sysfs_create_group(&sfp->class_dev->kobj,&cip->grp); | ||
593 | } | ||
594 | |||
595 | #ifdef CONFIG_VIDEO_PVRUSB2_DEBUGIFC | ||
596 | static ssize_t debuginfo_show(struct class_device *,char *); | ||
597 | static ssize_t debugcmd_show(struct class_device *,char *); | ||
598 | static ssize_t debugcmd_store(struct class_device *,const char *,size_t count); | ||
599 | |||
600 | static void pvr2_sysfs_add_debugifc(struct pvr2_sysfs *sfp) | ||
601 | { | ||
602 | struct pvr2_sysfs_debugifc *dip; | ||
603 | dip = kmalloc(sizeof(*dip),GFP_KERNEL); | ||
604 | if (!dip) return; | ||
605 | memset(dip,0,sizeof(*dip)); | ||
606 | dip->attr_debugcmd.attr.owner = THIS_MODULE; | ||
607 | dip->attr_debugcmd.attr.name = "debugcmd"; | ||
608 | dip->attr_debugcmd.attr.mode = S_IRUGO|S_IWUSR|S_IWGRP; | ||
609 | dip->attr_debugcmd.show = debugcmd_show; | ||
610 | dip->attr_debugcmd.store = debugcmd_store; | ||
611 | dip->attr_debuginfo.attr.owner = THIS_MODULE; | ||
612 | dip->attr_debuginfo.attr.name = "debuginfo"; | ||
613 | dip->attr_debuginfo.attr.mode = S_IRUGO; | ||
614 | dip->attr_debuginfo.show = debuginfo_show; | ||
615 | sfp->debugifc = dip; | ||
616 | class_device_create_file(sfp->class_dev,&dip->attr_debugcmd); | ||
617 | class_device_create_file(sfp->class_dev,&dip->attr_debuginfo); | ||
618 | } | ||
619 | |||
620 | |||
621 | static void pvr2_sysfs_tear_down_debugifc(struct pvr2_sysfs *sfp) | ||
622 | { | ||
623 | if (!sfp->debugifc) return; | ||
624 | class_device_remove_file(sfp->class_dev, | ||
625 | &sfp->debugifc->attr_debuginfo); | ||
626 | class_device_remove_file(sfp->class_dev,&sfp->debugifc->attr_debugcmd); | ||
627 | kfree(sfp->debugifc); | ||
628 | sfp->debugifc = 0; | ||
629 | } | ||
630 | #endif /* CONFIG_VIDEO_PVRUSB2_DEBUGIFC */ | ||
631 | |||
632 | |||
633 | static void pvr2_sysfs_add_controls(struct pvr2_sysfs *sfp) | ||
634 | { | ||
635 | unsigned int idx,cnt; | ||
636 | cnt = pvr2_hdw_get_ctrl_count(sfp->channel.hdw); | ||
637 | for (idx = 0; idx < cnt; idx++) { | ||
638 | pvr2_sysfs_add_control(sfp,idx); | ||
639 | } | ||
640 | } | ||
641 | |||
642 | |||
643 | static void pvr2_sysfs_tear_down_controls(struct pvr2_sysfs *sfp) | ||
644 | { | ||
645 | struct pvr2_sysfs_ctl_item *cip1,*cip2; | ||
646 | for (cip1 = sfp->item_first; cip1; cip1 = cip2) { | ||
647 | cip2 = cip1->item_next; | ||
648 | sysfs_remove_group(&sfp->class_dev->kobj,&cip1->grp); | ||
649 | pvr2_sysfs_trace("Destroying pvr2_sysfs_ctl_item id=%p",cip1); | ||
650 | kfree(cip1); | ||
651 | } | ||
652 | } | ||
653 | |||
654 | |||
655 | static void pvr2_sysfs_class_release(struct class *class) | ||
656 | { | ||
657 | struct pvr2_sysfs_class *clp; | ||
658 | clp = container_of(class,struct pvr2_sysfs_class,class); | ||
659 | pvr2_sysfs_trace("Destroying pvr2_sysfs_class id=%p",clp); | ||
660 | kfree(clp); | ||
661 | } | ||
662 | |||
663 | |||
664 | static void pvr2_sysfs_release(struct class_device *class_dev) | ||
665 | { | ||
666 | pvr2_sysfs_trace("Releasing class_dev id=%p",class_dev); | ||
667 | kfree(class_dev); | ||
668 | } | ||
669 | |||
670 | |||
671 | static void class_dev_destroy(struct pvr2_sysfs *sfp) | ||
672 | { | ||
673 | if (!sfp->class_dev) return; | ||
674 | #ifdef CONFIG_VIDEO_PVRUSB2_DEBUGIFC | ||
675 | pvr2_sysfs_tear_down_debugifc(sfp); | ||
676 | #endif /* CONFIG_VIDEO_PVRUSB2_DEBUGIFC */ | ||
677 | pvr2_sysfs_tear_down_controls(sfp); | ||
678 | class_device_remove_file(sfp->class_dev,&sfp->attr_v4l_minor_number); | ||
679 | class_device_remove_file(sfp->class_dev,&sfp->attr_unit_number); | ||
680 | pvr2_sysfs_trace("Destroying class_dev id=%p",sfp->class_dev); | ||
681 | sfp->class_dev->class_data = 0; | ||
682 | class_device_unregister(sfp->class_dev); | ||
683 | sfp->class_dev = 0; | ||
684 | } | ||
685 | |||
686 | |||
687 | static ssize_t v4l_minor_number_show(struct class_device *class_dev,char *buf) | ||
688 | { | ||
689 | struct pvr2_sysfs *sfp; | ||
690 | sfp = (struct pvr2_sysfs *)class_dev->class_data; | ||
691 | if (!sfp) return -EINVAL; | ||
692 | return scnprintf(buf,PAGE_SIZE,"%d\n", | ||
693 | pvr2_hdw_v4l_get_minor_number(sfp->channel.hdw)); | ||
694 | } | ||
695 | |||
696 | |||
697 | static ssize_t unit_number_show(struct class_device *class_dev,char *buf) | ||
698 | { | ||
699 | struct pvr2_sysfs *sfp; | ||
700 | sfp = (struct pvr2_sysfs *)class_dev->class_data; | ||
701 | if (!sfp) return -EINVAL; | ||
702 | return scnprintf(buf,PAGE_SIZE,"%d\n", | ||
703 | pvr2_hdw_get_unit_number(sfp->channel.hdw)); | ||
704 | } | ||
705 | |||
706 | |||
707 | static void class_dev_create(struct pvr2_sysfs *sfp, | ||
708 | struct pvr2_sysfs_class *class_ptr) | ||
709 | { | ||
710 | struct usb_device *usb_dev; | ||
711 | struct class_device *class_dev; | ||
712 | usb_dev = pvr2_hdw_get_dev(sfp->channel.hdw); | ||
713 | if (!usb_dev) return; | ||
714 | class_dev = kmalloc(sizeof(*class_dev),GFP_KERNEL); | ||
715 | if (!class_dev) return; | ||
716 | memset(class_dev,0,sizeof(*class_dev)); | ||
717 | |||
718 | pvr2_sysfs_trace("Creating class_dev id=%p",class_dev); | ||
719 | |||
720 | class_dev->class = &class_ptr->class; | ||
721 | if (pvr2_hdw_get_sn(sfp->channel.hdw)) { | ||
722 | snprintf(class_dev->class_id,BUS_ID_SIZE,"sn-%lu", | ||
723 | pvr2_hdw_get_sn(sfp->channel.hdw)); | ||
724 | } else if (pvr2_hdw_get_unit_number(sfp->channel.hdw) >= 0) { | ||
725 | snprintf(class_dev->class_id,BUS_ID_SIZE,"unit-%c", | ||
726 | pvr2_hdw_get_unit_number(sfp->channel.hdw) + 'a'); | ||
727 | } else { | ||
728 | kfree(class_dev); | ||
729 | return; | ||
730 | } | ||
731 | |||
732 | class_dev->dev = &usb_dev->dev; | ||
733 | |||
734 | sfp->class_dev = class_dev; | ||
735 | class_dev->class_data = sfp; | ||
736 | class_device_register(class_dev); | ||
737 | |||
738 | sfp->attr_v4l_minor_number.attr.owner = THIS_MODULE; | ||
739 | sfp->attr_v4l_minor_number.attr.name = "v4l_minor_number"; | ||
740 | sfp->attr_v4l_minor_number.attr.mode = S_IRUGO; | ||
741 | sfp->attr_v4l_minor_number.show = v4l_minor_number_show; | ||
742 | sfp->attr_v4l_minor_number.store = 0; | ||
743 | class_device_create_file(sfp->class_dev,&sfp->attr_v4l_minor_number); | ||
744 | sfp->attr_unit_number.attr.owner = THIS_MODULE; | ||
745 | sfp->attr_unit_number.attr.name = "unit_number"; | ||
746 | sfp->attr_unit_number.attr.mode = S_IRUGO; | ||
747 | sfp->attr_unit_number.show = unit_number_show; | ||
748 | sfp->attr_unit_number.store = 0; | ||
749 | class_device_create_file(sfp->class_dev,&sfp->attr_unit_number); | ||
750 | |||
751 | pvr2_sysfs_add_controls(sfp); | ||
752 | #ifdef CONFIG_VIDEO_PVRUSB2_DEBUGIFC | ||
753 | pvr2_sysfs_add_debugifc(sfp); | ||
754 | #endif /* CONFIG_VIDEO_PVRUSB2_DEBUGIFC */ | ||
755 | } | ||
756 | |||
757 | |||
758 | static void pvr2_sysfs_internal_check(struct pvr2_channel *chp) | ||
759 | { | ||
760 | struct pvr2_sysfs *sfp; | ||
761 | sfp = container_of(chp,struct pvr2_sysfs,channel); | ||
762 | if (!sfp->channel.mc_head->disconnect_flag) return; | ||
763 | pvr2_trace(PVR2_TRACE_STRUCT,"Destroying pvr2_sysfs id=%p",sfp); | ||
764 | class_dev_destroy(sfp); | ||
765 | pvr2_channel_done(&sfp->channel); | ||
766 | kfree(sfp); | ||
767 | } | ||
768 | |||
769 | |||
770 | struct pvr2_sysfs *pvr2_sysfs_create(struct pvr2_context *mp, | ||
771 | struct pvr2_sysfs_class *class_ptr) | ||
772 | { | ||
773 | struct pvr2_sysfs *sfp; | ||
774 | sfp = kmalloc(sizeof(*sfp),GFP_KERNEL); | ||
775 | if (!sfp) return sfp; | ||
776 | memset(sfp,0,sizeof(*sfp)); | ||
777 | pvr2_trace(PVR2_TRACE_STRUCT,"Creating pvr2_sysfs id=%p",sfp); | ||
778 | pvr2_channel_init(&sfp->channel,mp); | ||
779 | sfp->channel.check_func = pvr2_sysfs_internal_check; | ||
780 | |||
781 | class_dev_create(sfp,class_ptr); | ||
782 | return sfp; | ||
783 | } | ||
784 | |||
785 | |||
786 | static int pvr2_sysfs_hotplug(struct class_device *cd,char **envp, | ||
787 | int numenvp,char *buf,int size) | ||
788 | { | ||
789 | /* Even though we don't do anything here, we still need this function | ||
790 | because sysfs will still try to call it. */ | ||
791 | return 0; | ||
792 | } | ||
793 | |||
794 | struct pvr2_sysfs_class *pvr2_sysfs_class_create(void) | ||
795 | { | ||
796 | struct pvr2_sysfs_class *clp; | ||
797 | clp = kmalloc(sizeof(*clp),GFP_KERNEL); | ||
798 | if (!clp) return clp; | ||
799 | memset(clp,0,sizeof(*clp)); | ||
800 | pvr2_sysfs_trace("Creating pvr2_sysfs_class id=%p",clp); | ||
801 | clp->class.name = "pvrusb2"; | ||
802 | clp->class.class_release = pvr2_sysfs_class_release; | ||
803 | clp->class.release = pvr2_sysfs_release; | ||
804 | clp->class.uevent = pvr2_sysfs_hotplug; | ||
805 | if (class_register(&clp->class)) { | ||
806 | pvr2_sysfs_trace( | ||
807 | "Registration failed for pvr2_sysfs_class id=%p",clp); | ||
808 | kfree(clp); | ||
809 | clp = 0; | ||
810 | } | ||
811 | return clp; | ||
812 | } | ||
813 | |||
814 | |||
815 | void pvr2_sysfs_class_destroy(struct pvr2_sysfs_class *clp) | ||
816 | { | ||
817 | class_unregister(&clp->class); | ||
818 | } | ||
819 | |||
820 | |||
821 | #ifdef CONFIG_VIDEO_PVRUSB2_DEBUGIFC | ||
822 | static ssize_t debuginfo_show(struct class_device *class_dev,char *buf) | ||
823 | { | ||
824 | struct pvr2_sysfs *sfp; | ||
825 | sfp = (struct pvr2_sysfs *)class_dev->class_data; | ||
826 | if (!sfp) return -EINVAL; | ||
827 | pvr2_hdw_trigger_module_log(sfp->channel.hdw); | ||
828 | return pvr2_debugifc_print_info(sfp->channel.hdw,buf,PAGE_SIZE); | ||
829 | } | ||
830 | |||
831 | |||
832 | static ssize_t debugcmd_show(struct class_device *class_dev,char *buf) | ||
833 | { | ||
834 | struct pvr2_sysfs *sfp; | ||
835 | sfp = (struct pvr2_sysfs *)class_dev->class_data; | ||
836 | if (!sfp) return -EINVAL; | ||
837 | return pvr2_debugifc_print_status(sfp->channel.hdw,buf,PAGE_SIZE); | ||
838 | } | ||
839 | |||
840 | |||
841 | static ssize_t debugcmd_store(struct class_device *class_dev, | ||
842 | const char *buf,size_t count) | ||
843 | { | ||
844 | struct pvr2_sysfs *sfp; | ||
845 | int ret; | ||
846 | |||
847 | sfp = (struct pvr2_sysfs *)class_dev->class_data; | ||
848 | if (!sfp) return -EINVAL; | ||
849 | |||
850 | ret = pvr2_debugifc_docmd(sfp->channel.hdw,buf,count); | ||
851 | if (ret < 0) return ret; | ||
852 | return count; | ||
853 | } | ||
854 | #endif /* CONFIG_VIDEO_PVRUSB2_DEBUGIFC */ | ||
855 | |||
856 | |||
857 | /* | ||
858 | Stuff for Emacs to see, in order to encourage consistent editing style: | ||
859 | *** Local Variables: *** | ||
860 | *** mode: c *** | ||
861 | *** fill-column: 75 *** | ||
862 | *** tab-width: 8 *** | ||
863 | *** c-basic-offset: 8 *** | ||
864 | *** End: *** | ||
865 | */ | ||
diff --git a/drivers/media/video/pvrusb2/pvrusb2-sysfs.h b/drivers/media/video/pvrusb2/pvrusb2-sysfs.h new file mode 100644 index 000000000000..ff9373b47f8f --- /dev/null +++ b/drivers/media/video/pvrusb2/pvrusb2-sysfs.h | |||
@@ -0,0 +1,47 @@ | |||
1 | /* | ||
2 | * | ||
3 | * $Id$ | ||
4 | * | ||
5 | * Copyright (C) 2005 Mike Isely <isely@pobox.com> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License as published by | ||
9 | * the Free Software Foundation; either version 2 of the License | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
19 | * | ||
20 | */ | ||
21 | #ifndef __PVRUSB2_SYSFS_H | ||
22 | #define __PVRUSB2_SYSFS_H | ||
23 | |||
24 | #include <linux/list.h> | ||
25 | #include <linux/sysfs.h> | ||
26 | #include "pvrusb2-context.h" | ||
27 | |||
28 | struct pvr2_sysfs; | ||
29 | struct pvr2_sysfs_class; | ||
30 | |||
31 | struct pvr2_sysfs_class *pvr2_sysfs_class_create(void); | ||
32 | void pvr2_sysfs_class_destroy(struct pvr2_sysfs_class *); | ||
33 | |||
34 | struct pvr2_sysfs *pvr2_sysfs_create(struct pvr2_context *, | ||
35 | struct pvr2_sysfs_class *); | ||
36 | |||
37 | #endif /* __PVRUSB2_SYSFS_H */ | ||
38 | |||
39 | /* | ||
40 | Stuff for Emacs to see, in order to encourage consistent editing style: | ||
41 | *** Local Variables: *** | ||
42 | *** mode: c *** | ||
43 | *** fill-column: 75 *** | ||
44 | *** tab-width: 8 *** | ||
45 | *** c-basic-offset: 8 *** | ||
46 | *** End: *** | ||
47 | */ | ||
diff --git a/drivers/media/video/pvrusb2/pvrusb2-tuner.c b/drivers/media/video/pvrusb2/pvrusb2-tuner.c new file mode 100644 index 000000000000..f4aba8144ce0 --- /dev/null +++ b/drivers/media/video/pvrusb2/pvrusb2-tuner.c | |||
@@ -0,0 +1,122 @@ | |||
1 | /* | ||
2 | * | ||
3 | * $Id$ | ||
4 | * | ||
5 | * Copyright (C) 2005 Mike Isely <isely@pobox.com> | ||
6 | * Copyright (C) 2004 Aurelien Alleaume <slts@free.fr> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License as published by | ||
10 | * the Free Software Foundation; either version 2 of the License | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | * GNU General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU General Public License | ||
18 | * along with this program; if not, write to the Free Software | ||
19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
20 | * | ||
21 | */ | ||
22 | |||
23 | #include "pvrusb2.h" | ||
24 | #include "pvrusb2-util.h" | ||
25 | #include "pvrusb2-tuner.h" | ||
26 | #include "pvrusb2-hdw-internal.h" | ||
27 | #include "pvrusb2-debug.h" | ||
28 | #include <linux/videodev2.h> | ||
29 | #include <media/tuner.h> | ||
30 | #include <media/v4l2-common.h> | ||
31 | |||
32 | struct pvr2_tuner_handler { | ||
33 | struct pvr2_hdw *hdw; | ||
34 | struct pvr2_i2c_client *client; | ||
35 | struct pvr2_i2c_handler i2c_handler; | ||
36 | int type_update_fl; | ||
37 | }; | ||
38 | |||
39 | |||
40 | static void set_type(struct pvr2_tuner_handler *ctxt) | ||
41 | { | ||
42 | struct pvr2_hdw *hdw = ctxt->hdw; | ||
43 | struct tuner_setup setup; | ||
44 | pvr2_trace(PVR2_TRACE_CHIPS,"i2c tuner set_type(%d)",hdw->tuner_type); | ||
45 | if (((int)(hdw->tuner_type)) < 0) return; | ||
46 | |||
47 | setup.addr = ADDR_UNSET; | ||
48 | setup.type = hdw->tuner_type; | ||
49 | setup.mode_mask = T_RADIO | T_ANALOG_TV; | ||
50 | /* We may really want mode_mask to be T_ANALOG_TV for now */ | ||
51 | pvr2_i2c_client_cmd(ctxt->client,TUNER_SET_TYPE_ADDR,&setup); | ||
52 | ctxt->type_update_fl = 0; | ||
53 | } | ||
54 | |||
55 | |||
56 | static int tuner_check(struct pvr2_tuner_handler *ctxt) | ||
57 | { | ||
58 | struct pvr2_hdw *hdw = ctxt->hdw; | ||
59 | if (hdw->tuner_updated) ctxt->type_update_fl = !0; | ||
60 | return ctxt->type_update_fl != 0; | ||
61 | } | ||
62 | |||
63 | |||
64 | static void tuner_update(struct pvr2_tuner_handler *ctxt) | ||
65 | { | ||
66 | if (ctxt->type_update_fl) set_type(ctxt); | ||
67 | } | ||
68 | |||
69 | |||
70 | static void pvr2_tuner_detach(struct pvr2_tuner_handler *ctxt) | ||
71 | { | ||
72 | ctxt->client->handler = 0; | ||
73 | kfree(ctxt); | ||
74 | } | ||
75 | |||
76 | |||
77 | static unsigned int pvr2_tuner_describe(struct pvr2_tuner_handler *ctxt,char *buf,unsigned int cnt) | ||
78 | { | ||
79 | return scnprintf(buf,cnt,"handler: pvrusb2-tuner"); | ||
80 | } | ||
81 | |||
82 | |||
83 | const static struct pvr2_i2c_handler_functions tuner_funcs = { | ||
84 | .detach = (void (*)(void *))pvr2_tuner_detach, | ||
85 | .check = (int (*)(void *))tuner_check, | ||
86 | .update = (void (*)(void *))tuner_update, | ||
87 | .describe = (unsigned int (*)(void *,char *,unsigned int))pvr2_tuner_describe, | ||
88 | }; | ||
89 | |||
90 | |||
91 | int pvr2_i2c_tuner_setup(struct pvr2_hdw *hdw,struct pvr2_i2c_client *cp) | ||
92 | { | ||
93 | struct pvr2_tuner_handler *ctxt; | ||
94 | if (cp->handler) return 0; | ||
95 | |||
96 | ctxt = kmalloc(sizeof(*ctxt),GFP_KERNEL); | ||
97 | if (!ctxt) return 0; | ||
98 | memset(ctxt,0,sizeof(*ctxt)); | ||
99 | |||
100 | ctxt->i2c_handler.func_data = ctxt; | ||
101 | ctxt->i2c_handler.func_table = &tuner_funcs; | ||
102 | ctxt->type_update_fl = !0; | ||
103 | ctxt->client = cp; | ||
104 | ctxt->hdw = hdw; | ||
105 | cp->handler = &ctxt->i2c_handler; | ||
106 | pvr2_trace(PVR2_TRACE_CHIPS,"i2c 0x%x tuner handler set up", | ||
107 | cp->client->addr); | ||
108 | return !0; | ||
109 | } | ||
110 | |||
111 | |||
112 | |||
113 | |||
114 | /* | ||
115 | Stuff for Emacs to see, in order to encourage consistent editing style: | ||
116 | *** Local Variables: *** | ||
117 | *** mode: c *** | ||
118 | *** fill-column: 70 *** | ||
119 | *** tab-width: 8 *** | ||
120 | *** c-basic-offset: 8 *** | ||
121 | *** End: *** | ||
122 | */ | ||
diff --git a/drivers/media/video/pvrusb2/pvrusb2-tuner.h b/drivers/media/video/pvrusb2/pvrusb2-tuner.h new file mode 100644 index 000000000000..556f12aa9160 --- /dev/null +++ b/drivers/media/video/pvrusb2/pvrusb2-tuner.h | |||
@@ -0,0 +1,38 @@ | |||
1 | /* | ||
2 | * | ||
3 | * $Id$ | ||
4 | * | ||
5 | * Copyright (C) 2005 Mike Isely <isely@pobox.com> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License as published by | ||
9 | * the Free Software Foundation; either version 2 of the License | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
19 | * | ||
20 | */ | ||
21 | #ifndef __PVRUSB2_TUNER_H | ||
22 | #define __PVRUSB2_TUNER_H | ||
23 | |||
24 | #include "pvrusb2-i2c-core.h" | ||
25 | |||
26 | int pvr2_i2c_tuner_setup(struct pvr2_hdw *,struct pvr2_i2c_client *); | ||
27 | |||
28 | #endif /* __PVRUSB2_TUNER_H */ | ||
29 | |||
30 | /* | ||
31 | Stuff for Emacs to see, in order to encourage consistent editing style: | ||
32 | *** Local Variables: *** | ||
33 | *** mode: c *** | ||
34 | *** fill-column: 70 *** | ||
35 | *** tab-width: 8 *** | ||
36 | *** c-basic-offset: 8 *** | ||
37 | *** End: *** | ||
38 | */ | ||
diff --git a/drivers/media/video/pvrusb2/pvrusb2-util.h b/drivers/media/video/pvrusb2/pvrusb2-util.h new file mode 100644 index 000000000000..e53aee416f56 --- /dev/null +++ b/drivers/media/video/pvrusb2/pvrusb2-util.h | |||
@@ -0,0 +1,63 @@ | |||
1 | /* | ||
2 | * | ||
3 | * $Id$ | ||
4 | * | ||
5 | * Copyright (C) 2005 Mike Isely <isely@pobox.com> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License as published by | ||
9 | * the Free Software Foundation; either version 2 of the License | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
19 | * | ||
20 | */ | ||
21 | #ifndef __PVRUSB2_UTIL_H | ||
22 | #define __PVRUSB2_UTIL_H | ||
23 | |||
24 | #define PVR2_DECOMPOSE_LE(t,i,d) \ | ||
25 | do { \ | ||
26 | (t)[i] = (d) & 0xff;\ | ||
27 | (t)[i+1] = ((d) >> 8) & 0xff;\ | ||
28 | (t)[i+2] = ((d) >> 16) & 0xff;\ | ||
29 | (t)[i+3] = ((d) >> 24) & 0xff;\ | ||
30 | } while(0) | ||
31 | |||
32 | #define PVR2_DECOMPOSE_BE(t,i,d) \ | ||
33 | do { \ | ||
34 | (t)[i+3] = (d) & 0xff;\ | ||
35 | (t)[i+2] = ((d) >> 8) & 0xff;\ | ||
36 | (t)[i+1] = ((d) >> 16) & 0xff;\ | ||
37 | (t)[i] = ((d) >> 24) & 0xff;\ | ||
38 | } while(0) | ||
39 | |||
40 | #define PVR2_COMPOSE_LE(t,i) \ | ||
41 | ((((u32)((t)[i+3])) << 24) | \ | ||
42 | (((u32)((t)[i+2])) << 16) | \ | ||
43 | (((u32)((t)[i+1])) << 8) | \ | ||
44 | ((u32)((t)[i]))) | ||
45 | |||
46 | #define PVR2_COMPOSE_BE(t,i) \ | ||
47 | ((((u32)((t)[i])) << 24) | \ | ||
48 | (((u32)((t)[i+1])) << 16) | \ | ||
49 | (((u32)((t)[i+2])) << 8) | \ | ||
50 | ((u32)((t)[i+3]))) | ||
51 | |||
52 | |||
53 | #endif /* __PVRUSB2_UTIL_H */ | ||
54 | |||
55 | /* | ||
56 | Stuff for Emacs to see, in order to encourage consistent editing style: | ||
57 | *** Local Variables: *** | ||
58 | *** mode: c *** | ||
59 | *** fill-column: 75 *** | ||
60 | *** tab-width: 8 *** | ||
61 | *** c-basic-offset: 8 *** | ||
62 | *** End: *** | ||
63 | */ | ||
diff --git a/drivers/media/video/pvrusb2/pvrusb2-v4l2.c b/drivers/media/video/pvrusb2/pvrusb2-v4l2.c new file mode 100644 index 000000000000..961951010c27 --- /dev/null +++ b/drivers/media/video/pvrusb2/pvrusb2-v4l2.c | |||
@@ -0,0 +1,1126 @@ | |||
1 | /* | ||
2 | * | ||
3 | * $Id$ | ||
4 | * | ||
5 | * Copyright (C) 2005 Mike Isely <isely@pobox.com> | ||
6 | * Copyright (C) 2004 Aurelien Alleaume <slts@free.fr> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License as published by | ||
10 | * the Free Software Foundation; either version 2 of the License | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | * GNU General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU General Public License | ||
18 | * along with this program; if not, write to the Free Software | ||
19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
20 | * | ||
21 | */ | ||
22 | |||
23 | #include <linux/kernel.h> | ||
24 | #include <linux/version.h> | ||
25 | #include "pvrusb2-context.h" | ||
26 | #include "pvrusb2-hdw.h" | ||
27 | #include "pvrusb2.h" | ||
28 | #include "pvrusb2-debug.h" | ||
29 | #include "pvrusb2-v4l2.h" | ||
30 | #include "pvrusb2-ioread.h" | ||
31 | #include <linux/videodev2.h> | ||
32 | #include <media/v4l2-common.h> | ||
33 | |||
34 | struct pvr2_v4l2_dev; | ||
35 | struct pvr2_v4l2_fh; | ||
36 | struct pvr2_v4l2; | ||
37 | |||
38 | /* V4L no longer provide the ability to set / get a private context pointer | ||
39 | (i.e. video_get_drvdata / video_set_drvdata), which means we have to | ||
40 | concoct our own context locating mechanism. Supposedly this is intended | ||
41 | to simplify driver implementation. It's not clear to me how that can | ||
42 | possibly be true. Our solution here is to maintain a lookup table of | ||
43 | our context instances, indexed by the minor device number of the V4L | ||
44 | device. See pvr2_v4l2_open() for some implications of this approach. */ | ||
45 | static struct pvr2_v4l2_dev *devices[256]; | ||
46 | static DEFINE_MUTEX(device_lock); | ||
47 | |||
48 | struct pvr2_v4l2_dev { | ||
49 | struct pvr2_v4l2 *v4lp; | ||
50 | struct video_device *vdev; | ||
51 | struct pvr2_context_stream *stream; | ||
52 | int ctxt_idx; | ||
53 | enum pvr2_config config; | ||
54 | }; | ||
55 | |||
56 | struct pvr2_v4l2_fh { | ||
57 | struct pvr2_channel channel; | ||
58 | struct pvr2_v4l2_dev *dev_info; | ||
59 | enum v4l2_priority prio; | ||
60 | struct pvr2_ioread *rhp; | ||
61 | struct file *file; | ||
62 | struct pvr2_v4l2 *vhead; | ||
63 | struct pvr2_v4l2_fh *vnext; | ||
64 | struct pvr2_v4l2_fh *vprev; | ||
65 | wait_queue_head_t wait_data; | ||
66 | int fw_mode_flag; | ||
67 | }; | ||
68 | |||
69 | struct pvr2_v4l2 { | ||
70 | struct pvr2_channel channel; | ||
71 | struct pvr2_v4l2_fh *vfirst; | ||
72 | struct pvr2_v4l2_fh *vlast; | ||
73 | |||
74 | struct v4l2_prio_state prio; | ||
75 | |||
76 | /* streams */ | ||
77 | struct pvr2_v4l2_dev video_dev; | ||
78 | }; | ||
79 | |||
80 | static int video_nr[PVR_NUM] = {[0 ... PVR_NUM-1] = -1}; | ||
81 | module_param_array(video_nr, int, NULL, 0444); | ||
82 | MODULE_PARM_DESC(video_nr, "Offset for device's minor"); | ||
83 | |||
84 | struct v4l2_capability pvr_capability ={ | ||
85 | .driver = "pvrusb2", | ||
86 | .card = "Hauppauge WinTV pvr-usb2", | ||
87 | .bus_info = "usb", | ||
88 | .version = KERNEL_VERSION(0,8,0), | ||
89 | .capabilities = (V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VBI_CAPTURE | | ||
90 | V4L2_CAP_TUNER | V4L2_CAP_AUDIO | | ||
91 | V4L2_CAP_READWRITE), | ||
92 | .reserved = {0,0,0,0} | ||
93 | }; | ||
94 | |||
95 | static struct v4l2_tuner pvr_v4l2_tuners[]= { | ||
96 | { | ||
97 | .index = 0, | ||
98 | .name = "TV Tuner", | ||
99 | .type = V4L2_TUNER_ANALOG_TV, | ||
100 | .capability = (V4L2_TUNER_CAP_NORM | | ||
101 | V4L2_TUNER_CAP_STEREO | | ||
102 | V4L2_TUNER_CAP_LANG1 | | ||
103 | V4L2_TUNER_CAP_LANG2), | ||
104 | .rangelow = 0, | ||
105 | .rangehigh = 0, | ||
106 | .rxsubchans = V4L2_TUNER_SUB_STEREO, | ||
107 | .audmode = V4L2_TUNER_MODE_STEREO, | ||
108 | .signal = 0, | ||
109 | .afc = 0, | ||
110 | .reserved = {0,0,0,0} | ||
111 | } | ||
112 | }; | ||
113 | |||
114 | struct v4l2_fmtdesc pvr_fmtdesc [] = { | ||
115 | { | ||
116 | .index = 0, | ||
117 | .type = V4L2_BUF_TYPE_VIDEO_CAPTURE, | ||
118 | .flags = V4L2_FMT_FLAG_COMPRESSED, | ||
119 | .description = "MPEG1/2", | ||
120 | // This should really be V4L2_PIX_FMT_MPEG, but xawtv | ||
121 | // breaks when I do that. | ||
122 | .pixelformat = 0, // V4L2_PIX_FMT_MPEG, | ||
123 | .reserved = { 0, 0, 0, 0 } | ||
124 | } | ||
125 | }; | ||
126 | |||
127 | #define PVR_FORMAT_PIX 0 | ||
128 | #define PVR_FORMAT_VBI 1 | ||
129 | |||
130 | struct v4l2_format pvr_format [] = { | ||
131 | [PVR_FORMAT_PIX] = { | ||
132 | .type = V4L2_BUF_TYPE_VIDEO_CAPTURE, | ||
133 | .fmt = { | ||
134 | .pix = { | ||
135 | .width = 720, | ||
136 | .height = 576, | ||
137 | // This should really be V4L2_PIX_FMT_MPEG, | ||
138 | // but xawtv breaks when I do that. | ||
139 | .pixelformat = 0, // V4L2_PIX_FMT_MPEG, | ||
140 | .field = V4L2_FIELD_INTERLACED, | ||
141 | .bytesperline = 0, // doesn't make sense | ||
142 | // here | ||
143 | //FIXME : Don't know what to put here... | ||
144 | .sizeimage = (32*1024), | ||
145 | .colorspace = 0, // doesn't make sense here | ||
146 | .priv = 0 | ||
147 | } | ||
148 | } | ||
149 | }, | ||
150 | [PVR_FORMAT_VBI] = { | ||
151 | .type = V4L2_BUF_TYPE_VBI_CAPTURE, | ||
152 | .fmt = { | ||
153 | .vbi = { | ||
154 | .sampling_rate = 27000000, | ||
155 | .offset = 248, | ||
156 | .samples_per_line = 1443, | ||
157 | .sample_format = V4L2_PIX_FMT_GREY, | ||
158 | .start = { 0, 0 }, | ||
159 | .count = { 0, 0 }, | ||
160 | .flags = 0, | ||
161 | .reserved = { 0, 0 } | ||
162 | } | ||
163 | } | ||
164 | } | ||
165 | }; | ||
166 | |||
167 | /* | ||
168 | * pvr_ioctl() | ||
169 | * | ||
170 | * This is part of Video 4 Linux API. The procedure handles ioctl() calls. | ||
171 | * | ||
172 | */ | ||
173 | static int pvr2_v4l2_do_ioctl(struct inode *inode, struct file *file, | ||
174 | unsigned int cmd, void *arg) | ||
175 | { | ||
176 | struct pvr2_v4l2_fh *fh = file->private_data; | ||
177 | struct pvr2_v4l2 *vp = fh->vhead; | ||
178 | struct pvr2_v4l2_dev *dev_info = fh->dev_info; | ||
179 | struct pvr2_hdw *hdw = fh->channel.mc_head->hdw; | ||
180 | int ret = -EINVAL; | ||
181 | |||
182 | if (pvrusb2_debug & PVR2_TRACE_V4LIOCTL) { | ||
183 | v4l_print_ioctl(pvr2_hdw_get_driver_name(hdw),cmd); | ||
184 | } | ||
185 | |||
186 | if (!pvr2_hdw_dev_ok(hdw)) { | ||
187 | pvr2_trace(PVR2_TRACE_ERROR_LEGS, | ||
188 | "ioctl failed - bad or no context"); | ||
189 | return -EFAULT; | ||
190 | } | ||
191 | |||
192 | /* check priority */ | ||
193 | switch (cmd) { | ||
194 | case VIDIOC_S_CTRL: | ||
195 | case VIDIOC_S_STD: | ||
196 | case VIDIOC_S_INPUT: | ||
197 | case VIDIOC_S_TUNER: | ||
198 | case VIDIOC_S_FREQUENCY: | ||
199 | ret = v4l2_prio_check(&vp->prio, &fh->prio); | ||
200 | if (ret) | ||
201 | return ret; | ||
202 | } | ||
203 | |||
204 | switch (cmd) { | ||
205 | case VIDIOC_QUERYCAP: | ||
206 | { | ||
207 | struct v4l2_capability *cap = arg; | ||
208 | |||
209 | memcpy(cap, &pvr_capability, sizeof(struct v4l2_capability)); | ||
210 | |||
211 | ret = 0; | ||
212 | break; | ||
213 | } | ||
214 | |||
215 | case VIDIOC_G_PRIORITY: | ||
216 | { | ||
217 | enum v4l2_priority *p = arg; | ||
218 | |||
219 | *p = v4l2_prio_max(&vp->prio); | ||
220 | ret = 0; | ||
221 | break; | ||
222 | } | ||
223 | |||
224 | case VIDIOC_S_PRIORITY: | ||
225 | { | ||
226 | enum v4l2_priority *prio = arg; | ||
227 | |||
228 | ret = v4l2_prio_change(&vp->prio, &fh->prio, *prio); | ||
229 | break; | ||
230 | } | ||
231 | |||
232 | case VIDIOC_ENUMSTD: | ||
233 | { | ||
234 | struct v4l2_standard *vs = (struct v4l2_standard *)arg; | ||
235 | int idx = vs->index; | ||
236 | ret = pvr2_hdw_get_stdenum_value(hdw,vs,idx+1); | ||
237 | break; | ||
238 | } | ||
239 | |||
240 | case VIDIOC_G_STD: | ||
241 | { | ||
242 | int val = 0; | ||
243 | ret = pvr2_ctrl_get_value( | ||
244 | pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_STDCUR),&val); | ||
245 | *(v4l2_std_id *)arg = val; | ||
246 | break; | ||
247 | } | ||
248 | |||
249 | case VIDIOC_S_STD: | ||
250 | { | ||
251 | ret = pvr2_ctrl_set_value( | ||
252 | pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_STDCUR), | ||
253 | *(v4l2_std_id *)arg); | ||
254 | break; | ||
255 | } | ||
256 | |||
257 | case VIDIOC_ENUMINPUT: | ||
258 | { | ||
259 | struct pvr2_ctrl *cptr; | ||
260 | struct v4l2_input *vi = (struct v4l2_input *)arg; | ||
261 | struct v4l2_input tmp; | ||
262 | unsigned int cnt; | ||
263 | |||
264 | cptr = pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_INPUT); | ||
265 | |||
266 | memset(&tmp,0,sizeof(tmp)); | ||
267 | tmp.index = vi->index; | ||
268 | ret = 0; | ||
269 | switch (vi->index) { | ||
270 | case PVR2_CVAL_INPUT_TV: | ||
271 | case PVR2_CVAL_INPUT_RADIO: | ||
272 | tmp.type = V4L2_INPUT_TYPE_TUNER; | ||
273 | break; | ||
274 | case PVR2_CVAL_INPUT_SVIDEO: | ||
275 | case PVR2_CVAL_INPUT_COMPOSITE: | ||
276 | tmp.type = V4L2_INPUT_TYPE_CAMERA; | ||
277 | break; | ||
278 | default: | ||
279 | ret = -EINVAL; | ||
280 | break; | ||
281 | } | ||
282 | if (ret < 0) break; | ||
283 | |||
284 | cnt = 0; | ||
285 | pvr2_ctrl_get_valname(cptr,vi->index, | ||
286 | tmp.name,sizeof(tmp.name)-1,&cnt); | ||
287 | tmp.name[cnt] = 0; | ||
288 | |||
289 | /* Don't bother with audioset, since this driver currently | ||
290 | always switches the audio whenever the video is | ||
291 | switched. */ | ||
292 | |||
293 | /* Handling std is a tougher problem. It doesn't make | ||
294 | sense in cases where a device might be multi-standard. | ||
295 | We could just copy out the current value for the | ||
296 | standard, but it can change over time. For now just | ||
297 | leave it zero. */ | ||
298 | |||
299 | memcpy(vi, &tmp, sizeof(tmp)); | ||
300 | |||
301 | ret = 0; | ||
302 | break; | ||
303 | } | ||
304 | |||
305 | case VIDIOC_G_INPUT: | ||
306 | { | ||
307 | struct pvr2_ctrl *cptr; | ||
308 | struct v4l2_input *vi = (struct v4l2_input *)arg; | ||
309 | int val; | ||
310 | cptr = pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_INPUT); | ||
311 | val = 0; | ||
312 | ret = pvr2_ctrl_get_value(cptr,&val); | ||
313 | vi->index = val; | ||
314 | break; | ||
315 | } | ||
316 | |||
317 | case VIDIOC_S_INPUT: | ||
318 | { | ||
319 | struct v4l2_input *vi = (struct v4l2_input *)arg; | ||
320 | ret = pvr2_ctrl_set_value( | ||
321 | pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_INPUT), | ||
322 | vi->index); | ||
323 | break; | ||
324 | } | ||
325 | |||
326 | case VIDIOC_ENUMAUDIO: | ||
327 | { | ||
328 | ret = -EINVAL; | ||
329 | break; | ||
330 | } | ||
331 | |||
332 | case VIDIOC_G_AUDIO: | ||
333 | { | ||
334 | ret = -EINVAL; | ||
335 | break; | ||
336 | } | ||
337 | |||
338 | case VIDIOC_S_AUDIO: | ||
339 | { | ||
340 | ret = -EINVAL; | ||
341 | break; | ||
342 | } | ||
343 | case VIDIOC_G_TUNER: | ||
344 | { | ||
345 | struct v4l2_tuner *vt = (struct v4l2_tuner *)arg; | ||
346 | unsigned int status_mask; | ||
347 | int val; | ||
348 | if (vt->index !=0) break; | ||
349 | |||
350 | status_mask = pvr2_hdw_get_signal_status(hdw); | ||
351 | |||
352 | memcpy(vt, &pvr_v4l2_tuners[vt->index], | ||
353 | sizeof(struct v4l2_tuner)); | ||
354 | |||
355 | vt->signal = 0; | ||
356 | if (status_mask & PVR2_SIGNAL_OK) { | ||
357 | if (status_mask & PVR2_SIGNAL_STEREO) { | ||
358 | vt->rxsubchans = V4L2_TUNER_SUB_STEREO; | ||
359 | } else { | ||
360 | vt->rxsubchans = V4L2_TUNER_SUB_MONO; | ||
361 | } | ||
362 | if (status_mask & PVR2_SIGNAL_SAP) { | ||
363 | vt->rxsubchans |= (V4L2_TUNER_SUB_LANG1 | | ||
364 | V4L2_TUNER_SUB_LANG2); | ||
365 | } | ||
366 | vt->signal = 65535; | ||
367 | } | ||
368 | |||
369 | val = 0; | ||
370 | ret = pvr2_ctrl_get_value( | ||
371 | pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_AUDIOMODE), | ||
372 | &val); | ||
373 | vt->audmode = val; | ||
374 | break; | ||
375 | } | ||
376 | |||
377 | case VIDIOC_S_TUNER: | ||
378 | { | ||
379 | struct v4l2_tuner *vt=(struct v4l2_tuner *)arg; | ||
380 | |||
381 | if (vt->index != 0) | ||
382 | break; | ||
383 | |||
384 | ret = pvr2_ctrl_set_value( | ||
385 | pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_AUDIOMODE), | ||
386 | vt->audmode); | ||
387 | } | ||
388 | |||
389 | case VIDIOC_S_FREQUENCY: | ||
390 | { | ||
391 | const struct v4l2_frequency *vf = (struct v4l2_frequency *)arg; | ||
392 | ret = pvr2_ctrl_set_value( | ||
393 | pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_FREQUENCY), | ||
394 | vf->frequency * 62500); | ||
395 | break; | ||
396 | } | ||
397 | |||
398 | case VIDIOC_G_FREQUENCY: | ||
399 | { | ||
400 | struct v4l2_frequency *vf = (struct v4l2_frequency *)arg; | ||
401 | int val = 0; | ||
402 | ret = pvr2_ctrl_get_value( | ||
403 | pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_FREQUENCY), | ||
404 | &val); | ||
405 | val /= 62500; | ||
406 | vf->frequency = val; | ||
407 | break; | ||
408 | } | ||
409 | |||
410 | case VIDIOC_ENUM_FMT: | ||
411 | { | ||
412 | struct v4l2_fmtdesc *fd = (struct v4l2_fmtdesc *)arg; | ||
413 | |||
414 | /* Only one format is supported : mpeg.*/ | ||
415 | if (fd->index != 0) | ||
416 | break; | ||
417 | |||
418 | memcpy(fd, pvr_fmtdesc, sizeof(struct v4l2_fmtdesc)); | ||
419 | ret = 0; | ||
420 | break; | ||
421 | } | ||
422 | |||
423 | case VIDIOC_G_FMT: | ||
424 | { | ||
425 | struct v4l2_format *vf = (struct v4l2_format *)arg; | ||
426 | int val; | ||
427 | switch(vf->type) { | ||
428 | case V4L2_BUF_TYPE_VIDEO_CAPTURE: | ||
429 | memcpy(vf, &pvr_format[PVR_FORMAT_PIX], | ||
430 | sizeof(struct v4l2_format)); | ||
431 | val = 0; | ||
432 | pvr2_ctrl_get_value( | ||
433 | pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_HRES), | ||
434 | &val); | ||
435 | vf->fmt.pix.width = val; | ||
436 | val = 0; | ||
437 | pvr2_ctrl_get_value( | ||
438 | pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_VRES), | ||
439 | &val); | ||
440 | vf->fmt.pix.height = val; | ||
441 | ret = 0; | ||
442 | break; | ||
443 | case V4L2_BUF_TYPE_VBI_CAPTURE: | ||
444 | // ????? Still need to figure out to do VBI correctly | ||
445 | ret = -EINVAL; | ||
446 | break; | ||
447 | default: | ||
448 | ret = -EINVAL; | ||
449 | break; | ||
450 | } | ||
451 | break; | ||
452 | } | ||
453 | |||
454 | case VIDIOC_TRY_FMT: | ||
455 | case VIDIOC_S_FMT: | ||
456 | { | ||
457 | struct v4l2_format *vf = (struct v4l2_format *)arg; | ||
458 | |||
459 | ret = 0; | ||
460 | switch(vf->type) { | ||
461 | case V4L2_BUF_TYPE_VIDEO_CAPTURE: { | ||
462 | int h = vf->fmt.pix.height; | ||
463 | int w = vf->fmt.pix.width; | ||
464 | |||
465 | if (h < 200) { | ||
466 | h = 200; | ||
467 | } else if (h > 625) { | ||
468 | h = 625; | ||
469 | } | ||
470 | if (w < 320) { | ||
471 | w = 320; | ||
472 | } else if (w > 720) { | ||
473 | w = 720; | ||
474 | } | ||
475 | |||
476 | memcpy(vf, &pvr_format[PVR_FORMAT_PIX], | ||
477 | sizeof(struct v4l2_format)); | ||
478 | vf->fmt.pix.width = w; | ||
479 | vf->fmt.pix.height = h; | ||
480 | |||
481 | if (cmd == VIDIOC_S_FMT) { | ||
482 | pvr2_ctrl_set_value( | ||
483 | pvr2_hdw_get_ctrl_by_id(hdw, | ||
484 | PVR2_CID_HRES), | ||
485 | vf->fmt.pix.width); | ||
486 | pvr2_ctrl_set_value( | ||
487 | pvr2_hdw_get_ctrl_by_id(hdw, | ||
488 | PVR2_CID_VRES), | ||
489 | vf->fmt.pix.height); | ||
490 | } | ||
491 | } break; | ||
492 | case V4L2_BUF_TYPE_VBI_CAPTURE: | ||
493 | // ????? Still need to figure out to do VBI correctly | ||
494 | ret = -EINVAL; | ||
495 | break; | ||
496 | default: | ||
497 | ret = -EINVAL; | ||
498 | break; | ||
499 | } | ||
500 | break; | ||
501 | } | ||
502 | |||
503 | case VIDIOC_STREAMON: | ||
504 | { | ||
505 | ret = pvr2_hdw_set_stream_type(hdw,dev_info->config); | ||
506 | if (ret < 0) return ret; | ||
507 | ret = pvr2_hdw_set_streaming(hdw,!0); | ||
508 | break; | ||
509 | } | ||
510 | |||
511 | case VIDIOC_STREAMOFF: | ||
512 | { | ||
513 | ret = pvr2_hdw_set_streaming(hdw,0); | ||
514 | break; | ||
515 | } | ||
516 | |||
517 | case VIDIOC_QUERYCTRL: | ||
518 | { | ||
519 | struct pvr2_ctrl *cptr; | ||
520 | struct v4l2_queryctrl *vc = (struct v4l2_queryctrl *)arg; | ||
521 | ret = 0; | ||
522 | if (vc->id & V4L2_CTRL_FLAG_NEXT_CTRL) { | ||
523 | cptr = pvr2_hdw_get_ctrl_nextv4l( | ||
524 | hdw,(vc->id & ~V4L2_CTRL_FLAG_NEXT_CTRL)); | ||
525 | if (cptr) vc->id = pvr2_ctrl_get_v4lid(cptr); | ||
526 | } else { | ||
527 | cptr = pvr2_hdw_get_ctrl_v4l(hdw,vc->id); | ||
528 | } | ||
529 | if (!cptr) { | ||
530 | pvr2_trace(PVR2_TRACE_V4LIOCTL, | ||
531 | "QUERYCTRL id=0x%x not implemented here", | ||
532 | vc->id); | ||
533 | ret = -EINVAL; | ||
534 | break; | ||
535 | } | ||
536 | |||
537 | pvr2_trace(PVR2_TRACE_V4LIOCTL, | ||
538 | "QUERYCTRL id=0x%x mapping name=%s (%s)", | ||
539 | vc->id,pvr2_ctrl_get_name(cptr), | ||
540 | pvr2_ctrl_get_desc(cptr)); | ||
541 | strlcpy(vc->name,pvr2_ctrl_get_desc(cptr),sizeof(vc->name)); | ||
542 | vc->flags = pvr2_ctrl_get_v4lflags(cptr); | ||
543 | vc->default_value = pvr2_ctrl_get_def(cptr); | ||
544 | switch (pvr2_ctrl_get_type(cptr)) { | ||
545 | case pvr2_ctl_enum: | ||
546 | vc->type = V4L2_CTRL_TYPE_MENU; | ||
547 | vc->minimum = 0; | ||
548 | vc->maximum = pvr2_ctrl_get_cnt(cptr) - 1; | ||
549 | vc->step = 1; | ||
550 | break; | ||
551 | case pvr2_ctl_bool: | ||
552 | vc->type = V4L2_CTRL_TYPE_BOOLEAN; | ||
553 | vc->minimum = 0; | ||
554 | vc->maximum = 1; | ||
555 | vc->step = 1; | ||
556 | break; | ||
557 | case pvr2_ctl_int: | ||
558 | vc->type = V4L2_CTRL_TYPE_INTEGER; | ||
559 | vc->minimum = pvr2_ctrl_get_min(cptr); | ||
560 | vc->maximum = pvr2_ctrl_get_max(cptr); | ||
561 | vc->step = 1; | ||
562 | break; | ||
563 | default: | ||
564 | pvr2_trace(PVR2_TRACE_V4LIOCTL, | ||
565 | "QUERYCTRL id=0x%x name=%s not mappable", | ||
566 | vc->id,pvr2_ctrl_get_name(cptr)); | ||
567 | ret = -EINVAL; | ||
568 | break; | ||
569 | } | ||
570 | break; | ||
571 | } | ||
572 | |||
573 | case VIDIOC_QUERYMENU: | ||
574 | { | ||
575 | struct v4l2_querymenu *vm = (struct v4l2_querymenu *)arg; | ||
576 | unsigned int cnt = 0; | ||
577 | ret = pvr2_ctrl_get_valname(pvr2_hdw_get_ctrl_v4l(hdw,vm->id), | ||
578 | vm->index, | ||
579 | vm->name,sizeof(vm->name)-1, | ||
580 | &cnt); | ||
581 | vm->name[cnt] = 0; | ||
582 | break; | ||
583 | } | ||
584 | |||
585 | case VIDIOC_G_CTRL: | ||
586 | { | ||
587 | struct v4l2_control *vc = (struct v4l2_control *)arg; | ||
588 | int val = 0; | ||
589 | ret = pvr2_ctrl_get_value(pvr2_hdw_get_ctrl_v4l(hdw,vc->id), | ||
590 | &val); | ||
591 | vc->value = val; | ||
592 | break; | ||
593 | } | ||
594 | |||
595 | case VIDIOC_S_CTRL: | ||
596 | { | ||
597 | struct v4l2_control *vc = (struct v4l2_control *)arg; | ||
598 | ret = pvr2_ctrl_set_value(pvr2_hdw_get_ctrl_v4l(hdw,vc->id), | ||
599 | vc->value); | ||
600 | break; | ||
601 | } | ||
602 | |||
603 | case VIDIOC_G_EXT_CTRLS: | ||
604 | { | ||
605 | struct v4l2_ext_controls *ctls = | ||
606 | (struct v4l2_ext_controls *)arg; | ||
607 | struct v4l2_ext_control *ctrl; | ||
608 | unsigned int idx; | ||
609 | int val; | ||
610 | for (idx = 0; idx < ctls->count; idx++) { | ||
611 | ctrl = ctls->controls + idx; | ||
612 | ret = pvr2_ctrl_get_value( | ||
613 | pvr2_hdw_get_ctrl_v4l(hdw,ctrl->id),&val); | ||
614 | if (ret) { | ||
615 | ctls->error_idx = idx; | ||
616 | break; | ||
617 | } | ||
618 | /* Ensure that if read as a 64 bit value, the user | ||
619 | will still get a hopefully sane value */ | ||
620 | ctrl->value64 = 0; | ||
621 | ctrl->value = val; | ||
622 | } | ||
623 | break; | ||
624 | } | ||
625 | |||
626 | case VIDIOC_S_EXT_CTRLS: | ||
627 | { | ||
628 | struct v4l2_ext_controls *ctls = | ||
629 | (struct v4l2_ext_controls *)arg; | ||
630 | struct v4l2_ext_control *ctrl; | ||
631 | unsigned int idx; | ||
632 | for (idx = 0; idx < ctls->count; idx++) { | ||
633 | ctrl = ctls->controls + idx; | ||
634 | ret = pvr2_ctrl_set_value( | ||
635 | pvr2_hdw_get_ctrl_v4l(hdw,ctrl->id), | ||
636 | ctrl->value); | ||
637 | if (ret) { | ||
638 | ctls->error_idx = idx; | ||
639 | break; | ||
640 | } | ||
641 | } | ||
642 | break; | ||
643 | } | ||
644 | |||
645 | case VIDIOC_TRY_EXT_CTRLS: | ||
646 | { | ||
647 | struct v4l2_ext_controls *ctls = | ||
648 | (struct v4l2_ext_controls *)arg; | ||
649 | struct v4l2_ext_control *ctrl; | ||
650 | struct pvr2_ctrl *pctl; | ||
651 | unsigned int idx; | ||
652 | /* For the moment just validate that the requested control | ||
653 | actually exists. */ | ||
654 | for (idx = 0; idx < ctls->count; idx++) { | ||
655 | ctrl = ctls->controls + idx; | ||
656 | pctl = pvr2_hdw_get_ctrl_v4l(hdw,ctrl->id); | ||
657 | if (!pctl) { | ||
658 | ret = -EINVAL; | ||
659 | ctls->error_idx = idx; | ||
660 | break; | ||
661 | } | ||
662 | } | ||
663 | break; | ||
664 | } | ||
665 | |||
666 | case VIDIOC_LOG_STATUS: | ||
667 | { | ||
668 | pvr2_hdw_trigger_module_log(hdw); | ||
669 | ret = 0; | ||
670 | break; | ||
671 | } | ||
672 | |||
673 | default : | ||
674 | ret = v4l_compat_translate_ioctl(inode,file,cmd, | ||
675 | arg,pvr2_v4l2_do_ioctl); | ||
676 | } | ||
677 | |||
678 | pvr2_hdw_commit_ctl(hdw); | ||
679 | |||
680 | if (ret < 0) { | ||
681 | if (pvrusb2_debug & PVR2_TRACE_V4LIOCTL) { | ||
682 | pvr2_trace(PVR2_TRACE_V4LIOCTL, | ||
683 | "pvr2_v4l2_do_ioctl failure, ret=%d",ret); | ||
684 | } else { | ||
685 | if (pvrusb2_debug & PVR2_TRACE_V4LIOCTL) { | ||
686 | pvr2_trace(PVR2_TRACE_V4LIOCTL, | ||
687 | "pvr2_v4l2_do_ioctl failure, ret=%d" | ||
688 | " command was:",ret); | ||
689 | v4l_print_ioctl(pvr2_hdw_get_driver_name(hdw), | ||
690 | cmd); | ||
691 | } | ||
692 | } | ||
693 | } else { | ||
694 | pvr2_trace(PVR2_TRACE_V4LIOCTL, | ||
695 | "pvr2_v4l2_do_ioctl complete, ret=%d (0x%x)", | ||
696 | ret,ret); | ||
697 | } | ||
698 | return ret; | ||
699 | } | ||
700 | |||
701 | |||
702 | static void pvr2_v4l2_dev_destroy(struct pvr2_v4l2_dev *dip) | ||
703 | { | ||
704 | pvr2_trace(PVR2_TRACE_INIT, | ||
705 | "unregistering device video%d [%s]", | ||
706 | dip->vdev->minor,pvr2_config_get_name(dip->config)); | ||
707 | if (dip->ctxt_idx >= 0) { | ||
708 | mutex_lock(&device_lock); | ||
709 | devices[dip->ctxt_idx] = NULL; | ||
710 | dip->ctxt_idx = -1; | ||
711 | mutex_unlock(&device_lock); | ||
712 | } | ||
713 | video_unregister_device(dip->vdev); | ||
714 | } | ||
715 | |||
716 | |||
717 | static void pvr2_v4l2_destroy_no_lock(struct pvr2_v4l2 *vp) | ||
718 | { | ||
719 | pvr2_hdw_v4l_store_minor_number(vp->channel.mc_head->hdw,-1); | ||
720 | pvr2_v4l2_dev_destroy(&vp->video_dev); | ||
721 | |||
722 | pvr2_trace(PVR2_TRACE_STRUCT,"Destroying pvr2_v4l2 id=%p",vp); | ||
723 | pvr2_channel_done(&vp->channel); | ||
724 | kfree(vp); | ||
725 | } | ||
726 | |||
727 | |||
728 | void pvr2_v4l2_internal_check(struct pvr2_channel *chp) | ||
729 | { | ||
730 | struct pvr2_v4l2 *vp; | ||
731 | vp = container_of(chp,struct pvr2_v4l2,channel); | ||
732 | if (!vp->channel.mc_head->disconnect_flag) return; | ||
733 | if (vp->vfirst) return; | ||
734 | pvr2_v4l2_destroy_no_lock(vp); | ||
735 | } | ||
736 | |||
737 | |||
738 | int pvr2_v4l2_ioctl(struct inode *inode, struct file *file, | ||
739 | unsigned int cmd, unsigned long arg) | ||
740 | { | ||
741 | |||
742 | /* Temporary hack : use ivtv api until a v4l2 one is available. */ | ||
743 | #define IVTV_IOC_G_CODEC 0xFFEE7703 | ||
744 | #define IVTV_IOC_S_CODEC 0xFFEE7704 | ||
745 | if (cmd == IVTV_IOC_G_CODEC || cmd == IVTV_IOC_S_CODEC) return 0; | ||
746 | return video_usercopy(inode, file, cmd, arg, pvr2_v4l2_do_ioctl); | ||
747 | } | ||
748 | |||
749 | |||
750 | int pvr2_v4l2_release(struct inode *inode, struct file *file) | ||
751 | { | ||
752 | struct pvr2_v4l2_fh *fhp = file->private_data; | ||
753 | struct pvr2_v4l2 *vp = fhp->vhead; | ||
754 | struct pvr2_context *mp = fhp->vhead->channel.mc_head; | ||
755 | |||
756 | pvr2_trace(PVR2_TRACE_OPEN_CLOSE,"pvr2_v4l2_release"); | ||
757 | |||
758 | if (fhp->rhp) { | ||
759 | struct pvr2_stream *sp; | ||
760 | struct pvr2_hdw *hdw; | ||
761 | hdw = fhp->channel.mc_head->hdw; | ||
762 | pvr2_hdw_set_streaming(hdw,0); | ||
763 | sp = pvr2_ioread_get_stream(fhp->rhp); | ||
764 | if (sp) pvr2_stream_set_callback(sp,0,0); | ||
765 | pvr2_ioread_destroy(fhp->rhp); | ||
766 | fhp->rhp = 0; | ||
767 | } | ||
768 | v4l2_prio_close(&vp->prio, &fhp->prio); | ||
769 | file->private_data = NULL; | ||
770 | |||
771 | pvr2_context_enter(mp); do { | ||
772 | if (fhp->vnext) { | ||
773 | fhp->vnext->vprev = fhp->vprev; | ||
774 | } else { | ||
775 | vp->vlast = fhp->vprev; | ||
776 | } | ||
777 | if (fhp->vprev) { | ||
778 | fhp->vprev->vnext = fhp->vnext; | ||
779 | } else { | ||
780 | vp->vfirst = fhp->vnext; | ||
781 | } | ||
782 | fhp->vnext = 0; | ||
783 | fhp->vprev = 0; | ||
784 | fhp->vhead = 0; | ||
785 | pvr2_channel_done(&fhp->channel); | ||
786 | pvr2_trace(PVR2_TRACE_STRUCT, | ||
787 | "Destroying pvr_v4l2_fh id=%p",fhp); | ||
788 | kfree(fhp); | ||
789 | if (vp->channel.mc_head->disconnect_flag && !vp->vfirst) { | ||
790 | pvr2_v4l2_destroy_no_lock(vp); | ||
791 | } | ||
792 | } while (0); pvr2_context_exit(mp); | ||
793 | return 0; | ||
794 | } | ||
795 | |||
796 | |||
797 | int pvr2_v4l2_open(struct inode *inode, struct file *file) | ||
798 | { | ||
799 | struct pvr2_v4l2_dev *dip = 0; /* Our own context pointer */ | ||
800 | struct pvr2_v4l2_fh *fhp; | ||
801 | struct pvr2_v4l2 *vp; | ||
802 | struct pvr2_hdw *hdw; | ||
803 | |||
804 | mutex_lock(&device_lock); | ||
805 | /* MCI 7-Jun-2006 Even though we're just doing what amounts to an | ||
806 | atomic read of the device mapping array here, we still need the | ||
807 | mutex. The problem is that there is a tiny race possible when | ||
808 | we register the device. We can't update the device mapping | ||
809 | array until after the device has been registered, owing to the | ||
810 | fact that we can't know the minor device number until after the | ||
811 | registration succeeds. And if another thread tries to open the | ||
812 | device in the window of time after registration but before the | ||
813 | map is updated, then it will get back an erroneous null pointer | ||
814 | and the open will result in a spurious failure. The only way to | ||
815 | prevent that is to (a) be inside the mutex here before we access | ||
816 | the array, and (b) cover the entire registration process later | ||
817 | on with this same mutex. Thus if we get inside the mutex here, | ||
818 | then we can be assured that the registration process actually | ||
819 | completed correctly. This is an unhappy complication from the | ||
820 | use of global data in a driver that lives in a preemptible | ||
821 | environment. It sure would be nice if the video device itself | ||
822 | had a means for storing and retrieving a local context pointer. | ||
823 | Oh wait. It did. But now it's gone. Silly me. */ | ||
824 | { | ||
825 | unsigned int midx = iminor(file->f_dentry->d_inode); | ||
826 | if (midx < sizeof(devices)/sizeof(devices[0])) { | ||
827 | dip = devices[midx]; | ||
828 | } | ||
829 | } | ||
830 | mutex_unlock(&device_lock); | ||
831 | |||
832 | if (!dip) return -ENODEV; /* Should be impossible but I'm paranoid */ | ||
833 | |||
834 | vp = dip->v4lp; | ||
835 | hdw = vp->channel.hdw; | ||
836 | |||
837 | pvr2_trace(PVR2_TRACE_OPEN_CLOSE,"pvr2_v4l2_open"); | ||
838 | |||
839 | if (!pvr2_hdw_dev_ok(hdw)) { | ||
840 | pvr2_trace(PVR2_TRACE_OPEN_CLOSE, | ||
841 | "pvr2_v4l2_open: hardware not ready"); | ||
842 | return -EIO; | ||
843 | } | ||
844 | |||
845 | fhp = kmalloc(sizeof(*fhp),GFP_KERNEL); | ||
846 | if (!fhp) { | ||
847 | return -ENOMEM; | ||
848 | } | ||
849 | memset(fhp,0,sizeof(*fhp)); | ||
850 | |||
851 | init_waitqueue_head(&fhp->wait_data); | ||
852 | fhp->dev_info = dip; | ||
853 | |||
854 | pvr2_context_enter(vp->channel.mc_head); do { | ||
855 | pvr2_trace(PVR2_TRACE_STRUCT,"Creating pvr_v4l2_fh id=%p",fhp); | ||
856 | pvr2_channel_init(&fhp->channel,vp->channel.mc_head); | ||
857 | fhp->vnext = 0; | ||
858 | fhp->vprev = vp->vlast; | ||
859 | if (vp->vlast) { | ||
860 | vp->vlast->vnext = fhp; | ||
861 | } else { | ||
862 | vp->vfirst = fhp; | ||
863 | } | ||
864 | vp->vlast = fhp; | ||
865 | fhp->vhead = vp; | ||
866 | } while (0); pvr2_context_exit(vp->channel.mc_head); | ||
867 | |||
868 | fhp->file = file; | ||
869 | file->private_data = fhp; | ||
870 | v4l2_prio_open(&vp->prio,&fhp->prio); | ||
871 | |||
872 | fhp->fw_mode_flag = pvr2_hdw_cpufw_get_enabled(hdw); | ||
873 | |||
874 | return 0; | ||
875 | } | ||
876 | |||
877 | |||
878 | static void pvr2_v4l2_notify(struct pvr2_v4l2_fh *fhp) | ||
879 | { | ||
880 | wake_up(&fhp->wait_data); | ||
881 | } | ||
882 | |||
883 | static int pvr2_v4l2_iosetup(struct pvr2_v4l2_fh *fh) | ||
884 | { | ||
885 | int ret; | ||
886 | struct pvr2_stream *sp; | ||
887 | struct pvr2_hdw *hdw; | ||
888 | if (fh->rhp) return 0; | ||
889 | |||
890 | /* First read() attempt. Try to claim the stream and start | ||
891 | it... */ | ||
892 | if ((ret = pvr2_channel_claim_stream(&fh->channel, | ||
893 | fh->dev_info->stream)) != 0) { | ||
894 | /* Someone else must already have it */ | ||
895 | return ret; | ||
896 | } | ||
897 | |||
898 | fh->rhp = pvr2_channel_create_mpeg_stream(fh->dev_info->stream); | ||
899 | if (!fh->rhp) { | ||
900 | pvr2_channel_claim_stream(&fh->channel,0); | ||
901 | return -ENOMEM; | ||
902 | } | ||
903 | |||
904 | hdw = fh->channel.mc_head->hdw; | ||
905 | sp = fh->dev_info->stream->stream; | ||
906 | pvr2_stream_set_callback(sp,(pvr2_stream_callback)pvr2_v4l2_notify,fh); | ||
907 | pvr2_hdw_set_stream_type(hdw,fh->dev_info->config); | ||
908 | pvr2_hdw_set_streaming(hdw,!0); | ||
909 | ret = pvr2_ioread_set_enabled(fh->rhp,!0); | ||
910 | |||
911 | return ret; | ||
912 | } | ||
913 | |||
914 | |||
915 | static ssize_t pvr2_v4l2_read(struct file *file, | ||
916 | char __user *buff, size_t count, loff_t *ppos) | ||
917 | { | ||
918 | struct pvr2_v4l2_fh *fh = file->private_data; | ||
919 | int ret; | ||
920 | |||
921 | if (fh->fw_mode_flag) { | ||
922 | struct pvr2_hdw *hdw = fh->channel.mc_head->hdw; | ||
923 | char *tbuf; | ||
924 | int c1,c2; | ||
925 | int tcnt = 0; | ||
926 | unsigned int offs = *ppos; | ||
927 | |||
928 | tbuf = kmalloc(PAGE_SIZE,GFP_KERNEL); | ||
929 | if (!tbuf) return -ENOMEM; | ||
930 | |||
931 | while (count) { | ||
932 | c1 = count; | ||
933 | if (c1 > PAGE_SIZE) c1 = PAGE_SIZE; | ||
934 | c2 = pvr2_hdw_cpufw_get(hdw,offs,tbuf,c1); | ||
935 | if (c2 < 0) { | ||
936 | tcnt = c2; | ||
937 | break; | ||
938 | } | ||
939 | if (!c2) break; | ||
940 | if (copy_to_user(buff,tbuf,c2)) { | ||
941 | tcnt = -EFAULT; | ||
942 | break; | ||
943 | } | ||
944 | offs += c2; | ||
945 | tcnt += c2; | ||
946 | buff += c2; | ||
947 | count -= c2; | ||
948 | *ppos += c2; | ||
949 | } | ||
950 | kfree(tbuf); | ||
951 | return tcnt; | ||
952 | } | ||
953 | |||
954 | if (!fh->rhp) { | ||
955 | ret = pvr2_v4l2_iosetup(fh); | ||
956 | if (ret) { | ||
957 | return ret; | ||
958 | } | ||
959 | } | ||
960 | |||
961 | for (;;) { | ||
962 | ret = pvr2_ioread_read(fh->rhp,buff,count); | ||
963 | if (ret >= 0) break; | ||
964 | if (ret != -EAGAIN) break; | ||
965 | if (file->f_flags & O_NONBLOCK) break; | ||
966 | /* Doing blocking I/O. Wait here. */ | ||
967 | ret = wait_event_interruptible( | ||
968 | fh->wait_data, | ||
969 | pvr2_ioread_avail(fh->rhp) >= 0); | ||
970 | if (ret < 0) break; | ||
971 | } | ||
972 | |||
973 | return ret; | ||
974 | } | ||
975 | |||
976 | |||
977 | static unsigned int pvr2_v4l2_poll(struct file *file, poll_table *wait) | ||
978 | { | ||
979 | unsigned int mask = 0; | ||
980 | struct pvr2_v4l2_fh *fh = file->private_data; | ||
981 | int ret; | ||
982 | |||
983 | if (fh->fw_mode_flag) { | ||
984 | mask |= POLLIN | POLLRDNORM; | ||
985 | return mask; | ||
986 | } | ||
987 | |||
988 | if (!fh->rhp) { | ||
989 | ret = pvr2_v4l2_iosetup(fh); | ||
990 | if (ret) return POLLERR; | ||
991 | } | ||
992 | |||
993 | poll_wait(file,&fh->wait_data,wait); | ||
994 | |||
995 | if (pvr2_ioread_avail(fh->rhp) >= 0) { | ||
996 | mask |= POLLIN | POLLRDNORM; | ||
997 | } | ||
998 | |||
999 | return mask; | ||
1000 | } | ||
1001 | |||
1002 | |||
1003 | static struct file_operations vdev_fops = { | ||
1004 | .owner = THIS_MODULE, | ||
1005 | .open = pvr2_v4l2_open, | ||
1006 | .release = pvr2_v4l2_release, | ||
1007 | .read = pvr2_v4l2_read, | ||
1008 | .ioctl = pvr2_v4l2_ioctl, | ||
1009 | .llseek = no_llseek, | ||
1010 | .poll = pvr2_v4l2_poll, | ||
1011 | }; | ||
1012 | |||
1013 | |||
1014 | #define VID_HARDWARE_PVRUSB2 38 /* FIXME : need a good value */ | ||
1015 | |||
1016 | static struct video_device vdev_template = { | ||
1017 | .owner = THIS_MODULE, | ||
1018 | .type = VID_TYPE_CAPTURE | VID_TYPE_TUNER, | ||
1019 | .type2 = (V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VBI_CAPTURE | ||
1020 | | V4L2_CAP_TUNER | V4L2_CAP_AUDIO | ||
1021 | | V4L2_CAP_READWRITE), | ||
1022 | .hardware = VID_HARDWARE_PVRUSB2, | ||
1023 | .fops = &vdev_fops, | ||
1024 | }; | ||
1025 | |||
1026 | |||
1027 | static void pvr2_v4l2_dev_init(struct pvr2_v4l2_dev *dip, | ||
1028 | struct pvr2_v4l2 *vp, | ||
1029 | enum pvr2_config cfg) | ||
1030 | { | ||
1031 | int mindevnum; | ||
1032 | int unit_number; | ||
1033 | int v4l_type; | ||
1034 | dip->v4lp = vp; | ||
1035 | dip->config = cfg; | ||
1036 | |||
1037 | |||
1038 | switch (cfg) { | ||
1039 | case pvr2_config_mpeg: | ||
1040 | v4l_type = VFL_TYPE_GRABBER; | ||
1041 | dip->stream = &vp->channel.mc_head->video_stream; | ||
1042 | break; | ||
1043 | case pvr2_config_vbi: | ||
1044 | v4l_type = VFL_TYPE_VBI; | ||
1045 | break; | ||
1046 | case pvr2_config_radio: | ||
1047 | v4l_type = VFL_TYPE_RADIO; | ||
1048 | break; | ||
1049 | default: | ||
1050 | /* Bail out (this should be impossible) */ | ||
1051 | err("Failed to set up pvrusb2 v4l dev" | ||
1052 | " due to unrecognized config"); | ||
1053 | return; | ||
1054 | } | ||
1055 | |||
1056 | if (!dip->stream) { | ||
1057 | err("Failed to set up pvrusb2 v4l dev" | ||
1058 | " due to missing stream instance"); | ||
1059 | return; | ||
1060 | } | ||
1061 | |||
1062 | dip->vdev = video_device_alloc(); | ||
1063 | if (!dip->vdev) { | ||
1064 | err("Alloc of pvrusb2 v4l video device failed"); | ||
1065 | return; | ||
1066 | } | ||
1067 | |||
1068 | memcpy(dip->vdev,&vdev_template,sizeof(vdev_template)); | ||
1069 | dip->vdev->release = video_device_release; | ||
1070 | mutex_lock(&device_lock); | ||
1071 | |||
1072 | mindevnum = -1; | ||
1073 | unit_number = pvr2_hdw_get_unit_number(vp->channel.mc_head->hdw); | ||
1074 | if ((unit_number >= 0) && (unit_number < PVR_NUM)) { | ||
1075 | mindevnum = video_nr[unit_number]; | ||
1076 | } | ||
1077 | if ((video_register_device(dip->vdev, v4l_type, mindevnum) < 0) && | ||
1078 | (video_register_device(dip->vdev, v4l_type, -1) < 0)) { | ||
1079 | err("Failed to register pvrusb2 v4l video device"); | ||
1080 | } else { | ||
1081 | pvr2_trace(PVR2_TRACE_INIT, | ||
1082 | "registered device video%d [%s]", | ||
1083 | dip->vdev->minor,pvr2_config_get_name(dip->config)); | ||
1084 | } | ||
1085 | |||
1086 | if ((dip->vdev->minor < sizeof(devices)/sizeof(devices[0])) && | ||
1087 | (devices[dip->vdev->minor] == NULL)) { | ||
1088 | dip->ctxt_idx = dip->vdev->minor; | ||
1089 | devices[dip->ctxt_idx] = dip; | ||
1090 | } | ||
1091 | mutex_unlock(&device_lock); | ||
1092 | |||
1093 | pvr2_hdw_v4l_store_minor_number(vp->channel.mc_head->hdw, | ||
1094 | dip->vdev->minor); | ||
1095 | } | ||
1096 | |||
1097 | |||
1098 | struct pvr2_v4l2 *pvr2_v4l2_create(struct pvr2_context *mnp) | ||
1099 | { | ||
1100 | struct pvr2_v4l2 *vp; | ||
1101 | |||
1102 | vp = kmalloc(sizeof(*vp),GFP_KERNEL); | ||
1103 | if (!vp) return vp; | ||
1104 | memset(vp,0,sizeof(*vp)); | ||
1105 | vp->video_dev.ctxt_idx = -1; | ||
1106 | pvr2_channel_init(&vp->channel,mnp); | ||
1107 | pvr2_trace(PVR2_TRACE_STRUCT,"Creating pvr2_v4l2 id=%p",vp); | ||
1108 | |||
1109 | vp->channel.check_func = pvr2_v4l2_internal_check; | ||
1110 | |||
1111 | /* register streams */ | ||
1112 | pvr2_v4l2_dev_init(&vp->video_dev,vp,pvr2_config_mpeg); | ||
1113 | |||
1114 | |||
1115 | return vp; | ||
1116 | } | ||
1117 | |||
1118 | /* | ||
1119 | Stuff for Emacs to see, in order to encourage consistent editing style: | ||
1120 | *** Local Variables: *** | ||
1121 | *** mode: c *** | ||
1122 | *** fill-column: 75 *** | ||
1123 | *** tab-width: 8 *** | ||
1124 | *** c-basic-offset: 8 *** | ||
1125 | *** End: *** | ||
1126 | */ | ||
diff --git a/drivers/media/video/pvrusb2/pvrusb2-v4l2.h b/drivers/media/video/pvrusb2/pvrusb2-v4l2.h new file mode 100644 index 000000000000..9a995e2d2256 --- /dev/null +++ b/drivers/media/video/pvrusb2/pvrusb2-v4l2.h | |||
@@ -0,0 +1,40 @@ | |||
1 | /* | ||
2 | * | ||
3 | * $Id$ | ||
4 | * | ||
5 | * Copyright (C) 2005 Mike Isely <isely@pobox.com> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License as published by | ||
9 | * the Free Software Foundation; either version 2 of the License | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
19 | * | ||
20 | */ | ||
21 | #ifndef __PVRUSB2_V4L2_H | ||
22 | #define __PVRUSB2_V4L2_H | ||
23 | |||
24 | #include "pvrusb2-context.h" | ||
25 | |||
26 | struct pvr2_v4l2; | ||
27 | |||
28 | struct pvr2_v4l2 *pvr2_v4l2_create(struct pvr2_context *); | ||
29 | |||
30 | #endif /* __PVRUSB2_V4L2_H */ | ||
31 | |||
32 | /* | ||
33 | Stuff for Emacs to see, in order to encourage consistent editing style: | ||
34 | *** Local Variables: *** | ||
35 | *** mode: c *** | ||
36 | *** fill-column: 75 *** | ||
37 | *** tab-width: 8 *** | ||
38 | *** c-basic-offset: 8 *** | ||
39 | *** End: *** | ||
40 | */ | ||
diff --git a/drivers/media/video/pvrusb2/pvrusb2-video-v4l.c b/drivers/media/video/pvrusb2/pvrusb2-video-v4l.c new file mode 100644 index 000000000000..e4ec7f25194c --- /dev/null +++ b/drivers/media/video/pvrusb2/pvrusb2-video-v4l.c | |||
@@ -0,0 +1,253 @@ | |||
1 | /* | ||
2 | * | ||
3 | * $Id$ | ||
4 | * | ||
5 | * Copyright (C) 2005 Mike Isely <isely@pobox.com> | ||
6 | * Copyright (C) 2004 Aurelien Alleaume <slts@free.fr> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License as published by | ||
10 | * the Free Software Foundation; either version 2 of the License | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | * GNU General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU General Public License | ||
18 | * along with this program; if not, write to the Free Software | ||
19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
20 | * | ||
21 | */ | ||
22 | |||
23 | /* | ||
24 | |||
25 | This source file is specifically designed to interface with the | ||
26 | saa711x support that is available in the v4l available starting | ||
27 | with linux 2.6.15. | ||
28 | |||
29 | */ | ||
30 | |||
31 | #include "pvrusb2-video-v4l.h" | ||
32 | #include "pvrusb2-i2c-cmd-v4l2.h" | ||
33 | |||
34 | |||
35 | #include "pvrusb2-hdw-internal.h" | ||
36 | #include "pvrusb2-debug.h" | ||
37 | #include <linux/videodev2.h> | ||
38 | #include <media/v4l2-common.h> | ||
39 | #include <media/saa7115.h> | ||
40 | #include <linux/errno.h> | ||
41 | #include <linux/slab.h> | ||
42 | |||
43 | struct pvr2_v4l_decoder { | ||
44 | struct pvr2_i2c_handler handler; | ||
45 | struct pvr2_decoder_ctrl ctrl; | ||
46 | struct pvr2_i2c_client *client; | ||
47 | struct pvr2_hdw *hdw; | ||
48 | unsigned long stale_mask; | ||
49 | }; | ||
50 | |||
51 | |||
52 | static void set_input(struct pvr2_v4l_decoder *ctxt) | ||
53 | { | ||
54 | struct pvr2_hdw *hdw = ctxt->hdw; | ||
55 | struct v4l2_routing route; | ||
56 | |||
57 | pvr2_trace(PVR2_TRACE_CHIPS,"i2c v4l2 set_input(%d)",hdw->input_val); | ||
58 | switch(hdw->input_val) { | ||
59 | case PVR2_CVAL_INPUT_TV: | ||
60 | route.input = SAA7115_COMPOSITE4; | ||
61 | break; | ||
62 | case PVR2_CVAL_INPUT_COMPOSITE: | ||
63 | route.input = SAA7115_COMPOSITE5; | ||
64 | break; | ||
65 | case PVR2_CVAL_INPUT_SVIDEO: | ||
66 | route.input = SAA7115_SVIDEO2; | ||
67 | break; | ||
68 | case PVR2_CVAL_INPUT_RADIO: | ||
69 | // ????? No idea yet what to do here | ||
70 | default: | ||
71 | return; | ||
72 | } | ||
73 | route.output = 0; | ||
74 | pvr2_i2c_client_cmd(ctxt->client,VIDIOC_INT_S_VIDEO_ROUTING,&route); | ||
75 | } | ||
76 | |||
77 | |||
78 | static int check_input(struct pvr2_v4l_decoder *ctxt) | ||
79 | { | ||
80 | struct pvr2_hdw *hdw = ctxt->hdw; | ||
81 | return hdw->input_dirty != 0; | ||
82 | } | ||
83 | |||
84 | |||
85 | static void set_audio(struct pvr2_v4l_decoder *ctxt) | ||
86 | { | ||
87 | u32 val; | ||
88 | struct pvr2_hdw *hdw = ctxt->hdw; | ||
89 | |||
90 | pvr2_trace(PVR2_TRACE_CHIPS,"i2c v4l2 set_audio %d", | ||
91 | hdw->srate_val); | ||
92 | switch (hdw->srate_val) { | ||
93 | default: | ||
94 | case V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000: | ||
95 | val = 48000; | ||
96 | break; | ||
97 | case V4L2_MPEG_AUDIO_SAMPLING_FREQ_44100: | ||
98 | val = 44100; | ||
99 | break; | ||
100 | case V4L2_MPEG_AUDIO_SAMPLING_FREQ_32000: | ||
101 | val = 32000; | ||
102 | break; | ||
103 | } | ||
104 | pvr2_i2c_client_cmd(ctxt->client,VIDIOC_INT_AUDIO_CLOCK_FREQ,&val); | ||
105 | } | ||
106 | |||
107 | |||
108 | static int check_audio(struct pvr2_v4l_decoder *ctxt) | ||
109 | { | ||
110 | struct pvr2_hdw *hdw = ctxt->hdw; | ||
111 | return hdw->srate_dirty != 0; | ||
112 | } | ||
113 | |||
114 | |||
115 | struct pvr2_v4l_decoder_ops { | ||
116 | void (*update)(struct pvr2_v4l_decoder *); | ||
117 | int (*check)(struct pvr2_v4l_decoder *); | ||
118 | }; | ||
119 | |||
120 | |||
121 | static const struct pvr2_v4l_decoder_ops decoder_ops[] = { | ||
122 | { .update = set_input, .check = check_input}, | ||
123 | { .update = set_audio, .check = check_audio}, | ||
124 | }; | ||
125 | |||
126 | |||
127 | static void decoder_detach(struct pvr2_v4l_decoder *ctxt) | ||
128 | { | ||
129 | ctxt->client->handler = 0; | ||
130 | ctxt->hdw->decoder_ctrl = 0; | ||
131 | kfree(ctxt); | ||
132 | } | ||
133 | |||
134 | |||
135 | static int decoder_check(struct pvr2_v4l_decoder *ctxt) | ||
136 | { | ||
137 | unsigned long msk; | ||
138 | unsigned int idx; | ||
139 | |||
140 | for (idx = 0; idx < sizeof(decoder_ops)/sizeof(decoder_ops[0]); | ||
141 | idx++) { | ||
142 | msk = 1 << idx; | ||
143 | if (ctxt->stale_mask & msk) continue; | ||
144 | if (decoder_ops[idx].check(ctxt)) { | ||
145 | ctxt->stale_mask |= msk; | ||
146 | } | ||
147 | } | ||
148 | return ctxt->stale_mask != 0; | ||
149 | } | ||
150 | |||
151 | |||
152 | static void decoder_update(struct pvr2_v4l_decoder *ctxt) | ||
153 | { | ||
154 | unsigned long msk; | ||
155 | unsigned int idx; | ||
156 | |||
157 | for (idx = 0; idx < sizeof(decoder_ops)/sizeof(decoder_ops[0]); | ||
158 | idx++) { | ||
159 | msk = 1 << idx; | ||
160 | if (!(ctxt->stale_mask & msk)) continue; | ||
161 | ctxt->stale_mask &= ~msk; | ||
162 | decoder_ops[idx].update(ctxt); | ||
163 | } | ||
164 | } | ||
165 | |||
166 | |||
167 | static int decoder_detect(struct pvr2_i2c_client *cp) | ||
168 | { | ||
169 | /* Attempt to query the decoder - let's see if it will answer */ | ||
170 | struct v4l2_tuner vt; | ||
171 | int ret; | ||
172 | |||
173 | memset(&vt,0,sizeof(vt)); | ||
174 | ret = pvr2_i2c_client_cmd(cp,VIDIOC_G_TUNER,&vt); | ||
175 | return ret == 0; /* Return true if it answered */ | ||
176 | } | ||
177 | |||
178 | |||
179 | static void decoder_enable(struct pvr2_v4l_decoder *ctxt,int fl) | ||
180 | { | ||
181 | pvr2_trace(PVR2_TRACE_CHIPS,"i2c v4l2 decoder_enable(%d)",fl); | ||
182 | pvr2_v4l2_cmd_stream(ctxt->client,fl); | ||
183 | } | ||
184 | |||
185 | |||
186 | static int decoder_is_tuned(struct pvr2_v4l_decoder *ctxt) | ||
187 | { | ||
188 | struct v4l2_tuner vt; | ||
189 | int ret; | ||
190 | |||
191 | memset(&vt,0,sizeof(vt)); | ||
192 | ret = pvr2_i2c_client_cmd(ctxt->client,VIDIOC_G_TUNER,&vt); | ||
193 | if (ret < 0) return -EINVAL; | ||
194 | return vt.signal ? 1 : 0; | ||
195 | } | ||
196 | |||
197 | |||
198 | static unsigned int decoder_describe(struct pvr2_v4l_decoder *ctxt,char *buf,unsigned int cnt) | ||
199 | { | ||
200 | return scnprintf(buf,cnt,"handler: pvrusb2-video-v4l"); | ||
201 | } | ||
202 | |||
203 | |||
204 | const static struct pvr2_i2c_handler_functions hfuncs = { | ||
205 | .detach = (void (*)(void *))decoder_detach, | ||
206 | .check = (int (*)(void *))decoder_check, | ||
207 | .update = (void (*)(void *))decoder_update, | ||
208 | .describe = (unsigned int (*)(void *,char *,unsigned int))decoder_describe, | ||
209 | }; | ||
210 | |||
211 | |||
212 | int pvr2_i2c_decoder_v4l_setup(struct pvr2_hdw *hdw, | ||
213 | struct pvr2_i2c_client *cp) | ||
214 | { | ||
215 | struct pvr2_v4l_decoder *ctxt; | ||
216 | |||
217 | if (hdw->decoder_ctrl) return 0; | ||
218 | if (cp->handler) return 0; | ||
219 | if (!decoder_detect(cp)) return 0; | ||
220 | |||
221 | ctxt = kmalloc(sizeof(*ctxt),GFP_KERNEL); | ||
222 | if (!ctxt) return 0; | ||
223 | memset(ctxt,0,sizeof(*ctxt)); | ||
224 | |||
225 | ctxt->handler.func_data = ctxt; | ||
226 | ctxt->handler.func_table = &hfuncs; | ||
227 | ctxt->ctrl.ctxt = ctxt; | ||
228 | ctxt->ctrl.detach = (void (*)(void *))decoder_detach; | ||
229 | ctxt->ctrl.enable = (void (*)(void *,int))decoder_enable; | ||
230 | ctxt->ctrl.tuned = (int (*)(void *))decoder_is_tuned; | ||
231 | ctxt->client = cp; | ||
232 | ctxt->hdw = hdw; | ||
233 | ctxt->stale_mask = (1 << (sizeof(decoder_ops)/ | ||
234 | sizeof(decoder_ops[0]))) - 1; | ||
235 | hdw->decoder_ctrl = &ctxt->ctrl; | ||
236 | cp->handler = &ctxt->handler; | ||
237 | pvr2_trace(PVR2_TRACE_CHIPS,"i2c 0x%x saa711x V4L2 handler set up", | ||
238 | cp->client->addr); | ||
239 | return !0; | ||
240 | } | ||
241 | |||
242 | |||
243 | |||
244 | |||
245 | /* | ||
246 | Stuff for Emacs to see, in order to encourage consistent editing style: | ||
247 | *** Local Variables: *** | ||
248 | *** mode: c *** | ||
249 | *** fill-column: 70 *** | ||
250 | *** tab-width: 8 *** | ||
251 | *** c-basic-offset: 8 *** | ||
252 | *** End: *** | ||
253 | */ | ||
diff --git a/drivers/media/video/pvrusb2/pvrusb2-video-v4l.h b/drivers/media/video/pvrusb2/pvrusb2-video-v4l.h new file mode 100644 index 000000000000..2b917fda02e4 --- /dev/null +++ b/drivers/media/video/pvrusb2/pvrusb2-video-v4l.h | |||
@@ -0,0 +1,52 @@ | |||
1 | /* | ||
2 | * | ||
3 | * $Id$ | ||
4 | * | ||
5 | * Copyright (C) 2005 Mike Isely <isely@pobox.com> | ||
6 | * Copyright (C) 2004 Aurelien Alleaume <slts@free.fr> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License as published by | ||
10 | * the Free Software Foundation; either version 2 of the License | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | * GNU General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU General Public License | ||
18 | * along with this program; if not, write to the Free Software | ||
19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
20 | * | ||
21 | */ | ||
22 | |||
23 | #ifndef __PVRUSB2_VIDEO_V4L_H | ||
24 | #define __PVRUSB2_VIDEO_V4L_H | ||
25 | |||
26 | /* | ||
27 | |||
28 | This module connects the pvrusb2 driver to the I2C chip level | ||
29 | driver which handles device video processing. This interface is | ||
30 | used internally by the driver; higher level code should only | ||
31 | interact through the interface provided by pvrusb2-hdw.h. | ||
32 | |||
33 | */ | ||
34 | |||
35 | |||
36 | |||
37 | #include "pvrusb2-i2c-core.h" | ||
38 | |||
39 | int pvr2_i2c_decoder_v4l_setup(struct pvr2_hdw *,struct pvr2_i2c_client *); | ||
40 | |||
41 | |||
42 | #endif /* __PVRUSB2_VIDEO_V4L_H */ | ||
43 | |||
44 | /* | ||
45 | Stuff for Emacs to see, in order to encourage consistent editing style: | ||
46 | *** Local Variables: *** | ||
47 | *** mode: c *** | ||
48 | *** fill-column: 70 *** | ||
49 | *** tab-width: 8 *** | ||
50 | *** c-basic-offset: 8 *** | ||
51 | *** End: *** | ||
52 | */ | ||
diff --git a/drivers/media/video/pvrusb2/pvrusb2-wm8775.c b/drivers/media/video/pvrusb2/pvrusb2-wm8775.c new file mode 100644 index 000000000000..fcad346e3955 --- /dev/null +++ b/drivers/media/video/pvrusb2/pvrusb2-wm8775.c | |||
@@ -0,0 +1,170 @@ | |||
1 | /* | ||
2 | * | ||
3 | * $Id$ | ||
4 | * | ||
5 | * Copyright (C) 2005 Mike Isely <isely@pobox.com> | ||
6 | * Copyright (C) 2004 Aurelien Alleaume <slts@free.fr> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License as published by | ||
10 | * the Free Software Foundation; either version 2 of the License | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | * GNU General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU General Public License | ||
18 | * along with this program; if not, write to the Free Software | ||
19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
20 | * | ||
21 | */ | ||
22 | |||
23 | /* | ||
24 | |||
25 | This source file is specifically designed to interface with the | ||
26 | wm8775. | ||
27 | |||
28 | */ | ||
29 | |||
30 | #include "pvrusb2-wm8775.h" | ||
31 | #include "pvrusb2-i2c-cmd-v4l2.h" | ||
32 | |||
33 | |||
34 | #include "pvrusb2-hdw-internal.h" | ||
35 | #include "pvrusb2-debug.h" | ||
36 | #include <linux/videodev2.h> | ||
37 | #include <media/v4l2-common.h> | ||
38 | #include <linux/errno.h> | ||
39 | #include <linux/slab.h> | ||
40 | |||
41 | struct pvr2_v4l_wm8775 { | ||
42 | struct pvr2_i2c_handler handler; | ||
43 | struct pvr2_i2c_client *client; | ||
44 | struct pvr2_hdw *hdw; | ||
45 | unsigned long stale_mask; | ||
46 | }; | ||
47 | |||
48 | |||
49 | static void set_input(struct pvr2_v4l_wm8775 *ctxt) | ||
50 | { | ||
51 | struct v4l2_routing route; | ||
52 | struct pvr2_hdw *hdw = ctxt->hdw; | ||
53 | int msk = 0; | ||
54 | |||
55 | memset(&route,0,sizeof(route)); | ||
56 | |||
57 | pvr2_trace(PVR2_TRACE_CHIPS,"i2c wm8775 set_input(val=%d msk=0x%x)", | ||
58 | hdw->input_val,msk); | ||
59 | |||
60 | // Always point to input #1 no matter what | ||
61 | route.input = 2; | ||
62 | pvr2_i2c_client_cmd(ctxt->client,VIDIOC_INT_S_AUDIO_ROUTING,&route); | ||
63 | } | ||
64 | |||
65 | static int check_input(struct pvr2_v4l_wm8775 *ctxt) | ||
66 | { | ||
67 | struct pvr2_hdw *hdw = ctxt->hdw; | ||
68 | return hdw->input_dirty != 0; | ||
69 | } | ||
70 | |||
71 | |||
72 | struct pvr2_v4l_wm8775_ops { | ||
73 | void (*update)(struct pvr2_v4l_wm8775 *); | ||
74 | int (*check)(struct pvr2_v4l_wm8775 *); | ||
75 | }; | ||
76 | |||
77 | |||
78 | static const struct pvr2_v4l_wm8775_ops wm8775_ops[] = { | ||
79 | { .update = set_input, .check = check_input}, | ||
80 | }; | ||
81 | |||
82 | |||
83 | static unsigned int wm8775_describe(struct pvr2_v4l_wm8775 *ctxt, | ||
84 | char *buf,unsigned int cnt) | ||
85 | { | ||
86 | return scnprintf(buf,cnt,"handler: pvrusb2-wm8775"); | ||
87 | } | ||
88 | |||
89 | |||
90 | static void wm8775_detach(struct pvr2_v4l_wm8775 *ctxt) | ||
91 | { | ||
92 | ctxt->client->handler = 0; | ||
93 | kfree(ctxt); | ||
94 | } | ||
95 | |||
96 | |||
97 | static int wm8775_check(struct pvr2_v4l_wm8775 *ctxt) | ||
98 | { | ||
99 | unsigned long msk; | ||
100 | unsigned int idx; | ||
101 | |||
102 | for (idx = 0; idx < sizeof(wm8775_ops)/sizeof(wm8775_ops[0]); | ||
103 | idx++) { | ||
104 | msk = 1 << idx; | ||
105 | if (ctxt->stale_mask & msk) continue; | ||
106 | if (wm8775_ops[idx].check(ctxt)) { | ||
107 | ctxt->stale_mask |= msk; | ||
108 | } | ||
109 | } | ||
110 | return ctxt->stale_mask != 0; | ||
111 | } | ||
112 | |||
113 | |||
114 | static void wm8775_update(struct pvr2_v4l_wm8775 *ctxt) | ||
115 | { | ||
116 | unsigned long msk; | ||
117 | unsigned int idx; | ||
118 | |||
119 | for (idx = 0; idx < sizeof(wm8775_ops)/sizeof(wm8775_ops[0]); | ||
120 | idx++) { | ||
121 | msk = 1 << idx; | ||
122 | if (!(ctxt->stale_mask & msk)) continue; | ||
123 | ctxt->stale_mask &= ~msk; | ||
124 | wm8775_ops[idx].update(ctxt); | ||
125 | } | ||
126 | } | ||
127 | |||
128 | |||
129 | const static struct pvr2_i2c_handler_functions hfuncs = { | ||
130 | .detach = (void (*)(void *))wm8775_detach, | ||
131 | .check = (int (*)(void *))wm8775_check, | ||
132 | .update = (void (*)(void *))wm8775_update, | ||
133 | .describe = (unsigned int (*)(void *,char *,unsigned int))wm8775_describe, | ||
134 | }; | ||
135 | |||
136 | |||
137 | int pvr2_i2c_wm8775_setup(struct pvr2_hdw *hdw,struct pvr2_i2c_client *cp) | ||
138 | { | ||
139 | struct pvr2_v4l_wm8775 *ctxt; | ||
140 | |||
141 | if (cp->handler) return 0; | ||
142 | |||
143 | ctxt = kmalloc(sizeof(*ctxt),GFP_KERNEL); | ||
144 | if (!ctxt) return 0; | ||
145 | memset(ctxt,0,sizeof(*ctxt)); | ||
146 | |||
147 | ctxt->handler.func_data = ctxt; | ||
148 | ctxt->handler.func_table = &hfuncs; | ||
149 | ctxt->client = cp; | ||
150 | ctxt->hdw = hdw; | ||
151 | ctxt->stale_mask = (1 << (sizeof(wm8775_ops)/ | ||
152 | sizeof(wm8775_ops[0]))) - 1; | ||
153 | cp->handler = &ctxt->handler; | ||
154 | pvr2_trace(PVR2_TRACE_CHIPS,"i2c 0x%x wm8775 V4L2 handler set up", | ||
155 | cp->client->addr); | ||
156 | return !0; | ||
157 | } | ||
158 | |||
159 | |||
160 | |||
161 | |||
162 | /* | ||
163 | Stuff for Emacs to see, in order to encourage consistent editing style: | ||
164 | *** Local Variables: *** | ||
165 | *** mode: c *** | ||
166 | *** fill-column: 70 *** | ||
167 | *** tab-width: 8 *** | ||
168 | *** c-basic-offset: 8 *** | ||
169 | *** End: *** | ||
170 | */ | ||
diff --git a/drivers/media/video/pvrusb2/pvrusb2-wm8775.h b/drivers/media/video/pvrusb2/pvrusb2-wm8775.h new file mode 100644 index 000000000000..8aaeff4e1e20 --- /dev/null +++ b/drivers/media/video/pvrusb2/pvrusb2-wm8775.h | |||
@@ -0,0 +1,53 @@ | |||
1 | /* | ||
2 | * | ||
3 | * $Id$ | ||
4 | * | ||
5 | * Copyright (C) 2005 Mike Isely <isely@pobox.com> | ||
6 | * Copyright (C) 2004 Aurelien Alleaume <slts@free.fr> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License as published by | ||
10 | * the Free Software Foundation; either version 2 of the License | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | * GNU General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU General Public License | ||
18 | * along with this program; if not, write to the Free Software | ||
19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
20 | * | ||
21 | */ | ||
22 | |||
23 | #ifndef __PVRUSB2_WM8775_H | ||
24 | #define __PVRUSB2_WM8775_H | ||
25 | |||
26 | /* | ||
27 | |||
28 | This module connects the pvrusb2 driver to the I2C chip level | ||
29 | driver which performs analog -> digital audio conversion for | ||
30 | external audio inputs. This interface is used internally by the | ||
31 | driver; higher level code should only interact through the | ||
32 | interface provided by pvrusb2-hdw.h. | ||
33 | |||
34 | */ | ||
35 | |||
36 | |||
37 | |||
38 | #include "pvrusb2-i2c-core.h" | ||
39 | |||
40 | int pvr2_i2c_wm8775_setup(struct pvr2_hdw *,struct pvr2_i2c_client *); | ||
41 | |||
42 | |||
43 | #endif /* __PVRUSB2_WM8775_H */ | ||
44 | |||
45 | /* | ||
46 | Stuff for Emacs to see, in order to encourage consistent editing style: | ||
47 | *** Local Variables: *** | ||
48 | *** mode: c *** | ||
49 | *** fill-column: 70 *** | ||
50 | *** tab-width: 8 *** | ||
51 | *** c-basic-offset: 8 *** | ||
52 | *** End: *** | ||
53 | */ | ||
diff --git a/drivers/media/video/pvrusb2/pvrusb2.h b/drivers/media/video/pvrusb2/pvrusb2.h new file mode 100644 index 000000000000..074533e9c21e --- /dev/null +++ b/drivers/media/video/pvrusb2/pvrusb2.h | |||
@@ -0,0 +1,43 @@ | |||
1 | /* | ||
2 | * | ||
3 | * $Id$ | ||
4 | * | ||
5 | * Copyright (C) 2005 Mike Isely <isely@pobox.com> | ||
6 | * Copyright (C) 2004 Aurelien Alleaume <slts@free.fr> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License as published by | ||
10 | * the Free Software Foundation; either version 2 of the License | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | * GNU General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU General Public License | ||
18 | * along with this program; if not, write to the Free Software | ||
19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
20 | * | ||
21 | */ | ||
22 | |||
23 | #ifndef __PVRUSB2_H | ||
24 | #define __PVRUSB2_H | ||
25 | |||
26 | /* Maximum number of pvrusb2 instances we can track at once. You | ||
27 | might want to increase this - however the driver operation will not | ||
28 | be impaired if it is too small. Instead additional units just | ||
29 | won't have an ID assigned and it might not be possible to specify | ||
30 | module paramters for those extra units. */ | ||
31 | #define PVR_NUM 20 | ||
32 | |||
33 | #endif /* __PVRUSB2_H */ | ||
34 | |||
35 | /* | ||
36 | Stuff for Emacs to see, in order to encourage consistent editing style: | ||
37 | *** Local Variables: *** | ||
38 | *** mode: c *** | ||
39 | *** fill-column: 70 *** | ||
40 | *** tab-width: 8 *** | ||
41 | *** c-basic-offset: 8 *** | ||
42 | *** End: *** | ||
43 | */ | ||
diff --git a/drivers/media/video/saa7134/saa6752hs.c b/drivers/media/video/saa7134/saa6752hs.c index de7b9e6e932a..afc8f352b8e7 100644 --- a/drivers/media/video/saa7134/saa6752hs.c +++ b/drivers/media/video/saa7134/saa6752hs.c | |||
@@ -432,10 +432,10 @@ static void saa6752hs_old_set_params(struct i2c_client* client, | |||
432 | } | 432 | } |
433 | 433 | ||
434 | static int handle_ctrl(struct saa6752hs_mpeg_params *params, | 434 | static int handle_ctrl(struct saa6752hs_mpeg_params *params, |
435 | struct v4l2_ext_control *ctrl, int cmd) | 435 | struct v4l2_ext_control *ctrl, unsigned int cmd) |
436 | { | 436 | { |
437 | int old = 0, new; | 437 | int old = 0, new; |
438 | int set = cmd == VIDIOC_S_EXT_CTRLS; | 438 | int set = (cmd == VIDIOC_S_EXT_CTRLS); |
439 | 439 | ||
440 | new = ctrl->value; | 440 | new = ctrl->value; |
441 | switch (ctrl->id) { | 441 | switch (ctrl->id) { |
diff --git a/drivers/media/video/saa7134/saa7134-core.c b/drivers/media/video/saa7134/saa7134-core.c index f0c2111f14ad..da3007d2f411 100644 --- a/drivers/media/video/saa7134/saa7134-core.c +++ b/drivers/media/video/saa7134/saa7134-core.c | |||
@@ -871,9 +871,9 @@ static int __devinit saa7134_initdev(struct pci_dev *pci_dev, | |||
871 | pci_read_config_byte(pci_dev, PCI_CLASS_REVISION, &dev->pci_rev); | 871 | pci_read_config_byte(pci_dev, PCI_CLASS_REVISION, &dev->pci_rev); |
872 | pci_read_config_byte(pci_dev, PCI_LATENCY_TIMER, &dev->pci_lat); | 872 | pci_read_config_byte(pci_dev, PCI_LATENCY_TIMER, &dev->pci_lat); |
873 | printk(KERN_INFO "%s: found at %s, rev: %d, irq: %d, " | 873 | printk(KERN_INFO "%s: found at %s, rev: %d, irq: %d, " |
874 | "latency: %d, mmio: 0x%lx\n", dev->name, | 874 | "latency: %d, mmio: 0x%llx\n", dev->name, |
875 | pci_name(pci_dev), dev->pci_rev, pci_dev->irq, | 875 | pci_name(pci_dev), dev->pci_rev, pci_dev->irq, |
876 | dev->pci_lat,pci_resource_start(pci_dev,0)); | 876 | dev->pci_lat,(unsigned long long)pci_resource_start(pci_dev,0)); |
877 | pci_set_master(pci_dev); | 877 | pci_set_master(pci_dev); |
878 | if (!pci_dma_supported(pci_dev, DMA_32BIT_MASK)) { | 878 | if (!pci_dma_supported(pci_dev, DMA_32BIT_MASK)) { |
879 | printk("%s: Oops: no 32bit PCI DMA ???\n",dev->name); | 879 | printk("%s: Oops: no 32bit PCI DMA ???\n",dev->name); |
@@ -905,8 +905,8 @@ static int __devinit saa7134_initdev(struct pci_dev *pci_dev, | |||
905 | pci_resource_len(pci_dev,0), | 905 | pci_resource_len(pci_dev,0), |
906 | dev->name)) { | 906 | dev->name)) { |
907 | err = -EBUSY; | 907 | err = -EBUSY; |
908 | printk(KERN_ERR "%s: can't get MMIO memory @ 0x%lx\n", | 908 | printk(KERN_ERR "%s: can't get MMIO memory @ 0x%llx\n", |
909 | dev->name,pci_resource_start(pci_dev,0)); | 909 | dev->name,(unsigned long long)pci_resource_start(pci_dev,0)); |
910 | goto fail1; | 910 | goto fail1; |
911 | } | 911 | } |
912 | dev->lmmio = ioremap(pci_resource_start(pci_dev,0), 0x1000); | 912 | dev->lmmio = ioremap(pci_resource_start(pci_dev,0), 0x1000); |
diff --git a/drivers/media/video/stradis.c b/drivers/media/video/stradis.c index 6be9c1131e1f..c18b31d9928c 100644 --- a/drivers/media/video/stradis.c +++ b/drivers/media/video/stradis.c | |||
@@ -2190,7 +2190,7 @@ static struct pci_driver stradis_driver = { | |||
2190 | .remove = __devexit_p(stradis_remove) | 2190 | .remove = __devexit_p(stradis_remove) |
2191 | }; | 2191 | }; |
2192 | 2192 | ||
2193 | int __init stradis_init(void) | 2193 | static int __init stradis_init(void) |
2194 | { | 2194 | { |
2195 | int retval; | 2195 | int retval; |
2196 | 2196 | ||
@@ -2203,7 +2203,7 @@ int __init stradis_init(void) | |||
2203 | return retval; | 2203 | return retval; |
2204 | } | 2204 | } |
2205 | 2205 | ||
2206 | void __exit stradis_exit(void) | 2206 | static void __exit stradis_exit(void) |
2207 | { | 2207 | { |
2208 | pci_unregister_driver(&stradis_driver); | 2208 | pci_unregister_driver(&stradis_driver); |
2209 | printk(KERN_INFO "stradis: module cleanup complete\n"); | 2209 | printk(KERN_INFO "stradis: module cleanup complete\n"); |
diff --git a/drivers/media/video/tda9887.c b/drivers/media/video/tda9887.c index b6ae969563b2..2fadabf99688 100644 --- a/drivers/media/video/tda9887.c +++ b/drivers/media/video/tda9887.c | |||
@@ -22,11 +22,11 @@ | |||
22 | */ | 22 | */ |
23 | 23 | ||
24 | #define tda9887_info(fmt, arg...) do {\ | 24 | #define tda9887_info(fmt, arg...) do {\ |
25 | printk(KERN_INFO "%s %d-%04x (tda9887): " fmt, t->i2c.name, \ | 25 | printk(KERN_INFO "%s %d-%04x: " fmt, t->i2c.name, \ |
26 | i2c_adapter_id(t->i2c.adapter), t->i2c.addr , ##arg); } while (0) | 26 | i2c_adapter_id(t->i2c.adapter), t->i2c.addr , ##arg); } while (0) |
27 | #define tda9887_dbg(fmt, arg...) do {\ | 27 | #define tda9887_dbg(fmt, arg...) do {\ |
28 | if (tuner_debug) \ | 28 | if (tuner_debug) \ |
29 | printk(KERN_INFO "%s %d-%04x (tda9887): " fmt, t->i2c.name, \ | 29 | printk(KERN_INFO "%s %d-%04x: " fmt, t->i2c.name, \ |
30 | i2c_adapter_id(t->i2c.adapter), t->i2c.addr , ##arg); } while (0) | 30 | i2c_adapter_id(t->i2c.adapter), t->i2c.addr , ##arg); } while (0) |
31 | 31 | ||
32 | 32 | ||
@@ -84,8 +84,7 @@ struct tvnorm { | |||
84 | #define cAudioGain6 0x80 // bit c7 | 84 | #define cAudioGain6 0x80 // bit c7 |
85 | 85 | ||
86 | #define cTopMask 0x1f // bit c0:4 | 86 | #define cTopMask 0x1f // bit c0:4 |
87 | #define cTopPalSecamDefault 0x14 // bit c0:4 | 87 | #define cTopDefault 0x10 // bit c0:4 |
88 | #define cTopNtscRadioDefault 0x10 // bit c0:4 | ||
89 | 88 | ||
90 | //// third reg (e) | 89 | //// third reg (e) |
91 | #define cAudioIF_4_5 0x00 // bit e0:1 | 90 | #define cAudioIF_4_5 0x00 // bit e0:1 |
@@ -123,7 +122,7 @@ static struct tvnorm tvnorms[] = { | |||
123 | cQSS ), | 122 | cQSS ), |
124 | .c = ( cDeemphasisON | | 123 | .c = ( cDeemphasisON | |
125 | cDeemphasis50 | | 124 | cDeemphasis50 | |
126 | cTopPalSecamDefault), | 125 | cTopDefault), |
127 | .e = ( cGating_36 | | 126 | .e = ( cGating_36 | |
128 | cAudioIF_5_5 | | 127 | cAudioIF_5_5 | |
129 | cVideoIF_38_90 ), | 128 | cVideoIF_38_90 ), |
@@ -134,7 +133,7 @@ static struct tvnorm tvnorms[] = { | |||
134 | cQSS ), | 133 | cQSS ), |
135 | .c = ( cDeemphasisON | | 134 | .c = ( cDeemphasisON | |
136 | cDeemphasis50 | | 135 | cDeemphasis50 | |
137 | cTopPalSecamDefault), | 136 | cTopDefault), |
138 | .e = ( cGating_36 | | 137 | .e = ( cGating_36 | |
139 | cAudioIF_6_0 | | 138 | cAudioIF_6_0 | |
140 | cVideoIF_38_90 ), | 139 | cVideoIF_38_90 ), |
@@ -145,7 +144,7 @@ static struct tvnorm tvnorms[] = { | |||
145 | cQSS ), | 144 | cQSS ), |
146 | .c = ( cDeemphasisON | | 145 | .c = ( cDeemphasisON | |
147 | cDeemphasis50 | | 146 | cDeemphasis50 | |
148 | cTopPalSecamDefault), | 147 | cTopDefault), |
149 | .e = ( cGating_36 | | 148 | .e = ( cGating_36 | |
150 | cAudioIF_6_5 | | 149 | cAudioIF_6_5 | |
151 | cVideoIF_38_90 ), | 150 | cVideoIF_38_90 ), |
@@ -156,7 +155,7 @@ static struct tvnorm tvnorms[] = { | |||
156 | cQSS ), | 155 | cQSS ), |
157 | .c = ( cDeemphasisON | | 156 | .c = ( cDeemphasisON | |
158 | cDeemphasis75 | | 157 | cDeemphasis75 | |
159 | cTopNtscRadioDefault), | 158 | cTopDefault), |
160 | .e = ( cGating_36 | | 159 | .e = ( cGating_36 | |
161 | cAudioIF_4_5 | | 160 | cAudioIF_4_5 | |
162 | cVideoIF_45_75 ), | 161 | cVideoIF_45_75 ), |
@@ -165,7 +164,7 @@ static struct tvnorm tvnorms[] = { | |||
165 | .name = "SECAM-BGH", | 164 | .name = "SECAM-BGH", |
166 | .b = ( cPositiveAmTV | | 165 | .b = ( cPositiveAmTV | |
167 | cQSS ), | 166 | cQSS ), |
168 | .c = ( cTopPalSecamDefault), | 167 | .c = ( cTopDefault), |
169 | .e = ( cGating_36 | | 168 | .e = ( cGating_36 | |
170 | cAudioIF_5_5 | | 169 | cAudioIF_5_5 | |
171 | cVideoIF_38_90 ), | 170 | cVideoIF_38_90 ), |
@@ -174,7 +173,7 @@ static struct tvnorm tvnorms[] = { | |||
174 | .name = "SECAM-L", | 173 | .name = "SECAM-L", |
175 | .b = ( cPositiveAmTV | | 174 | .b = ( cPositiveAmTV | |
176 | cQSS ), | 175 | cQSS ), |
177 | .c = ( cTopPalSecamDefault), | 176 | .c = ( cTopDefault), |
178 | .e = ( cGating_36 | | 177 | .e = ( cGating_36 | |
179 | cAudioIF_6_5 | | 178 | cAudioIF_6_5 | |
180 | cVideoIF_38_90 ), | 179 | cVideoIF_38_90 ), |
@@ -184,7 +183,7 @@ static struct tvnorm tvnorms[] = { | |||
184 | .b = ( cOutputPort2Inactive | | 183 | .b = ( cOutputPort2Inactive | |
185 | cPositiveAmTV | | 184 | cPositiveAmTV | |
186 | cQSS ), | 185 | cQSS ), |
187 | .c = ( cTopPalSecamDefault), | 186 | .c = ( cTopDefault), |
188 | .e = ( cGating_36 | | 187 | .e = ( cGating_36 | |
189 | cAudioIF_6_5 | | 188 | cAudioIF_6_5 | |
190 | cVideoIF_33_90 ), | 189 | cVideoIF_33_90 ), |
@@ -195,7 +194,7 @@ static struct tvnorm tvnorms[] = { | |||
195 | cQSS ), | 194 | cQSS ), |
196 | .c = ( cDeemphasisON | | 195 | .c = ( cDeemphasisON | |
197 | cDeemphasis50 | | 196 | cDeemphasis50 | |
198 | cTopPalSecamDefault), | 197 | cTopDefault), |
199 | .e = ( cGating_36 | | 198 | .e = ( cGating_36 | |
200 | cAudioIF_6_5 | | 199 | cAudioIF_6_5 | |
201 | cVideoIF_38_90 ), | 200 | cVideoIF_38_90 ), |
@@ -206,7 +205,7 @@ static struct tvnorm tvnorms[] = { | |||
206 | cQSS ), | 205 | cQSS ), |
207 | .c = ( cDeemphasisON | | 206 | .c = ( cDeemphasisON | |
208 | cDeemphasis75 | | 207 | cDeemphasis75 | |
209 | cTopNtscRadioDefault), | 208 | cTopDefault), |
210 | .e = ( cGating_36 | | 209 | .e = ( cGating_36 | |
211 | cAudioIF_4_5 | | 210 | cAudioIF_4_5 | |
212 | cVideoIF_45_75 ), | 211 | cVideoIF_45_75 ), |
@@ -217,7 +216,7 @@ static struct tvnorm tvnorms[] = { | |||
217 | cQSS ), | 216 | cQSS ), |
218 | .c = ( cDeemphasisON | | 217 | .c = ( cDeemphasisON | |
219 | cDeemphasis50 | | 218 | cDeemphasis50 | |
220 | cTopNtscRadioDefault), | 219 | cTopDefault), |
221 | .e = ( cGating_36 | | 220 | .e = ( cGating_36 | |
222 | cAudioIF_4_5 | | 221 | cAudioIF_4_5 | |
223 | cVideoIF_58_75 ), | 222 | cVideoIF_58_75 ), |
@@ -230,7 +229,7 @@ static struct tvnorm radio_stereo = { | |||
230 | cQSS ), | 229 | cQSS ), |
231 | .c = ( cDeemphasisOFF | | 230 | .c = ( cDeemphasisOFF | |
232 | cAudioGain6 | | 231 | cAudioGain6 | |
233 | cTopNtscRadioDefault), | 232 | cTopDefault), |
234 | .e = ( cTunerGainLow | | 233 | .e = ( cTunerGainLow | |
235 | cAudioIF_5_5 | | 234 | cAudioIF_5_5 | |
236 | cRadioIF_38_90 ), | 235 | cRadioIF_38_90 ), |
@@ -242,7 +241,7 @@ static struct tvnorm radio_mono = { | |||
242 | cQSS ), | 241 | cQSS ), |
243 | .c = ( cDeemphasisON | | 242 | .c = ( cDeemphasisON | |
244 | cDeemphasis75 | | 243 | cDeemphasis75 | |
245 | cTopNtscRadioDefault), | 244 | cTopDefault), |
246 | .e = ( cTunerGainLow | | 245 | .e = ( cTunerGainLow | |
247 | cAudioIF_5_5 | | 246 | cAudioIF_5_5 | |
248 | cRadioIF_38_90 ), | 247 | cRadioIF_38_90 ), |
diff --git a/drivers/media/video/tuner-core.c b/drivers/media/video/tuner-core.c index a26ded7d6fae..011413cf34a8 100644 --- a/drivers/media/video/tuner-core.c +++ b/drivers/media/video/tuner-core.c | |||
@@ -40,7 +40,6 @@ static unsigned int no_autodetect = 0; | |||
40 | static unsigned int show_i2c = 0; | 40 | static unsigned int show_i2c = 0; |
41 | 41 | ||
42 | /* insmod options used at runtime => read/write */ | 42 | /* insmod options used at runtime => read/write */ |
43 | static unsigned int tuner_debug_old = 0; | ||
44 | int tuner_debug = 0; | 43 | int tuner_debug = 0; |
45 | 44 | ||
46 | static unsigned int tv_range[2] = { 44, 958 }; | 45 | static unsigned int tv_range[2] = { 44, 958 }; |
@@ -54,8 +53,6 @@ static char ntsc[] = "-"; | |||
54 | module_param(addr, int, 0444); | 53 | module_param(addr, int, 0444); |
55 | module_param(no_autodetect, int, 0444); | 54 | module_param(no_autodetect, int, 0444); |
56 | module_param(show_i2c, int, 0444); | 55 | module_param(show_i2c, int, 0444); |
57 | /* Note: tuner_debug is deprecated and will be removed in 2.6.17 */ | ||
58 | module_param_named(tuner_debug,tuner_debug_old, int, 0444); | ||
59 | module_param_named(debug,tuner_debug, int, 0644); | 56 | module_param_named(debug,tuner_debug, int, 0644); |
60 | module_param_string(pal, pal, sizeof(pal), 0644); | 57 | module_param_string(pal, pal, sizeof(pal), 0644); |
61 | module_param_string(secam, secam, sizeof(secam), 0644); | 58 | module_param_string(secam, secam, sizeof(secam), 0644); |
@@ -442,11 +439,6 @@ static int tuner_attach(struct i2c_adapter *adap, int addr, int kind) | |||
442 | t->audmode = V4L2_TUNER_MODE_STEREO; | 439 | t->audmode = V4L2_TUNER_MODE_STEREO; |
443 | t->mode_mask = T_UNINITIALIZED; | 440 | t->mode_mask = T_UNINITIALIZED; |
444 | t->tuner_status = tuner_status; | 441 | t->tuner_status = tuner_status; |
445 | if (tuner_debug_old) { | ||
446 | tuner_debug = tuner_debug_old; | ||
447 | printk(KERN_ERR "tuner: tuner_debug is deprecated and will be removed in 2.6.17.\n"); | ||
448 | printk(KERN_ERR "tuner: use the debug option instead.\n"); | ||
449 | } | ||
450 | 442 | ||
451 | if (show_i2c) { | 443 | if (show_i2c) { |
452 | unsigned char buffer[16]; | 444 | unsigned char buffer[16]; |
diff --git a/drivers/media/video/v4l2-common.c b/drivers/media/video/v4l2-common.c index f4b3d64ebf73..97f946db8597 100644 --- a/drivers/media/video/v4l2-common.c +++ b/drivers/media/video/v4l2-common.c | |||
@@ -1103,7 +1103,7 @@ const char **v4l2_ctrl_get_menu(u32 id) | |||
1103 | }; | 1103 | }; |
1104 | static const char *mpeg_stream_vbi_fmt[] = { | 1104 | static const char *mpeg_stream_vbi_fmt[] = { |
1105 | "No VBI", | 1105 | "No VBI", |
1106 | "VBI in private packets, IVTV format", | 1106 | "Private packet, IVTV format", |
1107 | NULL | 1107 | NULL |
1108 | }; | 1108 | }; |
1109 | 1109 | ||
diff --git a/drivers/media/video/videodev.c b/drivers/media/video/videodev.c index 2dfa7f23d0ca..b26ebaff226f 100644 --- a/drivers/media/video/videodev.c +++ b/drivers/media/video/videodev.c | |||
@@ -37,7 +37,6 @@ | |||
37 | #include <linux/init.h> | 37 | #include <linux/init.h> |
38 | #include <linux/kmod.h> | 38 | #include <linux/kmod.h> |
39 | #include <linux/slab.h> | 39 | #include <linux/slab.h> |
40 | #include <linux/devfs_fs_kernel.h> | ||
41 | #include <asm/uaccess.h> | 40 | #include <asm/uaccess.h> |
42 | #include <asm/system.h> | 41 | #include <asm/system.h> |
43 | 42 | ||
@@ -1563,10 +1562,6 @@ int video_register_device(struct video_device *vfd, int type, int nr) | |||
1563 | video_device[i]=vfd; | 1562 | video_device[i]=vfd; |
1564 | vfd->minor=i; | 1563 | vfd->minor=i; |
1565 | mutex_unlock(&videodev_lock); | 1564 | mutex_unlock(&videodev_lock); |
1566 | |||
1567 | sprintf(vfd->devfs_name, "v4l/%s%d", name_base, i - base); | ||
1568 | devfs_mk_cdev(MKDEV(VIDEO_MAJOR, vfd->minor), | ||
1569 | S_IFCHR | S_IRUSR | S_IWUSR, vfd->devfs_name); | ||
1570 | mutex_init(&vfd->lock); | 1565 | mutex_init(&vfd->lock); |
1571 | 1566 | ||
1572 | /* sysfs class */ | 1567 | /* sysfs class */ |
@@ -1575,7 +1570,7 @@ int video_register_device(struct video_device *vfd, int type, int nr) | |||
1575 | vfd->class_dev.dev = vfd->dev; | 1570 | vfd->class_dev.dev = vfd->dev; |
1576 | vfd->class_dev.class = &video_class; | 1571 | vfd->class_dev.class = &video_class; |
1577 | vfd->class_dev.devt = MKDEV(VIDEO_MAJOR, vfd->minor); | 1572 | vfd->class_dev.devt = MKDEV(VIDEO_MAJOR, vfd->minor); |
1578 | strlcpy(vfd->class_dev.class_id, vfd->devfs_name + 4, BUS_ID_SIZE); | 1573 | sprintf(vfd->class_dev.class_id, "%s%d", name_base, i - base); |
1579 | class_device_register(&vfd->class_dev); | 1574 | class_device_register(&vfd->class_dev); |
1580 | class_device_create_file(&vfd->class_dev, | 1575 | class_device_create_file(&vfd->class_dev, |
1581 | &class_device_attr_name); | 1576 | &class_device_attr_name); |
@@ -1604,7 +1599,6 @@ void video_unregister_device(struct video_device *vfd) | |||
1604 | if(video_device[vfd->minor]!=vfd) | 1599 | if(video_device[vfd->minor]!=vfd) |
1605 | panic("videodev: bad unregister"); | 1600 | panic("videodev: bad unregister"); |
1606 | 1601 | ||
1607 | devfs_remove(vfd->devfs_name); | ||
1608 | video_device[vfd->minor]=NULL; | 1602 | video_device[vfd->minor]=NULL; |
1609 | class_device_unregister(&vfd->class_dev); | 1603 | class_device_unregister(&vfd->class_dev); |
1610 | mutex_unlock(&videodev_lock); | 1604 | mutex_unlock(&videodev_lock); |
diff --git a/drivers/message/fusion/mptfc.c b/drivers/message/fusion/mptfc.c index 74714e5bcf03..3ff8378ea660 100644 --- a/drivers/message/fusion/mptfc.c +++ b/drivers/message/fusion/mptfc.c | |||
@@ -305,10 +305,8 @@ mptfc_GetFcDevPage0(MPT_ADAPTER *ioc, int ioc_port, | |||
305 | } | 305 | } |
306 | 306 | ||
307 | out: | 307 | out: |
308 | if (pp0_array) | 308 | kfree(pp0_array); |
309 | kfree(pp0_array); | 309 | kfree(p0_array); |
310 | if (p0_array) | ||
311 | kfree(p0_array); | ||
312 | return rc; | 310 | return rc; |
313 | } | 311 | } |
314 | 312 | ||
diff --git a/drivers/message/fusion/mptsas.c b/drivers/message/fusion/mptsas.c index af6ec553ff7c..85689ab46cbc 100644 --- a/drivers/message/fusion/mptsas.c +++ b/drivers/message/fusion/mptsas.c | |||
@@ -1378,8 +1378,7 @@ mptsas_probe_hba_phys(MPT_ADAPTER *ioc) | |||
1378 | return 0; | 1378 | return 0; |
1379 | 1379 | ||
1380 | out_free_port_info: | 1380 | out_free_port_info: |
1381 | if (hba) | 1381 | kfree(hba); |
1382 | kfree(hba); | ||
1383 | out: | 1382 | out: |
1384 | return error; | 1383 | return error; |
1385 | } | 1384 | } |
diff --git a/drivers/message/i2o/i2o_block.c b/drivers/message/i2o/i2o_block.c index 7d4c5497785b..1ddc2fb429d5 100644 --- a/drivers/message/i2o/i2o_block.c +++ b/drivers/message/i2o/i2o_block.c | |||
@@ -1089,7 +1089,6 @@ static int i2o_block_probe(struct device *dev) | |||
1089 | gd = i2o_blk_dev->gd; | 1089 | gd = i2o_blk_dev->gd; |
1090 | gd->first_minor = unit << 4; | 1090 | gd->first_minor = unit << 4; |
1091 | sprintf(gd->disk_name, "i2o/hd%c", 'a' + unit); | 1091 | sprintf(gd->disk_name, "i2o/hd%c", 'a' + unit); |
1092 | sprintf(gd->devfs_name, "i2o/hd%c", 'a' + unit); | ||
1093 | gd->driverfs_dev = &i2o_dev->device; | 1092 | gd->driverfs_dev = &i2o_dev->device; |
1094 | 1093 | ||
1095 | /* setup request queue */ | 1094 | /* setup request queue */ |
diff --git a/drivers/message/i2o/iop.c b/drivers/message/i2o/iop.c index febbdd4e0605..3305c12372a2 100644 --- a/drivers/message/i2o/iop.c +++ b/drivers/message/i2o/iop.c | |||
@@ -683,9 +683,10 @@ static int i2o_iop_systab_set(struct i2o_controller *c) | |||
683 | c->mem_alloc = 1; | 683 | c->mem_alloc = 1; |
684 | sb->current_mem_size = 1 + res->end - res->start; | 684 | sb->current_mem_size = 1 + res->end - res->start; |
685 | sb->current_mem_base = res->start; | 685 | sb->current_mem_base = res->start; |
686 | osm_info("%s: allocated %ld bytes of PCI memory at " | 686 | osm_info("%s: allocated %llu bytes of PCI memory at " |
687 | "0x%08lX.\n", c->name, | 687 | "0x%016llX.\n", c->name, |
688 | 1 + res->end - res->start, res->start); | 688 | (unsigned long long)(1 + res->end - res->start), |
689 | (unsigned long long)res->start); | ||
689 | } | 690 | } |
690 | } | 691 | } |
691 | 692 | ||
@@ -704,9 +705,10 @@ static int i2o_iop_systab_set(struct i2o_controller *c) | |||
704 | c->io_alloc = 1; | 705 | c->io_alloc = 1; |
705 | sb->current_io_size = 1 + res->end - res->start; | 706 | sb->current_io_size = 1 + res->end - res->start; |
706 | sb->current_mem_base = res->start; | 707 | sb->current_mem_base = res->start; |
707 | osm_info("%s: allocated %ld bytes of PCI I/O at 0x%08lX" | 708 | osm_info("%s: allocated %llu bytes of PCI I/O at " |
708 | ".\n", c->name, 1 + res->end - res->start, | 709 | "0x%016llX.\n", c->name, |
709 | res->start); | 710 | (unsigned long long)(1 + res->end - res->start), |
711 | (unsigned long long)res->start); | ||
710 | } | 712 | } |
711 | } | 713 | } |
712 | 714 | ||
@@ -1239,7 +1241,6 @@ EXPORT_SYMBOL(i2o_cntxt_list_remove); | |||
1239 | EXPORT_SYMBOL(i2o_cntxt_list_get_ptr); | 1241 | EXPORT_SYMBOL(i2o_cntxt_list_get_ptr); |
1240 | #endif | 1242 | #endif |
1241 | EXPORT_SYMBOL(i2o_msg_get_wait); | 1243 | EXPORT_SYMBOL(i2o_msg_get_wait); |
1242 | EXPORT_SYMBOL(i2o_msg_nop); | ||
1243 | EXPORT_SYMBOL(i2o_find_iop); | 1244 | EXPORT_SYMBOL(i2o_find_iop); |
1244 | EXPORT_SYMBOL(i2o_iop_find_device); | 1245 | EXPORT_SYMBOL(i2o_iop_find_device); |
1245 | EXPORT_SYMBOL(i2o_event_register); | 1246 | EXPORT_SYMBOL(i2o_event_register); |
diff --git a/drivers/misc/ibmasm/module.c b/drivers/misc/ibmasm/module.c index 1fdf03fd2da7..9706cc19134a 100644 --- a/drivers/misc/ibmasm/module.c +++ b/drivers/misc/ibmasm/module.c | |||
@@ -85,7 +85,7 @@ static int __devinit ibmasm_init_one(struct pci_dev *pdev, const struct pci_devi | |||
85 | } | 85 | } |
86 | memset(sp, 0, sizeof(struct service_processor)); | 86 | memset(sp, 0, sizeof(struct service_processor)); |
87 | 87 | ||
88 | sp->lock = SPIN_LOCK_UNLOCKED; | 88 | spin_lock_init(&sp->lock); |
89 | INIT_LIST_HEAD(&sp->command_queue); | 89 | INIT_LIST_HEAD(&sp->command_queue); |
90 | 90 | ||
91 | pci_set_drvdata(pdev, (void *)sp); | 91 | pci_set_drvdata(pdev, (void *)sp); |
diff --git a/drivers/mmc/mmc_block.c b/drivers/mmc/mmc_block.c index 587458b370b9..115cc21094b9 100644 --- a/drivers/mmc/mmc_block.c +++ b/drivers/mmc/mmc_block.c | |||
@@ -27,7 +27,6 @@ | |||
27 | #include <linux/hdreg.h> | 27 | #include <linux/hdreg.h> |
28 | #include <linux/kdev_t.h> | 28 | #include <linux/kdev_t.h> |
29 | #include <linux/blkdev.h> | 29 | #include <linux/blkdev.h> |
30 | #include <linux/devfs_fs_kernel.h> | ||
31 | #include <linux/mutex.h> | 30 | #include <linux/mutex.h> |
32 | 31 | ||
33 | #include <linux/mmc/card.h> | 32 | #include <linux/mmc/card.h> |
@@ -409,7 +408,6 @@ static struct mmc_blk_data *mmc_blk_alloc(struct mmc_card *card) | |||
409 | */ | 408 | */ |
410 | 409 | ||
411 | sprintf(md->disk->disk_name, "mmcblk%d", devidx); | 410 | sprintf(md->disk->disk_name, "mmcblk%d", devidx); |
412 | sprintf(md->disk->devfs_name, "mmc/blk%d", devidx); | ||
413 | 411 | ||
414 | blk_queue_hardsect_size(md->queue.queue, 1 << md->block_bits); | 412 | blk_queue_hardsect_size(md->queue.queue, 1 << md->block_bits); |
415 | 413 | ||
@@ -555,7 +553,6 @@ static int __init mmc_blk_init(void) | |||
555 | if (major == 0) | 553 | if (major == 0) |
556 | major = res; | 554 | major = res; |
557 | 555 | ||
558 | devfs_mk_dir("mmc"); | ||
559 | return mmc_register_driver(&mmc_driver); | 556 | return mmc_register_driver(&mmc_driver); |
560 | 557 | ||
561 | out: | 558 | out: |
@@ -565,7 +562,6 @@ static int __init mmc_blk_init(void) | |||
565 | static void __exit mmc_blk_exit(void) | 562 | static void __exit mmc_blk_exit(void) |
566 | { | 563 | { |
567 | mmc_unregister_driver(&mmc_driver); | 564 | mmc_unregister_driver(&mmc_driver); |
568 | devfs_remove("mmc"); | ||
569 | unregister_blkdev(major, "mmc"); | 565 | unregister_blkdev(major, "mmc"); |
570 | } | 566 | } |
571 | 567 | ||
diff --git a/drivers/mmc/mmci.c b/drivers/mmc/mmci.c index da8e4d7339cc..8576a65ca1c3 100644 --- a/drivers/mmc/mmci.c +++ b/drivers/mmc/mmci.c | |||
@@ -546,9 +546,9 @@ static int mmci_probe(struct amba_device *dev, void *id) | |||
546 | 546 | ||
547 | mmc_add_host(mmc); | 547 | mmc_add_host(mmc); |
548 | 548 | ||
549 | printk(KERN_INFO "%s: MMCI rev %x cfg %02x at 0x%08lx irq %d,%d\n", | 549 | printk(KERN_INFO "%s: MMCI rev %x cfg %02x at 0x%016llx irq %d,%d\n", |
550 | mmc_hostname(mmc), amba_rev(dev), amba_config(dev), | 550 | mmc_hostname(mmc), amba_rev(dev), amba_config(dev), |
551 | dev->res.start, dev->irq[0], dev->irq[1]); | 551 | (unsigned long long)dev->res.start, dev->irq[0], dev->irq[1]); |
552 | 552 | ||
553 | init_timer(&host->timer); | 553 | init_timer(&host->timer); |
554 | host->timer.data = (unsigned long)host; | 554 | host->timer.data = (unsigned long)host; |
diff --git a/drivers/mtd/chips/cfi_cmdset_0001.c b/drivers/mtd/chips/cfi_cmdset_0001.c index 0d435814aaa1..39edb8250fbc 100644 --- a/drivers/mtd/chips/cfi_cmdset_0001.c +++ b/drivers/mtd/chips/cfi_cmdset_0001.c | |||
@@ -357,6 +357,7 @@ struct mtd_info *cfi_cmdset_0001(struct map_info *map, int primary) | |||
357 | mtd->resume = cfi_intelext_resume; | 357 | mtd->resume = cfi_intelext_resume; |
358 | mtd->flags = MTD_CAP_NORFLASH; | 358 | mtd->flags = MTD_CAP_NORFLASH; |
359 | mtd->name = map->name; | 359 | mtd->name = map->name; |
360 | mtd->writesize = 1; | ||
360 | 361 | ||
361 | mtd->reboot_notifier.notifier_call = cfi_intelext_reboot; | 362 | mtd->reboot_notifier.notifier_call = cfi_intelext_reboot; |
362 | 363 | ||
diff --git a/drivers/mtd/chips/jedec.c b/drivers/mtd/chips/jedec.c index c40b48dabed3..2c3f019197c1 100644 --- a/drivers/mtd/chips/jedec.c +++ b/drivers/mtd/chips/jedec.c | |||
@@ -256,6 +256,7 @@ static struct mtd_info *jedec_probe(struct map_info *map) | |||
256 | MTD->name = map->name; | 256 | MTD->name = map->name; |
257 | MTD->type = MTD_NORFLASH; | 257 | MTD->type = MTD_NORFLASH; |
258 | MTD->flags = MTD_CAP_NORFLASH; | 258 | MTD->flags = MTD_CAP_NORFLASH; |
259 | MTD->writesize = 1; | ||
259 | MTD->erasesize = SectorSize*(map->buswidth); | 260 | MTD->erasesize = SectorSize*(map->buswidth); |
260 | // printk("MTD->erasesize is %x\n",(unsigned int)MTD->erasesize); | 261 | // printk("MTD->erasesize is %x\n",(unsigned int)MTD->erasesize); |
261 | MTD->size = priv->size; | 262 | MTD->size = priv->size; |
diff --git a/drivers/mtd/chips/map_absent.c b/drivers/mtd/chips/map_absent.c index a611de9b1515..ac01a949b687 100644 --- a/drivers/mtd/chips/map_absent.c +++ b/drivers/mtd/chips/map_absent.c | |||
@@ -64,7 +64,8 @@ static struct mtd_info *map_absent_probe(struct map_info *map) | |||
64 | mtd->write = map_absent_write; | 64 | mtd->write = map_absent_write; |
65 | mtd->sync = map_absent_sync; | 65 | mtd->sync = map_absent_sync; |
66 | mtd->flags = 0; | 66 | mtd->flags = 0; |
67 | mtd->erasesize = PAGE_SIZE; | 67 | mtd->erasesize = PAGE_SIZE; |
68 | mtd->writesize = 1; | ||
68 | 69 | ||
69 | __module_get(THIS_MODULE); | 70 | __module_get(THIS_MODULE); |
70 | return mtd; | 71 | return mtd; |
diff --git a/drivers/mtd/chips/map_ram.c b/drivers/mtd/chips/map_ram.c index 763925747db6..3a66680abfd0 100644 --- a/drivers/mtd/chips/map_ram.c +++ b/drivers/mtd/chips/map_ram.c | |||
@@ -71,6 +71,7 @@ static struct mtd_info *map_ram_probe(struct map_info *map) | |||
71 | mtd->write = mapram_write; | 71 | mtd->write = mapram_write; |
72 | mtd->sync = mapram_nop; | 72 | mtd->sync = mapram_nop; |
73 | mtd->flags = MTD_CAP_RAM; | 73 | mtd->flags = MTD_CAP_RAM; |
74 | mtd->writesize = 1; | ||
74 | 75 | ||
75 | mtd->erasesize = PAGE_SIZE; | 76 | mtd->erasesize = PAGE_SIZE; |
76 | while(mtd->size & (mtd->erasesize - 1)) | 77 | while(mtd->size & (mtd->erasesize - 1)) |
diff --git a/drivers/mtd/chips/map_rom.c b/drivers/mtd/chips/map_rom.c index bc6ee9ef8a31..1b328b1378fd 100644 --- a/drivers/mtd/chips/map_rom.c +++ b/drivers/mtd/chips/map_rom.c | |||
@@ -47,6 +47,7 @@ static struct mtd_info *map_rom_probe(struct map_info *map) | |||
47 | mtd->sync = maprom_nop; | 47 | mtd->sync = maprom_nop; |
48 | mtd->flags = MTD_CAP_ROM; | 48 | mtd->flags = MTD_CAP_ROM; |
49 | mtd->erasesize = map->size; | 49 | mtd->erasesize = map->size; |
50 | mtd->writesize = 1; | ||
50 | 51 | ||
51 | __module_get(THIS_MODULE); | 52 | __module_get(THIS_MODULE); |
52 | return mtd; | 53 | return mtd; |
diff --git a/drivers/mtd/devices/block2mtd.c b/drivers/mtd/devices/block2mtd.c index 0d98c223c5fc..be3f1c136d02 100644 --- a/drivers/mtd/devices/block2mtd.c +++ b/drivers/mtd/devices/block2mtd.c | |||
@@ -324,6 +324,7 @@ static struct block2mtd_dev *add_device(char *devname, int erase_size) | |||
324 | 324 | ||
325 | dev->mtd.size = dev->blkdev->bd_inode->i_size & PAGE_MASK; | 325 | dev->mtd.size = dev->blkdev->bd_inode->i_size & PAGE_MASK; |
326 | dev->mtd.erasesize = erase_size; | 326 | dev->mtd.erasesize = erase_size; |
327 | dev->mtd.writesize = 1; | ||
327 | dev->mtd.type = MTD_RAM; | 328 | dev->mtd.type = MTD_RAM; |
328 | dev->mtd.flags = MTD_CAP_RAM; | 329 | dev->mtd.flags = MTD_CAP_RAM; |
329 | dev->mtd.erase = block2mtd_erase; | 330 | dev->mtd.erase = block2mtd_erase; |
diff --git a/drivers/mtd/devices/ms02-nv.c b/drivers/mtd/devices/ms02-nv.c index 4ab7670770e4..08dfb899b272 100644 --- a/drivers/mtd/devices/ms02-nv.c +++ b/drivers/mtd/devices/ms02-nv.c | |||
@@ -225,6 +225,7 @@ static int __init ms02nv_init_one(ulong addr) | |||
225 | mtd->owner = THIS_MODULE; | 225 | mtd->owner = THIS_MODULE; |
226 | mtd->read = ms02nv_read; | 226 | mtd->read = ms02nv_read; |
227 | mtd->write = ms02nv_write; | 227 | mtd->write = ms02nv_write; |
228 | mtd->writesize = 1; | ||
228 | 229 | ||
229 | ret = -EIO; | 230 | ret = -EIO; |
230 | if (add_mtd_device(mtd)) { | 231 | if (add_mtd_device(mtd)) { |
diff --git a/drivers/mtd/devices/mtd_dataflash.c b/drivers/mtd/devices/mtd_dataflash.c index a19480d07888..04271d02b6b6 100644 --- a/drivers/mtd/devices/mtd_dataflash.c +++ b/drivers/mtd/devices/mtd_dataflash.c | |||
@@ -478,6 +478,7 @@ add_dataflash(struct spi_device *spi, char *name, | |||
478 | device->name = (pdata && pdata->name) ? pdata->name : priv->name; | 478 | device->name = (pdata && pdata->name) ? pdata->name : priv->name; |
479 | device->size = nr_pages * pagesize; | 479 | device->size = nr_pages * pagesize; |
480 | device->erasesize = pagesize; | 480 | device->erasesize = pagesize; |
481 | device->writesize = pagesize; | ||
481 | device->owner = THIS_MODULE; | 482 | device->owner = THIS_MODULE; |
482 | device->type = MTD_DATAFLASH; | 483 | device->type = MTD_DATAFLASH; |
483 | device->flags = MTD_CAP_NORFLASH; | 484 | device->flags = MTD_CAP_NORFLASH; |
diff --git a/drivers/mtd/devices/phram.c b/drivers/mtd/devices/phram.c index e09e416667d3..6c7337f9ebbb 100644 --- a/drivers/mtd/devices/phram.c +++ b/drivers/mtd/devices/phram.c | |||
@@ -151,6 +151,7 @@ static int register_device(char *name, unsigned long start, unsigned long len) | |||
151 | new->mtd.owner = THIS_MODULE; | 151 | new->mtd.owner = THIS_MODULE; |
152 | new->mtd.type = MTD_RAM; | 152 | new->mtd.type = MTD_RAM; |
153 | new->mtd.erasesize = PAGE_SIZE; | 153 | new->mtd.erasesize = PAGE_SIZE; |
154 | new->mtd.writesize = 1; | ||
154 | 155 | ||
155 | ret = -EAGAIN; | 156 | ret = -EAGAIN; |
156 | if (add_mtd_device(&new->mtd)) { | 157 | if (add_mtd_device(&new->mtd)) { |
diff --git a/drivers/mtd/devices/pmc551.c b/drivers/mtd/devices/pmc551.c index 666cce1bf60c..30f07b473ae2 100644 --- a/drivers/mtd/devices/pmc551.c +++ b/drivers/mtd/devices/pmc551.c | |||
@@ -551,11 +551,11 @@ static u32 fixup_pmc551 (struct pci_dev *dev) | |||
551 | /* | 551 | /* |
552 | * Some screen fun | 552 | * Some screen fun |
553 | */ | 553 | */ |
554 | printk(KERN_DEBUG "pmc551: %d%c (0x%x) of %sprefetchable memory at 0x%lx\n", | 554 | printk(KERN_DEBUG "pmc551: %d%c (0x%x) of %sprefetchable memory at 0x%llx\n", |
555 | (size<1024)?size:(size<1048576)?size>>10:size>>20, | 555 | (size<1024)?size:(size<1048576)?size>>10:size>>20, |
556 | (size<1024)?'B':(size<1048576)?'K':'M', | 556 | (size<1024)?'B':(size<1048576)?'K':'M', |
557 | size, ((dcmd&(0x1<<3)) == 0)?"non-":"", | 557 | size, ((dcmd&(0x1<<3)) == 0)?"non-":"", |
558 | (dev->resource[0].start)&PCI_BASE_ADDRESS_MEM_MASK ); | 558 | (unsigned long long)((dev->resource[0].start)&PCI_BASE_ADDRESS_MEM_MASK)); |
559 | 559 | ||
560 | /* | 560 | /* |
561 | * Check to see the state of the memory | 561 | * Check to see the state of the memory |
@@ -685,8 +685,8 @@ static int __init init_pmc551(void) | |||
685 | break; | 685 | break; |
686 | } | 686 | } |
687 | 687 | ||
688 | printk(KERN_NOTICE "pmc551: Found PCI V370PDC at 0x%lX\n", | 688 | printk(KERN_NOTICE "pmc551: Found PCI V370PDC at 0x%llx\n", |
689 | PCI_Device->resource[0].start); | 689 | (unsigned long long)PCI_Device->resource[0].start); |
690 | 690 | ||
691 | /* | 691 | /* |
692 | * The PMC551 device acts VERY weird if you don't init it | 692 | * The PMC551 device acts VERY weird if you don't init it |
@@ -778,7 +778,8 @@ static int __init init_pmc551(void) | |||
778 | mtd->type = MTD_RAM; | 778 | mtd->type = MTD_RAM; |
779 | mtd->name = "PMC551 RAM board"; | 779 | mtd->name = "PMC551 RAM board"; |
780 | mtd->erasesize = 0x10000; | 780 | mtd->erasesize = 0x10000; |
781 | mtd->owner = THIS_MODULE; | 781 | mtd->writesize = 1; |
782 | mtd->owner = THIS_MODULE; | ||
782 | 783 | ||
783 | if (add_mtd_device(mtd)) { | 784 | if (add_mtd_device(mtd)) { |
784 | printk(KERN_NOTICE "pmc551: Failed to register new device\n"); | 785 | printk(KERN_NOTICE "pmc551: Failed to register new device\n"); |
diff --git a/drivers/mtd/devices/slram.c b/drivers/mtd/devices/slram.c index b3f665e3c38b..542a0c009006 100644 --- a/drivers/mtd/devices/slram.c +++ b/drivers/mtd/devices/slram.c | |||
@@ -209,6 +209,7 @@ static int register_device(char *name, unsigned long start, unsigned long length | |||
209 | (*curmtd)->mtdinfo->owner = THIS_MODULE; | 209 | (*curmtd)->mtdinfo->owner = THIS_MODULE; |
210 | (*curmtd)->mtdinfo->type = MTD_RAM; | 210 | (*curmtd)->mtdinfo->type = MTD_RAM; |
211 | (*curmtd)->mtdinfo->erasesize = SLRAM_BLK_SZ; | 211 | (*curmtd)->mtdinfo->erasesize = SLRAM_BLK_SZ; |
212 | (*curmtd)->mtdinfo->writesize = 1; | ||
212 | 213 | ||
213 | if (add_mtd_device((*curmtd)->mtdinfo)) { | 214 | if (add_mtd_device((*curmtd)->mtdinfo)) { |
214 | E("slram: Failed to register new device\n"); | 215 | E("slram: Failed to register new device\n"); |
diff --git a/drivers/mtd/maps/amd76xrom.c b/drivers/mtd/maps/amd76xrom.c index c350878d4592..a50587005263 100644 --- a/drivers/mtd/maps/amd76xrom.c +++ b/drivers/mtd/maps/amd76xrom.c | |||
@@ -123,9 +123,10 @@ static int __devinit amd76xrom_init_one (struct pci_dev *pdev, | |||
123 | window->rsrc.parent = NULL; | 123 | window->rsrc.parent = NULL; |
124 | printk(KERN_ERR MOD_NAME | 124 | printk(KERN_ERR MOD_NAME |
125 | " %s(): Unable to register resource" | 125 | " %s(): Unable to register resource" |
126 | " 0x%.08lx-0x%.08lx - kernel bug?\n", | 126 | " 0x%.16llx-0x%.16llx - kernel bug?\n", |
127 | __func__, | 127 | __func__, |
128 | window->rsrc.start, window->rsrc.end); | 128 | (unsigned long long)window->rsrc.start, |
129 | (unsigned long long)window->rsrc.end); | ||
129 | } | 130 | } |
130 | 131 | ||
131 | #if 0 | 132 | #if 0 |
diff --git a/drivers/mtd/maps/ichxrom.c b/drivers/mtd/maps/ichxrom.c index ea5073781b3a..16732794edf3 100644 --- a/drivers/mtd/maps/ichxrom.c +++ b/drivers/mtd/maps/ichxrom.c | |||
@@ -177,9 +177,10 @@ static int __devinit ichxrom_init_one (struct pci_dev *pdev, | |||
177 | window->rsrc.parent = NULL; | 177 | window->rsrc.parent = NULL; |
178 | printk(KERN_DEBUG MOD_NAME | 178 | printk(KERN_DEBUG MOD_NAME |
179 | ": %s(): Unable to register resource" | 179 | ": %s(): Unable to register resource" |
180 | " 0x%.08lx-0x%.08lx - kernel bug?\n", | 180 | " 0x%.16llx-0x%.16llx - kernel bug?\n", |
181 | __func__, | 181 | __func__, |
182 | window->rsrc.start, window->rsrc.end); | 182 | (unsigned long long)window->rsrc.start, |
183 | (unsigned long long)window->rsrc.end); | ||
183 | } | 184 | } |
184 | 185 | ||
185 | /* Map the firmware hub into my address space. */ | 186 | /* Map the firmware hub into my address space. */ |
diff --git a/drivers/mtd/maps/ixp2000.c b/drivers/mtd/maps/ixp2000.c index 2c9cc7f37e92..c26488a1793a 100644 --- a/drivers/mtd/maps/ixp2000.c +++ b/drivers/mtd/maps/ixp2000.c | |||
@@ -42,7 +42,6 @@ struct ixp2000_flash_info { | |||
42 | struct map_info map; | 42 | struct map_info map; |
43 | struct mtd_partition *partitions; | 43 | struct mtd_partition *partitions; |
44 | struct resource *res; | 44 | struct resource *res; |
45 | int nr_banks; | ||
46 | }; | 45 | }; |
47 | 46 | ||
48 | static inline unsigned long flash_bank_setup(struct map_info *map, unsigned long ofs) | 47 | static inline unsigned long flash_bank_setup(struct map_info *map, unsigned long ofs) |
@@ -183,7 +182,6 @@ static int ixp2000_flash_probe(struct platform_device *dev) | |||
183 | */ | 182 | */ |
184 | info->map.phys = NO_XIP; | 183 | info->map.phys = NO_XIP; |
185 | 184 | ||
186 | info->nr_banks = ixp_data->nr_banks; | ||
187 | info->map.size = ixp_data->nr_banks * window_size; | 185 | info->map.size = ixp_data->nr_banks * window_size; |
188 | info->map.bankwidth = 1; | 186 | info->map.bankwidth = 1; |
189 | 187 | ||
diff --git a/drivers/mtd/maps/physmap.c b/drivers/mtd/maps/physmap.c index 433c3cac3ca9..d6301f08906d 100644 --- a/drivers/mtd/maps/physmap.c +++ b/drivers/mtd/maps/physmap.c | |||
@@ -182,7 +182,7 @@ static struct physmap_flash_data physmap_flash_data = { | |||
182 | 182 | ||
183 | static struct resource physmap_flash_resource = { | 183 | static struct resource physmap_flash_resource = { |
184 | .start = CONFIG_MTD_PHYSMAP_START, | 184 | .start = CONFIG_MTD_PHYSMAP_START, |
185 | .end = CONFIG_MTD_PHYSMAP_START + CONFIG_MTD_PHYSMAP_LEN, | 185 | .end = CONFIG_MTD_PHYSMAP_START + CONFIG_MTD_PHYSMAP_LEN - 1, |
186 | .flags = IORESOURCE_MEM, | 186 | .flags = IORESOURCE_MEM, |
187 | }; | 187 | }; |
188 | 188 | ||
diff --git a/drivers/mtd/maps/scx200_docflash.c b/drivers/mtd/maps/scx200_docflash.c index 28b8a571a91a..331a15859d71 100644 --- a/drivers/mtd/maps/scx200_docflash.c +++ b/drivers/mtd/maps/scx200_docflash.c | |||
@@ -164,8 +164,9 @@ static int __init init_scx200_docflash(void) | |||
164 | outl(pmr, scx200_cb_base + SCx200_PMR); | 164 | outl(pmr, scx200_cb_base + SCx200_PMR); |
165 | } | 165 | } |
166 | 166 | ||
167 | printk(KERN_INFO NAME ": DOCCS mapped at 0x%lx-0x%lx, width %d\n", | 167 | printk(KERN_INFO NAME ": DOCCS mapped at 0x%llx-0x%llx, width %d\n", |
168 | docmem.start, docmem.end, width); | 168 | (unsigned long long)docmem.start, |
169 | (unsigned long long)docmem.end, width); | ||
169 | 170 | ||
170 | scx200_docflash_map.size = size; | 171 | scx200_docflash_map.size = size; |
171 | if (width == 8) | 172 | if (width == 8) |
diff --git a/drivers/mtd/maps/sun_uflash.c b/drivers/mtd/maps/sun_uflash.c index 24a03152d196..4db2055cee31 100644 --- a/drivers/mtd/maps/sun_uflash.c +++ b/drivers/mtd/maps/sun_uflash.c | |||
@@ -62,9 +62,10 @@ int uflash_devinit(struct linux_ebus_device *edev, struct device_node *dp) | |||
62 | /* Non-CFI userflash device-- once I find one we | 62 | /* Non-CFI userflash device-- once I find one we |
63 | * can work on supporting it. | 63 | * can work on supporting it. |
64 | */ | 64 | */ |
65 | printk("%s: unsupported device at 0x%lx (%d regs): " \ | 65 | printk("%s: unsupported device at 0x%llx (%d regs): " \ |
66 | "email ebrower@usa.net\n", | 66 | "email ebrower@usa.net\n", |
67 | dp->full_name, res->start, edev->num_addrs); | 67 | dp->full_name, (unsigned long long)res->start, |
68 | edev->num_addrs); | ||
68 | 69 | ||
69 | return -ENODEV; | 70 | return -ENODEV; |
70 | } | 71 | } |
diff --git a/drivers/mtd/mtdchar.c b/drivers/mtd/mtdchar.c index aa18d45b264b..9a4b59d92525 100644 --- a/drivers/mtd/mtdchar.c +++ b/drivers/mtd/mtdchar.c | |||
@@ -78,7 +78,7 @@ static loff_t mtd_lseek (struct file *file, loff_t offset, int orig) | |||
78 | return -EINVAL; | 78 | return -EINVAL; |
79 | } | 79 | } |
80 | 80 | ||
81 | if (offset >= 0 && offset < mtd->size) | 81 | if (offset >= 0 && offset <= mtd->size) |
82 | return file->f_pos = offset; | 82 | return file->f_pos = offset; |
83 | 83 | ||
84 | return -EINVAL; | 84 | return -EINVAL; |
diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c index 27083ed0a017..80a76654d963 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c | |||
@@ -1176,7 +1176,7 @@ static int nand_write_oob_std(struct mtd_info *mtd, struct nand_chip *chip, | |||
1176 | 1176 | ||
1177 | status = chip->waitfunc(mtd, chip); | 1177 | status = chip->waitfunc(mtd, chip); |
1178 | 1178 | ||
1179 | return status; | 1179 | return status & NAND_STATUS_FAIL ? -EIO : 0; |
1180 | } | 1180 | } |
1181 | 1181 | ||
1182 | /** | 1182 | /** |
@@ -1271,10 +1271,6 @@ static int nand_do_read_oob(struct mtd_info *mtd, loff_t from, | |||
1271 | sndcmd = chip->ecc.read_oob(mtd, chip, page, sndcmd); | 1271 | sndcmd = chip->ecc.read_oob(mtd, chip, page, sndcmd); |
1272 | buf = nand_transfer_oob(chip, buf, ops); | 1272 | buf = nand_transfer_oob(chip, buf, ops); |
1273 | 1273 | ||
1274 | readlen -= ops->ooblen; | ||
1275 | if (!readlen) | ||
1276 | break; | ||
1277 | |||
1278 | if (!(chip->options & NAND_NO_READRDY)) { | 1274 | if (!(chip->options & NAND_NO_READRDY)) { |
1279 | /* | 1275 | /* |
1280 | * Apply delay or wait for ready/busy pin. Do this | 1276 | * Apply delay or wait for ready/busy pin. Do this |
@@ -1288,6 +1284,10 @@ static int nand_do_read_oob(struct mtd_info *mtd, loff_t from, | |||
1288 | nand_wait_ready(mtd); | 1284 | nand_wait_ready(mtd); |
1289 | } | 1285 | } |
1290 | 1286 | ||
1287 | readlen -= ops->ooblen; | ||
1288 | if (!readlen) | ||
1289 | break; | ||
1290 | |||
1291 | /* Increment page address */ | 1291 | /* Increment page address */ |
1292 | realpage++; | 1292 | realpage++; |
1293 | 1293 | ||
@@ -1610,13 +1610,13 @@ static int nand_do_write_ops(struct mtd_info *mtd, loff_t to, | |||
1610 | if (!writelen) | 1610 | if (!writelen) |
1611 | return 0; | 1611 | return 0; |
1612 | 1612 | ||
1613 | chipnr = (int)(to >> chip->chip_shift); | ||
1614 | chip->select_chip(mtd, chipnr); | ||
1615 | |||
1613 | /* Check, if it is write protected */ | 1616 | /* Check, if it is write protected */ |
1614 | if (nand_check_wp(mtd)) | 1617 | if (nand_check_wp(mtd)) |
1615 | return -EIO; | 1618 | return -EIO; |
1616 | 1619 | ||
1617 | chipnr = (int)(to >> chip->chip_shift); | ||
1618 | chip->select_chip(mtd, chipnr); | ||
1619 | |||
1620 | realpage = (int)(to >> chip->page_shift); | 1620 | realpage = (int)(to >> chip->page_shift); |
1621 | page = realpage & chip->pagemask; | 1621 | page = realpage & chip->pagemask; |
1622 | blockmask = (1 << (chip->phys_erase_shift - chip->page_shift)) - 1; | 1622 | blockmask = (1 << (chip->phys_erase_shift - chip->page_shift)) - 1; |
diff --git a/drivers/mtd/nand/ndfc.c b/drivers/mtd/nand/ndfc.c index fe8d38514ba6..e5bd88f2d560 100644 --- a/drivers/mtd/nand/ndfc.c +++ b/drivers/mtd/nand/ndfc.c | |||
@@ -61,15 +61,15 @@ static void ndfc_select_chip(struct mtd_info *mtd, int chip) | |||
61 | 61 | ||
62 | static void ndfc_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl) | 62 | static void ndfc_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl) |
63 | { | 63 | { |
64 | struct nand_chip *chip = mtd->priv; | 64 | struct ndfc_controller *ndfc = &ndfc_ctrl; |
65 | 65 | ||
66 | if (cmd == NAND_CMD_NONE) | 66 | if (cmd == NAND_CMD_NONE) |
67 | return; | 67 | return; |
68 | 68 | ||
69 | if (ctrl & NAND_CLE) | 69 | if (ctrl & NAND_CLE) |
70 | writel(cmd & 0xFF, chip->IO_ADDR_W + NDFC_CMD); | 70 | writel(cmd & 0xFF, ndfc->ndfcbase + NDFC_CMD); |
71 | else | 71 | else |
72 | writel(cmd & 0xFF, chip->IO_ADDR_W + NDFC_ALE); | 72 | writel(cmd & 0xFF, ndfc->ndfcbase + NDFC_ALE); |
73 | } | 73 | } |
74 | 74 | ||
75 | static int ndfc_ready(struct mtd_info *mtd) | 75 | static int ndfc_ready(struct mtd_info *mtd) |
diff --git a/drivers/mtd/nand/s3c2410.c b/drivers/mtd/nand/s3c2410.c index 2c262fe03d8a..ff5cef24d5bb 100644 --- a/drivers/mtd/nand/s3c2410.c +++ b/drivers/mtd/nand/s3c2410.c | |||
@@ -63,8 +63,6 @@ | |||
63 | #include <asm/arch/regs-nand.h> | 63 | #include <asm/arch/regs-nand.h> |
64 | #include <asm/arch/nand.h> | 64 | #include <asm/arch/nand.h> |
65 | 65 | ||
66 | #define PFX "s3c2410-nand: " | ||
67 | |||
68 | #ifdef CONFIG_MTD_NAND_S3C2410_HWECC | 66 | #ifdef CONFIG_MTD_NAND_S3C2410_HWECC |
69 | static int hardware_ecc = 1; | 67 | static int hardware_ecc = 1; |
70 | #else | 68 | #else |
@@ -99,6 +97,12 @@ struct s3c2410_nand_mtd { | |||
99 | int scan_res; | 97 | int scan_res; |
100 | }; | 98 | }; |
101 | 99 | ||
100 | enum s3c_cpu_type { | ||
101 | TYPE_S3C2410, | ||
102 | TYPE_S3C2412, | ||
103 | TYPE_S3C2440, | ||
104 | }; | ||
105 | |||
102 | /* overview of the s3c2410 nand state */ | 106 | /* overview of the s3c2410 nand state */ |
103 | 107 | ||
104 | struct s3c2410_nand_info { | 108 | struct s3c2410_nand_info { |
@@ -112,9 +116,11 @@ struct s3c2410_nand_info { | |||
112 | struct resource *area; | 116 | struct resource *area; |
113 | struct clk *clk; | 117 | struct clk *clk; |
114 | void __iomem *regs; | 118 | void __iomem *regs; |
119 | void __iomem *sel_reg; | ||
120 | int sel_bit; | ||
115 | int mtd_count; | 121 | int mtd_count; |
116 | 122 | ||
117 | unsigned char is_s3c2440; | 123 | enum s3c_cpu_type cpu_type; |
118 | }; | 124 | }; |
119 | 125 | ||
120 | /* conversion functions */ | 126 | /* conversion functions */ |
@@ -148,7 +154,7 @@ static inline int allow_clk_stop(struct s3c2410_nand_info *info) | |||
148 | 154 | ||
149 | #define NS_IN_KHZ 1000000 | 155 | #define NS_IN_KHZ 1000000 |
150 | 156 | ||
151 | static int s3c2410_nand_calc_rate(int wanted, unsigned long clk, int max) | 157 | static int s3c_nand_calc_rate(int wanted, unsigned long clk, int max) |
152 | { | 158 | { |
153 | int result; | 159 | int result; |
154 | 160 | ||
@@ -172,53 +178,58 @@ static int s3c2410_nand_calc_rate(int wanted, unsigned long clk, int max) | |||
172 | 178 | ||
173 | /* controller setup */ | 179 | /* controller setup */ |
174 | 180 | ||
175 | static int s3c2410_nand_inithw(struct s3c2410_nand_info *info, struct platform_device *pdev) | 181 | static int s3c2410_nand_inithw(struct s3c2410_nand_info *info, |
182 | struct platform_device *pdev) | ||
176 | { | 183 | { |
177 | struct s3c2410_platform_nand *plat = to_nand_plat(pdev); | 184 | struct s3c2410_platform_nand *plat = to_nand_plat(pdev); |
178 | unsigned long clkrate = clk_get_rate(info->clk); | 185 | unsigned long clkrate = clk_get_rate(info->clk); |
186 | int tacls_max = (info->cpu_type == TYPE_S3C2412) ? 8 : 4; | ||
179 | int tacls, twrph0, twrph1; | 187 | int tacls, twrph0, twrph1; |
180 | unsigned long cfg; | 188 | unsigned long cfg = 0; |
181 | 189 | ||
182 | /* calculate the timing information for the controller */ | 190 | /* calculate the timing information for the controller */ |
183 | 191 | ||
184 | clkrate /= 1000; /* turn clock into kHz for ease of use */ | 192 | clkrate /= 1000; /* turn clock into kHz for ease of use */ |
185 | 193 | ||
186 | if (plat != NULL) { | 194 | if (plat != NULL) { |
187 | tacls = s3c2410_nand_calc_rate(plat->tacls, clkrate, 4); | 195 | tacls = s3c_nand_calc_rate(plat->tacls, clkrate, tacls_max); |
188 | twrph0 = s3c2410_nand_calc_rate(plat->twrph0, clkrate, 8); | 196 | twrph0 = s3c_nand_calc_rate(plat->twrph0, clkrate, 8); |
189 | twrph1 = s3c2410_nand_calc_rate(plat->twrph1, clkrate, 8); | 197 | twrph1 = s3c_nand_calc_rate(plat->twrph1, clkrate, 8); |
190 | } else { | 198 | } else { |
191 | /* default timings */ | 199 | /* default timings */ |
192 | tacls = 4; | 200 | tacls = tacls_max; |
193 | twrph0 = 8; | 201 | twrph0 = 8; |
194 | twrph1 = 8; | 202 | twrph1 = 8; |
195 | } | 203 | } |
196 | 204 | ||
197 | if (tacls < 0 || twrph0 < 0 || twrph1 < 0) { | 205 | if (tacls < 0 || twrph0 < 0 || twrph1 < 0) { |
198 | printk(KERN_ERR PFX "cannot get timings suitable for board\n"); | 206 | dev_err(info->device, "cannot get suitable timings\n"); |
199 | return -EINVAL; | 207 | return -EINVAL; |
200 | } | 208 | } |
201 | 209 | ||
202 | printk(KERN_INFO PFX "Tacls=%d, %dns Twrph0=%d %dns, Twrph1=%d %dns\n", | 210 | dev_info(info->device, "Tacls=%d, %dns Twrph0=%d %dns, Twrph1=%d %dns\n", |
203 | tacls, to_ns(tacls, clkrate), twrph0, to_ns(twrph0, clkrate), twrph1, to_ns(twrph1, clkrate)); | 211 | tacls, to_ns(tacls, clkrate), twrph0, to_ns(twrph0, clkrate), twrph1, to_ns(twrph1, clkrate)); |
204 | 212 | ||
205 | if (!info->is_s3c2440) { | 213 | switch (info->cpu_type) { |
214 | case TYPE_S3C2410: | ||
206 | cfg = S3C2410_NFCONF_EN; | 215 | cfg = S3C2410_NFCONF_EN; |
207 | cfg |= S3C2410_NFCONF_TACLS(tacls - 1); | 216 | cfg |= S3C2410_NFCONF_TACLS(tacls - 1); |
208 | cfg |= S3C2410_NFCONF_TWRPH0(twrph0 - 1); | 217 | cfg |= S3C2410_NFCONF_TWRPH0(twrph0 - 1); |
209 | cfg |= S3C2410_NFCONF_TWRPH1(twrph1 - 1); | 218 | cfg |= S3C2410_NFCONF_TWRPH1(twrph1 - 1); |
210 | } else { | 219 | break; |
220 | |||
221 | case TYPE_S3C2440: | ||
222 | case TYPE_S3C2412: | ||
211 | cfg = S3C2440_NFCONF_TACLS(tacls - 1); | 223 | cfg = S3C2440_NFCONF_TACLS(tacls - 1); |
212 | cfg |= S3C2440_NFCONF_TWRPH0(twrph0 - 1); | 224 | cfg |= S3C2440_NFCONF_TWRPH0(twrph0 - 1); |
213 | cfg |= S3C2440_NFCONF_TWRPH1(twrph1 - 1); | 225 | cfg |= S3C2440_NFCONF_TWRPH1(twrph1 - 1); |
214 | 226 | ||
215 | /* enable the controller and de-assert nFCE */ | 227 | /* enable the controller and de-assert nFCE */ |
216 | 228 | ||
217 | writel(S3C2440_NFCONT_ENABLE | S3C2440_NFCONT_ENABLE, | 229 | writel(S3C2440_NFCONT_ENABLE, info->regs + S3C2440_NFCONT); |
218 | info->regs + S3C2440_NFCONT); | ||
219 | } | 230 | } |
220 | 231 | ||
221 | pr_debug(PFX "NF_CONF is 0x%lx\n", cfg); | 232 | dev_dbg(info->device, "NF_CONF is 0x%lx\n", cfg); |
222 | 233 | ||
223 | writel(cfg, info->regs + S3C2410_NFCONF); | 234 | writel(cfg, info->regs + S3C2410_NFCONF); |
224 | return 0; | 235 | return 0; |
@@ -231,26 +242,21 @@ static void s3c2410_nand_select_chip(struct mtd_info *mtd, int chip) | |||
231 | struct s3c2410_nand_info *info; | 242 | struct s3c2410_nand_info *info; |
232 | struct s3c2410_nand_mtd *nmtd; | 243 | struct s3c2410_nand_mtd *nmtd; |
233 | struct nand_chip *this = mtd->priv; | 244 | struct nand_chip *this = mtd->priv; |
234 | void __iomem *reg; | ||
235 | unsigned long cur; | 245 | unsigned long cur; |
236 | unsigned long bit; | ||
237 | 246 | ||
238 | nmtd = this->priv; | 247 | nmtd = this->priv; |
239 | info = nmtd->info; | 248 | info = nmtd->info; |
240 | 249 | ||
241 | bit = (info->is_s3c2440) ? S3C2440_NFCONT_nFCE : S3C2410_NFCONF_nFCE; | ||
242 | reg = info->regs + ((info->is_s3c2440) ? S3C2440_NFCONT : S3C2410_NFCONF); | ||
243 | |||
244 | if (chip != -1 && allow_clk_stop(info)) | 250 | if (chip != -1 && allow_clk_stop(info)) |
245 | clk_enable(info->clk); | 251 | clk_enable(info->clk); |
246 | 252 | ||
247 | cur = readl(reg); | 253 | cur = readl(info->sel_reg); |
248 | 254 | ||
249 | if (chip == -1) { | 255 | if (chip == -1) { |
250 | cur |= bit; | 256 | cur |= info->sel_bit; |
251 | } else { | 257 | } else { |
252 | if (nmtd->set != NULL && chip > nmtd->set->nr_chips) { | 258 | if (nmtd->set != NULL && chip > nmtd->set->nr_chips) { |
253 | printk(KERN_ERR PFX "chip %d out of range\n", chip); | 259 | dev_err(info->device, "invalid chip %d\n", chip); |
254 | return; | 260 | return; |
255 | } | 261 | } |
256 | 262 | ||
@@ -259,10 +265,10 @@ static void s3c2410_nand_select_chip(struct mtd_info *mtd, int chip) | |||
259 | (info->platform->select_chip) (nmtd->set, chip); | 265 | (info->platform->select_chip) (nmtd->set, chip); |
260 | } | 266 | } |
261 | 267 | ||
262 | cur &= ~bit; | 268 | cur &= ~info->sel_bit; |
263 | } | 269 | } |
264 | 270 | ||
265 | writel(cur, reg); | 271 | writel(cur, info->sel_reg); |
266 | 272 | ||
267 | if (chip == -1 && allow_clk_stop(info)) | 273 | if (chip == -1 && allow_clk_stop(info)) |
268 | clk_disable(info->clk); | 274 | clk_disable(info->clk); |
@@ -311,15 +317,25 @@ static void s3c2440_nand_hwcontrol(struct mtd_info *mtd, int cmd, | |||
311 | static int s3c2410_nand_devready(struct mtd_info *mtd) | 317 | static int s3c2410_nand_devready(struct mtd_info *mtd) |
312 | { | 318 | { |
313 | struct s3c2410_nand_info *info = s3c2410_nand_mtd_toinfo(mtd); | 319 | struct s3c2410_nand_info *info = s3c2410_nand_mtd_toinfo(mtd); |
314 | |||
315 | if (info->is_s3c2440) | ||
316 | return readb(info->regs + S3C2440_NFSTAT) & S3C2440_NFSTAT_READY; | ||
317 | return readb(info->regs + S3C2410_NFSTAT) & S3C2410_NFSTAT_BUSY; | 320 | return readb(info->regs + S3C2410_NFSTAT) & S3C2410_NFSTAT_BUSY; |
318 | } | 321 | } |
319 | 322 | ||
323 | static int s3c2440_nand_devready(struct mtd_info *mtd) | ||
324 | { | ||
325 | struct s3c2410_nand_info *info = s3c2410_nand_mtd_toinfo(mtd); | ||
326 | return readb(info->regs + S3C2440_NFSTAT) & S3C2440_NFSTAT_READY; | ||
327 | } | ||
328 | |||
329 | static int s3c2412_nand_devready(struct mtd_info *mtd) | ||
330 | { | ||
331 | struct s3c2410_nand_info *info = s3c2410_nand_mtd_toinfo(mtd); | ||
332 | return readb(info->regs + S3C2412_NFSTAT) & S3C2412_NFSTAT_READY; | ||
333 | } | ||
334 | |||
320 | /* ECC handling functions */ | 335 | /* ECC handling functions */ |
321 | 336 | ||
322 | static int s3c2410_nand_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_ecc, u_char *calc_ecc) | 337 | static int s3c2410_nand_correct_data(struct mtd_info *mtd, u_char *dat, |
338 | u_char *read_ecc, u_char *calc_ecc) | ||
323 | { | 339 | { |
324 | pr_debug("s3c2410_nand_correct_data(%p,%p,%p,%p)\n", mtd, dat, read_ecc, calc_ecc); | 340 | pr_debug("s3c2410_nand_correct_data(%p,%p,%p,%p)\n", mtd, dat, read_ecc, calc_ecc); |
325 | 341 | ||
@@ -487,11 +503,8 @@ static void s3c2410_nand_init_chip(struct s3c2410_nand_info *info, | |||
487 | struct s3c2410_nand_set *set) | 503 | struct s3c2410_nand_set *set) |
488 | { | 504 | { |
489 | struct nand_chip *chip = &nmtd->chip; | 505 | struct nand_chip *chip = &nmtd->chip; |
506 | void __iomem *regs = info->regs; | ||
490 | 507 | ||
491 | chip->IO_ADDR_R = info->regs + S3C2410_NFDATA; | ||
492 | chip->IO_ADDR_W = info->regs + S3C2410_NFDATA; | ||
493 | chip->cmd_ctrl = s3c2410_nand_hwcontrol; | ||
494 | chip->dev_ready = s3c2410_nand_devready; | ||
495 | chip->write_buf = s3c2410_nand_write_buf; | 508 | chip->write_buf = s3c2410_nand_write_buf; |
496 | chip->read_buf = s3c2410_nand_read_buf; | 509 | chip->read_buf = s3c2410_nand_read_buf; |
497 | chip->select_chip = s3c2410_nand_select_chip; | 510 | chip->select_chip = s3c2410_nand_select_chip; |
@@ -500,11 +513,37 @@ static void s3c2410_nand_init_chip(struct s3c2410_nand_info *info, | |||
500 | chip->options = 0; | 513 | chip->options = 0; |
501 | chip->controller = &info->controller; | 514 | chip->controller = &info->controller; |
502 | 515 | ||
503 | if (info->is_s3c2440) { | 516 | switch (info->cpu_type) { |
504 | chip->IO_ADDR_R = info->regs + S3C2440_NFDATA; | 517 | case TYPE_S3C2410: |
505 | chip->IO_ADDR_W = info->regs + S3C2440_NFDATA; | 518 | chip->IO_ADDR_W = regs + S3C2410_NFDATA; |
506 | chip->cmd_ctrl = s3c2440_nand_hwcontrol; | 519 | info->sel_reg = regs + S3C2410_NFCONF; |
507 | } | 520 | info->sel_bit = S3C2410_NFCONF_nFCE; |
521 | chip->cmd_ctrl = s3c2410_nand_hwcontrol; | ||
522 | chip->dev_ready = s3c2410_nand_devready; | ||
523 | break; | ||
524 | |||
525 | case TYPE_S3C2440: | ||
526 | chip->IO_ADDR_W = regs + S3C2440_NFDATA; | ||
527 | info->sel_reg = regs + S3C2440_NFCONT; | ||
528 | info->sel_bit = S3C2440_NFCONT_nFCE; | ||
529 | chip->cmd_ctrl = s3c2440_nand_hwcontrol; | ||
530 | chip->dev_ready = s3c2440_nand_devready; | ||
531 | break; | ||
532 | |||
533 | case TYPE_S3C2412: | ||
534 | chip->IO_ADDR_W = regs + S3C2440_NFDATA; | ||
535 | info->sel_reg = regs + S3C2440_NFCONT; | ||
536 | info->sel_bit = S3C2412_NFCONT_nFCE0; | ||
537 | chip->cmd_ctrl = s3c2440_nand_hwcontrol; | ||
538 | chip->dev_ready = s3c2412_nand_devready; | ||
539 | |||
540 | if (readl(regs + S3C2410_NFCONF) & S3C2412_NFCONF_NANDBOOT) | ||
541 | dev_info(info->device, "System booted from NAND\n"); | ||
542 | |||
543 | break; | ||
544 | } | ||
545 | |||
546 | chip->IO_ADDR_R = chip->IO_ADDR_W; | ||
508 | 547 | ||
509 | nmtd->info = info; | 548 | nmtd->info = info; |
510 | nmtd->mtd.priv = chip; | 549 | nmtd->mtd.priv = chip; |
@@ -512,17 +551,25 @@ static void s3c2410_nand_init_chip(struct s3c2410_nand_info *info, | |||
512 | nmtd->set = set; | 551 | nmtd->set = set; |
513 | 552 | ||
514 | if (hardware_ecc) { | 553 | if (hardware_ecc) { |
515 | chip->ecc.correct = s3c2410_nand_correct_data; | ||
516 | chip->ecc.hwctl = s3c2410_nand_enable_hwecc; | ||
517 | chip->ecc.calculate = s3c2410_nand_calculate_ecc; | 554 | chip->ecc.calculate = s3c2410_nand_calculate_ecc; |
555 | chip->ecc.correct = s3c2410_nand_correct_data; | ||
518 | chip->ecc.mode = NAND_ECC_HW; | 556 | chip->ecc.mode = NAND_ECC_HW; |
519 | chip->ecc.size = 512; | 557 | chip->ecc.size = 512; |
520 | chip->ecc.bytes = 3; | 558 | chip->ecc.bytes = 3; |
521 | chip->ecc.layout = &nand_hw_eccoob; | 559 | chip->ecc.layout = &nand_hw_eccoob; |
522 | 560 | ||
523 | if (info->is_s3c2440) { | 561 | switch (info->cpu_type) { |
524 | chip->ecc.hwctl = s3c2440_nand_enable_hwecc; | 562 | case TYPE_S3C2410: |
525 | chip->ecc.calculate = s3c2440_nand_calculate_ecc; | 563 | chip->ecc.hwctl = s3c2410_nand_enable_hwecc; |
564 | chip->ecc.calculate = s3c2410_nand_calculate_ecc; | ||
565 | break; | ||
566 | |||
567 | case TYPE_S3C2412: | ||
568 | case TYPE_S3C2440: | ||
569 | chip->ecc.hwctl = s3c2440_nand_enable_hwecc; | ||
570 | chip->ecc.calculate = s3c2440_nand_calculate_ecc; | ||
571 | break; | ||
572 | |||
526 | } | 573 | } |
527 | } else { | 574 | } else { |
528 | chip->ecc.mode = NAND_ECC_SOFT; | 575 | chip->ecc.mode = NAND_ECC_SOFT; |
@@ -537,7 +584,8 @@ static void s3c2410_nand_init_chip(struct s3c2410_nand_info *info, | |||
537 | * nand layer to look for devices | 584 | * nand layer to look for devices |
538 | */ | 585 | */ |
539 | 586 | ||
540 | static int s3c24xx_nand_probe(struct platform_device *pdev, int is_s3c2440) | 587 | static int s3c24xx_nand_probe(struct platform_device *pdev, |
588 | enum s3c_cpu_type cpu_type) | ||
541 | { | 589 | { |
542 | struct s3c2410_platform_nand *plat = to_nand_plat(pdev); | 590 | struct s3c2410_platform_nand *plat = to_nand_plat(pdev); |
543 | struct s3c2410_nand_info *info; | 591 | struct s3c2410_nand_info *info; |
@@ -592,7 +640,7 @@ static int s3c24xx_nand_probe(struct platform_device *pdev, int is_s3c2440) | |||
592 | info->device = &pdev->dev; | 640 | info->device = &pdev->dev; |
593 | info->platform = plat; | 641 | info->platform = plat; |
594 | info->regs = ioremap(res->start, size); | 642 | info->regs = ioremap(res->start, size); |
595 | info->is_s3c2440 = is_s3c2440; | 643 | info->cpu_type = cpu_type; |
596 | 644 | ||
597 | if (info->regs == NULL) { | 645 | if (info->regs == NULL) { |
598 | dev_err(&pdev->dev, "cannot reserve register region\n"); | 646 | dev_err(&pdev->dev, "cannot reserve register region\n"); |
@@ -699,12 +747,17 @@ static int s3c24xx_nand_resume(struct platform_device *dev) | |||
699 | 747 | ||
700 | static int s3c2410_nand_probe(struct platform_device *dev) | 748 | static int s3c2410_nand_probe(struct platform_device *dev) |
701 | { | 749 | { |
702 | return s3c24xx_nand_probe(dev, 0); | 750 | return s3c24xx_nand_probe(dev, TYPE_S3C2410); |
703 | } | 751 | } |
704 | 752 | ||
705 | static int s3c2440_nand_probe(struct platform_device *dev) | 753 | static int s3c2440_nand_probe(struct platform_device *dev) |
706 | { | 754 | { |
707 | return s3c24xx_nand_probe(dev, 1); | 755 | return s3c24xx_nand_probe(dev, TYPE_S3C2440); |
756 | } | ||
757 | |||
758 | static int s3c2412_nand_probe(struct platform_device *dev) | ||
759 | { | ||
760 | return s3c24xx_nand_probe(dev, TYPE_S3C2412); | ||
708 | } | 761 | } |
709 | 762 | ||
710 | static struct platform_driver s3c2410_nand_driver = { | 763 | static struct platform_driver s3c2410_nand_driver = { |
@@ -729,16 +782,29 @@ static struct platform_driver s3c2440_nand_driver = { | |||
729 | }, | 782 | }, |
730 | }; | 783 | }; |
731 | 784 | ||
785 | static struct platform_driver s3c2412_nand_driver = { | ||
786 | .probe = s3c2412_nand_probe, | ||
787 | .remove = s3c2410_nand_remove, | ||
788 | .suspend = s3c24xx_nand_suspend, | ||
789 | .resume = s3c24xx_nand_resume, | ||
790 | .driver = { | ||
791 | .name = "s3c2412-nand", | ||
792 | .owner = THIS_MODULE, | ||
793 | }, | ||
794 | }; | ||
795 | |||
732 | static int __init s3c2410_nand_init(void) | 796 | static int __init s3c2410_nand_init(void) |
733 | { | 797 | { |
734 | printk("S3C24XX NAND Driver, (c) 2004 Simtec Electronics\n"); | 798 | printk("S3C24XX NAND Driver, (c) 2004 Simtec Electronics\n"); |
735 | 799 | ||
800 | platform_driver_register(&s3c2412_nand_driver); | ||
736 | platform_driver_register(&s3c2440_nand_driver); | 801 | platform_driver_register(&s3c2440_nand_driver); |
737 | return platform_driver_register(&s3c2410_nand_driver); | 802 | return platform_driver_register(&s3c2410_nand_driver); |
738 | } | 803 | } |
739 | 804 | ||
740 | static void __exit s3c2410_nand_exit(void) | 805 | static void __exit s3c2410_nand_exit(void) |
741 | { | 806 | { |
807 | platform_driver_unregister(&s3c2412_nand_driver); | ||
742 | platform_driver_unregister(&s3c2440_nand_driver); | 808 | platform_driver_unregister(&s3c2440_nand_driver); |
743 | platform_driver_unregister(&s3c2410_nand_driver); | 809 | platform_driver_unregister(&s3c2410_nand_driver); |
744 | } | 810 | } |
diff --git a/drivers/mtd/nand/ts7250.c b/drivers/mtd/nand/ts7250.c index a0b4b1edcb0d..f40081069ab2 100644 --- a/drivers/mtd/nand/ts7250.c +++ b/drivers/mtd/nand/ts7250.c | |||
@@ -97,7 +97,7 @@ static void ts7250_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl) | |||
97 | unsigned long addr = TS72XX_NAND_CONTROL_VIRT_BASE; | 97 | unsigned long addr = TS72XX_NAND_CONTROL_VIRT_BASE; |
98 | unsigned char bits; | 98 | unsigned char bits; |
99 | 99 | ||
100 | bits = (ctrl & NAND_CNE) << 2; | 100 | bits = (ctrl & NAND_NCE) << 2; |
101 | bits |= ctrl & NAND_CLE; | 101 | bits |= ctrl & NAND_CLE; |
102 | bits |= (ctrl & NAND_ALE) >> 2; | 102 | bits |= (ctrl & NAND_ALE) >> 2; |
103 | 103 | ||
diff --git a/drivers/net/3c59x.c b/drivers/net/3c59x.c index e27778926eba..d2f808979a2b 100644 --- a/drivers/net/3c59x.c +++ b/drivers/net/3c59x.c | |||
@@ -375,8 +375,7 @@ limit of 4K. | |||
375 | of the drivers, and will likely be provided by some future kernel. | 375 | of the drivers, and will likely be provided by some future kernel. |
376 | */ | 376 | */ |
377 | enum pci_flags_bit { | 377 | enum pci_flags_bit { |
378 | PCI_USES_IO=1, PCI_USES_MEM=2, PCI_USES_MASTER=4, | 378 | PCI_USES_MASTER=4, |
379 | PCI_ADDR0=0x10<<0, PCI_ADDR1=0x10<<1, PCI_ADDR2=0x10<<2, PCI_ADDR3=0x10<<3, | ||
380 | }; | 379 | }; |
381 | 380 | ||
382 | enum { IS_VORTEX=1, IS_BOOMERANG=2, IS_CYCLONE=4, IS_TORNADO=8, | 381 | enum { IS_VORTEX=1, IS_BOOMERANG=2, IS_CYCLONE=4, IS_TORNADO=8, |
@@ -446,95 +445,95 @@ static struct vortex_chip_info { | |||
446 | int io_size; | 445 | int io_size; |
447 | } vortex_info_tbl[] __devinitdata = { | 446 | } vortex_info_tbl[] __devinitdata = { |
448 | {"3c590 Vortex 10Mbps", | 447 | {"3c590 Vortex 10Mbps", |
449 | PCI_USES_IO|PCI_USES_MASTER, IS_VORTEX, 32, }, | 448 | PCI_USES_MASTER, IS_VORTEX, 32, }, |
450 | {"3c592 EISA 10Mbps Demon/Vortex", /* AKPM: from Don's 3c59x_cb.c 0.49H */ | 449 | {"3c592 EISA 10Mbps Demon/Vortex", /* AKPM: from Don's 3c59x_cb.c 0.49H */ |
451 | PCI_USES_IO|PCI_USES_MASTER, IS_VORTEX, 32, }, | 450 | PCI_USES_MASTER, IS_VORTEX, 32, }, |
452 | {"3c597 EISA Fast Demon/Vortex", /* AKPM: from Don's 3c59x_cb.c 0.49H */ | 451 | {"3c597 EISA Fast Demon/Vortex", /* AKPM: from Don's 3c59x_cb.c 0.49H */ |
453 | PCI_USES_IO|PCI_USES_MASTER, IS_VORTEX, 32, }, | 452 | PCI_USES_MASTER, IS_VORTEX, 32, }, |
454 | {"3c595 Vortex 100baseTx", | 453 | {"3c595 Vortex 100baseTx", |
455 | PCI_USES_IO|PCI_USES_MASTER, IS_VORTEX, 32, }, | 454 | PCI_USES_MASTER, IS_VORTEX, 32, }, |
456 | {"3c595 Vortex 100baseT4", | 455 | {"3c595 Vortex 100baseT4", |
457 | PCI_USES_IO|PCI_USES_MASTER, IS_VORTEX, 32, }, | 456 | PCI_USES_MASTER, IS_VORTEX, 32, }, |
458 | 457 | ||
459 | {"3c595 Vortex 100base-MII", | 458 | {"3c595 Vortex 100base-MII", |
460 | PCI_USES_IO|PCI_USES_MASTER, IS_VORTEX, 32, }, | 459 | PCI_USES_MASTER, IS_VORTEX, 32, }, |
461 | {"3c900 Boomerang 10baseT", | 460 | {"3c900 Boomerang 10baseT", |
462 | PCI_USES_IO|PCI_USES_MASTER, IS_BOOMERANG|EEPROM_RESET, 64, }, | 461 | PCI_USES_MASTER, IS_BOOMERANG|EEPROM_RESET, 64, }, |
463 | {"3c900 Boomerang 10Mbps Combo", | 462 | {"3c900 Boomerang 10Mbps Combo", |
464 | PCI_USES_IO|PCI_USES_MASTER, IS_BOOMERANG|EEPROM_RESET, 64, }, | 463 | PCI_USES_MASTER, IS_BOOMERANG|EEPROM_RESET, 64, }, |
465 | {"3c900 Cyclone 10Mbps TPO", /* AKPM: from Don's 0.99M */ | 464 | {"3c900 Cyclone 10Mbps TPO", /* AKPM: from Don's 0.99M */ |
466 | PCI_USES_IO|PCI_USES_MASTER, IS_CYCLONE|HAS_HWCKSM, 128, }, | 465 | PCI_USES_MASTER, IS_CYCLONE|HAS_HWCKSM, 128, }, |
467 | {"3c900 Cyclone 10Mbps Combo", | 466 | {"3c900 Cyclone 10Mbps Combo", |
468 | PCI_USES_IO|PCI_USES_MASTER, IS_CYCLONE|HAS_HWCKSM, 128, }, | 467 | PCI_USES_MASTER, IS_CYCLONE|HAS_HWCKSM, 128, }, |
469 | 468 | ||
470 | {"3c900 Cyclone 10Mbps TPC", /* AKPM: from Don's 0.99M */ | 469 | {"3c900 Cyclone 10Mbps TPC", /* AKPM: from Don's 0.99M */ |
471 | PCI_USES_IO|PCI_USES_MASTER, IS_CYCLONE|HAS_HWCKSM, 128, }, | 470 | PCI_USES_MASTER, IS_CYCLONE|HAS_HWCKSM, 128, }, |
472 | {"3c900B-FL Cyclone 10base-FL", | 471 | {"3c900B-FL Cyclone 10base-FL", |
473 | PCI_USES_IO|PCI_USES_MASTER, IS_CYCLONE|HAS_HWCKSM, 128, }, | 472 | PCI_USES_MASTER, IS_CYCLONE|HAS_HWCKSM, 128, }, |
474 | {"3c905 Boomerang 100baseTx", | 473 | {"3c905 Boomerang 100baseTx", |
475 | PCI_USES_IO|PCI_USES_MASTER, IS_BOOMERANG|HAS_MII|EEPROM_RESET, 64, }, | 474 | PCI_USES_MASTER, IS_BOOMERANG|HAS_MII|EEPROM_RESET, 64, }, |
476 | {"3c905 Boomerang 100baseT4", | 475 | {"3c905 Boomerang 100baseT4", |
477 | PCI_USES_IO|PCI_USES_MASTER, IS_BOOMERANG|HAS_MII|EEPROM_RESET, 64, }, | 476 | PCI_USES_MASTER, IS_BOOMERANG|HAS_MII|EEPROM_RESET, 64, }, |
478 | {"3c905B Cyclone 100baseTx", | 477 | {"3c905B Cyclone 100baseTx", |
479 | PCI_USES_IO|PCI_USES_MASTER, IS_CYCLONE|HAS_NWAY|HAS_HWCKSM|EXTRA_PREAMBLE, 128, }, | 478 | PCI_USES_MASTER, IS_CYCLONE|HAS_NWAY|HAS_HWCKSM|EXTRA_PREAMBLE, 128, }, |
480 | 479 | ||
481 | {"3c905B Cyclone 10/100/BNC", | 480 | {"3c905B Cyclone 10/100/BNC", |
482 | PCI_USES_IO|PCI_USES_MASTER, IS_CYCLONE|HAS_NWAY|HAS_HWCKSM, 128, }, | 481 | PCI_USES_MASTER, IS_CYCLONE|HAS_NWAY|HAS_HWCKSM, 128, }, |
483 | {"3c905B-FX Cyclone 100baseFx", | 482 | {"3c905B-FX Cyclone 100baseFx", |
484 | PCI_USES_IO|PCI_USES_MASTER, IS_CYCLONE|HAS_HWCKSM, 128, }, | 483 | PCI_USES_MASTER, IS_CYCLONE|HAS_HWCKSM, 128, }, |
485 | {"3c905C Tornado", | 484 | {"3c905C Tornado", |
486 | PCI_USES_IO|PCI_USES_MASTER, IS_TORNADO|HAS_NWAY|HAS_HWCKSM|EXTRA_PREAMBLE, 128, }, | 485 | PCI_USES_MASTER, IS_TORNADO|HAS_NWAY|HAS_HWCKSM|EXTRA_PREAMBLE, 128, }, |
487 | {"3c920B-EMB-WNM (ATI Radeon 9100 IGP)", | 486 | {"3c920B-EMB-WNM (ATI Radeon 9100 IGP)", |
488 | PCI_USES_IO|PCI_USES_MASTER, IS_TORNADO|HAS_MII|HAS_HWCKSM, 128, }, | 487 | PCI_USES_MASTER, IS_TORNADO|HAS_MII|HAS_HWCKSM, 128, }, |
489 | {"3c980 Cyclone", | 488 | {"3c980 Cyclone", |
490 | PCI_USES_IO|PCI_USES_MASTER, IS_CYCLONE|HAS_HWCKSM, 128, }, | 489 | PCI_USES_MASTER, IS_CYCLONE|HAS_HWCKSM, 128, }, |
491 | 490 | ||
492 | {"3c980C Python-T", | 491 | {"3c980C Python-T", |
493 | PCI_USES_IO|PCI_USES_MASTER, IS_CYCLONE|HAS_NWAY|HAS_HWCKSM, 128, }, | 492 | PCI_USES_MASTER, IS_CYCLONE|HAS_NWAY|HAS_HWCKSM, 128, }, |
494 | {"3cSOHO100-TX Hurricane", | 493 | {"3cSOHO100-TX Hurricane", |
495 | PCI_USES_IO|PCI_USES_MASTER, IS_CYCLONE|HAS_NWAY|HAS_HWCKSM, 128, }, | 494 | PCI_USES_MASTER, IS_CYCLONE|HAS_NWAY|HAS_HWCKSM, 128, }, |
496 | {"3c555 Laptop Hurricane", | 495 | {"3c555 Laptop Hurricane", |
497 | PCI_USES_IO|PCI_USES_MASTER, IS_CYCLONE|EEPROM_8BIT|HAS_HWCKSM, 128, }, | 496 | PCI_USES_MASTER, IS_CYCLONE|EEPROM_8BIT|HAS_HWCKSM, 128, }, |
498 | {"3c556 Laptop Tornado", | 497 | {"3c556 Laptop Tornado", |
499 | PCI_USES_IO|PCI_USES_MASTER, IS_TORNADO|HAS_NWAY|EEPROM_8BIT|HAS_CB_FNS|INVERT_MII_PWR| | 498 | PCI_USES_MASTER, IS_TORNADO|HAS_NWAY|EEPROM_8BIT|HAS_CB_FNS|INVERT_MII_PWR| |
500 | HAS_HWCKSM, 128, }, | 499 | HAS_HWCKSM, 128, }, |
501 | {"3c556B Laptop Hurricane", | 500 | {"3c556B Laptop Hurricane", |
502 | PCI_USES_IO|PCI_USES_MASTER, IS_TORNADO|HAS_NWAY|EEPROM_OFFSET|HAS_CB_FNS|INVERT_MII_PWR| | 501 | PCI_USES_MASTER, IS_TORNADO|HAS_NWAY|EEPROM_OFFSET|HAS_CB_FNS|INVERT_MII_PWR| |
503 | WNO_XCVR_PWR|HAS_HWCKSM, 128, }, | 502 | WNO_XCVR_PWR|HAS_HWCKSM, 128, }, |
504 | 503 | ||
505 | {"3c575 [Megahertz] 10/100 LAN CardBus", | 504 | {"3c575 [Megahertz] 10/100 LAN CardBus", |
506 | PCI_USES_IO|PCI_USES_MASTER, IS_BOOMERANG|HAS_MII|EEPROM_8BIT, 128, }, | 505 | PCI_USES_MASTER, IS_BOOMERANG|HAS_MII|EEPROM_8BIT, 128, }, |
507 | {"3c575 Boomerang CardBus", | 506 | {"3c575 Boomerang CardBus", |
508 | PCI_USES_IO|PCI_USES_MASTER, IS_BOOMERANG|HAS_MII|EEPROM_8BIT, 128, }, | 507 | PCI_USES_MASTER, IS_BOOMERANG|HAS_MII|EEPROM_8BIT, 128, }, |
509 | {"3CCFE575BT Cyclone CardBus", | 508 | {"3CCFE575BT Cyclone CardBus", |
510 | PCI_USES_IO|PCI_USES_MASTER, IS_CYCLONE|HAS_NWAY|HAS_CB_FNS|EEPROM_8BIT| | 509 | PCI_USES_MASTER, IS_CYCLONE|HAS_NWAY|HAS_CB_FNS|EEPROM_8BIT| |
511 | INVERT_LED_PWR|HAS_HWCKSM, 128, }, | 510 | INVERT_LED_PWR|HAS_HWCKSM, 128, }, |
512 | {"3CCFE575CT Tornado CardBus", | 511 | {"3CCFE575CT Tornado CardBus", |
513 | PCI_USES_IO|PCI_USES_MASTER, IS_TORNADO|HAS_NWAY|HAS_CB_FNS|EEPROM_8BIT|INVERT_MII_PWR| | 512 | PCI_USES_MASTER, IS_TORNADO|HAS_NWAY|HAS_CB_FNS|EEPROM_8BIT|INVERT_MII_PWR| |
514 | MAX_COLLISION_RESET|HAS_HWCKSM, 128, }, | 513 | MAX_COLLISION_RESET|HAS_HWCKSM, 128, }, |
515 | {"3CCFE656 Cyclone CardBus", | 514 | {"3CCFE656 Cyclone CardBus", |
516 | PCI_USES_IO|PCI_USES_MASTER, IS_CYCLONE|HAS_NWAY|HAS_CB_FNS|EEPROM_8BIT|INVERT_MII_PWR| | 515 | PCI_USES_MASTER, IS_CYCLONE|HAS_NWAY|HAS_CB_FNS|EEPROM_8BIT|INVERT_MII_PWR| |
517 | INVERT_LED_PWR|HAS_HWCKSM, 128, }, | 516 | INVERT_LED_PWR|HAS_HWCKSM, 128, }, |
518 | 517 | ||
519 | {"3CCFEM656B Cyclone+Winmodem CardBus", | 518 | {"3CCFEM656B Cyclone+Winmodem CardBus", |
520 | PCI_USES_IO|PCI_USES_MASTER, IS_CYCLONE|HAS_NWAY|HAS_CB_FNS|EEPROM_8BIT|INVERT_MII_PWR| | 519 | PCI_USES_MASTER, IS_CYCLONE|HAS_NWAY|HAS_CB_FNS|EEPROM_8BIT|INVERT_MII_PWR| |
521 | INVERT_LED_PWR|HAS_HWCKSM, 128, }, | 520 | INVERT_LED_PWR|HAS_HWCKSM, 128, }, |
522 | {"3CXFEM656C Tornado+Winmodem CardBus", /* From pcmcia-cs-3.1.5 */ | 521 | {"3CXFEM656C Tornado+Winmodem CardBus", /* From pcmcia-cs-3.1.5 */ |
523 | PCI_USES_IO|PCI_USES_MASTER, IS_TORNADO|HAS_NWAY|HAS_CB_FNS|EEPROM_8BIT|INVERT_MII_PWR| | 522 | PCI_USES_MASTER, IS_TORNADO|HAS_NWAY|HAS_CB_FNS|EEPROM_8BIT|INVERT_MII_PWR| |
524 | MAX_COLLISION_RESET|HAS_HWCKSM, 128, }, | 523 | MAX_COLLISION_RESET|HAS_HWCKSM, 128, }, |
525 | {"3c450 HomePNA Tornado", /* AKPM: from Don's 0.99Q */ | 524 | {"3c450 HomePNA Tornado", /* AKPM: from Don's 0.99Q */ |
526 | PCI_USES_IO|PCI_USES_MASTER, IS_TORNADO|HAS_NWAY|HAS_HWCKSM, 128, }, | 525 | PCI_USES_MASTER, IS_TORNADO|HAS_NWAY|HAS_HWCKSM, 128, }, |
527 | {"3c920 Tornado", | 526 | {"3c920 Tornado", |
528 | PCI_USES_IO|PCI_USES_MASTER, IS_TORNADO|HAS_NWAY|HAS_HWCKSM, 128, }, | 527 | PCI_USES_MASTER, IS_TORNADO|HAS_NWAY|HAS_HWCKSM, 128, }, |
529 | {"3c982 Hydra Dual Port A", | 528 | {"3c982 Hydra Dual Port A", |
530 | PCI_USES_IO|PCI_USES_MASTER, IS_TORNADO|HAS_HWCKSM|HAS_NWAY, 128, }, | 529 | PCI_USES_MASTER, IS_TORNADO|HAS_HWCKSM|HAS_NWAY, 128, }, |
531 | 530 | ||
532 | {"3c982 Hydra Dual Port B", | 531 | {"3c982 Hydra Dual Port B", |
533 | PCI_USES_IO|PCI_USES_MASTER, IS_TORNADO|HAS_HWCKSM|HAS_NWAY, 128, }, | 532 | PCI_USES_MASTER, IS_TORNADO|HAS_HWCKSM|HAS_NWAY, 128, }, |
534 | {"3c905B-T4", | 533 | {"3c905B-T4", |
535 | PCI_USES_IO|PCI_USES_MASTER, IS_CYCLONE|HAS_NWAY|HAS_HWCKSM|EXTRA_PREAMBLE, 128, }, | 534 | PCI_USES_MASTER, IS_CYCLONE|HAS_NWAY|HAS_HWCKSM|EXTRA_PREAMBLE, 128, }, |
536 | {"3c920B-EMB-WNM Tornado", | 535 | {"3c920B-EMB-WNM Tornado", |
537 | PCI_USES_IO|PCI_USES_MASTER, IS_TORNADO|HAS_NWAY|HAS_HWCKSM, 128, }, | 536 | PCI_USES_MASTER, IS_TORNADO|HAS_NWAY|HAS_HWCKSM, 128, }, |
538 | 537 | ||
539 | {NULL,}, /* NULL terminated list. */ | 538 | {NULL,}, /* NULL terminated list. */ |
540 | }; | 539 | }; |
@@ -1408,8 +1407,10 @@ static int __devinit vortex_probe1(struct device *gendev, | |||
1408 | } | 1407 | } |
1409 | 1408 | ||
1410 | if (print_info) { | 1409 | if (print_info) { |
1411 | printk(KERN_INFO "%s: CardBus functions mapped %8.8lx->%p\n", | 1410 | printk(KERN_INFO "%s: CardBus functions mapped " |
1412 | print_name, pci_resource_start(pdev, 2), | 1411 | "%16.16llx->%p\n", |
1412 | print_name, | ||
1413 | (unsigned long long)pci_resource_start(pdev, 2), | ||
1413 | vp->cb_fn_base); | 1414 | vp->cb_fn_base); |
1414 | } | 1415 | } |
1415 | EL3WINDOW(2); | 1416 | EL3WINDOW(2); |
diff --git a/drivers/net/8139cp.c b/drivers/net/8139cp.c index 0cdc830449d8..d26dd6a7062d 100644 --- a/drivers/net/8139cp.c +++ b/drivers/net/8139cp.c | |||
@@ -1823,7 +1823,7 @@ static int cp_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) | |||
1823 | struct cp_private *cp; | 1823 | struct cp_private *cp; |
1824 | int rc; | 1824 | int rc; |
1825 | void __iomem *regs; | 1825 | void __iomem *regs; |
1826 | long pciaddr; | 1826 | resource_size_t pciaddr; |
1827 | unsigned int addr_len, i, pci_using_dac; | 1827 | unsigned int addr_len, i, pci_using_dac; |
1828 | u8 pci_rev; | 1828 | u8 pci_rev; |
1829 | 1829 | ||
@@ -1883,8 +1883,8 @@ static int cp_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) | |||
1883 | } | 1883 | } |
1884 | if (pci_resource_len(pdev, 1) < CP_REGS_SIZE) { | 1884 | if (pci_resource_len(pdev, 1) < CP_REGS_SIZE) { |
1885 | rc = -EIO; | 1885 | rc = -EIO; |
1886 | printk(KERN_ERR PFX "MMIO resource (%lx) too small on pci dev %s\n", | 1886 | printk(KERN_ERR PFX "MMIO resource (%llx) too small on pci dev %s\n", |
1887 | pci_resource_len(pdev, 1), pci_name(pdev)); | 1887 | (unsigned long long)pci_resource_len(pdev, 1), pci_name(pdev)); |
1888 | goto err_out_res; | 1888 | goto err_out_res; |
1889 | } | 1889 | } |
1890 | 1890 | ||
@@ -1916,8 +1916,9 @@ static int cp_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) | |||
1916 | regs = ioremap(pciaddr, CP_REGS_SIZE); | 1916 | regs = ioremap(pciaddr, CP_REGS_SIZE); |
1917 | if (!regs) { | 1917 | if (!regs) { |
1918 | rc = -EIO; | 1918 | rc = -EIO; |
1919 | printk(KERN_ERR PFX "Cannot map PCI MMIO (%lx@%lx) on pci dev %s\n", | 1919 | printk(KERN_ERR PFX "Cannot map PCI MMIO (%llx@%llx) on pci dev %s\n", |
1920 | pci_resource_len(pdev, 1), pciaddr, pci_name(pdev)); | 1920 | (unsigned long long)pci_resource_len(pdev, 1), |
1921 | (unsigned long long)pciaddr, pci_name(pdev)); | ||
1921 | goto err_out_res; | 1922 | goto err_out_res; |
1922 | } | 1923 | } |
1923 | dev->base_addr = (unsigned long) regs; | 1924 | dev->base_addr = (unsigned long) regs; |
diff --git a/drivers/net/8139too.c b/drivers/net/8139too.c index abd6261465f1..ed2e3c03bc88 100644 --- a/drivers/net/8139too.c +++ b/drivers/net/8139too.c | |||
@@ -1341,9 +1341,9 @@ static int rtl8139_open (struct net_device *dev) | |||
1341 | netif_start_queue (dev); | 1341 | netif_start_queue (dev); |
1342 | 1342 | ||
1343 | if (netif_msg_ifup(tp)) | 1343 | if (netif_msg_ifup(tp)) |
1344 | printk(KERN_DEBUG "%s: rtl8139_open() ioaddr %#lx IRQ %d" | 1344 | printk(KERN_DEBUG "%s: rtl8139_open() ioaddr %#llx IRQ %d" |
1345 | " GP Pins %2.2x %s-duplex.\n", | 1345 | " GP Pins %2.2x %s-duplex.\n", dev->name, |
1346 | dev->name, pci_resource_start (tp->pci_dev, 1), | 1346 | (unsigned long long)pci_resource_start (tp->pci_dev, 1), |
1347 | dev->irq, RTL_R8 (MediaStatus), | 1347 | dev->irq, RTL_R8 (MediaStatus), |
1348 | tp->mii.full_duplex ? "full" : "half"); | 1348 | tp->mii.full_duplex ? "full" : "half"); |
1349 | 1349 | ||
diff --git a/drivers/net/dl2k.h b/drivers/net/dl2k.h index 6e75482d75f2..53449207e53b 100644 --- a/drivers/net/dl2k.h +++ b/drivers/net/dl2k.h | |||
@@ -683,11 +683,6 @@ struct netdev_private { | |||
683 | }; | 683 | }; |
684 | 684 | ||
685 | /* The station address location in the EEPROM. */ | 685 | /* The station address location in the EEPROM. */ |
686 | #ifdef MEM_MAPPING | ||
687 | #define PCI_IOTYPE (PCI_USES_MASTER | PCI_USES_MEM | PCI_ADDR1) | ||
688 | #else | ||
689 | #define PCI_IOTYPE (PCI_USES_MASTER | PCI_USES_IO | PCI_ADDR0) | ||
690 | #endif | ||
691 | /* The struct pci_device_id consist of: | 686 | /* The struct pci_device_id consist of: |
692 | vendor, device Vendor and device ID to match (or PCI_ANY_ID) | 687 | vendor, device Vendor and device ID to match (or PCI_ANY_ID) |
693 | subvendor, subdevice Subsystem vendor and device ID to match (or PCI_ANY_ID) | 688 | subvendor, subdevice Subsystem vendor and device ID to match (or PCI_ANY_ID) |
@@ -695,9 +690,10 @@ struct netdev_private { | |||
695 | class_mask of the class are honored during the comparison. | 690 | class_mask of the class are honored during the comparison. |
696 | driver_data Data private to the driver. | 691 | driver_data Data private to the driver. |
697 | */ | 692 | */ |
698 | static struct pci_device_id rio_pci_tbl[] = { | 693 | |
699 | {0x1186, 0x4000, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, | 694 | static const struct pci_device_id rio_pci_tbl[] = { |
700 | {0,} | 695 | {0x1186, 0x4000, PCI_ANY_ID, PCI_ANY_ID, }, |
696 | { } | ||
701 | }; | 697 | }; |
702 | MODULE_DEVICE_TABLE (pci, rio_pci_tbl); | 698 | MODULE_DEVICE_TABLE (pci, rio_pci_tbl); |
703 | #define TX_TIMEOUT (4*HZ) | 699 | #define TX_TIMEOUT (4*HZ) |
diff --git a/drivers/net/dm9000.c b/drivers/net/dm9000.c index 24996da4c1c4..7965a9b08e79 100644 --- a/drivers/net/dm9000.c +++ b/drivers/net/dm9000.c | |||
@@ -410,10 +410,7 @@ dm9000_probe(struct platform_device *pdev) | |||
410 | if (pdev->num_resources < 2) { | 410 | if (pdev->num_resources < 2) { |
411 | ret = -ENODEV; | 411 | ret = -ENODEV; |
412 | goto out; | 412 | goto out; |
413 | } | 413 | } else if (pdev->num_resources == 2) { |
414 | |||
415 | switch (pdev->num_resources) { | ||
416 | case 2: | ||
417 | base = pdev->resource[0].start; | 414 | base = pdev->resource[0].start; |
418 | 415 | ||
419 | if (!request_mem_region(base, 4, ndev->name)) { | 416 | if (!request_mem_region(base, 4, ndev->name)) { |
@@ -423,17 +420,16 @@ dm9000_probe(struct platform_device *pdev) | |||
423 | 420 | ||
424 | ndev->base_addr = base; | 421 | ndev->base_addr = base; |
425 | ndev->irq = pdev->resource[1].start; | 422 | ndev->irq = pdev->resource[1].start; |
426 | db->io_addr = (void *)base; | 423 | db->io_addr = (void __iomem *)base; |
427 | db->io_data = (void *)(base + 4); | 424 | db->io_data = (void __iomem *)(base + 4); |
428 | |||
429 | break; | ||
430 | 425 | ||
431 | case 3: | 426 | } else { |
432 | db->addr_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 427 | db->addr_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
433 | db->data_res = platform_get_resource(pdev, IORESOURCE_MEM, 1); | 428 | db->data_res = platform_get_resource(pdev, IORESOURCE_MEM, 1); |
434 | db->irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); | 429 | db->irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); |
435 | 430 | ||
436 | if (db->addr_res == NULL || db->data_res == NULL) { | 431 | if (db->addr_res == NULL || db->data_res == NULL || |
432 | db->irq_res == NULL) { | ||
437 | printk(KERN_ERR PFX "insufficient resources\n"); | 433 | printk(KERN_ERR PFX "insufficient resources\n"); |
438 | ret = -ENOENT; | 434 | ret = -ENOENT; |
439 | goto out; | 435 | goto out; |
@@ -482,7 +478,6 @@ dm9000_probe(struct platform_device *pdev) | |||
482 | 478 | ||
483 | /* ensure at least we have a default set of IO routines */ | 479 | /* ensure at least we have a default set of IO routines */ |
484 | dm9000_set_io(db, iosize); | 480 | dm9000_set_io(db, iosize); |
485 | |||
486 | } | 481 | } |
487 | 482 | ||
488 | /* check to see if anything is being over-ridden */ | 483 | /* check to see if anything is being over-ridden */ |
@@ -564,6 +559,13 @@ dm9000_probe(struct platform_device *pdev) | |||
564 | for (i = 0; i < 6; i++) | 559 | for (i = 0; i < 6; i++) |
565 | ndev->dev_addr[i] = db->srom[i]; | 560 | ndev->dev_addr[i] = db->srom[i]; |
566 | 561 | ||
562 | if (!is_valid_ether_addr(ndev->dev_addr)) { | ||
563 | /* try reading from mac */ | ||
564 | |||
565 | for (i = 0; i < 6; i++) | ||
566 | ndev->dev_addr[i] = ior(db, i+DM9000_PAR); | ||
567 | } | ||
568 | |||
567 | if (!is_valid_ether_addr(ndev->dev_addr)) | 569 | if (!is_valid_ether_addr(ndev->dev_addr)) |
568 | printk("%s: Invalid ethernet MAC address. Please " | 570 | printk("%s: Invalid ethernet MAC address. Please " |
569 | "set using ifconfig\n", ndev->name); | 571 | "set using ifconfig\n", ndev->name); |
@@ -663,7 +665,6 @@ dm9000_init_dm9000(struct net_device *dev) | |||
663 | db->tx_pkt_cnt = 0; | 665 | db->tx_pkt_cnt = 0; |
664 | db->queue_pkt_len = 0; | 666 | db->queue_pkt_len = 0; |
665 | dev->trans_start = 0; | 667 | dev->trans_start = 0; |
666 | spin_lock_init(&db->lock); | ||
667 | } | 668 | } |
668 | 669 | ||
669 | /* | 670 | /* |
@@ -767,7 +768,7 @@ dm9000_stop(struct net_device *ndev) | |||
767 | * receive the packet to upper layer, free the transmitted packet | 768 | * receive the packet to upper layer, free the transmitted packet |
768 | */ | 769 | */ |
769 | 770 | ||
770 | void | 771 | static void |
771 | dm9000_tx_done(struct net_device *dev, board_info_t * db) | 772 | dm9000_tx_done(struct net_device *dev, board_info_t * db) |
772 | { | 773 | { |
773 | int tx_status = ior(db, DM9000_NSR); /* Got TX status */ | 774 | int tx_status = ior(db, DM9000_NSR); /* Got TX status */ |
@@ -1187,13 +1188,14 @@ dm9000_drv_remove(struct platform_device *pdev) | |||
1187 | } | 1188 | } |
1188 | 1189 | ||
1189 | static struct platform_driver dm9000_driver = { | 1190 | static struct platform_driver dm9000_driver = { |
1191 | .driver = { | ||
1192 | .name = "dm9000", | ||
1193 | .owner = THIS_MODULE, | ||
1194 | }, | ||
1190 | .probe = dm9000_probe, | 1195 | .probe = dm9000_probe, |
1191 | .remove = dm9000_drv_remove, | 1196 | .remove = dm9000_drv_remove, |
1192 | .suspend = dm9000_drv_suspend, | 1197 | .suspend = dm9000_drv_suspend, |
1193 | .resume = dm9000_drv_resume, | 1198 | .resume = dm9000_drv_resume, |
1194 | .driver = { | ||
1195 | .name = "dm9000", | ||
1196 | }, | ||
1197 | }; | 1199 | }; |
1198 | 1200 | ||
1199 | static int __init | 1201 | static int __init |
diff --git a/drivers/net/e100.c b/drivers/net/e100.c index f37170cc1a37..93a286570923 100644 --- a/drivers/net/e100.c +++ b/drivers/net/e100.c | |||
@@ -2678,9 +2678,9 @@ static int __devinit e100_probe(struct pci_dev *pdev, | |||
2678 | goto err_out_free; | 2678 | goto err_out_free; |
2679 | } | 2679 | } |
2680 | 2680 | ||
2681 | DPRINTK(PROBE, INFO, "addr 0x%lx, irq %d, " | 2681 | DPRINTK(PROBE, INFO, "addr 0x%llx, irq %d, " |
2682 | "MAC addr %02X:%02X:%02X:%02X:%02X:%02X\n", | 2682 | "MAC addr %02X:%02X:%02X:%02X:%02X:%02X\n", |
2683 | pci_resource_start(pdev, 0), pdev->irq, | 2683 | (unsigned long long)pci_resource_start(pdev, 0), pdev->irq, |
2684 | netdev->dev_addr[0], netdev->dev_addr[1], netdev->dev_addr[2], | 2684 | netdev->dev_addr[0], netdev->dev_addr[1], netdev->dev_addr[2], |
2685 | netdev->dev_addr[3], netdev->dev_addr[4], netdev->dev_addr[5]); | 2685 | netdev->dev_addr[3], netdev->dev_addr[4], netdev->dev_addr[5]); |
2686 | 2686 | ||
diff --git a/drivers/net/eepro100.c b/drivers/net/eepro100.c index 467fc861360d..ecf5ad85a684 100644 --- a/drivers/net/eepro100.c +++ b/drivers/net/eepro100.c | |||
@@ -278,11 +278,6 @@ having to sign an Intel NDA when I'm helping Intel sell their own product! | |||
278 | 278 | ||
279 | static int speedo_found1(struct pci_dev *pdev, void __iomem *ioaddr, int fnd_cnt, int acpi_idle_state); | 279 | static int speedo_found1(struct pci_dev *pdev, void __iomem *ioaddr, int fnd_cnt, int acpi_idle_state); |
280 | 280 | ||
281 | enum pci_flags_bit { | ||
282 | PCI_USES_IO=1, PCI_USES_MEM=2, PCI_USES_MASTER=4, | ||
283 | PCI_ADDR0=0x10<<0, PCI_ADDR1=0x10<<1, PCI_ADDR2=0x10<<2, PCI_ADDR3=0x10<<3, | ||
284 | }; | ||
285 | |||
286 | /* Offsets to the various registers. | 281 | /* Offsets to the various registers. |
287 | All accesses need not be longword aligned. */ | 282 | All accesses need not be longword aligned. */ |
288 | enum speedo_offsets { | 283 | enum speedo_offsets { |
diff --git a/drivers/net/epic100.c b/drivers/net/epic100.c index 724d7dc35fa3..ee34a16eb4e2 100644 --- a/drivers/net/epic100.c +++ b/drivers/net/epic100.c | |||
@@ -191,23 +191,10 @@ IVc. Errata | |||
191 | */ | 191 | */ |
192 | 192 | ||
193 | 193 | ||
194 | enum pci_id_flags_bits { | ||
195 | /* Set PCI command register bits before calling probe1(). */ | ||
196 | PCI_USES_IO=1, PCI_USES_MEM=2, PCI_USES_MASTER=4, | ||
197 | /* Read and map the single following PCI BAR. */ | ||
198 | PCI_ADDR0=0<<4, PCI_ADDR1=1<<4, PCI_ADDR2=2<<4, PCI_ADDR3=3<<4, | ||
199 | PCI_ADDR_64BITS=0x100, PCI_NO_ACPI_WAKE=0x200, PCI_NO_MIN_LATENCY=0x400, | ||
200 | }; | ||
201 | |||
202 | enum chip_capability_flags { MII_PWRDWN=1, TYPE2_INTR=2, NO_MII=4 }; | 194 | enum chip_capability_flags { MII_PWRDWN=1, TYPE2_INTR=2, NO_MII=4 }; |
203 | 195 | ||
204 | #define EPIC_TOTAL_SIZE 0x100 | 196 | #define EPIC_TOTAL_SIZE 0x100 |
205 | #define USE_IO_OPS 1 | 197 | #define USE_IO_OPS 1 |
206 | #ifdef USE_IO_OPS | ||
207 | #define EPIC_IOTYPE PCI_USES_MASTER|PCI_USES_IO|PCI_ADDR0 | ||
208 | #else | ||
209 | #define EPIC_IOTYPE PCI_USES_MASTER|PCI_USES_MEM|PCI_ADDR1 | ||
210 | #endif | ||
211 | 198 | ||
212 | typedef enum { | 199 | typedef enum { |
213 | SMSC_83C170_0, | 200 | SMSC_83C170_0, |
@@ -218,7 +205,6 @@ typedef enum { | |||
218 | 205 | ||
219 | struct epic_chip_info { | 206 | struct epic_chip_info { |
220 | const char *name; | 207 | const char *name; |
221 | enum pci_id_flags_bits pci_flags; | ||
222 | int io_size; /* Needed for I/O region check or ioremap(). */ | 208 | int io_size; /* Needed for I/O region check or ioremap(). */ |
223 | int drv_flags; /* Driver use, intended as capability flags. */ | 209 | int drv_flags; /* Driver use, intended as capability flags. */ |
224 | }; | 210 | }; |
@@ -227,11 +213,11 @@ struct epic_chip_info { | |||
227 | /* indexed by chip_t */ | 213 | /* indexed by chip_t */ |
228 | static const struct epic_chip_info pci_id_tbl[] = { | 214 | static const struct epic_chip_info pci_id_tbl[] = { |
229 | { "SMSC EPIC/100 83c170", | 215 | { "SMSC EPIC/100 83c170", |
230 | EPIC_IOTYPE, EPIC_TOTAL_SIZE, TYPE2_INTR | NO_MII | MII_PWRDWN }, | 216 | EPIC_TOTAL_SIZE, TYPE2_INTR | NO_MII | MII_PWRDWN }, |
231 | { "SMSC EPIC/100 83c170", | 217 | { "SMSC EPIC/100 83c170", |
232 | EPIC_IOTYPE, EPIC_TOTAL_SIZE, TYPE2_INTR }, | 218 | EPIC_TOTAL_SIZE, TYPE2_INTR }, |
233 | { "SMSC EPIC/C 83c175", | 219 | { "SMSC EPIC/C 83c175", |
234 | EPIC_IOTYPE, EPIC_TOTAL_SIZE, TYPE2_INTR | MII_PWRDWN }, | 220 | EPIC_TOTAL_SIZE, TYPE2_INTR | MII_PWRDWN }, |
235 | }; | 221 | }; |
236 | 222 | ||
237 | 223 | ||
diff --git a/drivers/net/fealnx.c b/drivers/net/fealnx.c index a8449265e5fd..13eca7ede2af 100644 --- a/drivers/net/fealnx.c +++ b/drivers/net/fealnx.c | |||
@@ -126,16 +126,6 @@ MODULE_PARM_DESC(full_duplex, "fealnx full duplex setting(s) (1)"); | |||
126 | 126 | ||
127 | #define MIN_REGION_SIZE 136 | 127 | #define MIN_REGION_SIZE 136 |
128 | 128 | ||
129 | enum pci_flags_bit { | ||
130 | PCI_USES_IO = 1, | ||
131 | PCI_USES_MEM = 2, | ||
132 | PCI_USES_MASTER = 4, | ||
133 | PCI_ADDR0 = 0x10 << 0, | ||
134 | PCI_ADDR1 = 0x10 << 1, | ||
135 | PCI_ADDR2 = 0x10 << 2, | ||
136 | PCI_ADDR3 = 0x10 << 3, | ||
137 | }; | ||
138 | |||
139 | /* A chip capabilities table, matching the entries in pci_tbl[] above. */ | 129 | /* A chip capabilities table, matching the entries in pci_tbl[] above. */ |
140 | enum chip_capability_flags { | 130 | enum chip_capability_flags { |
141 | HAS_MII_XCVR, | 131 | HAS_MII_XCVR, |
diff --git a/drivers/net/fec.c b/drivers/net/fec.c index bd6983d1afba..db694c832989 100644 --- a/drivers/net/fec.c +++ b/drivers/net/fec.c | |||
@@ -22,7 +22,7 @@ | |||
22 | * Copyright (c) 2001-2005 Greg Ungerer (gerg@snapgear.com) | 22 | * Copyright (c) 2001-2005 Greg Ungerer (gerg@snapgear.com) |
23 | * | 23 | * |
24 | * Bug fixes and cleanup by Philippe De Muyter (phdm@macqel.be) | 24 | * Bug fixes and cleanup by Philippe De Muyter (phdm@macqel.be) |
25 | * Copyright (c) 2004-2005 Macq Electronique SA. | 25 | * Copyright (c) 2004-2006 Macq Electronique SA. |
26 | */ | 26 | */ |
27 | 27 | ||
28 | #include <linux/config.h> | 28 | #include <linux/config.h> |
@@ -51,7 +51,7 @@ | |||
51 | 51 | ||
52 | #if defined(CONFIG_M523x) || defined(CONFIG_M527x) || \ | 52 | #if defined(CONFIG_M523x) || defined(CONFIG_M527x) || \ |
53 | defined(CONFIG_M5272) || defined(CONFIG_M528x) || \ | 53 | defined(CONFIG_M5272) || defined(CONFIG_M528x) || \ |
54 | defined(CONFIG_M520x) | 54 | defined(CONFIG_M520x) || defined(CONFIG_M532x) |
55 | #include <asm/coldfire.h> | 55 | #include <asm/coldfire.h> |
56 | #include <asm/mcfsim.h> | 56 | #include <asm/mcfsim.h> |
57 | #include "fec.h" | 57 | #include "fec.h" |
@@ -80,6 +80,8 @@ static unsigned int fec_hw[] = { | |||
80 | (MCF_MBAR + 0x1000), | 80 | (MCF_MBAR + 0x1000), |
81 | #elif defined(CONFIG_M520x) | 81 | #elif defined(CONFIG_M520x) |
82 | (MCF_MBAR+0x30000), | 82 | (MCF_MBAR+0x30000), |
83 | #elif defined(CONFIG_M532x) | ||
84 | (MCF_MBAR+0xfc030000), | ||
83 | #else | 85 | #else |
84 | &(((immap_t *)IMAP_ADDR)->im_cpm.cp_fec), | 86 | &(((immap_t *)IMAP_ADDR)->im_cpm.cp_fec), |
85 | #endif | 87 | #endif |
@@ -143,7 +145,7 @@ typedef struct { | |||
143 | #define TX_RING_MOD_MASK 15 /* for this to work */ | 145 | #define TX_RING_MOD_MASK 15 /* for this to work */ |
144 | 146 | ||
145 | #if (((RX_RING_SIZE + TX_RING_SIZE) * 8) > PAGE_SIZE) | 147 | #if (((RX_RING_SIZE + TX_RING_SIZE) * 8) > PAGE_SIZE) |
146 | #error "FEC: descriptor ring size contants too large" | 148 | #error "FEC: descriptor ring size constants too large" |
147 | #endif | 149 | #endif |
148 | 150 | ||
149 | /* Interrupt events/masks. | 151 | /* Interrupt events/masks. |
@@ -167,12 +169,12 @@ typedef struct { | |||
167 | 169 | ||
168 | 170 | ||
169 | /* | 171 | /* |
170 | * The 5270/5271/5280/5282 RX control register also contains maximum frame | 172 | * The 5270/5271/5280/5282/532x RX control register also contains maximum frame |
171 | * size bits. Other FEC hardware does not, so we need to take that into | 173 | * size bits. Other FEC hardware does not, so we need to take that into |
172 | * account when setting it. | 174 | * account when setting it. |
173 | */ | 175 | */ |
174 | #if defined(CONFIG_M523x) || defined(CONFIG_M527x) || defined(CONFIG_M528x) || \ | 176 | #if defined(CONFIG_M523x) || defined(CONFIG_M527x) || defined(CONFIG_M528x) || \ |
175 | defined(CONFIG_M520x) | 177 | defined(CONFIG_M520x) || defined(CONFIG_M532x) |
176 | #define OPT_FRAME_SIZE (PKT_MAXBUF_SIZE << 16) | 178 | #define OPT_FRAME_SIZE (PKT_MAXBUF_SIZE << 16) |
177 | #else | 179 | #else |
178 | #define OPT_FRAME_SIZE 0 | 180 | #define OPT_FRAME_SIZE 0 |
@@ -308,6 +310,7 @@ fec_enet_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
308 | struct fec_enet_private *fep; | 310 | struct fec_enet_private *fep; |
309 | volatile fec_t *fecp; | 311 | volatile fec_t *fecp; |
310 | volatile cbd_t *bdp; | 312 | volatile cbd_t *bdp; |
313 | unsigned short status; | ||
311 | 314 | ||
312 | fep = netdev_priv(dev); | 315 | fep = netdev_priv(dev); |
313 | fecp = (volatile fec_t*)dev->base_addr; | 316 | fecp = (volatile fec_t*)dev->base_addr; |
@@ -320,8 +323,9 @@ fec_enet_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
320 | /* Fill in a Tx ring entry */ | 323 | /* Fill in a Tx ring entry */ |
321 | bdp = fep->cur_tx; | 324 | bdp = fep->cur_tx; |
322 | 325 | ||
326 | status = bdp->cbd_sc; | ||
323 | #ifndef final_version | 327 | #ifndef final_version |
324 | if (bdp->cbd_sc & BD_ENET_TX_READY) { | 328 | if (status & BD_ENET_TX_READY) { |
325 | /* Ooops. All transmit buffers are full. Bail out. | 329 | /* Ooops. All transmit buffers are full. Bail out. |
326 | * This should not happen, since dev->tbusy should be set. | 330 | * This should not happen, since dev->tbusy should be set. |
327 | */ | 331 | */ |
@@ -332,7 +336,7 @@ fec_enet_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
332 | 336 | ||
333 | /* Clear all of the status flags. | 337 | /* Clear all of the status flags. |
334 | */ | 338 | */ |
335 | bdp->cbd_sc &= ~BD_ENET_TX_STATS; | 339 | status &= ~BD_ENET_TX_STATS; |
336 | 340 | ||
337 | /* Set buffer length and buffer pointer. | 341 | /* Set buffer length and buffer pointer. |
338 | */ | 342 | */ |
@@ -366,21 +370,22 @@ fec_enet_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
366 | 370 | ||
367 | spin_lock_irq(&fep->lock); | 371 | spin_lock_irq(&fep->lock); |
368 | 372 | ||
369 | /* Send it on its way. Tell FEC its ready, interrupt when done, | 373 | /* Send it on its way. Tell FEC it's ready, interrupt when done, |
370 | * its the last BD of the frame, and to put the CRC on the end. | 374 | * it's the last BD of the frame, and to put the CRC on the end. |
371 | */ | 375 | */ |
372 | 376 | ||
373 | bdp->cbd_sc |= (BD_ENET_TX_READY | BD_ENET_TX_INTR | 377 | status |= (BD_ENET_TX_READY | BD_ENET_TX_INTR |
374 | | BD_ENET_TX_LAST | BD_ENET_TX_TC); | 378 | | BD_ENET_TX_LAST | BD_ENET_TX_TC); |
379 | bdp->cbd_sc = status; | ||
375 | 380 | ||
376 | dev->trans_start = jiffies; | 381 | dev->trans_start = jiffies; |
377 | 382 | ||
378 | /* Trigger transmission start */ | 383 | /* Trigger transmission start */ |
379 | fecp->fec_x_des_active = 0x01000000; | 384 | fecp->fec_x_des_active = 0; |
380 | 385 | ||
381 | /* If this was the last BD in the ring, start at the beginning again. | 386 | /* If this was the last BD in the ring, start at the beginning again. |
382 | */ | 387 | */ |
383 | if (bdp->cbd_sc & BD_ENET_TX_WRAP) { | 388 | if (status & BD_ENET_TX_WRAP) { |
384 | bdp = fep->tx_bd_base; | 389 | bdp = fep->tx_bd_base; |
385 | } else { | 390 | } else { |
386 | bdp++; | 391 | bdp++; |
@@ -491,43 +496,44 @@ fec_enet_tx(struct net_device *dev) | |||
491 | { | 496 | { |
492 | struct fec_enet_private *fep; | 497 | struct fec_enet_private *fep; |
493 | volatile cbd_t *bdp; | 498 | volatile cbd_t *bdp; |
499 | unsigned short status; | ||
494 | struct sk_buff *skb; | 500 | struct sk_buff *skb; |
495 | 501 | ||
496 | fep = netdev_priv(dev); | 502 | fep = netdev_priv(dev); |
497 | spin_lock(&fep->lock); | 503 | spin_lock(&fep->lock); |
498 | bdp = fep->dirty_tx; | 504 | bdp = fep->dirty_tx; |
499 | 505 | ||
500 | while ((bdp->cbd_sc&BD_ENET_TX_READY) == 0) { | 506 | while (((status = bdp->cbd_sc) & BD_ENET_TX_READY) == 0) { |
501 | if (bdp == fep->cur_tx && fep->tx_full == 0) break; | 507 | if (bdp == fep->cur_tx && fep->tx_full == 0) break; |
502 | 508 | ||
503 | skb = fep->tx_skbuff[fep->skb_dirty]; | 509 | skb = fep->tx_skbuff[fep->skb_dirty]; |
504 | /* Check for errors. */ | 510 | /* Check for errors. */ |
505 | if (bdp->cbd_sc & (BD_ENET_TX_HB | BD_ENET_TX_LC | | 511 | if (status & (BD_ENET_TX_HB | BD_ENET_TX_LC | |
506 | BD_ENET_TX_RL | BD_ENET_TX_UN | | 512 | BD_ENET_TX_RL | BD_ENET_TX_UN | |
507 | BD_ENET_TX_CSL)) { | 513 | BD_ENET_TX_CSL)) { |
508 | fep->stats.tx_errors++; | 514 | fep->stats.tx_errors++; |
509 | if (bdp->cbd_sc & BD_ENET_TX_HB) /* No heartbeat */ | 515 | if (status & BD_ENET_TX_HB) /* No heartbeat */ |
510 | fep->stats.tx_heartbeat_errors++; | 516 | fep->stats.tx_heartbeat_errors++; |
511 | if (bdp->cbd_sc & BD_ENET_TX_LC) /* Late collision */ | 517 | if (status & BD_ENET_TX_LC) /* Late collision */ |
512 | fep->stats.tx_window_errors++; | 518 | fep->stats.tx_window_errors++; |
513 | if (bdp->cbd_sc & BD_ENET_TX_RL) /* Retrans limit */ | 519 | if (status & BD_ENET_TX_RL) /* Retrans limit */ |
514 | fep->stats.tx_aborted_errors++; | 520 | fep->stats.tx_aborted_errors++; |
515 | if (bdp->cbd_sc & BD_ENET_TX_UN) /* Underrun */ | 521 | if (status & BD_ENET_TX_UN) /* Underrun */ |
516 | fep->stats.tx_fifo_errors++; | 522 | fep->stats.tx_fifo_errors++; |
517 | if (bdp->cbd_sc & BD_ENET_TX_CSL) /* Carrier lost */ | 523 | if (status & BD_ENET_TX_CSL) /* Carrier lost */ |
518 | fep->stats.tx_carrier_errors++; | 524 | fep->stats.tx_carrier_errors++; |
519 | } else { | 525 | } else { |
520 | fep->stats.tx_packets++; | 526 | fep->stats.tx_packets++; |
521 | } | 527 | } |
522 | 528 | ||
523 | #ifndef final_version | 529 | #ifndef final_version |
524 | if (bdp->cbd_sc & BD_ENET_TX_READY) | 530 | if (status & BD_ENET_TX_READY) |
525 | printk("HEY! Enet xmit interrupt and TX_READY.\n"); | 531 | printk("HEY! Enet xmit interrupt and TX_READY.\n"); |
526 | #endif | 532 | #endif |
527 | /* Deferred means some collisions occurred during transmit, | 533 | /* Deferred means some collisions occurred during transmit, |
528 | * but we eventually sent the packet OK. | 534 | * but we eventually sent the packet OK. |
529 | */ | 535 | */ |
530 | if (bdp->cbd_sc & BD_ENET_TX_DEF) | 536 | if (status & BD_ENET_TX_DEF) |
531 | fep->stats.collisions++; | 537 | fep->stats.collisions++; |
532 | 538 | ||
533 | /* Free the sk buffer associated with this last transmit. | 539 | /* Free the sk buffer associated with this last transmit. |
@@ -538,7 +544,7 @@ fec_enet_tx(struct net_device *dev) | |||
538 | 544 | ||
539 | /* Update pointer to next buffer descriptor to be transmitted. | 545 | /* Update pointer to next buffer descriptor to be transmitted. |
540 | */ | 546 | */ |
541 | if (bdp->cbd_sc & BD_ENET_TX_WRAP) | 547 | if (status & BD_ENET_TX_WRAP) |
542 | bdp = fep->tx_bd_base; | 548 | bdp = fep->tx_bd_base; |
543 | else | 549 | else |
544 | bdp++; | 550 | bdp++; |
@@ -568,9 +574,14 @@ fec_enet_rx(struct net_device *dev) | |||
568 | struct fec_enet_private *fep; | 574 | struct fec_enet_private *fep; |
569 | volatile fec_t *fecp; | 575 | volatile fec_t *fecp; |
570 | volatile cbd_t *bdp; | 576 | volatile cbd_t *bdp; |
577 | unsigned short status; | ||
571 | struct sk_buff *skb; | 578 | struct sk_buff *skb; |
572 | ushort pkt_len; | 579 | ushort pkt_len; |
573 | __u8 *data; | 580 | __u8 *data; |
581 | |||
582 | #ifdef CONFIG_M532x | ||
583 | flush_cache_all(); | ||
584 | #endif | ||
574 | 585 | ||
575 | fep = netdev_priv(dev); | 586 | fep = netdev_priv(dev); |
576 | fecp = (volatile fec_t*)dev->base_addr; | 587 | fecp = (volatile fec_t*)dev->base_addr; |
@@ -580,13 +591,13 @@ fec_enet_rx(struct net_device *dev) | |||
580 | */ | 591 | */ |
581 | bdp = fep->cur_rx; | 592 | bdp = fep->cur_rx; |
582 | 593 | ||
583 | while (!(bdp->cbd_sc & BD_ENET_RX_EMPTY)) { | 594 | while (!((status = bdp->cbd_sc) & BD_ENET_RX_EMPTY)) { |
584 | 595 | ||
585 | #ifndef final_version | 596 | #ifndef final_version |
586 | /* Since we have allocated space to hold a complete frame, | 597 | /* Since we have allocated space to hold a complete frame, |
587 | * the last indicator should be set. | 598 | * the last indicator should be set. |
588 | */ | 599 | */ |
589 | if ((bdp->cbd_sc & BD_ENET_RX_LAST) == 0) | 600 | if ((status & BD_ENET_RX_LAST) == 0) |
590 | printk("FEC ENET: rcv is not +last\n"); | 601 | printk("FEC ENET: rcv is not +last\n"); |
591 | #endif | 602 | #endif |
592 | 603 | ||
@@ -594,26 +605,26 @@ while (!(bdp->cbd_sc & BD_ENET_RX_EMPTY)) { | |||
594 | goto rx_processing_done; | 605 | goto rx_processing_done; |
595 | 606 | ||
596 | /* Check for errors. */ | 607 | /* Check for errors. */ |
597 | if (bdp->cbd_sc & (BD_ENET_RX_LG | BD_ENET_RX_SH | BD_ENET_RX_NO | | 608 | if (status & (BD_ENET_RX_LG | BD_ENET_RX_SH | BD_ENET_RX_NO | |
598 | BD_ENET_RX_CR | BD_ENET_RX_OV)) { | 609 | BD_ENET_RX_CR | BD_ENET_RX_OV)) { |
599 | fep->stats.rx_errors++; | 610 | fep->stats.rx_errors++; |
600 | if (bdp->cbd_sc & (BD_ENET_RX_LG | BD_ENET_RX_SH)) { | 611 | if (status & (BD_ENET_RX_LG | BD_ENET_RX_SH)) { |
601 | /* Frame too long or too short. */ | 612 | /* Frame too long or too short. */ |
602 | fep->stats.rx_length_errors++; | 613 | fep->stats.rx_length_errors++; |
603 | } | 614 | } |
604 | if (bdp->cbd_sc & BD_ENET_RX_NO) /* Frame alignment */ | 615 | if (status & BD_ENET_RX_NO) /* Frame alignment */ |
605 | fep->stats.rx_frame_errors++; | 616 | fep->stats.rx_frame_errors++; |
606 | if (bdp->cbd_sc & BD_ENET_RX_CR) /* CRC Error */ | 617 | if (status & BD_ENET_RX_CR) /* CRC Error */ |
607 | fep->stats.rx_crc_errors++; | ||
608 | if (bdp->cbd_sc & BD_ENET_RX_OV) /* FIFO overrun */ | ||
609 | fep->stats.rx_crc_errors++; | 618 | fep->stats.rx_crc_errors++; |
619 | if (status & BD_ENET_RX_OV) /* FIFO overrun */ | ||
620 | fep->stats.rx_fifo_errors++; | ||
610 | } | 621 | } |
611 | 622 | ||
612 | /* Report late collisions as a frame error. | 623 | /* Report late collisions as a frame error. |
613 | * On this error, the BD is closed, but we don't know what we | 624 | * On this error, the BD is closed, but we don't know what we |
614 | * have in the buffer. So, just drop this frame on the floor. | 625 | * have in the buffer. So, just drop this frame on the floor. |
615 | */ | 626 | */ |
616 | if (bdp->cbd_sc & BD_ENET_RX_CL) { | 627 | if (status & BD_ENET_RX_CL) { |
617 | fep->stats.rx_errors++; | 628 | fep->stats.rx_errors++; |
618 | fep->stats.rx_frame_errors++; | 629 | fep->stats.rx_frame_errors++; |
619 | goto rx_processing_done; | 630 | goto rx_processing_done; |
@@ -639,9 +650,7 @@ while (!(bdp->cbd_sc & BD_ENET_RX_EMPTY)) { | |||
639 | } else { | 650 | } else { |
640 | skb->dev = dev; | 651 | skb->dev = dev; |
641 | skb_put(skb,pkt_len-4); /* Make room */ | 652 | skb_put(skb,pkt_len-4); /* Make room */ |
642 | eth_copy_and_sum(skb, | 653 | eth_copy_and_sum(skb, data, pkt_len-4, 0); |
643 | (unsigned char *)__va(bdp->cbd_bufaddr), | ||
644 | pkt_len-4, 0); | ||
645 | skb->protocol=eth_type_trans(skb,dev); | 654 | skb->protocol=eth_type_trans(skb,dev); |
646 | netif_rx(skb); | 655 | netif_rx(skb); |
647 | } | 656 | } |
@@ -649,15 +658,16 @@ while (!(bdp->cbd_sc & BD_ENET_RX_EMPTY)) { | |||
649 | 658 | ||
650 | /* Clear the status flags for this buffer. | 659 | /* Clear the status flags for this buffer. |
651 | */ | 660 | */ |
652 | bdp->cbd_sc &= ~BD_ENET_RX_STATS; | 661 | status &= ~BD_ENET_RX_STATS; |
653 | 662 | ||
654 | /* Mark the buffer empty. | 663 | /* Mark the buffer empty. |
655 | */ | 664 | */ |
656 | bdp->cbd_sc |= BD_ENET_RX_EMPTY; | 665 | status |= BD_ENET_RX_EMPTY; |
666 | bdp->cbd_sc = status; | ||
657 | 667 | ||
658 | /* Update BD pointer to next entry. | 668 | /* Update BD pointer to next entry. |
659 | */ | 669 | */ |
660 | if (bdp->cbd_sc & BD_ENET_RX_WRAP) | 670 | if (status & BD_ENET_RX_WRAP) |
661 | bdp = fep->rx_bd_base; | 671 | bdp = fep->rx_bd_base; |
662 | else | 672 | else |
663 | bdp++; | 673 | bdp++; |
@@ -667,9 +677,9 @@ while (!(bdp->cbd_sc & BD_ENET_RX_EMPTY)) { | |||
667 | * incoming frames. On a heavily loaded network, we should be | 677 | * incoming frames. On a heavily loaded network, we should be |
668 | * able to keep up at the expense of system resources. | 678 | * able to keep up at the expense of system resources. |
669 | */ | 679 | */ |
670 | fecp->fec_r_des_active = 0x01000000; | 680 | fecp->fec_r_des_active = 0; |
671 | #endif | 681 | #endif |
672 | } /* while (!(bdp->cbd_sc & BD_ENET_RX_EMPTY)) */ | 682 | } /* while (!((status = bdp->cbd_sc) & BD_ENET_RX_EMPTY)) */ |
673 | fep->cur_rx = (cbd_t *)bdp; | 683 | fep->cur_rx = (cbd_t *)bdp; |
674 | 684 | ||
675 | #if 0 | 685 | #if 0 |
@@ -680,11 +690,12 @@ while (!(bdp->cbd_sc & BD_ENET_RX_EMPTY)) { | |||
680 | * our way back to the interrupt return only to come right back | 690 | * our way back to the interrupt return only to come right back |
681 | * here. | 691 | * here. |
682 | */ | 692 | */ |
683 | fecp->fec_r_des_active = 0x01000000; | 693 | fecp->fec_r_des_active = 0; |
684 | #endif | 694 | #endif |
685 | } | 695 | } |
686 | 696 | ||
687 | 697 | ||
698 | /* called from interrupt context */ | ||
688 | static void | 699 | static void |
689 | fec_enet_mii(struct net_device *dev) | 700 | fec_enet_mii(struct net_device *dev) |
690 | { | 701 | { |
@@ -696,10 +707,12 @@ fec_enet_mii(struct net_device *dev) | |||
696 | fep = netdev_priv(dev); | 707 | fep = netdev_priv(dev); |
697 | ep = fep->hwp; | 708 | ep = fep->hwp; |
698 | mii_reg = ep->fec_mii_data; | 709 | mii_reg = ep->fec_mii_data; |
710 | |||
711 | spin_lock(&fep->lock); | ||
699 | 712 | ||
700 | if ((mip = mii_head) == NULL) { | 713 | if ((mip = mii_head) == NULL) { |
701 | printk("MII and no head!\n"); | 714 | printk("MII and no head!\n"); |
702 | return; | 715 | goto unlock; |
703 | } | 716 | } |
704 | 717 | ||
705 | if (mip->mii_func != NULL) | 718 | if (mip->mii_func != NULL) |
@@ -711,6 +724,9 @@ fec_enet_mii(struct net_device *dev) | |||
711 | 724 | ||
712 | if ((mip = mii_head) != NULL) | 725 | if ((mip = mii_head) != NULL) |
713 | ep->fec_mii_data = mip->mii_regval; | 726 | ep->fec_mii_data = mip->mii_regval; |
727 | |||
728 | unlock: | ||
729 | spin_unlock(&fep->lock); | ||
714 | } | 730 | } |
715 | 731 | ||
716 | static int | 732 | static int |
@@ -728,8 +744,7 @@ mii_queue(struct net_device *dev, int regval, void (*func)(uint, struct net_devi | |||
728 | 744 | ||
729 | retval = 0; | 745 | retval = 0; |
730 | 746 | ||
731 | save_flags(flags); | 747 | spin_lock_irqsave(&fep->lock,flags); |
732 | cli(); | ||
733 | 748 | ||
734 | if ((mip = mii_free) != NULL) { | 749 | if ((mip = mii_free) != NULL) { |
735 | mii_free = mip->mii_next; | 750 | mii_free = mip->mii_next; |
@@ -749,7 +764,7 @@ mii_queue(struct net_device *dev, int regval, void (*func)(uint, struct net_devi | |||
749 | retval = 1; | 764 | retval = 1; |
750 | } | 765 | } |
751 | 766 | ||
752 | restore_flags(flags); | 767 | spin_unlock_irqrestore(&fep->lock,flags); |
753 | 768 | ||
754 | return(retval); | 769 | return(retval); |
755 | } | 770 | } |
@@ -1216,7 +1231,7 @@ static phy_info_t const * const phy_info[] = { | |||
1216 | }; | 1231 | }; |
1217 | 1232 | ||
1218 | /* ------------------------------------------------------------------------- */ | 1233 | /* ------------------------------------------------------------------------- */ |
1219 | 1234 | #if !defined(CONFIG_M532x) | |
1220 | #ifdef CONFIG_RPXCLASSIC | 1235 | #ifdef CONFIG_RPXCLASSIC |
1221 | static void | 1236 | static void |
1222 | mii_link_interrupt(void *dev_id); | 1237 | mii_link_interrupt(void *dev_id); |
@@ -1224,6 +1239,7 @@ mii_link_interrupt(void *dev_id); | |||
1224 | static irqreturn_t | 1239 | static irqreturn_t |
1225 | mii_link_interrupt(int irq, void * dev_id, struct pt_regs * regs); | 1240 | mii_link_interrupt(int irq, void * dev_id, struct pt_regs * regs); |
1226 | #endif | 1241 | #endif |
1242 | #endif | ||
1227 | 1243 | ||
1228 | #if defined(CONFIG_M5272) | 1244 | #if defined(CONFIG_M5272) |
1229 | 1245 | ||
@@ -1384,13 +1400,13 @@ static void __inline__ fec_request_intrs(struct net_device *dev) | |||
1384 | { | 1400 | { |
1385 | volatile unsigned char *icrp; | 1401 | volatile unsigned char *icrp; |
1386 | volatile unsigned long *imrp; | 1402 | volatile unsigned long *imrp; |
1387 | int i; | 1403 | int i, ilip; |
1388 | 1404 | ||
1389 | b = (fep->index) ? MCFICM_INTC1 : MCFICM_INTC0; | 1405 | b = (fep->index) ? MCFICM_INTC1 : MCFICM_INTC0; |
1390 | icrp = (volatile unsigned char *) (MCF_IPSBAR + b + | 1406 | icrp = (volatile unsigned char *) (MCF_IPSBAR + b + |
1391 | MCFINTC_ICR0); | 1407 | MCFINTC_ICR0); |
1392 | for (i = 23; (i < 36); i++) | 1408 | for (i = 23, ilip = 0x28; (i < 36); i++) |
1393 | icrp[i] = 0x23; | 1409 | icrp[i] = ilip--; |
1394 | 1410 | ||
1395 | imrp = (volatile unsigned long *) (MCF_IPSBAR + b + | 1411 | imrp = (volatile unsigned long *) (MCF_IPSBAR + b + |
1396 | MCFINTC_IMRH); | 1412 | MCFINTC_IMRH); |
@@ -1618,6 +1634,159 @@ static void __inline__ fec_uncache(unsigned long addr) | |||
1618 | 1634 | ||
1619 | /* ------------------------------------------------------------------------- */ | 1635 | /* ------------------------------------------------------------------------- */ |
1620 | 1636 | ||
1637 | #elif defined(CONFIG_M532x) | ||
1638 | /* | ||
1639 | * Code specific for M532x | ||
1640 | */ | ||
1641 | static void __inline__ fec_request_intrs(struct net_device *dev) | ||
1642 | { | ||
1643 | struct fec_enet_private *fep; | ||
1644 | int b; | ||
1645 | static const struct idesc { | ||
1646 | char *name; | ||
1647 | unsigned short irq; | ||
1648 | } *idp, id[] = { | ||
1649 | { "fec(TXF)", 36 }, | ||
1650 | { "fec(TXB)", 37 }, | ||
1651 | { "fec(TXFIFO)", 38 }, | ||
1652 | { "fec(TXCR)", 39 }, | ||
1653 | { "fec(RXF)", 40 }, | ||
1654 | { "fec(RXB)", 41 }, | ||
1655 | { "fec(MII)", 42 }, | ||
1656 | { "fec(LC)", 43 }, | ||
1657 | { "fec(HBERR)", 44 }, | ||
1658 | { "fec(GRA)", 45 }, | ||
1659 | { "fec(EBERR)", 46 }, | ||
1660 | { "fec(BABT)", 47 }, | ||
1661 | { "fec(BABR)", 48 }, | ||
1662 | { NULL }, | ||
1663 | }; | ||
1664 | |||
1665 | fep = netdev_priv(dev); | ||
1666 | b = (fep->index) ? 128 : 64; | ||
1667 | |||
1668 | /* Setup interrupt handlers. */ | ||
1669 | for (idp = id; idp->name; idp++) { | ||
1670 | if (request_irq(b+idp->irq,fec_enet_interrupt,0,idp->name,dev)!=0) | ||
1671 | printk("FEC: Could not allocate %s IRQ(%d)!\n", | ||
1672 | idp->name, b+idp->irq); | ||
1673 | } | ||
1674 | |||
1675 | /* Unmask interrupts */ | ||
1676 | MCF_INTC0_ICR36 = 0x2; | ||
1677 | MCF_INTC0_ICR37 = 0x2; | ||
1678 | MCF_INTC0_ICR38 = 0x2; | ||
1679 | MCF_INTC0_ICR39 = 0x2; | ||
1680 | MCF_INTC0_ICR40 = 0x2; | ||
1681 | MCF_INTC0_ICR41 = 0x2; | ||
1682 | MCF_INTC0_ICR42 = 0x2; | ||
1683 | MCF_INTC0_ICR43 = 0x2; | ||
1684 | MCF_INTC0_ICR44 = 0x2; | ||
1685 | MCF_INTC0_ICR45 = 0x2; | ||
1686 | MCF_INTC0_ICR46 = 0x2; | ||
1687 | MCF_INTC0_ICR47 = 0x2; | ||
1688 | MCF_INTC0_ICR48 = 0x2; | ||
1689 | |||
1690 | MCF_INTC0_IMRH &= ~( | ||
1691 | MCF_INTC_IMRH_INT_MASK36 | | ||
1692 | MCF_INTC_IMRH_INT_MASK37 | | ||
1693 | MCF_INTC_IMRH_INT_MASK38 | | ||
1694 | MCF_INTC_IMRH_INT_MASK39 | | ||
1695 | MCF_INTC_IMRH_INT_MASK40 | | ||
1696 | MCF_INTC_IMRH_INT_MASK41 | | ||
1697 | MCF_INTC_IMRH_INT_MASK42 | | ||
1698 | MCF_INTC_IMRH_INT_MASK43 | | ||
1699 | MCF_INTC_IMRH_INT_MASK44 | | ||
1700 | MCF_INTC_IMRH_INT_MASK45 | | ||
1701 | MCF_INTC_IMRH_INT_MASK46 | | ||
1702 | MCF_INTC_IMRH_INT_MASK47 | | ||
1703 | MCF_INTC_IMRH_INT_MASK48 ); | ||
1704 | |||
1705 | /* Set up gpio outputs for MII lines */ | ||
1706 | MCF_GPIO_PAR_FECI2C |= (0 | | ||
1707 | MCF_GPIO_PAR_FECI2C_PAR_MDC_EMDC | | ||
1708 | MCF_GPIO_PAR_FECI2C_PAR_MDIO_EMDIO); | ||
1709 | MCF_GPIO_PAR_FEC = (0 | | ||
1710 | MCF_GPIO_PAR_FEC_PAR_FEC_7W_FEC | | ||
1711 | MCF_GPIO_PAR_FEC_PAR_FEC_MII_FEC); | ||
1712 | } | ||
1713 | |||
1714 | static void __inline__ fec_set_mii(struct net_device *dev, struct fec_enet_private *fep) | ||
1715 | { | ||
1716 | volatile fec_t *fecp; | ||
1717 | |||
1718 | fecp = fep->hwp; | ||
1719 | fecp->fec_r_cntrl = OPT_FRAME_SIZE | 0x04; | ||
1720 | fecp->fec_x_cntrl = 0x00; | ||
1721 | |||
1722 | /* | ||
1723 | * Set MII speed to 2.5 MHz | ||
1724 | */ | ||
1725 | fep->phy_speed = ((((MCF_CLK / 2) / (2500000 / 10)) + 5) / 10) * 2; | ||
1726 | fecp->fec_mii_speed = fep->phy_speed; | ||
1727 | |||
1728 | fec_restart(dev, 0); | ||
1729 | } | ||
1730 | |||
1731 | static void __inline__ fec_get_mac(struct net_device *dev) | ||
1732 | { | ||
1733 | struct fec_enet_private *fep = netdev_priv(dev); | ||
1734 | volatile fec_t *fecp; | ||
1735 | unsigned char *iap, tmpaddr[ETH_ALEN]; | ||
1736 | |||
1737 | fecp = fep->hwp; | ||
1738 | |||
1739 | if (FEC_FLASHMAC) { | ||
1740 | /* | ||
1741 | * Get MAC address from FLASH. | ||
1742 | * If it is all 1's or 0's, use the default. | ||
1743 | */ | ||
1744 | iap = FEC_FLASHMAC; | ||
1745 | if ((iap[0] == 0) && (iap[1] == 0) && (iap[2] == 0) && | ||
1746 | (iap[3] == 0) && (iap[4] == 0) && (iap[5] == 0)) | ||
1747 | iap = fec_mac_default; | ||
1748 | if ((iap[0] == 0xff) && (iap[1] == 0xff) && (iap[2] == 0xff) && | ||
1749 | (iap[3] == 0xff) && (iap[4] == 0xff) && (iap[5] == 0xff)) | ||
1750 | iap = fec_mac_default; | ||
1751 | } else { | ||
1752 | *((unsigned long *) &tmpaddr[0]) = fecp->fec_addr_low; | ||
1753 | *((unsigned short *) &tmpaddr[4]) = (fecp->fec_addr_high >> 16); | ||
1754 | iap = &tmpaddr[0]; | ||
1755 | } | ||
1756 | |||
1757 | memcpy(dev->dev_addr, iap, ETH_ALEN); | ||
1758 | |||
1759 | /* Adjust MAC if using default MAC address */ | ||
1760 | if (iap == fec_mac_default) | ||
1761 | dev->dev_addr[ETH_ALEN-1] = fec_mac_default[ETH_ALEN-1] + fep->index; | ||
1762 | } | ||
1763 | |||
1764 | static void __inline__ fec_enable_phy_intr(void) | ||
1765 | { | ||
1766 | } | ||
1767 | |||
1768 | static void __inline__ fec_disable_phy_intr(void) | ||
1769 | { | ||
1770 | } | ||
1771 | |||
1772 | static void __inline__ fec_phy_ack_intr(void) | ||
1773 | { | ||
1774 | } | ||
1775 | |||
1776 | static void __inline__ fec_localhw_setup(void) | ||
1777 | { | ||
1778 | } | ||
1779 | |||
1780 | /* | ||
1781 | * Do not need to make region uncached on 532x. | ||
1782 | */ | ||
1783 | static void __inline__ fec_uncache(unsigned long addr) | ||
1784 | { | ||
1785 | } | ||
1786 | |||
1787 | /* ------------------------------------------------------------------------- */ | ||
1788 | |||
1789 | |||
1621 | #else | 1790 | #else |
1622 | 1791 | ||
1623 | /* | 1792 | /* |
@@ -1985,9 +2154,12 @@ fec_enet_open(struct net_device *dev) | |||
1985 | mii_do_cmd(dev, fep->phy->config); | 2154 | mii_do_cmd(dev, fep->phy->config); |
1986 | mii_do_cmd(dev, phy_cmd_config); /* display configuration */ | 2155 | mii_do_cmd(dev, phy_cmd_config); /* display configuration */ |
1987 | 2156 | ||
1988 | /* FIXME: use netif_carrier_{on,off} ; this polls | 2157 | /* Poll until the PHY tells us its configuration |
1989 | * until link is up which is wrong... could be | 2158 | * (not link state). |
1990 | * 30 seconds or more we are trapped in here. -jgarzik | 2159 | * Request is initiated by mii_do_cmd above, but answer |
2160 | * comes by interrupt. | ||
2161 | * This should take about 25 usec per register at 2.5 MHz, | ||
2162 | * and we read approximately 5 registers. | ||
1991 | */ | 2163 | */ |
1992 | while(!fep->sequence_done) | 2164 | while(!fep->sequence_done) |
1993 | schedule(); | 2165 | schedule(); |
@@ -2253,15 +2425,11 @@ int __init fec_enet_init(struct net_device *dev) | |||
2253 | */ | 2425 | */ |
2254 | fec_request_intrs(dev); | 2426 | fec_request_intrs(dev); |
2255 | 2427 | ||
2256 | /* Clear and enable interrupts */ | ||
2257 | fecp->fec_ievent = 0xffc00000; | ||
2258 | fecp->fec_imask = (FEC_ENET_TXF | FEC_ENET_TXB | | ||
2259 | FEC_ENET_RXF | FEC_ENET_RXB | FEC_ENET_MII); | ||
2260 | fecp->fec_hash_table_high = 0; | 2428 | fecp->fec_hash_table_high = 0; |
2261 | fecp->fec_hash_table_low = 0; | 2429 | fecp->fec_hash_table_low = 0; |
2262 | fecp->fec_r_buff_size = PKT_MAXBLR_SIZE; | 2430 | fecp->fec_r_buff_size = PKT_MAXBLR_SIZE; |
2263 | fecp->fec_ecntrl = 2; | 2431 | fecp->fec_ecntrl = 2; |
2264 | fecp->fec_r_des_active = 0x01000000; | 2432 | fecp->fec_r_des_active = 0; |
2265 | 2433 | ||
2266 | dev->base_addr = (unsigned long)fecp; | 2434 | dev->base_addr = (unsigned long)fecp; |
2267 | 2435 | ||
@@ -2281,6 +2449,11 @@ int __init fec_enet_init(struct net_device *dev) | |||
2281 | /* setup MII interface */ | 2449 | /* setup MII interface */ |
2282 | fec_set_mii(dev, fep); | 2450 | fec_set_mii(dev, fep); |
2283 | 2451 | ||
2452 | /* Clear and enable interrupts */ | ||
2453 | fecp->fec_ievent = 0xffc00000; | ||
2454 | fecp->fec_imask = (FEC_ENET_TXF | FEC_ENET_TXB | | ||
2455 | FEC_ENET_RXF | FEC_ENET_RXB | FEC_ENET_MII); | ||
2456 | |||
2284 | /* Queue up command to detect the PHY and initialize the | 2457 | /* Queue up command to detect the PHY and initialize the |
2285 | * remainder of the interface. | 2458 | * remainder of the interface. |
2286 | */ | 2459 | */ |
@@ -2312,11 +2485,6 @@ fec_restart(struct net_device *dev, int duplex) | |||
2312 | fecp->fec_ecntrl = 1; | 2485 | fecp->fec_ecntrl = 1; |
2313 | udelay(10); | 2486 | udelay(10); |
2314 | 2487 | ||
2315 | /* Enable interrupts we wish to service. | ||
2316 | */ | ||
2317 | fecp->fec_imask = (FEC_ENET_TXF | FEC_ENET_TXB | | ||
2318 | FEC_ENET_RXF | FEC_ENET_RXB | FEC_ENET_MII); | ||
2319 | |||
2320 | /* Clear any outstanding interrupt. | 2488 | /* Clear any outstanding interrupt. |
2321 | */ | 2489 | */ |
2322 | fecp->fec_ievent = 0xffc00000; | 2490 | fecp->fec_ievent = 0xffc00000; |
@@ -2408,7 +2576,12 @@ fec_restart(struct net_device *dev, int duplex) | |||
2408 | /* And last, enable the transmit and receive processing. | 2576 | /* And last, enable the transmit and receive processing. |
2409 | */ | 2577 | */ |
2410 | fecp->fec_ecntrl = 2; | 2578 | fecp->fec_ecntrl = 2; |
2411 | fecp->fec_r_des_active = 0x01000000; | 2579 | fecp->fec_r_des_active = 0; |
2580 | |||
2581 | /* Enable interrupts we wish to service. | ||
2582 | */ | ||
2583 | fecp->fec_imask = (FEC_ENET_TXF | FEC_ENET_TXB | | ||
2584 | FEC_ENET_RXF | FEC_ENET_RXB | FEC_ENET_MII); | ||
2412 | } | 2585 | } |
2413 | 2586 | ||
2414 | static void | 2587 | static void |
@@ -2420,9 +2593,16 @@ fec_stop(struct net_device *dev) | |||
2420 | fep = netdev_priv(dev); | 2593 | fep = netdev_priv(dev); |
2421 | fecp = fep->hwp; | 2594 | fecp = fep->hwp; |
2422 | 2595 | ||
2423 | fecp->fec_x_cntrl = 0x01; /* Graceful transmit stop */ | 2596 | /* |
2424 | 2597 | ** We cannot expect a graceful transmit stop without link !!! | |
2425 | while(!(fecp->fec_ievent & FEC_ENET_GRA)); | 2598 | */ |
2599 | if (fep->link) | ||
2600 | { | ||
2601 | fecp->fec_x_cntrl = 0x01; /* Graceful transmit stop */ | ||
2602 | udelay(10); | ||
2603 | if (!(fecp->fec_ievent & FEC_ENET_GRA)) | ||
2604 | printk("fec_stop : Graceful transmit stop did not complete !\n"); | ||
2605 | } | ||
2426 | 2606 | ||
2427 | /* Whack a reset. We should wait for this. | 2607 | /* Whack a reset. We should wait for this. |
2428 | */ | 2608 | */ |
diff --git a/drivers/net/fs_enet/fs_enet-mii.c b/drivers/net/fs_enet/fs_enet-mii.c index c6770377ef87..0cd07150bf4a 100644 --- a/drivers/net/fs_enet/fs_enet-mii.c +++ b/drivers/net/fs_enet/fs_enet-mii.c | |||
@@ -431,8 +431,7 @@ static struct fs_enet_mii_bus *create_bus(const struct fs_mii_bus_info *bi) | |||
431 | return bus; | 431 | return bus; |
432 | 432 | ||
433 | err: | 433 | err: |
434 | if (bus) | 434 | kfree(bus); |
435 | kfree(bus); | ||
436 | return ERR_PTR(ret); | 435 | return ERR_PTR(ret); |
437 | } | 436 | } |
438 | 437 | ||
diff --git a/drivers/net/hamradio/dmascc.c b/drivers/net/hamradio/dmascc.c index 0d5fccc984bb..c9a46b89942a 100644 --- a/drivers/net/hamradio/dmascc.c +++ b/drivers/net/hamradio/dmascc.c | |||
@@ -436,7 +436,7 @@ static int __init dmascc_init(void) | |||
436 | module_init(dmascc_init); | 436 | module_init(dmascc_init); |
437 | module_exit(dmascc_exit); | 437 | module_exit(dmascc_exit); |
438 | 438 | ||
439 | static void dev_setup(struct net_device *dev) | 439 | static void __init dev_setup(struct net_device *dev) |
440 | { | 440 | { |
441 | dev->type = ARPHRD_AX25; | 441 | dev->type = ARPHRD_AX25; |
442 | dev->hard_header_len = AX25_MAX_HEADER_LEN; | 442 | dev->hard_header_len = AX25_MAX_HEADER_LEN; |
diff --git a/drivers/net/natsemi.c b/drivers/net/natsemi.c index 2e4ecedba057..5657049c2160 100644 --- a/drivers/net/natsemi.c +++ b/drivers/net/natsemi.c | |||
@@ -226,7 +226,6 @@ static int full_duplex[MAX_UNITS]; | |||
226 | NATSEMI_PG1_NREGS) | 226 | NATSEMI_PG1_NREGS) |
227 | #define NATSEMI_REGS_VER 1 /* v1 added RFDR registers */ | 227 | #define NATSEMI_REGS_VER 1 /* v1 added RFDR registers */ |
228 | #define NATSEMI_REGS_SIZE (NATSEMI_NREGS * sizeof(u32)) | 228 | #define NATSEMI_REGS_SIZE (NATSEMI_NREGS * sizeof(u32)) |
229 | #define NATSEMI_DEF_EEPROM_SIZE 24 /* 12 16-bit values */ | ||
230 | 229 | ||
231 | /* Buffer sizes: | 230 | /* Buffer sizes: |
232 | * The nic writes 32-bit values, even if the upper bytes of | 231 | * The nic writes 32-bit values, even if the upper bytes of |
@@ -344,18 +343,6 @@ None characterised. | |||
344 | 343 | ||
345 | 344 | ||
346 | 345 | ||
347 | enum pcistuff { | ||
348 | PCI_USES_IO = 0x01, | ||
349 | PCI_USES_MEM = 0x02, | ||
350 | PCI_USES_MASTER = 0x04, | ||
351 | PCI_ADDR0 = 0x08, | ||
352 | PCI_ADDR1 = 0x10, | ||
353 | }; | ||
354 | |||
355 | /* MMIO operations required */ | ||
356 | #define PCI_IOTYPE (PCI_USES_MASTER | PCI_USES_MEM | PCI_ADDR1) | ||
357 | |||
358 | |||
359 | /* | 346 | /* |
360 | * Support for fibre connections on Am79C874: | 347 | * Support for fibre connections on Am79C874: |
361 | * This phy needs a special setup when connected to a fibre cable. | 348 | * This phy needs a special setup when connected to a fibre cable. |
@@ -363,22 +350,25 @@ enum pcistuff { | |||
363 | */ | 350 | */ |
364 | #define PHYID_AM79C874 0x0022561b | 351 | #define PHYID_AM79C874 0x0022561b |
365 | 352 | ||
366 | #define MII_MCTRL 0x15 /* mode control register */ | 353 | enum { |
367 | #define MII_FX_SEL 0x0001 /* 100BASE-FX (fiber) */ | 354 | MII_MCTRL = 0x15, /* mode control register */ |
368 | #define MII_EN_SCRM 0x0004 /* enable scrambler (tp) */ | 355 | MII_FX_SEL = 0x0001, /* 100BASE-FX (fiber) */ |
356 | MII_EN_SCRM = 0x0004, /* enable scrambler (tp) */ | ||
357 | }; | ||
369 | 358 | ||
370 | 359 | ||
371 | /* array of board data directly indexed by pci_tbl[x].driver_data */ | 360 | /* array of board data directly indexed by pci_tbl[x].driver_data */ |
372 | static const struct { | 361 | static const struct { |
373 | const char *name; | 362 | const char *name; |
374 | unsigned long flags; | 363 | unsigned long flags; |
364 | unsigned int eeprom_size; | ||
375 | } natsemi_pci_info[] __devinitdata = { | 365 | } natsemi_pci_info[] __devinitdata = { |
376 | { "NatSemi DP8381[56]", PCI_IOTYPE }, | 366 | { "NatSemi DP8381[56]", 0, 24 }, |
377 | }; | 367 | }; |
378 | 368 | ||
379 | static struct pci_device_id natsemi_pci_tbl[] = { | 369 | static const struct pci_device_id natsemi_pci_tbl[] __devinitdata = { |
380 | { PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_83815, PCI_ANY_ID, PCI_ANY_ID, }, | 370 | { PCI_VENDOR_ID_NS, 0x0020, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, |
381 | { 0, }, | 371 | { } /* terminate list */ |
382 | }; | 372 | }; |
383 | MODULE_DEVICE_TABLE(pci, natsemi_pci_tbl); | 373 | MODULE_DEVICE_TABLE(pci, natsemi_pci_tbl); |
384 | 374 | ||
@@ -813,6 +803,42 @@ static void move_int_phy(struct net_device *dev, int addr) | |||
813 | udelay(1); | 803 | udelay(1); |
814 | } | 804 | } |
815 | 805 | ||
806 | static void __devinit natsemi_init_media (struct net_device *dev) | ||
807 | { | ||
808 | struct netdev_private *np = netdev_priv(dev); | ||
809 | u32 tmp; | ||
810 | |||
811 | netif_carrier_off(dev); | ||
812 | |||
813 | /* get the initial settings from hardware */ | ||
814 | tmp = mdio_read(dev, MII_BMCR); | ||
815 | np->speed = (tmp & BMCR_SPEED100)? SPEED_100 : SPEED_10; | ||
816 | np->duplex = (tmp & BMCR_FULLDPLX)? DUPLEX_FULL : DUPLEX_HALF; | ||
817 | np->autoneg = (tmp & BMCR_ANENABLE)? AUTONEG_ENABLE: AUTONEG_DISABLE; | ||
818 | np->advertising= mdio_read(dev, MII_ADVERTISE); | ||
819 | |||
820 | if ((np->advertising & ADVERTISE_ALL) != ADVERTISE_ALL | ||
821 | && netif_msg_probe(np)) { | ||
822 | printk(KERN_INFO "natsemi %s: Transceiver default autonegotiation %s " | ||
823 | "10%s %s duplex.\n", | ||
824 | pci_name(np->pci_dev), | ||
825 | (mdio_read(dev, MII_BMCR) & BMCR_ANENABLE)? | ||
826 | "enabled, advertise" : "disabled, force", | ||
827 | (np->advertising & | ||
828 | (ADVERTISE_100FULL|ADVERTISE_100HALF))? | ||
829 | "0" : "", | ||
830 | (np->advertising & | ||
831 | (ADVERTISE_100FULL|ADVERTISE_10FULL))? | ||
832 | "full" : "half"); | ||
833 | } | ||
834 | if (netif_msg_probe(np)) | ||
835 | printk(KERN_INFO | ||
836 | "natsemi %s: Transceiver status %#04x advertising %#04x.\n", | ||
837 | pci_name(np->pci_dev), mdio_read(dev, MII_BMSR), | ||
838 | np->advertising); | ||
839 | |||
840 | } | ||
841 | |||
816 | static int __devinit natsemi_probe1 (struct pci_dev *pdev, | 842 | static int __devinit natsemi_probe1 (struct pci_dev *pdev, |
817 | const struct pci_device_id *ent) | 843 | const struct pci_device_id *ent) |
818 | { | 844 | { |
@@ -852,8 +878,7 @@ static int __devinit natsemi_probe1 (struct pci_dev *pdev, | |||
852 | iosize = pci_resource_len(pdev, pcibar); | 878 | iosize = pci_resource_len(pdev, pcibar); |
853 | irq = pdev->irq; | 879 | irq = pdev->irq; |
854 | 880 | ||
855 | if (natsemi_pci_info[chip_idx].flags & PCI_USES_MASTER) | 881 | pci_set_master(pdev); |
856 | pci_set_master(pdev); | ||
857 | 882 | ||
858 | dev = alloc_etherdev(sizeof (struct netdev_private)); | 883 | dev = alloc_etherdev(sizeof (struct netdev_private)); |
859 | if (!dev) | 884 | if (!dev) |
@@ -892,7 +917,7 @@ static int __devinit natsemi_probe1 (struct pci_dev *pdev, | |||
892 | np->msg_enable = (debug >= 0) ? (1<<debug)-1 : NATSEMI_DEF_MSG; | 917 | np->msg_enable = (debug >= 0) ? (1<<debug)-1 : NATSEMI_DEF_MSG; |
893 | np->hands_off = 0; | 918 | np->hands_off = 0; |
894 | np->intr_status = 0; | 919 | np->intr_status = 0; |
895 | np->eeprom_size = NATSEMI_DEF_EEPROM_SIZE; | 920 | np->eeprom_size = natsemi_pci_info[chip_idx].eeprom_size; |
896 | 921 | ||
897 | /* Initial port: | 922 | /* Initial port: |
898 | * - If the nic was configured to use an external phy and if find_mii | 923 | * - If the nic was configured to use an external phy and if find_mii |
@@ -957,34 +982,7 @@ static int __devinit natsemi_probe1 (struct pci_dev *pdev, | |||
957 | if (mtu) | 982 | if (mtu) |
958 | dev->mtu = mtu; | 983 | dev->mtu = mtu; |
959 | 984 | ||
960 | netif_carrier_off(dev); | 985 | natsemi_init_media(dev); |
961 | |||
962 | /* get the initial settings from hardware */ | ||
963 | tmp = mdio_read(dev, MII_BMCR); | ||
964 | np->speed = (tmp & BMCR_SPEED100)? SPEED_100 : SPEED_10; | ||
965 | np->duplex = (tmp & BMCR_FULLDPLX)? DUPLEX_FULL : DUPLEX_HALF; | ||
966 | np->autoneg = (tmp & BMCR_ANENABLE)? AUTONEG_ENABLE: AUTONEG_DISABLE; | ||
967 | np->advertising= mdio_read(dev, MII_ADVERTISE); | ||
968 | |||
969 | if ((np->advertising & ADVERTISE_ALL) != ADVERTISE_ALL | ||
970 | && netif_msg_probe(np)) { | ||
971 | printk(KERN_INFO "natsemi %s: Transceiver default autonegotiation %s " | ||
972 | "10%s %s duplex.\n", | ||
973 | pci_name(np->pci_dev), | ||
974 | (mdio_read(dev, MII_BMCR) & BMCR_ANENABLE)? | ||
975 | "enabled, advertise" : "disabled, force", | ||
976 | (np->advertising & | ||
977 | (ADVERTISE_100FULL|ADVERTISE_100HALF))? | ||
978 | "0" : "", | ||
979 | (np->advertising & | ||
980 | (ADVERTISE_100FULL|ADVERTISE_10FULL))? | ||
981 | "full" : "half"); | ||
982 | } | ||
983 | if (netif_msg_probe(np)) | ||
984 | printk(KERN_INFO | ||
985 | "natsemi %s: Transceiver status %#04x advertising %#04x.\n", | ||
986 | pci_name(np->pci_dev), mdio_read(dev, MII_BMSR), | ||
987 | np->advertising); | ||
988 | 986 | ||
989 | /* save the silicon revision for later querying */ | 987 | /* save the silicon revision for later querying */ |
990 | np->srr = readl(ioaddr + SiliconRev); | 988 | np->srr = readl(ioaddr + SiliconRev); |
diff --git a/drivers/net/pcnet32.c b/drivers/net/pcnet32.c index fc08c4af506c..0e01c75da429 100644 --- a/drivers/net/pcnet32.c +++ b/drivers/net/pcnet32.c | |||
@@ -309,12 +309,6 @@ static int pcnet32_alloc_ring(struct net_device *dev, char *name); | |||
309 | static void pcnet32_free_ring(struct net_device *dev); | 309 | static void pcnet32_free_ring(struct net_device *dev); |
310 | static void pcnet32_check_media(struct net_device *dev, int verbose); | 310 | static void pcnet32_check_media(struct net_device *dev, int verbose); |
311 | 311 | ||
312 | enum pci_flags_bit { | ||
313 | PCI_USES_IO = 1, PCI_USES_MEM = 2, PCI_USES_MASTER = 4, | ||
314 | PCI_ADDR0 = 0x10 << 0, PCI_ADDR1 = 0x10 << 1, PCI_ADDR2 = | ||
315 | 0x10 << 2, PCI_ADDR3 = 0x10 << 3, | ||
316 | }; | ||
317 | |||
318 | static u16 pcnet32_wio_read_csr(unsigned long addr, int index) | 312 | static u16 pcnet32_wio_read_csr(unsigned long addr, int index) |
319 | { | 313 | { |
320 | outw(index, addr + PCNET32_WIO_RAP); | 314 | outw(index, addr + PCNET32_WIO_RAP); |
diff --git a/drivers/net/phy/lxt.c b/drivers/net/phy/lxt.c index bef79e454c33..3f702c503afe 100644 --- a/drivers/net/phy/lxt.c +++ b/drivers/net/phy/lxt.c | |||
@@ -123,9 +123,9 @@ static int lxt971_config_intr(struct phy_device *phydev) | |||
123 | } | 123 | } |
124 | 124 | ||
125 | static struct phy_driver lxt970_driver = { | 125 | static struct phy_driver lxt970_driver = { |
126 | .phy_id = 0x07810000, | 126 | .phy_id = 0x78100000, |
127 | .name = "LXT970", | 127 | .name = "LXT970", |
128 | .phy_id_mask = 0x0fffffff, | 128 | .phy_id_mask = 0xfffffff0, |
129 | .features = PHY_BASIC_FEATURES, | 129 | .features = PHY_BASIC_FEATURES, |
130 | .flags = PHY_HAS_INTERRUPT, | 130 | .flags = PHY_HAS_INTERRUPT, |
131 | .config_init = lxt970_config_init, | 131 | .config_init = lxt970_config_init, |
@@ -137,9 +137,9 @@ static struct phy_driver lxt970_driver = { | |||
137 | }; | 137 | }; |
138 | 138 | ||
139 | static struct phy_driver lxt971_driver = { | 139 | static struct phy_driver lxt971_driver = { |
140 | .phy_id = 0x0001378e, | 140 | .phy_id = 0x001378e0, |
141 | .name = "LXT971", | 141 | .name = "LXT971", |
142 | .phy_id_mask = 0x0fffffff, | 142 | .phy_id_mask = 0xfffffff0, |
143 | .features = PHY_BASIC_FEATURES, | 143 | .features = PHY_BASIC_FEATURES, |
144 | .flags = PHY_HAS_INTERRUPT, | 144 | .flags = PHY_HAS_INTERRUPT, |
145 | .config_aneg = genphy_config_aneg, | 145 | .config_aneg = genphy_config_aneg, |
diff --git a/drivers/net/ppp_generic.c b/drivers/net/ppp_generic.c index d643a097faa5..425ff5b117f1 100644 --- a/drivers/net/ppp_generic.c +++ b/drivers/net/ppp_generic.c | |||
@@ -28,7 +28,6 @@ | |||
28 | #include <linux/kmod.h> | 28 | #include <linux/kmod.h> |
29 | #include <linux/init.h> | 29 | #include <linux/init.h> |
30 | #include <linux/list.h> | 30 | #include <linux/list.h> |
31 | #include <linux/devfs_fs_kernel.h> | ||
32 | #include <linux/netdevice.h> | 31 | #include <linux/netdevice.h> |
33 | #include <linux/poll.h> | 32 | #include <linux/poll.h> |
34 | #include <linux/ppp_defs.h> | 33 | #include <linux/ppp_defs.h> |
@@ -863,10 +862,6 @@ static int __init ppp_init(void) | |||
863 | goto out_chrdev; | 862 | goto out_chrdev; |
864 | } | 863 | } |
865 | class_device_create(ppp_class, NULL, MKDEV(PPP_MAJOR, 0), NULL, "ppp"); | 864 | class_device_create(ppp_class, NULL, MKDEV(PPP_MAJOR, 0), NULL, "ppp"); |
866 | err = devfs_mk_cdev(MKDEV(PPP_MAJOR, 0), | ||
867 | S_IFCHR|S_IRUSR|S_IWUSR, "ppp"); | ||
868 | if (err) | ||
869 | goto out_class; | ||
870 | } | 865 | } |
871 | 866 | ||
872 | out: | 867 | out: |
@@ -874,9 +869,6 @@ out: | |||
874 | printk(KERN_ERR "failed to register PPP device (%d)\n", err); | 869 | printk(KERN_ERR "failed to register PPP device (%d)\n", err); |
875 | return err; | 870 | return err; |
876 | 871 | ||
877 | out_class: | ||
878 | class_device_destroy(ppp_class, MKDEV(PPP_MAJOR,0)); | ||
879 | class_destroy(ppp_class); | ||
880 | out_chrdev: | 872 | out_chrdev: |
881 | unregister_chrdev(PPP_MAJOR, "ppp"); | 873 | unregister_chrdev(PPP_MAJOR, "ppp"); |
882 | goto out; | 874 | goto out; |
@@ -2681,7 +2673,6 @@ static void __exit ppp_cleanup(void) | |||
2681 | cardmap_destroy(&all_ppp_units); | 2673 | cardmap_destroy(&all_ppp_units); |
2682 | if (unregister_chrdev(PPP_MAJOR, "ppp") != 0) | 2674 | if (unregister_chrdev(PPP_MAJOR, "ppp") != 0) |
2683 | printk(KERN_ERR "PPP: failed to unregister PPP device\n"); | 2675 | printk(KERN_ERR "PPP: failed to unregister PPP device\n"); |
2684 | devfs_remove("ppp"); | ||
2685 | class_device_destroy(ppp_class, MKDEV(PPP_MAJOR, 0)); | 2676 | class_device_destroy(ppp_class, MKDEV(PPP_MAJOR, 0)); |
2686 | class_destroy(ppp_class); | 2677 | class_destroy(ppp_class); |
2687 | } | 2678 | } |
diff --git a/drivers/net/skge.c b/drivers/net/skge.c index 19a4a16055dc..1608efab4e3d 100644 --- a/drivers/net/skge.c +++ b/drivers/net/skge.c | |||
@@ -3354,8 +3354,8 @@ static int __devinit skge_probe(struct pci_dev *pdev, | |||
3354 | if (err) | 3354 | if (err) |
3355 | goto err_out_free_irq; | 3355 | goto err_out_free_irq; |
3356 | 3356 | ||
3357 | printk(KERN_INFO PFX DRV_VERSION " addr 0x%lx irq %d chip %s rev %d\n", | 3357 | printk(KERN_INFO PFX DRV_VERSION " addr 0x%llx irq %d chip %s rev %d\n", |
3358 | pci_resource_start(pdev, 0), pdev->irq, | 3358 | (unsigned long long)pci_resource_start(pdev, 0), pdev->irq, |
3359 | skge_board_name(hw), hw->chip_rev); | 3359 | skge_board_name(hw), hw->chip_rev); |
3360 | 3360 | ||
3361 | if ((dev = skge_devinit(hw, 0, using_dac)) == NULL) | 3361 | if ((dev = skge_devinit(hw, 0, using_dac)) == NULL) |
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c index d3577871be28..e122007e16da 100644 --- a/drivers/net/sky2.c +++ b/drivers/net/sky2.c | |||
@@ -3311,9 +3311,9 @@ static int __devinit sky2_probe(struct pci_dev *pdev, | |||
3311 | if (err) | 3311 | if (err) |
3312 | goto err_out_iounmap; | 3312 | goto err_out_iounmap; |
3313 | 3313 | ||
3314 | printk(KERN_INFO PFX "v%s addr 0x%lx irq %d Yukon-%s (0x%x) rev %d\n", | 3314 | printk(KERN_INFO PFX "v%s addr 0x%llx irq %d Yukon-%s (0x%x) rev %d\n", |
3315 | DRV_VERSION, pci_resource_start(pdev, 0), pdev->irq, | 3315 | DRV_VERSION, (unsigned long long)pci_resource_start(pdev, 0), |
3316 | yukon2_name[hw->chip_id - CHIP_ID_YUKON_XL], | 3316 | pdev->irq, yukon2_name[hw->chip_id - CHIP_ID_YUKON_XL], |
3317 | hw->chip_id, hw->chip_rev); | 3317 | hw->chip_id, hw->chip_rev); |
3318 | 3318 | ||
3319 | dev = sky2_init_netdev(hw, 0, using_dac); | 3319 | dev = sky2_init_netdev(hw, 0, using_dac); |
diff --git a/drivers/net/tulip/de2104x.c b/drivers/net/tulip/de2104x.c index 5f743b972949..fc2468ecce0b 100644 --- a/drivers/net/tulip/de2104x.c +++ b/drivers/net/tulip/de2104x.c | |||
@@ -2007,8 +2007,8 @@ static int __init de_init_one (struct pci_dev *pdev, | |||
2007 | } | 2007 | } |
2008 | if (pci_resource_len(pdev, 1) < DE_REGS_SIZE) { | 2008 | if (pci_resource_len(pdev, 1) < DE_REGS_SIZE) { |
2009 | rc = -EIO; | 2009 | rc = -EIO; |
2010 | printk(KERN_ERR PFX "MMIO resource (%lx) too small on pci dev %s\n", | 2010 | printk(KERN_ERR PFX "MMIO resource (%llx) too small on pci dev %s\n", |
2011 | pci_resource_len(pdev, 1), pci_name(pdev)); | 2011 | (unsigned long long)pci_resource_len(pdev, 1), pci_name(pdev)); |
2012 | goto err_out_res; | 2012 | goto err_out_res; |
2013 | } | 2013 | } |
2014 | 2014 | ||
@@ -2016,8 +2016,9 @@ static int __init de_init_one (struct pci_dev *pdev, | |||
2016 | regs = ioremap_nocache(pciaddr, DE_REGS_SIZE); | 2016 | regs = ioremap_nocache(pciaddr, DE_REGS_SIZE); |
2017 | if (!regs) { | 2017 | if (!regs) { |
2018 | rc = -EIO; | 2018 | rc = -EIO; |
2019 | printk(KERN_ERR PFX "Cannot map PCI MMIO (%lx@%lx) on pci dev %s\n", | 2019 | printk(KERN_ERR PFX "Cannot map PCI MMIO (%llx@%lx) on pci dev %s\n", |
2020 | pci_resource_len(pdev, 1), pciaddr, pci_name(pdev)); | 2020 | (unsigned long long)pci_resource_len(pdev, 1), |
2021 | pciaddr, pci_name(pdev)); | ||
2021 | goto err_out_res; | 2022 | goto err_out_res; |
2022 | } | 2023 | } |
2023 | dev->base_addr = (unsigned long) regs; | 2024 | dev->base_addr = (unsigned long) regs; |
diff --git a/drivers/net/tulip/tulip_core.c b/drivers/net/tulip/tulip_core.c index e0de66739a42..53fd9b56d0bd 100644 --- a/drivers/net/tulip/tulip_core.c +++ b/drivers/net/tulip/tulip_core.c | |||
@@ -1350,10 +1350,10 @@ static int __devinit tulip_init_one (struct pci_dev *pdev, | |||
1350 | SET_MODULE_OWNER(dev); | 1350 | SET_MODULE_OWNER(dev); |
1351 | SET_NETDEV_DEV(dev, &pdev->dev); | 1351 | SET_NETDEV_DEV(dev, &pdev->dev); |
1352 | if (pci_resource_len (pdev, 0) < tulip_tbl[chip_idx].io_size) { | 1352 | if (pci_resource_len (pdev, 0) < tulip_tbl[chip_idx].io_size) { |
1353 | printk (KERN_ERR PFX "%s: I/O region (0x%lx@0x%lx) too small, " | 1353 | printk (KERN_ERR PFX "%s: I/O region (0x%llx@0x%llx) too small, " |
1354 | "aborting\n", pci_name(pdev), | 1354 | "aborting\n", pci_name(pdev), |
1355 | pci_resource_len (pdev, 0), | 1355 | (unsigned long long)pci_resource_len (pdev, 0), |
1356 | pci_resource_start (pdev, 0)); | 1356 | (unsigned long long)pci_resource_start (pdev, 0)); |
1357 | goto err_out_free_netdev; | 1357 | goto err_out_free_netdev; |
1358 | } | 1358 | } |
1359 | 1359 | ||
diff --git a/drivers/net/tulip/winbond-840.c b/drivers/net/tulip/winbond-840.c index 8fea2aa455d4..602a6e5002a0 100644 --- a/drivers/net/tulip/winbond-840.c +++ b/drivers/net/tulip/winbond-840.c | |||
@@ -212,26 +212,15 @@ Test with 'ping -s 10000' on a fast computer. | |||
212 | /* | 212 | /* |
213 | PCI probe table. | 213 | PCI probe table. |
214 | */ | 214 | */ |
215 | enum pci_id_flags_bits { | ||
216 | /* Set PCI command register bits before calling probe1(). */ | ||
217 | PCI_USES_IO=1, PCI_USES_MEM=2, PCI_USES_MASTER=4, | ||
218 | /* Read and map the single following PCI BAR. */ | ||
219 | PCI_ADDR0=0<<4, PCI_ADDR1=1<<4, PCI_ADDR2=2<<4, PCI_ADDR3=3<<4, | ||
220 | PCI_ADDR_64BITS=0x100, PCI_NO_ACPI_WAKE=0x200, PCI_NO_MIN_LATENCY=0x400, | ||
221 | }; | ||
222 | enum chip_capability_flags { | 215 | enum chip_capability_flags { |
223 | CanHaveMII=1, HasBrokenTx=2, AlwaysFDX=4, FDXOnNoMII=8,}; | 216 | CanHaveMII=1, HasBrokenTx=2, AlwaysFDX=4, FDXOnNoMII=8, |
224 | #ifdef USE_IO_OPS | 217 | }; |
225 | #define W840_FLAGS (PCI_USES_IO | PCI_ADDR0 | PCI_USES_MASTER) | ||
226 | #else | ||
227 | #define W840_FLAGS (PCI_USES_MEM | PCI_ADDR1 | PCI_USES_MASTER) | ||
228 | #endif | ||
229 | 218 | ||
230 | static struct pci_device_id w840_pci_tbl[] = { | 219 | static const struct pci_device_id w840_pci_tbl[] = { |
231 | { 0x1050, 0x0840, PCI_ANY_ID, 0x8153, 0, 0, 0 }, | 220 | { 0x1050, 0x0840, PCI_ANY_ID, 0x8153, 0, 0, 0 }, |
232 | { 0x1050, 0x0840, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1 }, | 221 | { 0x1050, 0x0840, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1 }, |
233 | { 0x11f6, 0x2011, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 2 }, | 222 | { 0x11f6, 0x2011, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 2 }, |
234 | { 0, } | 223 | { } |
235 | }; | 224 | }; |
236 | MODULE_DEVICE_TABLE(pci, w840_pci_tbl); | 225 | MODULE_DEVICE_TABLE(pci, w840_pci_tbl); |
237 | 226 | ||
@@ -241,18 +230,17 @@ struct pci_id_info { | |||
241 | int pci, pci_mask, subsystem, subsystem_mask; | 230 | int pci, pci_mask, subsystem, subsystem_mask; |
242 | int revision, revision_mask; /* Only 8 bits. */ | 231 | int revision, revision_mask; /* Only 8 bits. */ |
243 | } id; | 232 | } id; |
244 | enum pci_id_flags_bits pci_flags; | ||
245 | int io_size; /* Needed for I/O region check or ioremap(). */ | 233 | int io_size; /* Needed for I/O region check or ioremap(). */ |
246 | int drv_flags; /* Driver use, intended as capability flags. */ | 234 | int drv_flags; /* Driver use, intended as capability flags. */ |
247 | }; | 235 | }; |
248 | static struct pci_id_info pci_id_tbl[] = { | 236 | static struct pci_id_info pci_id_tbl[] = { |
249 | {"Winbond W89c840", /* Sometime a Level-One switch card. */ | 237 | {"Winbond W89c840", /* Sometime a Level-One switch card. */ |
250 | { 0x08401050, 0xffffffff, 0x81530000, 0xffff0000 }, | 238 | { 0x08401050, 0xffffffff, 0x81530000, 0xffff0000 }, |
251 | W840_FLAGS, 128, CanHaveMII | HasBrokenTx | FDXOnNoMII}, | 239 | 128, CanHaveMII | HasBrokenTx | FDXOnNoMII}, |
252 | {"Winbond W89c840", { 0x08401050, 0xffffffff, }, | 240 | {"Winbond W89c840", { 0x08401050, 0xffffffff, }, |
253 | W840_FLAGS, 128, CanHaveMII | HasBrokenTx}, | 241 | 128, CanHaveMII | HasBrokenTx}, |
254 | {"Compex RL100-ATX", { 0x201111F6, 0xffffffff,}, | 242 | {"Compex RL100-ATX", { 0x201111F6, 0xffffffff,}, |
255 | W840_FLAGS, 128, CanHaveMII | HasBrokenTx}, | 243 | 128, CanHaveMII | HasBrokenTx}, |
256 | {NULL,}, /* 0 terminated list. */ | 244 | {NULL,}, /* 0 terminated list. */ |
257 | }; | 245 | }; |
258 | 246 | ||
diff --git a/drivers/net/tun.c b/drivers/net/tun.c index 6c62d5c88268..732c5edec2e5 100644 --- a/drivers/net/tun.c +++ b/drivers/net/tun.c | |||
@@ -780,7 +780,6 @@ static struct miscdevice tun_miscdev = { | |||
780 | .minor = TUN_MINOR, | 780 | .minor = TUN_MINOR, |
781 | .name = "tun", | 781 | .name = "tun", |
782 | .fops = &tun_fops, | 782 | .fops = &tun_fops, |
783 | .devfs_name = "net/tun", | ||
784 | }; | 783 | }; |
785 | 784 | ||
786 | /* ethtool interface */ | 785 | /* ethtool interface */ |
diff --git a/drivers/net/typhoon.c b/drivers/net/typhoon.c index e49e8b520c28..e24d2dafcf6c 100644 --- a/drivers/net/typhoon.c +++ b/drivers/net/typhoon.c | |||
@@ -2568,9 +2568,10 @@ typhoon_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
2568 | 2568 | ||
2569 | pci_set_drvdata(pdev, dev); | 2569 | pci_set_drvdata(pdev, dev); |
2570 | 2570 | ||
2571 | printk(KERN_INFO "%s: %s at %s 0x%lx, ", | 2571 | printk(KERN_INFO "%s: %s at %s 0x%llx, ", |
2572 | dev->name, typhoon_card_info[card_id].name, | 2572 | dev->name, typhoon_card_info[card_id].name, |
2573 | use_mmio ? "MMIO" : "IO", pci_resource_start(pdev, use_mmio)); | 2573 | use_mmio ? "MMIO" : "IO", |
2574 | (unsigned long long)pci_resource_start(pdev, use_mmio)); | ||
2574 | for(i = 0; i < 5; i++) | 2575 | for(i = 0; i < 5; i++) |
2575 | printk("%2.2x:", dev->dev_addr[i]); | 2576 | printk("%2.2x:", dev->dev_addr[i]); |
2576 | printk("%2.2x\n", dev->dev_addr[i]); | 2577 | printk("%2.2x\n", dev->dev_addr[i]); |
diff --git a/drivers/net/wan/c101.c b/drivers/net/wan/c101.c index b60ef02db7b0..c92ac9fde083 100644 --- a/drivers/net/wan/c101.c +++ b/drivers/net/wan/c101.c | |||
@@ -7,7 +7,7 @@ | |||
7 | * under the terms of version 2 of the GNU General Public License | 7 | * under the terms of version 2 of the GNU General Public License |
8 | * as published by the Free Software Foundation. | 8 | * as published by the Free Software Foundation. |
9 | * | 9 | * |
10 | * For information see http://hq.pm.waw.pl/hdlc/ | 10 | * For information see <http://www.kernel.org/pub/linux/utils/net/hdlc/> |
11 | * | 11 | * |
12 | * Sources of information: | 12 | * Sources of information: |
13 | * Hitachi HD64570 SCA User's Manual | 13 | * Hitachi HD64570 SCA User's Manual |
diff --git a/drivers/net/wan/cosa.c b/drivers/net/wan/cosa.c index e392ee8b37a1..be5e33814cb1 100644 --- a/drivers/net/wan/cosa.c +++ b/drivers/net/wan/cosa.c | |||
@@ -85,7 +85,6 @@ | |||
85 | #include <linux/slab.h> | 85 | #include <linux/slab.h> |
86 | #include <linux/poll.h> | 86 | #include <linux/poll.h> |
87 | #include <linux/fs.h> | 87 | #include <linux/fs.h> |
88 | #include <linux/devfs_fs_kernel.h> | ||
89 | #include <linux/interrupt.h> | 88 | #include <linux/interrupt.h> |
90 | #include <linux/delay.h> | 89 | #include <linux/delay.h> |
91 | #include <linux/errno.h> | 90 | #include <linux/errno.h> |
@@ -393,7 +392,6 @@ static int __init cosa_init(void) | |||
393 | err = -ENODEV; | 392 | err = -ENODEV; |
394 | goto out; | 393 | goto out; |
395 | } | 394 | } |
396 | devfs_mk_dir("cosa"); | ||
397 | cosa_class = class_create(THIS_MODULE, "cosa"); | 395 | cosa_class = class_create(THIS_MODULE, "cosa"); |
398 | if (IS_ERR(cosa_class)) { | 396 | if (IS_ERR(cosa_class)) { |
399 | err = PTR_ERR(cosa_class); | 397 | err = PTR_ERR(cosa_class); |
@@ -402,13 +400,6 @@ static int __init cosa_init(void) | |||
402 | for (i=0; i<nr_cards; i++) { | 400 | for (i=0; i<nr_cards; i++) { |
403 | class_device_create(cosa_class, NULL, MKDEV(cosa_major, i), | 401 | class_device_create(cosa_class, NULL, MKDEV(cosa_major, i), |
404 | NULL, "cosa%d", i); | 402 | NULL, "cosa%d", i); |
405 | err = devfs_mk_cdev(MKDEV(cosa_major, i), | ||
406 | S_IFCHR|S_IRUSR|S_IWUSR, | ||
407 | "cosa/%d", i); | ||
408 | if (err) { | ||
409 | class_device_destroy(cosa_class, MKDEV(cosa_major, i)); | ||
410 | goto out_chrdev; | ||
411 | } | ||
412 | } | 403 | } |
413 | err = 0; | 404 | err = 0; |
414 | goto out; | 405 | goto out; |
@@ -426,12 +417,9 @@ static void __exit cosa_exit(void) | |||
426 | int i; | 417 | int i; |
427 | printk(KERN_INFO "Unloading the cosa module\n"); | 418 | printk(KERN_INFO "Unloading the cosa module\n"); |
428 | 419 | ||
429 | for (i=0; i<nr_cards; i++) { | 420 | for (i=0; i<nr_cards; i++) |
430 | class_device_destroy(cosa_class, MKDEV(cosa_major, i)); | 421 | class_device_destroy(cosa_class, MKDEV(cosa_major, i)); |
431 | devfs_remove("cosa/%d", i); | ||
432 | } | ||
433 | class_destroy(cosa_class); | 422 | class_destroy(cosa_class); |
434 | devfs_remove("cosa"); | ||
435 | for (cosa=cosa_cards; nr_cards--; cosa++) { | 423 | for (cosa=cosa_cards; nr_cards--; cosa++) { |
436 | /* Clean up the per-channel data */ | 424 | /* Clean up the per-channel data */ |
437 | for (i=0; i<cosa->nchannels; i++) { | 425 | for (i=0; i<cosa->nchannels; i++) { |
diff --git a/drivers/net/wan/dscc4.c b/drivers/net/wan/dscc4.c index 4505540e3c59..04a376ec0ed8 100644 --- a/drivers/net/wan/dscc4.c +++ b/drivers/net/wan/dscc4.c | |||
@@ -732,15 +732,15 @@ static int __devinit dscc4_init_one(struct pci_dev *pdev, | |||
732 | ioaddr = ioremap(pci_resource_start(pdev, 0), | 732 | ioaddr = ioremap(pci_resource_start(pdev, 0), |
733 | pci_resource_len(pdev, 0)); | 733 | pci_resource_len(pdev, 0)); |
734 | if (!ioaddr) { | 734 | if (!ioaddr) { |
735 | printk(KERN_ERR "%s: cannot remap MMIO region %lx @ %lx\n", | 735 | printk(KERN_ERR "%s: cannot remap MMIO region %llx @ %llx\n", |
736 | DRV_NAME, pci_resource_len(pdev, 0), | 736 | DRV_NAME, (unsigned long long)pci_resource_len(pdev, 0), |
737 | pci_resource_start(pdev, 0)); | 737 | (unsigned long long)pci_resource_start(pdev, 0)); |
738 | rc = -EIO; | 738 | rc = -EIO; |
739 | goto err_free_mmio_regions_2; | 739 | goto err_free_mmio_regions_2; |
740 | } | 740 | } |
741 | printk(KERN_DEBUG "Siemens DSCC4, MMIO at %#lx (regs), %#lx (lbi), IRQ %d\n", | 741 | printk(KERN_DEBUG "Siemens DSCC4, MMIO at %#llx (regs), %#llx (lbi), IRQ %d\n", |
742 | pci_resource_start(pdev, 0), | 742 | (unsigned long long)pci_resource_start(pdev, 0), |
743 | pci_resource_start(pdev, 1), pdev->irq); | 743 | (unsigned long long)pci_resource_start(pdev, 1), pdev->irq); |
744 | 744 | ||
745 | /* Cf errata DS5 p.2 */ | 745 | /* Cf errata DS5 p.2 */ |
746 | pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0xf8); | 746 | pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0xf8); |
diff --git a/drivers/net/wan/n2.c b/drivers/net/wan/n2.c index b7d88db89a5c..e013b817cab8 100644 --- a/drivers/net/wan/n2.c +++ b/drivers/net/wan/n2.c | |||
@@ -7,7 +7,7 @@ | |||
7 | * under the terms of version 2 of the GNU General Public License | 7 | * under the terms of version 2 of the GNU General Public License |
8 | * as published by the Free Software Foundation. | 8 | * as published by the Free Software Foundation. |
9 | * | 9 | * |
10 | * For information see http://hq.pm.waw.pl/hdlc/ | 10 | * For information see <http://www.kernel.org/pub/linux/utils/net/hdlc/> |
11 | * | 11 | * |
12 | * Note: integrated CSU/DSU/DDS are not supported by this driver | 12 | * Note: integrated CSU/DSU/DDS are not supported by this driver |
13 | * | 13 | * |
diff --git a/drivers/net/wan/pc300_drv.c b/drivers/net/wan/pc300_drv.c index a3e65d1bc19b..d7897ae89f90 100644 --- a/drivers/net/wan/pc300_drv.c +++ b/drivers/net/wan/pc300_drv.c | |||
@@ -3445,9 +3445,9 @@ cpc_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
3445 | 3445 | ||
3446 | card = (pc300_t *) kmalloc(sizeof(pc300_t), GFP_KERNEL); | 3446 | card = (pc300_t *) kmalloc(sizeof(pc300_t), GFP_KERNEL); |
3447 | if (card == NULL) { | 3447 | if (card == NULL) { |
3448 | printk("PC300 found at RAM 0x%08lx, " | 3448 | printk("PC300 found at RAM 0x%016llx, " |
3449 | "but could not allocate card structure.\n", | 3449 | "but could not allocate card structure.\n", |
3450 | pci_resource_start(pdev, 3)); | 3450 | (unsigned long long)pci_resource_start(pdev, 3)); |
3451 | err = -ENOMEM; | 3451 | err = -ENOMEM; |
3452 | goto err_disable_dev; | 3452 | goto err_disable_dev; |
3453 | } | 3453 | } |
diff --git a/drivers/net/wan/pci200syn.c b/drivers/net/wan/pci200syn.c index 670e8bd2245c..24c3c57c13c9 100644 --- a/drivers/net/wan/pci200syn.c +++ b/drivers/net/wan/pci200syn.c | |||
@@ -7,7 +7,7 @@ | |||
7 | * under the terms of version 2 of the GNU General Public License | 7 | * under the terms of version 2 of the GNU General Public License |
8 | * as published by the Free Software Foundation. | 8 | * as published by the Free Software Foundation. |
9 | * | 9 | * |
10 | * For information see http://hq.pm.waw.pl/hdlc/ | 10 | * For information see <http://www.kernel.org/pub/linux/utils/net/hdlc/> |
11 | * | 11 | * |
12 | * Sources of information: | 12 | * Sources of information: |
13 | * Hitachi HD64572 SCA-II User's Manual | 13 | * Hitachi HD64572 SCA-II User's Manual |
diff --git a/drivers/net/wireless/ipw2200.c b/drivers/net/wireless/ipw2200.c index 081a8999666e..a8a8f975432f 100644 --- a/drivers/net/wireless/ipw2200.c +++ b/drivers/net/wireless/ipw2200.c | |||
@@ -1229,12 +1229,6 @@ static struct ipw_fw_error *ipw_alloc_error_log(struct ipw_priv *priv) | |||
1229 | return error; | 1229 | return error; |
1230 | } | 1230 | } |
1231 | 1231 | ||
1232 | static void ipw_free_error_log(struct ipw_fw_error *error) | ||
1233 | { | ||
1234 | if (error) | ||
1235 | kfree(error); | ||
1236 | } | ||
1237 | |||
1238 | static ssize_t show_event_log(struct device *d, | 1232 | static ssize_t show_event_log(struct device *d, |
1239 | struct device_attribute *attr, char *buf) | 1233 | struct device_attribute *attr, char *buf) |
1240 | { | 1234 | { |
@@ -1296,10 +1290,9 @@ static ssize_t clear_error(struct device *d, | |||
1296 | const char *buf, size_t count) | 1290 | const char *buf, size_t count) |
1297 | { | 1291 | { |
1298 | struct ipw_priv *priv = dev_get_drvdata(d); | 1292 | struct ipw_priv *priv = dev_get_drvdata(d); |
1299 | if (priv->error) { | 1293 | |
1300 | ipw_free_error_log(priv->error); | 1294 | kfree(priv->error); |
1301 | priv->error = NULL; | 1295 | priv->error = NULL; |
1302 | } | ||
1303 | return count; | 1296 | return count; |
1304 | } | 1297 | } |
1305 | 1298 | ||
@@ -1970,8 +1963,7 @@ static void ipw_irq_tasklet(struct ipw_priv *priv) | |||
1970 | struct ipw_fw_error *error = | 1963 | struct ipw_fw_error *error = |
1971 | ipw_alloc_error_log(priv); | 1964 | ipw_alloc_error_log(priv); |
1972 | ipw_dump_error_log(priv, error); | 1965 | ipw_dump_error_log(priv, error); |
1973 | if (error) | 1966 | kfree(error); |
1974 | ipw_free_error_log(error); | ||
1975 | } | 1967 | } |
1976 | #endif | 1968 | #endif |
1977 | } else { | 1969 | } else { |
@@ -11693,10 +11685,8 @@ static void ipw_pci_remove(struct pci_dev *pdev) | |||
11693 | } | 11685 | } |
11694 | } | 11686 | } |
11695 | 11687 | ||
11696 | if (priv->error) { | 11688 | kfree(priv->error); |
11697 | ipw_free_error_log(priv->error); | 11689 | priv->error = NULL; |
11698 | priv->error = NULL; | ||
11699 | } | ||
11700 | 11690 | ||
11701 | #ifdef CONFIG_IPW2200_PROMISCUOUS | 11691 | #ifdef CONFIG_IPW2200_PROMISCUOUS |
11702 | ipw_prom_free(priv); | 11692 | ipw_prom_free(priv); |
diff --git a/drivers/net/yellowfin.c b/drivers/net/yellowfin.c index ecec8e5db786..569305f57561 100644 --- a/drivers/net/yellowfin.c +++ b/drivers/net/yellowfin.c | |||
@@ -234,14 +234,6 @@ See Packet Engines confidential appendix (prototype chips only). | |||
234 | 234 | ||
235 | 235 | ||
236 | 236 | ||
237 | enum pci_id_flags_bits { | ||
238 | /* Set PCI command register bits before calling probe1(). */ | ||
239 | PCI_USES_IO=1, PCI_USES_MEM=2, PCI_USES_MASTER=4, | ||
240 | /* Read and map the single following PCI BAR. */ | ||
241 | PCI_ADDR0=0<<4, PCI_ADDR1=1<<4, PCI_ADDR2=2<<4, PCI_ADDR3=3<<4, | ||
242 | PCI_ADDR_64BITS=0x100, PCI_NO_ACPI_WAKE=0x200, PCI_NO_MIN_LATENCY=0x400, | ||
243 | PCI_UNUSED_IRQ=0x800, | ||
244 | }; | ||
245 | enum capability_flags { | 237 | enum capability_flags { |
246 | HasMII=1, FullTxStatus=2, IsGigabit=4, HasMulticastBug=8, FullRxStatus=16, | 238 | HasMII=1, FullTxStatus=2, IsGigabit=4, HasMulticastBug=8, FullRxStatus=16, |
247 | HasMACAddrBug=32, /* Only on early revs. */ | 239 | HasMACAddrBug=32, /* Only on early revs. */ |
@@ -249,11 +241,6 @@ enum capability_flags { | |||
249 | }; | 241 | }; |
250 | /* The PCI I/O space extent. */ | 242 | /* The PCI I/O space extent. */ |
251 | #define YELLOWFIN_SIZE 0x100 | 243 | #define YELLOWFIN_SIZE 0x100 |
252 | #ifdef USE_IO_OPS | ||
253 | #define PCI_IOTYPE (PCI_USES_MASTER | PCI_USES_IO | PCI_ADDR0) | ||
254 | #else | ||
255 | #define PCI_IOTYPE (PCI_USES_MASTER | PCI_USES_MEM | PCI_ADDR1) | ||
256 | #endif | ||
257 | 244 | ||
258 | struct pci_id_info { | 245 | struct pci_id_info { |
259 | const char *name; | 246 | const char *name; |
@@ -261,24 +248,23 @@ struct pci_id_info { | |||
261 | int pci, pci_mask, subsystem, subsystem_mask; | 248 | int pci, pci_mask, subsystem, subsystem_mask; |
262 | int revision, revision_mask; /* Only 8 bits. */ | 249 | int revision, revision_mask; /* Only 8 bits. */ |
263 | } id; | 250 | } id; |
264 | enum pci_id_flags_bits pci_flags; | ||
265 | int io_size; /* Needed for I/O region check or ioremap(). */ | 251 | int io_size; /* Needed for I/O region check or ioremap(). */ |
266 | int drv_flags; /* Driver use, intended as capability flags. */ | 252 | int drv_flags; /* Driver use, intended as capability flags. */ |
267 | }; | 253 | }; |
268 | 254 | ||
269 | static const struct pci_id_info pci_id_tbl[] = { | 255 | static const struct pci_id_info pci_id_tbl[] = { |
270 | {"Yellowfin G-NIC Gigabit Ethernet", { 0x07021000, 0xffffffff}, | 256 | {"Yellowfin G-NIC Gigabit Ethernet", { 0x07021000, 0xffffffff}, |
271 | PCI_IOTYPE, YELLOWFIN_SIZE, | 257 | YELLOWFIN_SIZE, |
272 | FullTxStatus | IsGigabit | HasMulticastBug | HasMACAddrBug | DontUseEeprom}, | 258 | FullTxStatus | IsGigabit | HasMulticastBug | HasMACAddrBug | DontUseEeprom}, |
273 | {"Symbios SYM83C885", { 0x07011000, 0xffffffff}, | 259 | {"Symbios SYM83C885", { 0x07011000, 0xffffffff}, |
274 | PCI_IOTYPE, YELLOWFIN_SIZE, HasMII | DontUseEeprom }, | 260 | YELLOWFIN_SIZE, HasMII | DontUseEeprom }, |
275 | {NULL,}, | 261 | { } |
276 | }; | 262 | }; |
277 | 263 | ||
278 | static struct pci_device_id yellowfin_pci_tbl[] = { | 264 | static const struct pci_device_id yellowfin_pci_tbl[] = { |
279 | { 0x1000, 0x0702, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, | 265 | { 0x1000, 0x0702, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, |
280 | { 0x1000, 0x0701, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1 }, | 266 | { 0x1000, 0x0701, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1 }, |
281 | { 0, } | 267 | { } |
282 | }; | 268 | }; |
283 | MODULE_DEVICE_TABLE (pci, yellowfin_pci_tbl); | 269 | MODULE_DEVICE_TABLE (pci, yellowfin_pci_tbl); |
284 | 270 | ||
diff --git a/drivers/parisc/Kconfig b/drivers/parisc/Kconfig index 3f5de867acd7..1d3b84b4af3f 100644 --- a/drivers/parisc/Kconfig +++ b/drivers/parisc/Kconfig | |||
@@ -140,18 +140,37 @@ config CHASSIS_LCD_LED | |||
140 | If unsure, say Y. | 140 | If unsure, say Y. |
141 | 141 | ||
142 | config PDC_CHASSIS | 142 | config PDC_CHASSIS |
143 | bool "PDC chassis State Panel support" | 143 | bool "PDC chassis state codes support" |
144 | default y | 144 | default y |
145 | help | 145 | help |
146 | Say Y here if you want to enable support for the LED State front | 146 | Say Y here if you want to enable support for Chassis codes. |
147 | panel as found on E class, and support for the GSP Virtual Front | 147 | That includes support for LED State front panel as found on E |
148 | Panel (LED State and message logging) as found on high end | 148 | class, and support for the GSP Virtual Front Panel (LED State and |
149 | servers such as A, L and N-class. | 149 | message logging) as found on high end servers such as A, L and |
150 | 150 | N-class. | |
151 | This has nothing to do with Chassis LCD and LED support. | 151 | This driver will also display progress messages on LCD display, |
152 | such as "INI", "RUN" and "FLT", and might thus clobber messages | ||
153 | shown by the LED/LCD driver. | ||
154 | This driver updates the state panel (LED and/or LCD) upon system | ||
155 | state change (eg: boot, shutdown or panic). | ||
152 | 156 | ||
153 | If unsure, say Y. | 157 | If unsure, say Y. |
154 | 158 | ||
159 | |||
160 | config PDC_CHASSIS_WARN | ||
161 | bool "PDC chassis warnings support" | ||
162 | depends on PROC_FS | ||
163 | default y | ||
164 | help | ||
165 | Say Y here if you want to enable support for Chassis warnings. | ||
166 | This will add a proc entry '/proc/chassis' giving some information | ||
167 | about the overall health state of the system. | ||
168 | This includes NVRAM battery level, overtemp or failures such as | ||
169 | fans or power units. | ||
170 | |||
171 | If unsure, say Y. | ||
172 | |||
173 | |||
155 | config PDC_STABLE | 174 | config PDC_STABLE |
156 | tristate "PDC Stable Storage support" | 175 | tristate "PDC Stable Storage support" |
157 | depends on SYSFS | 176 | depends on SYSFS |
diff --git a/drivers/parisc/dino.c b/drivers/parisc/dino.c index 6e8ed0c81a6c..ce0a6ebcff15 100644 --- a/drivers/parisc/dino.c +++ b/drivers/parisc/dino.c | |||
@@ -299,7 +299,7 @@ struct pci_port_ops dino_port_ops = { | |||
299 | 299 | ||
300 | static void dino_disable_irq(unsigned int irq) | 300 | static void dino_disable_irq(unsigned int irq) |
301 | { | 301 | { |
302 | struct dino_device *dino_dev = irq_desc[irq].handler_data; | 302 | struct dino_device *dino_dev = irq_desc[irq].chip_data; |
303 | int local_irq = gsc_find_local_irq(irq, dino_dev->global_irq, DINO_LOCAL_IRQS); | 303 | int local_irq = gsc_find_local_irq(irq, dino_dev->global_irq, DINO_LOCAL_IRQS); |
304 | 304 | ||
305 | DBG(KERN_WARNING "%s(0x%p, %d)\n", __FUNCTION__, dino_dev, irq); | 305 | DBG(KERN_WARNING "%s(0x%p, %d)\n", __FUNCTION__, dino_dev, irq); |
@@ -311,7 +311,7 @@ static void dino_disable_irq(unsigned int irq) | |||
311 | 311 | ||
312 | static void dino_enable_irq(unsigned int irq) | 312 | static void dino_enable_irq(unsigned int irq) |
313 | { | 313 | { |
314 | struct dino_device *dino_dev = irq_desc[irq].handler_data; | 314 | struct dino_device *dino_dev = irq_desc[irq].chip_data; |
315 | int local_irq = gsc_find_local_irq(irq, dino_dev->global_irq, DINO_LOCAL_IRQS); | 315 | int local_irq = gsc_find_local_irq(irq, dino_dev->global_irq, DINO_LOCAL_IRQS); |
316 | u32 tmp; | 316 | u32 tmp; |
317 | 317 | ||
diff --git a/drivers/parisc/eisa.c b/drivers/parisc/eisa.c index 9d3bd15bf53b..58f0ce8d78e0 100644 --- a/drivers/parisc/eisa.c +++ b/drivers/parisc/eisa.c | |||
@@ -350,7 +350,7 @@ static int __devinit eisa_probe(struct parisc_device *dev) | |||
350 | irq_desc[2].action = &irq2_action; | 350 | irq_desc[2].action = &irq2_action; |
351 | 351 | ||
352 | for (i = 0; i < 16; i++) { | 352 | for (i = 0; i < 16; i++) { |
353 | irq_desc[i].handler = &eisa_interrupt_type; | 353 | irq_desc[i].chip = &eisa_interrupt_type; |
354 | } | 354 | } |
355 | 355 | ||
356 | EISA_bus = 1; | 356 | EISA_bus = 1; |
diff --git a/drivers/parisc/gsc.c b/drivers/parisc/gsc.c index 16d40f95978d..5476ba7709b3 100644 --- a/drivers/parisc/gsc.c +++ b/drivers/parisc/gsc.c | |||
@@ -109,7 +109,7 @@ int gsc_find_local_irq(unsigned int irq, int *global_irqs, int limit) | |||
109 | 109 | ||
110 | static void gsc_asic_disable_irq(unsigned int irq) | 110 | static void gsc_asic_disable_irq(unsigned int irq) |
111 | { | 111 | { |
112 | struct gsc_asic *irq_dev = irq_desc[irq].handler_data; | 112 | struct gsc_asic *irq_dev = irq_desc[irq].chip_data; |
113 | int local_irq = gsc_find_local_irq(irq, irq_dev->global_irq, 32); | 113 | int local_irq = gsc_find_local_irq(irq, irq_dev->global_irq, 32); |
114 | u32 imr; | 114 | u32 imr; |
115 | 115 | ||
@@ -124,7 +124,7 @@ static void gsc_asic_disable_irq(unsigned int irq) | |||
124 | 124 | ||
125 | static void gsc_asic_enable_irq(unsigned int irq) | 125 | static void gsc_asic_enable_irq(unsigned int irq) |
126 | { | 126 | { |
127 | struct gsc_asic *irq_dev = irq_desc[irq].handler_data; | 127 | struct gsc_asic *irq_dev = irq_desc[irq].chip_data; |
128 | int local_irq = gsc_find_local_irq(irq, irq_dev->global_irq, 32); | 128 | int local_irq = gsc_find_local_irq(irq, irq_dev->global_irq, 32); |
129 | u32 imr; | 129 | u32 imr; |
130 | 130 | ||
@@ -164,8 +164,8 @@ int gsc_assign_irq(struct hw_interrupt_type *type, void *data) | |||
164 | if (irq > GSC_IRQ_MAX) | 164 | if (irq > GSC_IRQ_MAX) |
165 | return NO_IRQ; | 165 | return NO_IRQ; |
166 | 166 | ||
167 | irq_desc[irq].handler = type; | 167 | irq_desc[irq].chip = type; |
168 | irq_desc[irq].handler_data = data; | 168 | irq_desc[irq].chip_data = data; |
169 | return irq++; | 169 | return irq++; |
170 | } | 170 | } |
171 | 171 | ||
diff --git a/drivers/parisc/iosapic.c b/drivers/parisc/iosapic.c index 7a458d5bc751..1fbda77cefc2 100644 --- a/drivers/parisc/iosapic.c +++ b/drivers/parisc/iosapic.c | |||
@@ -619,7 +619,7 @@ iosapic_set_irt_data( struct vector_info *vi, u32 *dp0, u32 *dp1) | |||
619 | 619 | ||
620 | static struct vector_info *iosapic_get_vector(unsigned int irq) | 620 | static struct vector_info *iosapic_get_vector(unsigned int irq) |
621 | { | 621 | { |
622 | return irq_desc[irq].handler_data; | 622 | return irq_desc[irq].chip_data; |
623 | } | 623 | } |
624 | 624 | ||
625 | static void iosapic_disable_irq(unsigned int irq) | 625 | static void iosapic_disable_irq(unsigned int irq) |
diff --git a/drivers/parisc/pdc_stable.c b/drivers/parisc/pdc_stable.c index bbeabe3fc4c6..ea1b7a63598e 100644 --- a/drivers/parisc/pdc_stable.c +++ b/drivers/parisc/pdc_stable.c | |||
@@ -28,8 +28,15 @@ | |||
28 | * following code can deal with just 96 bytes of Stable Storage, and all | 28 | * following code can deal with just 96 bytes of Stable Storage, and all |
29 | * sizes between 96 and 192 bytes (provided they are multiple of struct | 29 | * sizes between 96 and 192 bytes (provided they are multiple of struct |
30 | * device_path size, eg: 128, 160 and 192) to provide full information. | 30 | * device_path size, eg: 128, 160 and 192) to provide full information. |
31 | * The code makes no use of data above 192 bytes. One last word: there's one | 31 | * One last word: there's one path we can always count on: the primary path. |
32 | * path we can always count on: the primary path. | 32 | * Anything above 224 bytes is used for 'osdep2' OS-dependent storage area. |
33 | * | ||
34 | * The first OS-dependent area should always be available. Obviously, this is | ||
35 | * not true for the other one. Also bear in mind that reading/writing from/to | ||
36 | * osdep2 is much more expensive than from/to osdep1. | ||
37 | * NOTE: We do not handle the 2 bytes OS-dep area at 0x5D, nor the first | ||
38 | * 2 bytes of storage available right after OSID. That's a total of 4 bytes | ||
39 | * sacrificed: -ETOOLAZY :P | ||
33 | * | 40 | * |
34 | * The current policy wrt file permissions is: | 41 | * The current policy wrt file permissions is: |
35 | * - write: root only | 42 | * - write: root only |
@@ -64,15 +71,18 @@ | |||
64 | #include <asm/uaccess.h> | 71 | #include <asm/uaccess.h> |
65 | #include <asm/hardware.h> | 72 | #include <asm/hardware.h> |
66 | 73 | ||
67 | #define PDCS_VERSION "0.22" | 74 | #define PDCS_VERSION "0.30" |
68 | #define PDCS_PREFIX "PDC Stable Storage" | 75 | #define PDCS_PREFIX "PDC Stable Storage" |
69 | 76 | ||
70 | #define PDCS_ADDR_PPRI 0x00 | 77 | #define PDCS_ADDR_PPRI 0x00 |
71 | #define PDCS_ADDR_OSID 0x40 | 78 | #define PDCS_ADDR_OSID 0x40 |
79 | #define PDCS_ADDR_OSD1 0x48 | ||
80 | #define PDCS_ADDR_DIAG 0x58 | ||
72 | #define PDCS_ADDR_FSIZ 0x5C | 81 | #define PDCS_ADDR_FSIZ 0x5C |
73 | #define PDCS_ADDR_PCON 0x60 | 82 | #define PDCS_ADDR_PCON 0x60 |
74 | #define PDCS_ADDR_PALT 0x80 | 83 | #define PDCS_ADDR_PALT 0x80 |
75 | #define PDCS_ADDR_PKBD 0xA0 | 84 | #define PDCS_ADDR_PKBD 0xA0 |
85 | #define PDCS_ADDR_OSD2 0xE0 | ||
76 | 86 | ||
77 | MODULE_AUTHOR("Thibaut VARENE <varenet@parisc-linux.org>"); | 87 | MODULE_AUTHOR("Thibaut VARENE <varenet@parisc-linux.org>"); |
78 | MODULE_DESCRIPTION("sysfs interface to HP PDC Stable Storage data"); | 88 | MODULE_DESCRIPTION("sysfs interface to HP PDC Stable Storage data"); |
@@ -82,6 +92,9 @@ MODULE_VERSION(PDCS_VERSION); | |||
82 | /* holds Stable Storage size. Initialized once and for all, no lock needed */ | 92 | /* holds Stable Storage size. Initialized once and for all, no lock needed */ |
83 | static unsigned long pdcs_size __read_mostly; | 93 | static unsigned long pdcs_size __read_mostly; |
84 | 94 | ||
95 | /* holds OS ID. Initialized once and for all, hopefully to 0x0006 */ | ||
96 | static u16 pdcs_osid __read_mostly; | ||
97 | |||
85 | /* This struct defines what we need to deal with a parisc pdc path entry */ | 98 | /* This struct defines what we need to deal with a parisc pdc path entry */ |
86 | struct pdcspath_entry { | 99 | struct pdcspath_entry { |
87 | rwlock_t rw_lock; /* to protect path entry access */ | 100 | rwlock_t rw_lock; /* to protect path entry access */ |
@@ -609,27 +622,64 @@ static ssize_t | |||
609 | pdcs_osid_read(struct subsystem *entry, char *buf) | 622 | pdcs_osid_read(struct subsystem *entry, char *buf) |
610 | { | 623 | { |
611 | char *out = buf; | 624 | char *out = buf; |
612 | __u32 result; | ||
613 | char *tmpstr = NULL; | ||
614 | 625 | ||
615 | if (!entry || !buf) | 626 | if (!entry || !buf) |
616 | return -EINVAL; | 627 | return -EINVAL; |
617 | 628 | ||
618 | /* get OSID */ | 629 | out += sprintf(out, "%s dependent data (0x%.4x)\n", |
619 | if (pdc_stable_read(PDCS_ADDR_OSID, &result, sizeof(result)) != PDC_OK) | 630 | os_id_to_string(pdcs_osid), pdcs_osid); |
631 | |||
632 | return out - buf; | ||
633 | } | ||
634 | |||
635 | /** | ||
636 | * pdcs_osdep1_read - Stable Storage OS-Dependent data area 1 output. | ||
637 | * @entry: An allocated and populated subsytem struct. We don't use it tho. | ||
638 | * @buf: The output buffer to write to. | ||
639 | * | ||
640 | * This can hold 16 bytes of OS-Dependent data. | ||
641 | */ | ||
642 | static ssize_t | ||
643 | pdcs_osdep1_read(struct subsystem *entry, char *buf) | ||
644 | { | ||
645 | char *out = buf; | ||
646 | u32 result[4]; | ||
647 | |||
648 | if (!entry || !buf) | ||
649 | return -EINVAL; | ||
650 | |||
651 | if (pdc_stable_read(PDCS_ADDR_OSD1, &result, sizeof(result)) != PDC_OK) | ||
620 | return -EIO; | 652 | return -EIO; |
621 | 653 | ||
622 | /* the actual result is 16 bits away */ | 654 | out += sprintf(out, "0x%.8x\n", result[0]); |
623 | switch (result >> 16) { | 655 | out += sprintf(out, "0x%.8x\n", result[1]); |
624 | case 0x0000: tmpstr = "No OS-dependent data"; break; | 656 | out += sprintf(out, "0x%.8x\n", result[2]); |
625 | case 0x0001: tmpstr = "HP-UX dependent data"; break; | 657 | out += sprintf(out, "0x%.8x\n", result[3]); |
626 | case 0x0002: tmpstr = "MPE-iX dependent data"; break; | 658 | |
627 | case 0x0003: tmpstr = "OSF dependent data"; break; | 659 | return out - buf; |
628 | case 0x0004: tmpstr = "HP-RT dependent data"; break; | 660 | } |
629 | case 0x0005: tmpstr = "Novell Netware dependent data"; break; | 661 | |
630 | default: tmpstr = "Unknown"; break; | 662 | /** |
631 | } | 663 | * pdcs_diagnostic_read - Stable Storage Diagnostic register output. |
632 | out += sprintf(out, "%s (0x%.4x)\n", tmpstr, (result >> 16)); | 664 | * @entry: An allocated and populated subsytem struct. We don't use it tho. |
665 | * @buf: The output buffer to write to. | ||
666 | * | ||
667 | * I have NFC how to interpret the content of that register ;-). | ||
668 | */ | ||
669 | static ssize_t | ||
670 | pdcs_diagnostic_read(struct subsystem *entry, char *buf) | ||
671 | { | ||
672 | char *out = buf; | ||
673 | u32 result; | ||
674 | |||
675 | if (!entry || !buf) | ||
676 | return -EINVAL; | ||
677 | |||
678 | /* get diagnostic */ | ||
679 | if (pdc_stable_read(PDCS_ADDR_DIAG, &result, sizeof(result)) != PDC_OK) | ||
680 | return -EIO; | ||
681 | |||
682 | out += sprintf(out, "0x%.4x\n", (result >> 16)); | ||
633 | 683 | ||
634 | return out - buf; | 684 | return out - buf; |
635 | } | 685 | } |
@@ -645,7 +695,7 @@ static ssize_t | |||
645 | pdcs_fastsize_read(struct subsystem *entry, char *buf) | 695 | pdcs_fastsize_read(struct subsystem *entry, char *buf) |
646 | { | 696 | { |
647 | char *out = buf; | 697 | char *out = buf; |
648 | __u32 result; | 698 | u32 result; |
649 | 699 | ||
650 | if (!entry || !buf) | 700 | if (!entry || !buf) |
651 | return -EINVAL; | 701 | return -EINVAL; |
@@ -664,6 +714,39 @@ pdcs_fastsize_read(struct subsystem *entry, char *buf) | |||
664 | } | 714 | } |
665 | 715 | ||
666 | /** | 716 | /** |
717 | * pdcs_osdep2_read - Stable Storage OS-Dependent data area 2 output. | ||
718 | * @entry: An allocated and populated subsytem struct. We don't use it tho. | ||
719 | * @buf: The output buffer to write to. | ||
720 | * | ||
721 | * This can hold pdcs_size - 224 bytes of OS-Dependent data, when available. | ||
722 | */ | ||
723 | static ssize_t | ||
724 | pdcs_osdep2_read(struct subsystem *entry, char *buf) | ||
725 | { | ||
726 | char *out = buf; | ||
727 | unsigned long size; | ||
728 | unsigned short i; | ||
729 | u32 result; | ||
730 | |||
731 | if (unlikely(pdcs_size <= 224)) | ||
732 | return -ENODATA; | ||
733 | |||
734 | size = pdcs_size - 224; | ||
735 | |||
736 | if (!entry || !buf) | ||
737 | return -EINVAL; | ||
738 | |||
739 | for (i=0; i<size; i+=4) { | ||
740 | if (unlikely(pdc_stable_read(PDCS_ADDR_OSD2 + i, &result, | ||
741 | sizeof(result)) != PDC_OK)) | ||
742 | return -EIO; | ||
743 | out += sprintf(out, "0x%.8x\n", result); | ||
744 | } | ||
745 | |||
746 | return out - buf; | ||
747 | } | ||
748 | |||
749 | /** | ||
667 | * pdcs_auto_write - This function handles autoboot/search flag modifying. | 750 | * pdcs_auto_write - This function handles autoboot/search flag modifying. |
668 | * @entry: An allocated and populated subsytem struct. We don't use it tho. | 751 | * @entry: An allocated and populated subsytem struct. We don't use it tho. |
669 | * @buf: The input buffer to read from. | 752 | * @buf: The input buffer to read from. |
@@ -770,13 +853,100 @@ pdcs_autosearch_write(struct subsystem *entry, const char *buf, size_t count) | |||
770 | return pdcs_auto_write(entry, buf, count, PF_AUTOSEARCH); | 853 | return pdcs_auto_write(entry, buf, count, PF_AUTOSEARCH); |
771 | } | 854 | } |
772 | 855 | ||
856 | /** | ||
857 | * pdcs_osdep1_write - Stable Storage OS-Dependent data area 1 input. | ||
858 | * @entry: An allocated and populated subsytem struct. We don't use it tho. | ||
859 | * @buf: The input buffer to read from. | ||
860 | * @count: The number of bytes to be read. | ||
861 | * | ||
862 | * This can store 16 bytes of OS-Dependent data. We use a byte-by-byte | ||
863 | * write approach. It's up to userspace to deal with it when constructing | ||
864 | * its input buffer. | ||
865 | */ | ||
866 | static ssize_t | ||
867 | pdcs_osdep1_write(struct subsystem *entry, const char *buf, size_t count) | ||
868 | { | ||
869 | u8 in[16]; | ||
870 | |||
871 | if (!capable(CAP_SYS_ADMIN)) | ||
872 | return -EACCES; | ||
873 | |||
874 | if (!entry || !buf || !count) | ||
875 | return -EINVAL; | ||
876 | |||
877 | if (unlikely(pdcs_osid != OS_ID_LINUX)) | ||
878 | return -EPERM; | ||
879 | |||
880 | if (count > 16) | ||
881 | return -EMSGSIZE; | ||
882 | |||
883 | /* We'll use a local copy of buf */ | ||
884 | memset(in, 0, 16); | ||
885 | memcpy(in, buf, count); | ||
886 | |||
887 | if (pdc_stable_write(PDCS_ADDR_OSD1, &in, sizeof(in)) != PDC_OK) | ||
888 | return -EIO; | ||
889 | |||
890 | return count; | ||
891 | } | ||
892 | |||
893 | /** | ||
894 | * pdcs_osdep2_write - Stable Storage OS-Dependent data area 2 input. | ||
895 | * @entry: An allocated and populated subsytem struct. We don't use it tho. | ||
896 | * @buf: The input buffer to read from. | ||
897 | * @count: The number of bytes to be read. | ||
898 | * | ||
899 | * This can store pdcs_size - 224 bytes of OS-Dependent data. We use a | ||
900 | * byte-by-byte write approach. It's up to userspace to deal with it when | ||
901 | * constructing its input buffer. | ||
902 | */ | ||
903 | static ssize_t | ||
904 | pdcs_osdep2_write(struct subsystem *entry, const char *buf, size_t count) | ||
905 | { | ||
906 | unsigned long size; | ||
907 | unsigned short i; | ||
908 | u8 in[4]; | ||
909 | |||
910 | if (!capable(CAP_SYS_ADMIN)) | ||
911 | return -EACCES; | ||
912 | |||
913 | if (!entry || !buf || !count) | ||
914 | return -EINVAL; | ||
915 | |||
916 | if (unlikely(pdcs_size <= 224)) | ||
917 | return -ENOSYS; | ||
918 | |||
919 | if (unlikely(pdcs_osid != OS_ID_LINUX)) | ||
920 | return -EPERM; | ||
921 | |||
922 | size = pdcs_size - 224; | ||
923 | |||
924 | if (count > size) | ||
925 | return -EMSGSIZE; | ||
926 | |||
927 | /* We'll use a local copy of buf */ | ||
928 | |||
929 | for (i=0; i<count; i+=4) { | ||
930 | memset(in, 0, 4); | ||
931 | memcpy(in, buf+i, (count-i < 4) ? count-i : 4); | ||
932 | if (unlikely(pdc_stable_write(PDCS_ADDR_OSD2 + i, &in, | ||
933 | sizeof(in)) != PDC_OK)) | ||
934 | return -EIO; | ||
935 | } | ||
936 | |||
937 | return count; | ||
938 | } | ||
939 | |||
773 | /* The remaining attributes. */ | 940 | /* The remaining attributes. */ |
774 | static PDCS_ATTR(size, 0444, pdcs_size_read, NULL); | 941 | static PDCS_ATTR(size, 0444, pdcs_size_read, NULL); |
775 | static PDCS_ATTR(autoboot, 0644, pdcs_autoboot_read, pdcs_autoboot_write); | 942 | static PDCS_ATTR(autoboot, 0644, pdcs_autoboot_read, pdcs_autoboot_write); |
776 | static PDCS_ATTR(autosearch, 0644, pdcs_autosearch_read, pdcs_autosearch_write); | 943 | static PDCS_ATTR(autosearch, 0644, pdcs_autosearch_read, pdcs_autosearch_write); |
777 | static PDCS_ATTR(timer, 0444, pdcs_timer_read, NULL); | 944 | static PDCS_ATTR(timer, 0444, pdcs_timer_read, NULL); |
778 | static PDCS_ATTR(osid, 0400, pdcs_osid_read, NULL); | 945 | static PDCS_ATTR(osid, 0444, pdcs_osid_read, NULL); |
946 | static PDCS_ATTR(osdep1, 0600, pdcs_osdep1_read, pdcs_osdep1_write); | ||
947 | static PDCS_ATTR(diagnostic, 0400, pdcs_diagnostic_read, NULL); | ||
779 | static PDCS_ATTR(fastsize, 0400, pdcs_fastsize_read, NULL); | 948 | static PDCS_ATTR(fastsize, 0400, pdcs_fastsize_read, NULL); |
949 | static PDCS_ATTR(osdep2, 0600, pdcs_osdep2_read, pdcs_osdep2_write); | ||
780 | 950 | ||
781 | static struct subsys_attribute *pdcs_subsys_attrs[] = { | 951 | static struct subsys_attribute *pdcs_subsys_attrs[] = { |
782 | &pdcs_attr_size, | 952 | &pdcs_attr_size, |
@@ -784,7 +954,10 @@ static struct subsys_attribute *pdcs_subsys_attrs[] = { | |||
784 | &pdcs_attr_autosearch, | 954 | &pdcs_attr_autosearch, |
785 | &pdcs_attr_timer, | 955 | &pdcs_attr_timer, |
786 | &pdcs_attr_osid, | 956 | &pdcs_attr_osid, |
957 | &pdcs_attr_osdep1, | ||
958 | &pdcs_attr_diagnostic, | ||
787 | &pdcs_attr_fastsize, | 959 | &pdcs_attr_fastsize, |
960 | &pdcs_attr_osdep2, | ||
788 | NULL, | 961 | NULL, |
789 | }; | 962 | }; |
790 | 963 | ||
@@ -865,6 +1038,7 @@ pdc_stable_init(void) | |||
865 | { | 1038 | { |
866 | struct subsys_attribute *attr; | 1039 | struct subsys_attribute *attr; |
867 | int i, rc = 0, error = 0; | 1040 | int i, rc = 0, error = 0; |
1041 | u32 result; | ||
868 | 1042 | ||
869 | /* find the size of the stable storage */ | 1043 | /* find the size of the stable storage */ |
870 | if (pdc_stable_get_size(&pdcs_size) != PDC_OK) | 1044 | if (pdc_stable_get_size(&pdcs_size) != PDC_OK) |
@@ -876,6 +1050,13 @@ pdc_stable_init(void) | |||
876 | 1050 | ||
877 | printk(KERN_INFO PDCS_PREFIX " facility v%s\n", PDCS_VERSION); | 1051 | printk(KERN_INFO PDCS_PREFIX " facility v%s\n", PDCS_VERSION); |
878 | 1052 | ||
1053 | /* get OSID */ | ||
1054 | if (pdc_stable_read(PDCS_ADDR_OSID, &result, sizeof(result)) != PDC_OK) | ||
1055 | return -EIO; | ||
1056 | |||
1057 | /* the actual result is 16 bits away */ | ||
1058 | pdcs_osid = (u16)(result >> 16); | ||
1059 | |||
879 | /* For now we'll register the stable subsys within this driver */ | 1060 | /* For now we'll register the stable subsys within this driver */ |
880 | if ((rc = firmware_register(&stable_subsys))) | 1061 | if ((rc = firmware_register(&stable_subsys))) |
881 | goto fail_firmreg; | 1062 | goto fail_firmreg; |
@@ -887,7 +1068,7 @@ pdc_stable_init(void) | |||
887 | 1068 | ||
888 | /* register the paths subsys as a subsystem of stable subsys */ | 1069 | /* register the paths subsys as a subsystem of stable subsys */ |
889 | kset_set_kset_s(&paths_subsys, stable_subsys); | 1070 | kset_set_kset_s(&paths_subsys, stable_subsys); |
890 | if ((rc= subsystem_register(&paths_subsys))) | 1071 | if ((rc = subsystem_register(&paths_subsys))) |
891 | goto fail_subsysreg; | 1072 | goto fail_subsysreg; |
892 | 1073 | ||
893 | /* now we create all "files" for the paths subsys */ | 1074 | /* now we create all "files" for the paths subsys */ |
diff --git a/drivers/parisc/sba_iommu.c b/drivers/parisc/sba_iommu.c index 278f325021ee..d09e39e39c60 100644 --- a/drivers/parisc/sba_iommu.c +++ b/drivers/parisc/sba_iommu.c | |||
@@ -316,10 +316,10 @@ static int reserve_sba_gart = 1; | |||
316 | ** | 316 | ** |
317 | ** Superdome (in particular, REO) allows only 64-bit CSR accesses. | 317 | ** Superdome (in particular, REO) allows only 64-bit CSR accesses. |
318 | */ | 318 | */ |
319 | #define READ_REG32(addr) le32_to_cpu(__raw_readl(addr)) | 319 | #define READ_REG32(addr) readl(addr) |
320 | #define READ_REG64(addr) le64_to_cpu(__raw_readq(addr)) | 320 | #define READ_REG64(addr) readq(addr) |
321 | #define WRITE_REG32(val, addr) __raw_writel(cpu_to_le32(val), addr) | 321 | #define WRITE_REG32(val, addr) writel((val), (addr)) |
322 | #define WRITE_REG64(val, addr) __raw_writeq(cpu_to_le64(val), addr) | 322 | #define WRITE_REG64(val, addr) writeq((val), (addr)) |
323 | 323 | ||
324 | #ifdef CONFIG_64BIT | 324 | #ifdef CONFIG_64BIT |
325 | #define READ_REG(addr) READ_REG64(addr) | 325 | #define READ_REG(addr) READ_REG64(addr) |
@@ -1427,7 +1427,7 @@ sba_ioc_init_pluto(struct parisc_device *sba, struct ioc *ioc, int ioc_num) | |||
1427 | iov_order = get_order(iova_space_size >> (IOVP_SHIFT - PAGE_SHIFT)); | 1427 | iov_order = get_order(iova_space_size >> (IOVP_SHIFT - PAGE_SHIFT)); |
1428 | ioc->pdir_size = (iova_space_size / IOVP_SIZE) * sizeof(u64); | 1428 | ioc->pdir_size = (iova_space_size / IOVP_SIZE) * sizeof(u64); |
1429 | 1429 | ||
1430 | DBG_INIT("%s() hpa 0x%lx IOV %dMB (%d bits)\n", | 1430 | DBG_INIT("%s() hpa 0x%p IOV %dMB (%d bits)\n", |
1431 | __FUNCTION__, ioc->ioc_hpa, iova_space_size >> 20, | 1431 | __FUNCTION__, ioc->ioc_hpa, iova_space_size >> 20, |
1432 | iov_order + PAGE_SHIFT); | 1432 | iov_order + PAGE_SHIFT); |
1433 | 1433 | ||
@@ -1764,7 +1764,7 @@ printk("sba_hw_init(): mem_boot 0x%x 0x%x 0x%x 0x%x\n", PAGE0->mem_boot.hpa, | |||
1764 | 1764 | ||
1765 | sba_dev->num_ioc = num_ioc; | 1765 | sba_dev->num_ioc = num_ioc; |
1766 | for (i = 0; i < num_ioc; i++) { | 1766 | for (i = 0; i < num_ioc; i++) { |
1767 | unsigned long ioc_hpa = sba_dev->ioc[i].ioc_hpa; | 1767 | void __iomem *ioc_hpa = sba_dev->ioc[i].ioc_hpa; |
1768 | unsigned int j; | 1768 | unsigned int j; |
1769 | 1769 | ||
1770 | for (j=0; j < sizeof(u64) * ROPES_PER_IOC; j+=sizeof(u64)) { | 1770 | for (j=0; j < sizeof(u64) * ROPES_PER_IOC; j+=sizeof(u64)) { |
@@ -1776,7 +1776,8 @@ printk("sba_hw_init(): mem_boot 0x%x 0x%x 0x%x 0x%x\n", PAGE0->mem_boot.hpa, | |||
1776 | * Improves netperf UDP_STREAM by ~10% for bcm5701. | 1776 | * Improves netperf UDP_STREAM by ~10% for bcm5701. |
1777 | */ | 1777 | */ |
1778 | if (IS_PLUTO(sba_dev->iodc)) { | 1778 | if (IS_PLUTO(sba_dev->iodc)) { |
1779 | unsigned long rope_cfg, cfg_val; | 1779 | void __iomem *rope_cfg; |
1780 | unsigned long cfg_val; | ||
1780 | 1781 | ||
1781 | rope_cfg = ioc_hpa + IOC_ROPE0_CFG + j; | 1782 | rope_cfg = ioc_hpa + IOC_ROPE0_CFG + j; |
1782 | cfg_val = READ_REG(rope_cfg); | 1783 | cfg_val = READ_REG(rope_cfg); |
@@ -1902,7 +1903,7 @@ sba_common_init(struct sba_device *sba_dev) | |||
1902 | * (bit #61, big endian), we have to flush and sync every time | 1903 | * (bit #61, big endian), we have to flush and sync every time |
1903 | * IO-PDIR is changed in Ike/Astro. | 1904 | * IO-PDIR is changed in Ike/Astro. |
1904 | */ | 1905 | */ |
1905 | if (boot_cpu_data.pdc.capabilities & PDC_MODEL_IOPDIR_FDC) { | 1906 | if (ioc_needs_fdc) { |
1906 | printk(KERN_INFO MODULE_NAME " FDC/SYNC required.\n"); | 1907 | printk(KERN_INFO MODULE_NAME " FDC/SYNC required.\n"); |
1907 | } else { | 1908 | } else { |
1908 | printk(KERN_INFO MODULE_NAME " IOC has cache coherent PDIR.\n"); | 1909 | printk(KERN_INFO MODULE_NAME " IOC has cache coherent PDIR.\n"); |
diff --git a/drivers/parisc/superio.c b/drivers/parisc/superio.c index 828eb45062de..a988dc7a9abd 100644 --- a/drivers/parisc/superio.c +++ b/drivers/parisc/superio.c | |||
@@ -360,7 +360,7 @@ int superio_fixup_irq(struct pci_dev *pcidev) | |||
360 | #endif | 360 | #endif |
361 | 361 | ||
362 | for (i = 0; i < 16; i++) { | 362 | for (i = 0; i < 16; i++) { |
363 | irq_desc[i].handler = &superio_interrupt_type; | 363 | irq_desc[i].chip = &superio_interrupt_type; |
364 | } | 364 | } |
365 | 365 | ||
366 | /* | 366 | /* |
diff --git a/drivers/pci/bus.c b/drivers/pci/bus.c index 723092682023..5f7db9d2436e 100644 --- a/drivers/pci/bus.c +++ b/drivers/pci/bus.c | |||
@@ -34,11 +34,11 @@ | |||
34 | */ | 34 | */ |
35 | int | 35 | int |
36 | pci_bus_alloc_resource(struct pci_bus *bus, struct resource *res, | 36 | pci_bus_alloc_resource(struct pci_bus *bus, struct resource *res, |
37 | unsigned long size, unsigned long align, unsigned long min, | 37 | resource_size_t size, resource_size_t align, |
38 | unsigned int type_mask, | 38 | resource_size_t min, unsigned int type_mask, |
39 | void (*alignf)(void *, struct resource *, | 39 | void (*alignf)(void *, struct resource *, resource_size_t, |
40 | unsigned long, unsigned long), | 40 | resource_size_t), |
41 | void *alignf_data) | 41 | void *alignf_data) |
42 | { | 42 | { |
43 | int i, ret = -ENOMEM; | 43 | int i, ret = -ENOMEM; |
44 | 44 | ||
diff --git a/drivers/pci/hotplug/cpcihp_zt5550.c b/drivers/pci/hotplug/cpcihp_zt5550.c index f7cb00da38df..1ec165df8522 100644 --- a/drivers/pci/hotplug/cpcihp_zt5550.c +++ b/drivers/pci/hotplug/cpcihp_zt5550.c | |||
@@ -95,8 +95,8 @@ static int zt5550_hc_config(struct pci_dev *pdev) | |||
95 | 95 | ||
96 | hc_dev = pdev; | 96 | hc_dev = pdev; |
97 | dbg("hc_dev = %p", hc_dev); | 97 | dbg("hc_dev = %p", hc_dev); |
98 | dbg("pci resource start %lx", pci_resource_start(hc_dev, 1)); | 98 | dbg("pci resource start %llx", (unsigned long long)pci_resource_start(hc_dev, 1)); |
99 | dbg("pci resource len %lx", pci_resource_len(hc_dev, 1)); | 99 | dbg("pci resource len %llx", (unsigned long long)pci_resource_len(hc_dev, 1)); |
100 | 100 | ||
101 | if(!request_mem_region(pci_resource_start(hc_dev, 1), | 101 | if(!request_mem_region(pci_resource_start(hc_dev, 1), |
102 | pci_resource_len(hc_dev, 1), MY_NAME)) { | 102 | pci_resource_len(hc_dev, 1), MY_NAME)) { |
@@ -108,8 +108,9 @@ static int zt5550_hc_config(struct pci_dev *pdev) | |||
108 | hc_registers = | 108 | hc_registers = |
109 | ioremap(pci_resource_start(hc_dev, 1), pci_resource_len(hc_dev, 1)); | 109 | ioremap(pci_resource_start(hc_dev, 1), pci_resource_len(hc_dev, 1)); |
110 | if(!hc_registers) { | 110 | if(!hc_registers) { |
111 | err("cannot remap MMIO region %lx @ %lx", | 111 | err("cannot remap MMIO region %llx @ %llx", |
112 | pci_resource_len(hc_dev, 1), pci_resource_start(hc_dev, 1)); | 112 | (unsigned long long)pci_resource_len(hc_dev, 1), |
113 | (unsigned long long)pci_resource_start(hc_dev, 1)); | ||
113 | ret = -ENODEV; | 114 | ret = -ENODEV; |
114 | goto exit_release_region; | 115 | goto exit_release_region; |
115 | } | 116 | } |
diff --git a/drivers/pci/hotplug/cpqphp_core.c b/drivers/pci/hotplug/cpqphp_core.c index 9bc1deb8df52..f8658d63f077 100644 --- a/drivers/pci/hotplug/cpqphp_core.c +++ b/drivers/pci/hotplug/cpqphp_core.c | |||
@@ -1089,8 +1089,8 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
1089 | } | 1089 | } |
1090 | 1090 | ||
1091 | dbg("pdev = %p\n", pdev); | 1091 | dbg("pdev = %p\n", pdev); |
1092 | dbg("pci resource start %lx\n", pci_resource_start(pdev, 0)); | 1092 | dbg("pci resource start %llx\n", (unsigned long long)pci_resource_start(pdev, 0)); |
1093 | dbg("pci resource len %lx\n", pci_resource_len(pdev, 0)); | 1093 | dbg("pci resource len %llx\n", (unsigned long long)pci_resource_len(pdev, 0)); |
1094 | 1094 | ||
1095 | if (!request_mem_region(pci_resource_start(pdev, 0), | 1095 | if (!request_mem_region(pci_resource_start(pdev, 0), |
1096 | pci_resource_len(pdev, 0), MY_NAME)) { | 1096 | pci_resource_len(pdev, 0), MY_NAME)) { |
@@ -1102,9 +1102,9 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
1102 | ctrl->hpc_reg = ioremap(pci_resource_start(pdev, 0), | 1102 | ctrl->hpc_reg = ioremap(pci_resource_start(pdev, 0), |
1103 | pci_resource_len(pdev, 0)); | 1103 | pci_resource_len(pdev, 0)); |
1104 | if (!ctrl->hpc_reg) { | 1104 | if (!ctrl->hpc_reg) { |
1105 | err("cannot remap MMIO region %lx @ %lx\n", | 1105 | err("cannot remap MMIO region %llx @ %llx\n", |
1106 | pci_resource_len(pdev, 0), | 1106 | (unsigned long long)pci_resource_len(pdev, 0), |
1107 | pci_resource_start(pdev, 0)); | 1107 | (unsigned long long)pci_resource_start(pdev, 0)); |
1108 | rc = -ENODEV; | 1108 | rc = -ENODEV; |
1109 | goto err_free_mem_region; | 1109 | goto err_free_mem_region; |
1110 | } | 1110 | } |
diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c index d77138ecb098..11f7858f0064 100644 --- a/drivers/pci/hotplug/pciehp_hpc.c +++ b/drivers/pci/hotplug/pciehp_hpc.c | |||
@@ -1398,8 +1398,9 @@ int pcie_init(struct controller * ctrl, struct pcie_device *dev) | |||
1398 | 1398 | ||
1399 | for ( rc = 0; rc < DEVICE_COUNT_RESOURCE; rc++) | 1399 | for ( rc = 0; rc < DEVICE_COUNT_RESOURCE; rc++) |
1400 | if (pci_resource_len(pdev, rc) > 0) | 1400 | if (pci_resource_len(pdev, rc) > 0) |
1401 | dbg("pci resource[%d] start=0x%lx(len=0x%lx)\n", rc, | 1401 | dbg("pci resource[%d] start=0x%llx(len=0x%llx)\n", rc, |
1402 | pci_resource_start(pdev, rc), pci_resource_len(pdev, rc)); | 1402 | (unsigned long long)pci_resource_start(pdev, rc), |
1403 | (unsigned long long)pci_resource_len(pdev, rc)); | ||
1403 | 1404 | ||
1404 | info("HPC vendor_id %x device_id %x ss_vid %x ss_did %x\n", pdev->vendor, pdev->device, | 1405 | info("HPC vendor_id %x device_id %x ss_vid %x ss_did %x\n", pdev->vendor, pdev->device, |
1405 | pdev->subsystem_vendor, pdev->subsystem_device); | 1406 | pdev->subsystem_vendor, pdev->subsystem_device); |
diff --git a/drivers/pci/hotplug/shpchp_sysfs.c b/drivers/pci/hotplug/shpchp_sysfs.c index f5cfbf2c047c..620e1139e607 100644 --- a/drivers/pci/hotplug/shpchp_sysfs.c +++ b/drivers/pci/hotplug/shpchp_sysfs.c | |||
@@ -51,8 +51,10 @@ static ssize_t show_ctrl (struct device *dev, struct device_attribute *attr, cha | |||
51 | res = bus->resource[index]; | 51 | res = bus->resource[index]; |
52 | if (res && (res->flags & IORESOURCE_MEM) && | 52 | if (res && (res->flags & IORESOURCE_MEM) && |
53 | !(res->flags & IORESOURCE_PREFETCH)) { | 53 | !(res->flags & IORESOURCE_PREFETCH)) { |
54 | out += sprintf(out, "start = %8.8lx, length = %8.8lx\n", | 54 | out += sprintf(out, "start = %8.8llx, " |
55 | res->start, (res->end - res->start)); | 55 | "length = %8.8llx\n", |
56 | (unsigned long long)res->start, | ||
57 | (unsigned long long)(res->end - res->start)); | ||
56 | } | 58 | } |
57 | } | 59 | } |
58 | out += sprintf(out, "Free resources: prefetchable memory\n"); | 60 | out += sprintf(out, "Free resources: prefetchable memory\n"); |
@@ -60,16 +62,20 @@ static ssize_t show_ctrl (struct device *dev, struct device_attribute *attr, cha | |||
60 | res = bus->resource[index]; | 62 | res = bus->resource[index]; |
61 | if (res && (res->flags & IORESOURCE_MEM) && | 63 | if (res && (res->flags & IORESOURCE_MEM) && |
62 | (res->flags & IORESOURCE_PREFETCH)) { | 64 | (res->flags & IORESOURCE_PREFETCH)) { |
63 | out += sprintf(out, "start = %8.8lx, length = %8.8lx\n", | 65 | out += sprintf(out, "start = %8.8llx, " |
64 | res->start, (res->end - res->start)); | 66 | "length = %8.8llx\n", |
67 | (unsigned long long)res->start, | ||
68 | (unsigned long long)(res->end - res->start)); | ||
65 | } | 69 | } |
66 | } | 70 | } |
67 | out += sprintf(out, "Free resources: IO\n"); | 71 | out += sprintf(out, "Free resources: IO\n"); |
68 | for (index = 0; index < PCI_BUS_NUM_RESOURCES; index++) { | 72 | for (index = 0; index < PCI_BUS_NUM_RESOURCES; index++) { |
69 | res = bus->resource[index]; | 73 | res = bus->resource[index]; |
70 | if (res && (res->flags & IORESOURCE_IO)) { | 74 | if (res && (res->flags & IORESOURCE_IO)) { |
71 | out += sprintf(out, "start = %8.8lx, length = %8.8lx\n", | 75 | out += sprintf(out, "start = %8.8llx, " |
72 | res->start, (res->end - res->start)); | 76 | "length = %8.8llx\n", |
77 | (unsigned long long)res->start, | ||
78 | (unsigned long long)(res->end - res->start)); | ||
73 | } | 79 | } |
74 | } | 80 | } |
75 | out += sprintf(out, "Free resources: bus numbers\n"); | 81 | out += sprintf(out, "Free resources: bus numbers\n"); |
diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c index 7f8429284fab..76d023d8a33b 100644 --- a/drivers/pci/msi.c +++ b/drivers/pci/msi.c | |||
@@ -429,12 +429,12 @@ static void irq_handler_init(int cap_id, int pos, int mask) | |||
429 | 429 | ||
430 | spin_lock_irqsave(&irq_desc[pos].lock, flags); | 430 | spin_lock_irqsave(&irq_desc[pos].lock, flags); |
431 | if (cap_id == PCI_CAP_ID_MSIX) | 431 | if (cap_id == PCI_CAP_ID_MSIX) |
432 | irq_desc[pos].handler = &msix_irq_type; | 432 | irq_desc[pos].chip = &msix_irq_type; |
433 | else { | 433 | else { |
434 | if (!mask) | 434 | if (!mask) |
435 | irq_desc[pos].handler = &msi_irq_wo_maskbit_type; | 435 | irq_desc[pos].chip = &msi_irq_wo_maskbit_type; |
436 | else | 436 | else |
437 | irq_desc[pos].handler = &msi_irq_w_maskbit_type; | 437 | irq_desc[pos].chip = &msi_irq_w_maskbit_type; |
438 | } | 438 | } |
439 | spin_unlock_irqrestore(&irq_desc[pos].lock, flags); | 439 | spin_unlock_irqrestore(&irq_desc[pos].lock, flags); |
440 | } | 440 | } |
diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c index bc405c035ce3..606f9b6f70eb 100644 --- a/drivers/pci/pci-sysfs.c +++ b/drivers/pci/pci-sysfs.c | |||
@@ -87,7 +87,7 @@ resource_show(struct device * dev, struct device_attribute *attr, char * buf) | |||
87 | char * str = buf; | 87 | char * str = buf; |
88 | int i; | 88 | int i; |
89 | int max = 7; | 89 | int max = 7; |
90 | u64 start, end; | 90 | resource_size_t start, end; |
91 | 91 | ||
92 | if (pci_dev->subordinate) | 92 | if (pci_dev->subordinate) |
93 | max = DEVICE_COUNT_RESOURCE; | 93 | max = DEVICE_COUNT_RESOURCE; |
@@ -365,7 +365,7 @@ pci_mmap_resource(struct kobject *kobj, struct bin_attribute *attr, | |||
365 | struct device, kobj)); | 365 | struct device, kobj)); |
366 | struct resource *res = (struct resource *)attr->private; | 366 | struct resource *res = (struct resource *)attr->private; |
367 | enum pci_mmap_state mmap_type; | 367 | enum pci_mmap_state mmap_type; |
368 | u64 start, end; | 368 | resource_size_t start, end; |
369 | int i; | 369 | int i; |
370 | 370 | ||
371 | for (i = 0; i < PCI_ROM_RESOURCE; i++) | 371 | for (i = 0; i < PCI_ROM_RESOURCE; i++) |
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 23d3b17c8cad..cf57d7de3765 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c | |||
@@ -691,10 +691,12 @@ int pci_request_region(struct pci_dev *pdev, int bar, const char *res_name) | |||
691 | return 0; | 691 | return 0; |
692 | 692 | ||
693 | err_out: | 693 | err_out: |
694 | printk (KERN_WARNING "PCI: Unable to reserve %s region #%d:%lx@%lx for device %s\n", | 694 | printk (KERN_WARNING "PCI: Unable to reserve %s region #%d:%llx@%llx " |
695 | "for device %s\n", | ||
695 | pci_resource_flags(pdev, bar) & IORESOURCE_IO ? "I/O" : "mem", | 696 | pci_resource_flags(pdev, bar) & IORESOURCE_IO ? "I/O" : "mem", |
696 | bar + 1, /* PCI BAR # */ | 697 | bar + 1, /* PCI BAR # */ |
697 | pci_resource_len(pdev, bar), pci_resource_start(pdev, bar), | 698 | (unsigned long long)pci_resource_len(pdev, bar), |
699 | (unsigned long long)pci_resource_start(pdev, bar), | ||
698 | pci_name(pdev)); | 700 | pci_name(pdev)); |
699 | return -EBUSY; | 701 | return -EBUSY; |
700 | } | 702 | } |
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h index 29bdeca031a8..9cc842b666eb 100644 --- a/drivers/pci/pci.h +++ b/drivers/pci/pci.h | |||
@@ -6,10 +6,10 @@ extern int pci_create_sysfs_dev_files(struct pci_dev *pdev); | |||
6 | extern void pci_remove_sysfs_dev_files(struct pci_dev *pdev); | 6 | extern void pci_remove_sysfs_dev_files(struct pci_dev *pdev); |
7 | extern void pci_cleanup_rom(struct pci_dev *dev); | 7 | extern void pci_cleanup_rom(struct pci_dev *dev); |
8 | extern int pci_bus_alloc_resource(struct pci_bus *bus, struct resource *res, | 8 | extern int pci_bus_alloc_resource(struct pci_bus *bus, struct resource *res, |
9 | unsigned long size, unsigned long align, | 9 | resource_size_t size, resource_size_t align, |
10 | unsigned long min, unsigned int type_mask, | 10 | resource_size_t min, unsigned int type_mask, |
11 | void (*alignf)(void *, struct resource *, | 11 | void (*alignf)(void *, struct resource *, |
12 | unsigned long, unsigned long), | 12 | resource_size_t, resource_size_t), |
13 | void *alignf_data); | 13 | void *alignf_data); |
14 | /* Firmware callbacks */ | 14 | /* Firmware callbacks */ |
15 | extern int (*platform_pci_choose_state)(struct pci_dev *dev, pm_message_t state); | 15 | extern int (*platform_pci_choose_state)(struct pci_dev *dev, pm_message_t state); |
diff --git a/drivers/pci/proc.c b/drivers/pci/proc.c index 54b2ebc9c91a..99cf33379769 100644 --- a/drivers/pci/proc.c +++ b/drivers/pci/proc.c | |||
@@ -302,12 +302,6 @@ static struct file_operations proc_bus_pci_operations = { | |||
302 | #endif /* HAVE_PCI_MMAP */ | 302 | #endif /* HAVE_PCI_MMAP */ |
303 | }; | 303 | }; |
304 | 304 | ||
305 | #if BITS_PER_LONG == 32 | ||
306 | #define LONG_FORMAT "\t%08lx" | ||
307 | #else | ||
308 | #define LONG_FORMAT "\t%16lx" | ||
309 | #endif | ||
310 | |||
311 | /* iterator */ | 305 | /* iterator */ |
312 | static void *pci_seq_start(struct seq_file *m, loff_t *pos) | 306 | static void *pci_seq_start(struct seq_file *m, loff_t *pos) |
313 | { | 307 | { |
@@ -356,18 +350,18 @@ static int show_device(struct seq_file *m, void *v) | |||
356 | dev->irq); | 350 | dev->irq); |
357 | /* Here should be 7 and not PCI_NUM_RESOURCES as we need to preserve compatibility */ | 351 | /* Here should be 7 and not PCI_NUM_RESOURCES as we need to preserve compatibility */ |
358 | for (i=0; i<7; i++) { | 352 | for (i=0; i<7; i++) { |
359 | u64 start, end; | 353 | resource_size_t start, end; |
360 | pci_resource_to_user(dev, i, &dev->resource[i], &start, &end); | 354 | pci_resource_to_user(dev, i, &dev->resource[i], &start, &end); |
361 | seq_printf(m, LONG_FORMAT, | 355 | seq_printf(m, "\t%16llx", |
362 | ((unsigned long)start) | | 356 | (unsigned long long)(start | |
363 | (dev->resource[i].flags & PCI_REGION_FLAG_MASK)); | 357 | (dev->resource[i].flags & PCI_REGION_FLAG_MASK))); |
364 | } | 358 | } |
365 | for (i=0; i<7; i++) { | 359 | for (i=0; i<7; i++) { |
366 | u64 start, end; | 360 | resource_size_t start, end; |
367 | pci_resource_to_user(dev, i, &dev->resource[i], &start, &end); | 361 | pci_resource_to_user(dev, i, &dev->resource[i], &start, &end); |
368 | seq_printf(m, LONG_FORMAT, | 362 | seq_printf(m, "\t%16llx", |
369 | dev->resource[i].start < dev->resource[i].end ? | 363 | dev->resource[i].start < dev->resource[i].end ? |
370 | (unsigned long)(end - start) + 1 : 0); | 364 | (unsigned long long)(end - start) + 1 : 0); |
371 | } | 365 | } |
372 | seq_putc(m, '\t'); | 366 | seq_putc(m, '\t'); |
373 | if (drv) | 367 | if (drv) |
diff --git a/drivers/pci/rom.c b/drivers/pci/rom.c index 598a115cd00e..cbb69cf41311 100644 --- a/drivers/pci/rom.c +++ b/drivers/pci/rom.c | |||
@@ -80,8 +80,8 @@ void __iomem *pci_map_rom(struct pci_dev *pdev, size_t *size) | |||
80 | } else { | 80 | } else { |
81 | if (res->flags & IORESOURCE_ROM_COPY) { | 81 | if (res->flags & IORESOURCE_ROM_COPY) { |
82 | *size = pci_resource_len(pdev, PCI_ROM_RESOURCE); | 82 | *size = pci_resource_len(pdev, PCI_ROM_RESOURCE); |
83 | return (void __iomem *)pci_resource_start(pdev, | 83 | return (void __iomem *)(unsigned long) |
84 | PCI_ROM_RESOURCE); | 84 | pci_resource_start(pdev, PCI_ROM_RESOURCE); |
85 | } else { | 85 | } else { |
86 | /* assign the ROM an address if it doesn't have one */ | 86 | /* assign the ROM an address if it doesn't have one */ |
87 | if (res->parent == NULL && | 87 | if (res->parent == NULL && |
@@ -170,11 +170,11 @@ void __iomem *pci_map_rom_copy(struct pci_dev *pdev, size_t *size) | |||
170 | return rom; | 170 | return rom; |
171 | 171 | ||
172 | res->end = res->start + *size; | 172 | res->end = res->start + *size; |
173 | memcpy_fromio((void*)res->start, rom, *size); | 173 | memcpy_fromio((void*)(unsigned long)res->start, rom, *size); |
174 | pci_unmap_rom(pdev, rom); | 174 | pci_unmap_rom(pdev, rom); |
175 | res->flags |= IORESOURCE_ROM_COPY; | 175 | res->flags |= IORESOURCE_ROM_COPY; |
176 | 176 | ||
177 | return (void __iomem *)res->start; | 177 | return (void __iomem *)(unsigned long)res->start; |
178 | } | 178 | } |
179 | 179 | ||
180 | /** | 180 | /** |
@@ -227,7 +227,7 @@ void pci_cleanup_rom(struct pci_dev *pdev) | |||
227 | { | 227 | { |
228 | struct resource *res = &pdev->resource[PCI_ROM_RESOURCE]; | 228 | struct resource *res = &pdev->resource[PCI_ROM_RESOURCE]; |
229 | if (res->flags & IORESOURCE_ROM_COPY) { | 229 | if (res->flags & IORESOURCE_ROM_COPY) { |
230 | kfree((void*)res->start); | 230 | kfree((void*)(unsigned long)res->start); |
231 | res->flags &= ~IORESOURCE_ROM_COPY; | 231 | res->flags &= ~IORESOURCE_ROM_COPY; |
232 | res->start = 0; | 232 | res->start = 0; |
233 | res->end = 0; | 233 | res->end = 0; |
diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c index 35086e80faa9..47c1071ad84e 100644 --- a/drivers/pci/setup-bus.c +++ b/drivers/pci/setup-bus.c | |||
@@ -357,8 +357,10 @@ pbus_size_mem(struct pci_bus *bus, unsigned long mask, unsigned long type) | |||
357 | order = __ffs(align) - 20; | 357 | order = __ffs(align) - 20; |
358 | if (order > 11) { | 358 | if (order > 11) { |
359 | printk(KERN_WARNING "PCI: region %s/%d " | 359 | printk(KERN_WARNING "PCI: region %s/%d " |
360 | "too large: %lx-%lx\n", | 360 | "too large: %llx-%llx\n", |
361 | pci_name(dev), i, r->start, r->end); | 361 | pci_name(dev), i, |
362 | (unsigned long long)r->start, | ||
363 | (unsigned long long)r->end); | ||
362 | r->flags = 0; | 364 | r->flags = 0; |
363 | continue; | 365 | continue; |
364 | } | 366 | } |
diff --git a/drivers/pci/setup-res.c b/drivers/pci/setup-res.c index 577f4b55c46d..ab78e4bbdd83 100644 --- a/drivers/pci/setup-res.c +++ b/drivers/pci/setup-res.c | |||
@@ -40,8 +40,9 @@ pci_update_resource(struct pci_dev *dev, struct resource *res, int resno) | |||
40 | 40 | ||
41 | pcibios_resource_to_bus(dev, ®ion, res); | 41 | pcibios_resource_to_bus(dev, ®ion, res); |
42 | 42 | ||
43 | pr_debug(" got res [%lx:%lx] bus [%lx:%lx] flags %lx for " | 43 | pr_debug(" got res [%llx:%llx] bus [%lx:%lx] flags %lx for " |
44 | "BAR %d of %s\n", res->start, res->end, | 44 | "BAR %d of %s\n", (unsigned long long)res->start, |
45 | (unsigned long long)res->end, | ||
45 | region.start, region.end, res->flags, resno, pci_name(dev)); | 46 | region.start, region.end, res->flags, resno, pci_name(dev)); |
46 | 47 | ||
47 | new = region.start | (res->flags & PCI_REGION_FLAG_MASK); | 48 | new = region.start | (res->flags & PCI_REGION_FLAG_MASK); |
@@ -104,10 +105,12 @@ pci_claim_resource(struct pci_dev *dev, int resource) | |||
104 | err = insert_resource(root, res); | 105 | err = insert_resource(root, res); |
105 | 106 | ||
106 | if (err) { | 107 | if (err) { |
107 | printk(KERN_ERR "PCI: %s region %d of %s %s [%lx:%lx]\n", | 108 | printk(KERN_ERR "PCI: %s region %d of %s %s [%llx:%llx]\n", |
108 | root ? "Address space collision on" : | 109 | root ? "Address space collision on" : |
109 | "No parent found for", | 110 | "No parent found for", |
110 | resource, dtype, pci_name(dev), res->start, res->end); | 111 | resource, dtype, pci_name(dev), |
112 | (unsigned long long)res->start, | ||
113 | (unsigned long long)res->end); | ||
111 | } | 114 | } |
112 | 115 | ||
113 | return err; | 116 | return err; |
@@ -118,7 +121,7 @@ int pci_assign_resource(struct pci_dev *dev, int resno) | |||
118 | { | 121 | { |
119 | struct pci_bus *bus = dev->bus; | 122 | struct pci_bus *bus = dev->bus; |
120 | struct resource *res = dev->resource + resno; | 123 | struct resource *res = dev->resource + resno; |
121 | unsigned long size, min, align; | 124 | resource_size_t size, min, align; |
122 | int ret; | 125 | int ret; |
123 | 126 | ||
124 | size = res->end - res->start + 1; | 127 | size = res->end - res->start + 1; |
@@ -145,9 +148,11 @@ int pci_assign_resource(struct pci_dev *dev, int resno) | |||
145 | } | 148 | } |
146 | 149 | ||
147 | if (ret) { | 150 | if (ret) { |
148 | printk(KERN_ERR "PCI: Failed to allocate %s resource #%d:%lx@%lx for %s\n", | 151 | printk(KERN_ERR "PCI: Failed to allocate %s resource " |
149 | res->flags & IORESOURCE_IO ? "I/O" : "mem", | 152 | "#%d:%llx@%llx for %s\n", |
150 | resno, size, res->start, pci_name(dev)); | 153 | res->flags & IORESOURCE_IO ? "I/O" : "mem", |
154 | resno, (unsigned long long)size, | ||
155 | (unsigned long long)res->start, pci_name(dev)); | ||
151 | } else if (resno < PCI_BRIDGE_RESOURCES) { | 156 | } else if (resno < PCI_BRIDGE_RESOURCES) { |
152 | pci_update_resource(dev, res, resno); | 157 | pci_update_resource(dev, res, resno); |
153 | } | 158 | } |
@@ -204,7 +209,7 @@ pdev_sort_resources(struct pci_dev *dev, struct resource_list *head) | |||
204 | for (i = 0; i < PCI_NUM_RESOURCES; i++) { | 209 | for (i = 0; i < PCI_NUM_RESOURCES; i++) { |
205 | struct resource *r; | 210 | struct resource *r; |
206 | struct resource_list *list, *tmp; | 211 | struct resource_list *list, *tmp; |
207 | unsigned long r_align; | 212 | resource_size_t r_align; |
208 | 213 | ||
209 | r = &dev->resource[i]; | 214 | r = &dev->resource[i]; |
210 | r_align = r->end - r->start; | 215 | r_align = r->end - r->start; |
@@ -213,13 +218,14 @@ pdev_sort_resources(struct pci_dev *dev, struct resource_list *head) | |||
213 | continue; | 218 | continue; |
214 | if (!r_align) { | 219 | if (!r_align) { |
215 | printk(KERN_WARNING "PCI: Ignore bogus resource %d " | 220 | printk(KERN_WARNING "PCI: Ignore bogus resource %d " |
216 | "[%lx:%lx] of %s\n", | 221 | "[%llx:%llx] of %s\n", |
217 | i, r->start, r->end, pci_name(dev)); | 222 | i, (unsigned long long)r->start, |
223 | (unsigned long long)r->end, pci_name(dev)); | ||
218 | continue; | 224 | continue; |
219 | } | 225 | } |
220 | r_align = (i < PCI_BRIDGE_RESOURCES) ? r_align + 1 : r->start; | 226 | r_align = (i < PCI_BRIDGE_RESOURCES) ? r_align + 1 : r->start; |
221 | for (list = head; ; list = list->next) { | 227 | for (list = head; ; list = list->next) { |
222 | unsigned long align = 0; | 228 | resource_size_t align = 0; |
223 | struct resource_list *ln = list->next; | 229 | struct resource_list *ln = list->next; |
224 | int idx; | 230 | int idx; |
225 | 231 | ||
diff --git a/drivers/pcmcia/hd64465_ss.c b/drivers/pcmcia/hd64465_ss.c index b39435bbfaeb..c662e4f89d46 100644 --- a/drivers/pcmcia/hd64465_ss.c +++ b/drivers/pcmcia/hd64465_ss.c | |||
@@ -244,8 +244,8 @@ static void hs_map_irq(hs_socket_t *sp, unsigned int irq) | |||
244 | 244 | ||
245 | hs_mapped_irq[irq].sock = sp; | 245 | hs_mapped_irq[irq].sock = sp; |
246 | /* insert ourselves as the irq controller */ | 246 | /* insert ourselves as the irq controller */ |
247 | hs_mapped_irq[irq].old_handler = irq_desc[irq].handler; | 247 | hs_mapped_irq[irq].old_handler = irq_desc[irq].chip; |
248 | irq_desc[irq].handler = &hd64465_ss_irq_type; | 248 | irq_desc[irq].chip = &hd64465_ss_irq_type; |
249 | } | 249 | } |
250 | 250 | ||
251 | 251 | ||
@@ -260,7 +260,7 @@ static void hs_unmap_irq(hs_socket_t *sp, unsigned int irq) | |||
260 | return; | 260 | return; |
261 | 261 | ||
262 | /* restore the original irq controller */ | 262 | /* restore the original irq controller */ |
263 | irq_desc[irq].handler = hs_mapped_irq[irq].old_handler; | 263 | irq_desc[irq].chip = hs_mapped_irq[irq].old_handler; |
264 | } | 264 | } |
265 | 265 | ||
266 | /*============================================================*/ | 266 | /*============================================================*/ |
diff --git a/drivers/pcmcia/i82365.c b/drivers/pcmcia/i82365.c index a2f05f485156..ff51a65d9433 100644 --- a/drivers/pcmcia/i82365.c +++ b/drivers/pcmcia/i82365.c | |||
@@ -1084,9 +1084,10 @@ static int i365_set_mem_map(u_short sock, struct pccard_mem_map *mem) | |||
1084 | u_short base, i; | 1084 | u_short base, i; |
1085 | u_char map; | 1085 | u_char map; |
1086 | 1086 | ||
1087 | debug(1, "SetMemMap(%d, %d, %#2.2x, %d ns, %#lx-%#lx, " | 1087 | debug(1, "SetMemMap(%d, %d, %#2.2x, %d ns, %#llx-%#llx, " |
1088 | "%#x)\n", sock, mem->map, mem->flags, mem->speed, | 1088 | "%#x)\n", sock, mem->map, mem->flags, mem->speed, |
1089 | mem->res->start, mem->res->end, mem->card_start); | 1089 | (unsigned long long)mem->res->start, |
1090 | (unsigned long long)mem->res->end, mem->card_start); | ||
1090 | 1091 | ||
1091 | map = mem->map; | 1092 | map = mem->map; |
1092 | if ((map > 4) || (mem->card_start > 0x3ffffff) || | 1093 | if ((map > 4) || (mem->card_start > 0x3ffffff) || |
diff --git a/drivers/pcmcia/m8xx_pcmcia.c b/drivers/pcmcia/m8xx_pcmcia.c index 0e07d9535116..d0f68ab8f041 100644 --- a/drivers/pcmcia/m8xx_pcmcia.c +++ b/drivers/pcmcia/m8xx_pcmcia.c | |||
@@ -157,7 +157,7 @@ MODULE_LICENSE("Dual MPL/GPL"); | |||
157 | 157 | ||
158 | static int pcmcia_schlvl = PCMCIA_SCHLVL; | 158 | static int pcmcia_schlvl = PCMCIA_SCHLVL; |
159 | 159 | ||
160 | static spinlock_t events_lock = SPIN_LOCK_UNLOCKED; | 160 | static DEFINE_SPINLOCK(events_lock); |
161 | 161 | ||
162 | 162 | ||
163 | #define PCMCIA_SOCKET_KEY_5V 1 | 163 | #define PCMCIA_SOCKET_KEY_5V 1 |
@@ -644,7 +644,7 @@ static struct platform_device m8xx_device = { | |||
644 | }; | 644 | }; |
645 | 645 | ||
646 | static u32 pending_events[PCMCIA_SOCKETS_NO]; | 646 | static u32 pending_events[PCMCIA_SOCKETS_NO]; |
647 | static spinlock_t pending_event_lock = SPIN_LOCK_UNLOCKED; | 647 | static DEFINE_SPINLOCK(pending_event_lock); |
648 | 648 | ||
649 | static irqreturn_t m8xx_interrupt(int irq, void *dev, struct pt_regs *regs) | 649 | static irqreturn_t m8xx_interrupt(int irq, void *dev, struct pt_regs *regs) |
650 | { | 650 | { |
diff --git a/drivers/pcmcia/pd6729.c b/drivers/pcmcia/pd6729.c index 247ab837f841..9ee26c1b8635 100644 --- a/drivers/pcmcia/pd6729.c +++ b/drivers/pcmcia/pd6729.c | |||
@@ -642,7 +642,8 @@ static int __devinit pd6729_pci_probe(struct pci_dev *dev, | |||
642 | goto err_out_free_mem; | 642 | goto err_out_free_mem; |
643 | 643 | ||
644 | printk(KERN_INFO "pd6729: Cirrus PD6729 PCI to PCMCIA Bridge " | 644 | printk(KERN_INFO "pd6729: Cirrus PD6729 PCI to PCMCIA Bridge " |
645 | "at 0x%lx on irq %d\n", pci_resource_start(dev, 0), dev->irq); | 645 | "at 0x%llx on irq %d\n", |
646 | (unsigned long long)pci_resource_start(dev, 0), dev->irq); | ||
646 | /* | 647 | /* |
647 | * Since we have no memory BARs some firmware may not | 648 | * Since we have no memory BARs some firmware may not |
648 | * have had PCI_COMMAND_MEMORY enabled, yet the device needs it. | 649 | * have had PCI_COMMAND_MEMORY enabled, yet the device needs it. |
diff --git a/drivers/pcmcia/rsrc_nonstatic.c b/drivers/pcmcia/rsrc_nonstatic.c index 0f8b157c9717..c3176b16b7be 100644 --- a/drivers/pcmcia/rsrc_nonstatic.c +++ b/drivers/pcmcia/rsrc_nonstatic.c | |||
@@ -72,7 +72,7 @@ static DEFINE_MUTEX(rsrc_mutex); | |||
72 | ======================================================================*/ | 72 | ======================================================================*/ |
73 | 73 | ||
74 | static struct resource * | 74 | static struct resource * |
75 | make_resource(unsigned long b, unsigned long n, int flags, char *name) | 75 | make_resource(resource_size_t b, resource_size_t n, int flags, char *name) |
76 | { | 76 | { |
77 | struct resource *res = kzalloc(sizeof(*res), GFP_KERNEL); | 77 | struct resource *res = kzalloc(sizeof(*res), GFP_KERNEL); |
78 | 78 | ||
@@ -86,8 +86,8 @@ make_resource(unsigned long b, unsigned long n, int flags, char *name) | |||
86 | } | 86 | } |
87 | 87 | ||
88 | static struct resource * | 88 | static struct resource * |
89 | claim_region(struct pcmcia_socket *s, unsigned long base, unsigned long size, | 89 | claim_region(struct pcmcia_socket *s, resource_size_t base, |
90 | int type, char *name) | 90 | resource_size_t size, int type, char *name) |
91 | { | 91 | { |
92 | struct resource *res, *parent; | 92 | struct resource *res, *parent; |
93 | 93 | ||
@@ -519,10 +519,10 @@ struct pcmcia_align_data { | |||
519 | 519 | ||
520 | static void | 520 | static void |
521 | pcmcia_common_align(void *align_data, struct resource *res, | 521 | pcmcia_common_align(void *align_data, struct resource *res, |
522 | unsigned long size, unsigned long align) | 522 | resource_size_t size, resource_size_t align) |
523 | { | 523 | { |
524 | struct pcmcia_align_data *data = align_data; | 524 | struct pcmcia_align_data *data = align_data; |
525 | unsigned long start; | 525 | resource_size_t start; |
526 | /* | 526 | /* |
527 | * Ensure that we have the correct start address | 527 | * Ensure that we have the correct start address |
528 | */ | 528 | */ |
@@ -533,8 +533,8 @@ pcmcia_common_align(void *align_data, struct resource *res, | |||
533 | } | 533 | } |
534 | 534 | ||
535 | static void | 535 | static void |
536 | pcmcia_align(void *align_data, struct resource *res, | 536 | pcmcia_align(void *align_data, struct resource *res, resource_size_t size, |
537 | unsigned long size, unsigned long align) | 537 | resource_size_t align) |
538 | { | 538 | { |
539 | struct pcmcia_align_data *data = align_data; | 539 | struct pcmcia_align_data *data = align_data; |
540 | struct resource_map *m; | 540 | struct resource_map *m; |
@@ -808,8 +808,10 @@ static int nonstatic_autoadd_resources(struct pcmcia_socket *s) | |||
808 | if (res->flags & IORESOURCE_IO) { | 808 | if (res->flags & IORESOURCE_IO) { |
809 | if (res == &ioport_resource) | 809 | if (res == &ioport_resource) |
810 | continue; | 810 | continue; |
811 | printk(KERN_INFO "pcmcia: parent PCI bridge I/O window: 0x%lx - 0x%lx\n", | 811 | printk(KERN_INFO "pcmcia: parent PCI bridge I/O " |
812 | res->start, res->end); | 812 | "window: 0x%llx - 0x%llx\n", |
813 | (unsigned long long)res->start, | ||
814 | (unsigned long long)res->end); | ||
813 | if (!adjust_io(s, ADD_MANAGED_RESOURCE, res->start, res->end)) | 815 | if (!adjust_io(s, ADD_MANAGED_RESOURCE, res->start, res->end)) |
814 | done |= IORESOURCE_IO; | 816 | done |= IORESOURCE_IO; |
815 | 817 | ||
@@ -818,8 +820,10 @@ static int nonstatic_autoadd_resources(struct pcmcia_socket *s) | |||
818 | if (res->flags & IORESOURCE_MEM) { | 820 | if (res->flags & IORESOURCE_MEM) { |
819 | if (res == &iomem_resource) | 821 | if (res == &iomem_resource) |
820 | continue; | 822 | continue; |
821 | printk(KERN_INFO "pcmcia: parent PCI bridge Memory window: 0x%lx - 0x%lx\n", | 823 | printk(KERN_INFO "pcmcia: parent PCI bridge Memory " |
822 | res->start, res->end); | 824 | "window: 0x%llx - 0x%llx\n", |
825 | (unsigned long long)res->start, | ||
826 | (unsigned long long)res->end); | ||
823 | if (!adjust_memory(s, ADD_MANAGED_RESOURCE, res->start, res->end)) | 827 | if (!adjust_memory(s, ADD_MANAGED_RESOURCE, res->start, res->end)) |
824 | done |= IORESOURCE_MEM; | 828 | done |= IORESOURCE_MEM; |
825 | } | 829 | } |
diff --git a/drivers/pcmcia/tcic.c b/drivers/pcmcia/tcic.c index 73bad1d5cb23..65a60671659f 100644 --- a/drivers/pcmcia/tcic.c +++ b/drivers/pcmcia/tcic.c | |||
@@ -756,8 +756,9 @@ static int tcic_set_mem_map(struct pcmcia_socket *sock, struct pccard_mem_map *m | |||
756 | u_long base, len, mmap; | 756 | u_long base, len, mmap; |
757 | 757 | ||
758 | debug(1, "SetMemMap(%d, %d, %#2.2x, %d ns, " | 758 | debug(1, "SetMemMap(%d, %d, %#2.2x, %d ns, " |
759 | "%#lx-%#lx, %#x)\n", psock, mem->map, mem->flags, | 759 | "%#llx-%#llx, %#x)\n", psock, mem->map, mem->flags, |
760 | mem->speed, mem->res->start, mem->res->end, mem->card_start); | 760 | mem->speed, (unsigned long long)mem->res->start, |
761 | (unsigned long long)mem->res->end, mem->card_start); | ||
761 | if ((mem->map > 3) || (mem->card_start > 0x3ffffff) || | 762 | if ((mem->map > 3) || (mem->card_start > 0x3ffffff) || |
762 | (mem->res->start > 0xffffff) || (mem->res->end > 0xffffff) || | 763 | (mem->res->start > 0xffffff) || (mem->res->end > 0xffffff) || |
763 | (mem->res->start > mem->res->end) || (mem->speed > 1000)) | 764 | (mem->res->start > mem->res->end) || (mem->speed > 1000)) |
diff --git a/drivers/pnp/interface.c b/drivers/pnp/interface.c index a2d8ce7fef9c..3163e3d73da1 100644 --- a/drivers/pnp/interface.c +++ b/drivers/pnp/interface.c | |||
@@ -264,7 +264,7 @@ static ssize_t pnp_show_current_resources(struct device *dmdev, struct device_at | |||
264 | if (pnp_port_flags(dev, i) & IORESOURCE_DISABLED) | 264 | if (pnp_port_flags(dev, i) & IORESOURCE_DISABLED) |
265 | pnp_printf(buffer," disabled\n"); | 265 | pnp_printf(buffer," disabled\n"); |
266 | else | 266 | else |
267 | pnp_printf(buffer," 0x%lx-0x%lx\n", | 267 | pnp_printf(buffer," 0x%llx-0x%llx\n", |
268 | pnp_port_start(dev, i), | 268 | pnp_port_start(dev, i), |
269 | pnp_port_end(dev, i)); | 269 | pnp_port_end(dev, i)); |
270 | } | 270 | } |
@@ -275,7 +275,7 @@ static ssize_t pnp_show_current_resources(struct device *dmdev, struct device_at | |||
275 | if (pnp_mem_flags(dev, i) & IORESOURCE_DISABLED) | 275 | if (pnp_mem_flags(dev, i) & IORESOURCE_DISABLED) |
276 | pnp_printf(buffer," disabled\n"); | 276 | pnp_printf(buffer," disabled\n"); |
277 | else | 277 | else |
278 | pnp_printf(buffer," 0x%lx-0x%lx\n", | 278 | pnp_printf(buffer," 0x%llx-0x%llx\n", |
279 | pnp_mem_start(dev, i), | 279 | pnp_mem_start(dev, i), |
280 | pnp_mem_end(dev, i)); | 280 | pnp_mem_end(dev, i)); |
281 | } | 281 | } |
@@ -286,7 +286,7 @@ static ssize_t pnp_show_current_resources(struct device *dmdev, struct device_at | |||
286 | if (pnp_irq_flags(dev, i) & IORESOURCE_DISABLED) | 286 | if (pnp_irq_flags(dev, i) & IORESOURCE_DISABLED) |
287 | pnp_printf(buffer," disabled\n"); | 287 | pnp_printf(buffer," disabled\n"); |
288 | else | 288 | else |
289 | pnp_printf(buffer," %ld\n", | 289 | pnp_printf(buffer," %lld\n", |
290 | pnp_irq(dev, i)); | 290 | pnp_irq(dev, i)); |
291 | } | 291 | } |
292 | } | 292 | } |
@@ -296,7 +296,7 @@ static ssize_t pnp_show_current_resources(struct device *dmdev, struct device_at | |||
296 | if (pnp_dma_flags(dev, i) & IORESOURCE_DISABLED) | 296 | if (pnp_dma_flags(dev, i) & IORESOURCE_DISABLED) |
297 | pnp_printf(buffer," disabled\n"); | 297 | pnp_printf(buffer," disabled\n"); |
298 | else | 298 | else |
299 | pnp_printf(buffer," %ld\n", | 299 | pnp_printf(buffer," %lld\n", |
300 | pnp_dma(dev, i)); | 300 | pnp_dma(dev, i)); |
301 | } | 301 | } |
302 | } | 302 | } |
diff --git a/drivers/pnp/manager.c b/drivers/pnp/manager.c index 6fff109bdab6..1d7a5b87f4cb 100644 --- a/drivers/pnp/manager.c +++ b/drivers/pnp/manager.c | |||
@@ -20,7 +20,8 @@ DECLARE_MUTEX(pnp_res_mutex); | |||
20 | 20 | ||
21 | static int pnp_assign_port(struct pnp_dev *dev, struct pnp_port *rule, int idx) | 21 | static int pnp_assign_port(struct pnp_dev *dev, struct pnp_port *rule, int idx) |
22 | { | 22 | { |
23 | unsigned long *start, *end, *flags; | 23 | resource_size_t *start, *end; |
24 | unsigned long *flags; | ||
24 | 25 | ||
25 | if (!dev || !rule) | 26 | if (!dev || !rule) |
26 | return -EINVAL; | 27 | return -EINVAL; |
@@ -63,7 +64,8 @@ static int pnp_assign_port(struct pnp_dev *dev, struct pnp_port *rule, int idx) | |||
63 | 64 | ||
64 | static int pnp_assign_mem(struct pnp_dev *dev, struct pnp_mem *rule, int idx) | 65 | static int pnp_assign_mem(struct pnp_dev *dev, struct pnp_mem *rule, int idx) |
65 | { | 66 | { |
66 | unsigned long *start, *end, *flags; | 67 | resource_size_t *start, *end; |
68 | unsigned long *flags; | ||
67 | 69 | ||
68 | if (!dev || !rule) | 70 | if (!dev || !rule) |
69 | return -EINVAL; | 71 | return -EINVAL; |
@@ -116,7 +118,8 @@ static int pnp_assign_mem(struct pnp_dev *dev, struct pnp_mem *rule, int idx) | |||
116 | 118 | ||
117 | static int pnp_assign_irq(struct pnp_dev * dev, struct pnp_irq *rule, int idx) | 119 | static int pnp_assign_irq(struct pnp_dev * dev, struct pnp_irq *rule, int idx) |
118 | { | 120 | { |
119 | unsigned long *start, *end, *flags; | 121 | resource_size_t *start, *end; |
122 | unsigned long *flags; | ||
120 | int i; | 123 | int i; |
121 | 124 | ||
122 | /* IRQ priority: this table is good for i386 */ | 125 | /* IRQ priority: this table is good for i386 */ |
@@ -168,7 +171,8 @@ static int pnp_assign_irq(struct pnp_dev * dev, struct pnp_irq *rule, int idx) | |||
168 | 171 | ||
169 | static int pnp_assign_dma(struct pnp_dev *dev, struct pnp_dma *rule, int idx) | 172 | static int pnp_assign_dma(struct pnp_dev *dev, struct pnp_dma *rule, int idx) |
170 | { | 173 | { |
171 | unsigned long *start, *end, *flags; | 174 | resource_size_t *start, *end; |
175 | unsigned long *flags; | ||
172 | int i; | 176 | int i; |
173 | 177 | ||
174 | /* DMA priority: this table is good for i386 */ | 178 | /* DMA priority: this table is good for i386 */ |
@@ -582,7 +586,8 @@ int pnp_disable_dev(struct pnp_dev *dev) | |||
582 | * @size: size of region | 586 | * @size: size of region |
583 | * | 587 | * |
584 | */ | 588 | */ |
585 | void pnp_resource_change(struct resource *resource, unsigned long start, unsigned long size) | 589 | void pnp_resource_change(struct resource *resource, resource_size_t start, |
590 | resource_size_t size) | ||
586 | { | 591 | { |
587 | if (resource == NULL) | 592 | if (resource == NULL) |
588 | return; | 593 | return; |
diff --git a/drivers/pnp/resource.c b/drivers/pnp/resource.c index 6ded527169f4..7bb892f58cc0 100644 --- a/drivers/pnp/resource.c +++ b/drivers/pnp/resource.c | |||
@@ -241,7 +241,7 @@ int pnp_check_port(struct pnp_dev * dev, int idx) | |||
241 | { | 241 | { |
242 | int tmp; | 242 | int tmp; |
243 | struct pnp_dev *tdev; | 243 | struct pnp_dev *tdev; |
244 | unsigned long *port, *end, *tport, *tend; | 244 | resource_size_t *port, *end, *tport, *tend; |
245 | port = &dev->res.port_resource[idx].start; | 245 | port = &dev->res.port_resource[idx].start; |
246 | end = &dev->res.port_resource[idx].end; | 246 | end = &dev->res.port_resource[idx].end; |
247 | 247 | ||
@@ -297,7 +297,7 @@ int pnp_check_mem(struct pnp_dev * dev, int idx) | |||
297 | { | 297 | { |
298 | int tmp; | 298 | int tmp; |
299 | struct pnp_dev *tdev; | 299 | struct pnp_dev *tdev; |
300 | unsigned long *addr, *end, *taddr, *tend; | 300 | resource_size_t *addr, *end, *taddr, *tend; |
301 | addr = &dev->res.mem_resource[idx].start; | 301 | addr = &dev->res.mem_resource[idx].start; |
302 | end = &dev->res.mem_resource[idx].end; | 302 | end = &dev->res.mem_resource[idx].end; |
303 | 303 | ||
@@ -358,7 +358,7 @@ int pnp_check_irq(struct pnp_dev * dev, int idx) | |||
358 | { | 358 | { |
359 | int tmp; | 359 | int tmp; |
360 | struct pnp_dev *tdev; | 360 | struct pnp_dev *tdev; |
361 | unsigned long * irq = &dev->res.irq_resource[idx].start; | 361 | resource_size_t * irq = &dev->res.irq_resource[idx].start; |
362 | 362 | ||
363 | /* if the resource doesn't exist, don't complain about it */ | 363 | /* if the resource doesn't exist, don't complain about it */ |
364 | if (cannot_compare(dev->res.irq_resource[idx].flags)) | 364 | if (cannot_compare(dev->res.irq_resource[idx].flags)) |
@@ -423,7 +423,7 @@ int pnp_check_dma(struct pnp_dev * dev, int idx) | |||
423 | #ifndef CONFIG_IA64 | 423 | #ifndef CONFIG_IA64 |
424 | int tmp; | 424 | int tmp; |
425 | struct pnp_dev *tdev; | 425 | struct pnp_dev *tdev; |
426 | unsigned long * dma = &dev->res.dma_resource[idx].start; | 426 | resource_size_t * dma = &dev->res.dma_resource[idx].start; |
427 | 427 | ||
428 | /* if the resource doesn't exist, don't complain about it */ | 428 | /* if the resource doesn't exist, don't complain about it */ |
429 | if (cannot_compare(dev->res.dma_resource[idx].flags)) | 429 | if (cannot_compare(dev->res.dma_resource[idx].flags)) |
diff --git a/drivers/rapidio/rio-access.c b/drivers/rapidio/rio-access.c index b9fab2ae3a36..8b56bbdd011e 100644 --- a/drivers/rapidio/rio-access.c +++ b/drivers/rapidio/rio-access.c | |||
@@ -17,8 +17,8 @@ | |||
17 | * These interrupt-safe spinlocks protect all accesses to RIO | 17 | * These interrupt-safe spinlocks protect all accesses to RIO |
18 | * configuration space and doorbell access. | 18 | * configuration space and doorbell access. |
19 | */ | 19 | */ |
20 | static spinlock_t rio_config_lock = SPIN_LOCK_UNLOCKED; | 20 | static DEFINE_SPINLOCK(rio_config_lock); |
21 | static spinlock_t rio_doorbell_lock = SPIN_LOCK_UNLOCKED; | 21 | static DEFINE_SPINLOCK(rio_doorbell_lock); |
22 | 22 | ||
23 | /* | 23 | /* |
24 | * Wrappers for all RIO configuration access functions. They just check | 24 | * Wrappers for all RIO configuration access functions. They just check |
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index bccff400b198..f2fc81a9074d 100644 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig | |||
@@ -162,6 +162,16 @@ config RTC_DRV_PCF8583 | |||
162 | This driver can also be built as a module. If so, the module | 162 | This driver can also be built as a module. If so, the module |
163 | will be called rtc-pcf8583. | 163 | will be called rtc-pcf8583. |
164 | 164 | ||
165 | config RTC_DRV_RS5C348 | ||
166 | tristate "Ricoh RS5C348A/B" | ||
167 | depends on RTC_CLASS && SPI | ||
168 | help | ||
169 | If you say yes here you get support for the | ||
170 | Ricoh RS5C348A and RS5C348B RTC chips. | ||
171 | |||
172 | This driver can also be built as a module. If so, the module | ||
173 | will be called rtc-rs5c348. | ||
174 | |||
165 | config RTC_DRV_RS5C372 | 175 | config RTC_DRV_RS5C372 |
166 | tristate "Ricoh RS5C372A/B" | 176 | tristate "Ricoh RS5C372A/B" |
167 | depends on RTC_CLASS && I2C | 177 | depends on RTC_CLASS && I2C |
diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile index 900d210dd1a2..da5e38774e13 100644 --- a/drivers/rtc/Makefile +++ b/drivers/rtc/Makefile | |||
@@ -19,6 +19,7 @@ obj-$(CONFIG_RTC_DRV_DS1742) += rtc-ds1742.o | |||
19 | obj-$(CONFIG_RTC_DRV_PCF8563) += rtc-pcf8563.o | 19 | obj-$(CONFIG_RTC_DRV_PCF8563) += rtc-pcf8563.o |
20 | obj-$(CONFIG_RTC_DRV_PCF8583) += rtc-pcf8583.o | 20 | obj-$(CONFIG_RTC_DRV_PCF8583) += rtc-pcf8583.o |
21 | obj-$(CONFIG_RTC_DRV_RS5C372) += rtc-rs5c372.o | 21 | obj-$(CONFIG_RTC_DRV_RS5C372) += rtc-rs5c372.o |
22 | obj-$(CONFIG_RTC_DRV_RS5C348) += rtc-rs5c348.o | ||
22 | obj-$(CONFIG_RTC_DRV_M48T86) += rtc-m48t86.o | 23 | obj-$(CONFIG_RTC_DRV_M48T86) += rtc-m48t86.o |
23 | obj-$(CONFIG_RTC_DRV_DS1553) += rtc-ds1553.o | 24 | obj-$(CONFIG_RTC_DRV_DS1553) += rtc-ds1553.o |
24 | obj-$(CONFIG_RTC_DRV_EP93XX) += rtc-ep93xx.o | 25 | obj-$(CONFIG_RTC_DRV_EP93XX) += rtc-ep93xx.o |
diff --git a/drivers/rtc/class.c b/drivers/rtc/class.c index 5396beec30d0..1cb61a761cb2 100644 --- a/drivers/rtc/class.c +++ b/drivers/rtc/class.c | |||
@@ -94,7 +94,9 @@ exit_kfree: | |||
94 | kfree(rtc); | 94 | kfree(rtc); |
95 | 95 | ||
96 | exit_idr: | 96 | exit_idr: |
97 | mutex_lock(&idr_lock); | ||
97 | idr_remove(&rtc_idr, id); | 98 | idr_remove(&rtc_idr, id); |
99 | mutex_unlock(&idr_lock); | ||
98 | 100 | ||
99 | exit: | 101 | exit: |
100 | dev_err(dev, "rtc core: unable to register %s, err = %d\n", | 102 | dev_err(dev, "rtc core: unable to register %s, err = %d\n", |
diff --git a/drivers/rtc/rtc-ds1553.c b/drivers/rtc/rtc-ds1553.c index ecafbad41a24..762521a1419c 100644 --- a/drivers/rtc/rtc-ds1553.c +++ b/drivers/rtc/rtc-ds1553.c | |||
@@ -226,7 +226,7 @@ static int ds1553_rtc_ioctl(struct device *dev, unsigned int cmd, | |||
226 | struct rtc_plat_data *pdata = platform_get_drvdata(pdev); | 226 | struct rtc_plat_data *pdata = platform_get_drvdata(pdev); |
227 | 227 | ||
228 | if (pdata->irq < 0) | 228 | if (pdata->irq < 0) |
229 | return -ENOIOCTLCMD; | 229 | return -ENOIOCTLCMD; /* fall back into rtc-dev's emulation */ |
230 | switch (cmd) { | 230 | switch (cmd) { |
231 | case RTC_AIE_OFF: | 231 | case RTC_AIE_OFF: |
232 | pdata->irqen &= ~RTC_AF; | 232 | pdata->irqen &= ~RTC_AF; |
diff --git a/drivers/rtc/rtc-rs5c348.c b/drivers/rtc/rtc-rs5c348.c new file mode 100644 index 000000000000..0964d1dba925 --- /dev/null +++ b/drivers/rtc/rtc-rs5c348.c | |||
@@ -0,0 +1,246 @@ | |||
1 | /* | ||
2 | * A SPI driver for the Ricoh RS5C348 RTC | ||
3 | * | ||
4 | * Copyright (C) 2006 Atsushi Nemoto <anemo@mba.ocn.ne.jp> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 as | ||
8 | * published by the Free Software Foundation. | ||
9 | * | ||
10 | * The board specific init code should provide characteristics of this | ||
11 | * device: | ||
12 | * Mode 1 (High-Active, Shift-Then-Sample), High Avtive CS | ||
13 | */ | ||
14 | |||
15 | #include <linux/bcd.h> | ||
16 | #include <linux/delay.h> | ||
17 | #include <linux/device.h> | ||
18 | #include <linux/errno.h> | ||
19 | #include <linux/init.h> | ||
20 | #include <linux/kernel.h> | ||
21 | #include <linux/string.h> | ||
22 | #include <linux/rtc.h> | ||
23 | #include <linux/workqueue.h> | ||
24 | #include <linux/spi/spi.h> | ||
25 | |||
26 | #define DRV_VERSION "0.1" | ||
27 | |||
28 | #define RS5C348_REG_SECS 0 | ||
29 | #define RS5C348_REG_MINS 1 | ||
30 | #define RS5C348_REG_HOURS 2 | ||
31 | #define RS5C348_REG_WDAY 3 | ||
32 | #define RS5C348_REG_DAY 4 | ||
33 | #define RS5C348_REG_MONTH 5 | ||
34 | #define RS5C348_REG_YEAR 6 | ||
35 | #define RS5C348_REG_CTL1 14 | ||
36 | #define RS5C348_REG_CTL2 15 | ||
37 | |||
38 | #define RS5C348_SECS_MASK 0x7f | ||
39 | #define RS5C348_MINS_MASK 0x7f | ||
40 | #define RS5C348_HOURS_MASK 0x3f | ||
41 | #define RS5C348_WDAY_MASK 0x03 | ||
42 | #define RS5C348_DAY_MASK 0x3f | ||
43 | #define RS5C348_MONTH_MASK 0x1f | ||
44 | |||
45 | #define RS5C348_BIT_PM 0x20 /* REG_HOURS */ | ||
46 | #define RS5C348_BIT_Y2K 0x80 /* REG_MONTH */ | ||
47 | #define RS5C348_BIT_24H 0x20 /* REG_CTL1 */ | ||
48 | #define RS5C348_BIT_XSTP 0x10 /* REG_CTL2 */ | ||
49 | #define RS5C348_BIT_VDET 0x40 /* REG_CTL2 */ | ||
50 | |||
51 | #define RS5C348_CMD_W(addr) (((addr) << 4) | 0x08) /* single write */ | ||
52 | #define RS5C348_CMD_R(addr) (((addr) << 4) | 0x0c) /* single read */ | ||
53 | #define RS5C348_CMD_MW(addr) (((addr) << 4) | 0x00) /* burst write */ | ||
54 | #define RS5C348_CMD_MR(addr) (((addr) << 4) | 0x04) /* burst read */ | ||
55 | |||
56 | struct rs5c348_plat_data { | ||
57 | struct rtc_device *rtc; | ||
58 | int rtc_24h; | ||
59 | }; | ||
60 | |||
61 | static int | ||
62 | rs5c348_rtc_set_time(struct device *dev, struct rtc_time *tm) | ||
63 | { | ||
64 | struct spi_device *spi = to_spi_device(dev); | ||
65 | struct rs5c348_plat_data *pdata = spi->dev.platform_data; | ||
66 | u8 txbuf[5+7], *txp; | ||
67 | int ret; | ||
68 | |||
69 | /* Transfer 5 bytes before writing SEC. This gives 31us for carry. */ | ||
70 | txp = txbuf; | ||
71 | txbuf[0] = RS5C348_CMD_R(RS5C348_REG_CTL2); /* cmd, ctl2 */ | ||
72 | txbuf[1] = 0; /* dummy */ | ||
73 | txbuf[2] = RS5C348_CMD_R(RS5C348_REG_CTL2); /* cmd, ctl2 */ | ||
74 | txbuf[3] = 0; /* dummy */ | ||
75 | txbuf[4] = RS5C348_CMD_MW(RS5C348_REG_SECS); /* cmd, sec, ... */ | ||
76 | txp = &txbuf[5]; | ||
77 | txp[RS5C348_REG_SECS] = BIN2BCD(tm->tm_sec); | ||
78 | txp[RS5C348_REG_MINS] = BIN2BCD(tm->tm_min); | ||
79 | if (pdata->rtc_24h) { | ||
80 | txp[RS5C348_REG_HOURS] = BIN2BCD(tm->tm_hour); | ||
81 | } else { | ||
82 | /* hour 0 is AM12, noon is PM12 */ | ||
83 | txp[RS5C348_REG_HOURS] = BIN2BCD((tm->tm_hour + 11) % 12 + 1) | | ||
84 | (tm->tm_hour >= 12 ? RS5C348_BIT_PM : 0); | ||
85 | } | ||
86 | txp[RS5C348_REG_WDAY] = BIN2BCD(tm->tm_wday); | ||
87 | txp[RS5C348_REG_DAY] = BIN2BCD(tm->tm_mday); | ||
88 | txp[RS5C348_REG_MONTH] = BIN2BCD(tm->tm_mon + 1) | | ||
89 | (tm->tm_year >= 100 ? RS5C348_BIT_Y2K : 0); | ||
90 | txp[RS5C348_REG_YEAR] = BIN2BCD(tm->tm_year % 100); | ||
91 | /* write in one transfer to avoid data inconsistency */ | ||
92 | ret = spi_write_then_read(spi, txbuf, sizeof(txbuf), NULL, 0); | ||
93 | udelay(62); /* Tcsr 62us */ | ||
94 | return ret; | ||
95 | } | ||
96 | |||
97 | static int | ||
98 | rs5c348_rtc_read_time(struct device *dev, struct rtc_time *tm) | ||
99 | { | ||
100 | struct spi_device *spi = to_spi_device(dev); | ||
101 | struct rs5c348_plat_data *pdata = spi->dev.platform_data; | ||
102 | u8 txbuf[5], rxbuf[7]; | ||
103 | int ret; | ||
104 | |||
105 | /* Transfer 5 byte befores reading SEC. This gives 31us for carry. */ | ||
106 | txbuf[0] = RS5C348_CMD_R(RS5C348_REG_CTL2); /* cmd, ctl2 */ | ||
107 | txbuf[1] = 0; /* dummy */ | ||
108 | txbuf[2] = RS5C348_CMD_R(RS5C348_REG_CTL2); /* cmd, ctl2 */ | ||
109 | txbuf[3] = 0; /* dummy */ | ||
110 | txbuf[4] = RS5C348_CMD_MR(RS5C348_REG_SECS); /* cmd, sec, ... */ | ||
111 | |||
112 | /* read in one transfer to avoid data inconsistency */ | ||
113 | ret = spi_write_then_read(spi, txbuf, sizeof(txbuf), | ||
114 | rxbuf, sizeof(rxbuf)); | ||
115 | udelay(62); /* Tcsr 62us */ | ||
116 | if (ret < 0) | ||
117 | return ret; | ||
118 | |||
119 | tm->tm_sec = BCD2BIN(rxbuf[RS5C348_REG_SECS] & RS5C348_SECS_MASK); | ||
120 | tm->tm_min = BCD2BIN(rxbuf[RS5C348_REG_MINS] & RS5C348_MINS_MASK); | ||
121 | tm->tm_hour = BCD2BIN(rxbuf[RS5C348_REG_HOURS] & RS5C348_HOURS_MASK); | ||
122 | if (!pdata->rtc_24h) { | ||
123 | tm->tm_hour %= 12; | ||
124 | if (rxbuf[RS5C348_REG_HOURS] & RS5C348_BIT_PM) | ||
125 | tm->tm_hour += 12; | ||
126 | } | ||
127 | tm->tm_wday = BCD2BIN(rxbuf[RS5C348_REG_WDAY] & RS5C348_WDAY_MASK); | ||
128 | tm->tm_mday = BCD2BIN(rxbuf[RS5C348_REG_DAY] & RS5C348_DAY_MASK); | ||
129 | tm->tm_mon = | ||
130 | BCD2BIN(rxbuf[RS5C348_REG_MONTH] & RS5C348_MONTH_MASK) - 1; | ||
131 | /* year is 1900 + tm->tm_year */ | ||
132 | tm->tm_year = BCD2BIN(rxbuf[RS5C348_REG_YEAR]) + | ||
133 | ((rxbuf[RS5C348_REG_MONTH] & RS5C348_BIT_Y2K) ? 100 : 0); | ||
134 | |||
135 | if (rtc_valid_tm(tm) < 0) { | ||
136 | dev_err(&spi->dev, "retrieved date/time is not valid.\n"); | ||
137 | rtc_time_to_tm(0, tm); | ||
138 | } | ||
139 | |||
140 | return 0; | ||
141 | } | ||
142 | |||
143 | static struct rtc_class_ops rs5c348_rtc_ops = { | ||
144 | .read_time = rs5c348_rtc_read_time, | ||
145 | .set_time = rs5c348_rtc_set_time, | ||
146 | }; | ||
147 | |||
148 | static struct spi_driver rs5c348_driver; | ||
149 | |||
150 | static int __devinit rs5c348_probe(struct spi_device *spi) | ||
151 | { | ||
152 | int ret; | ||
153 | struct rtc_device *rtc; | ||
154 | struct rs5c348_plat_data *pdata; | ||
155 | |||
156 | pdata = kzalloc(sizeof(struct rs5c348_plat_data), GFP_KERNEL); | ||
157 | if (!pdata) | ||
158 | return -ENOMEM; | ||
159 | spi->dev.platform_data = pdata; | ||
160 | |||
161 | /* Check D7 of SECOND register */ | ||
162 | ret = spi_w8r8(spi, RS5C348_CMD_R(RS5C348_REG_SECS)); | ||
163 | if (ret < 0 || (ret & 0x80)) { | ||
164 | dev_err(&spi->dev, "not found.\n"); | ||
165 | goto kfree_exit; | ||
166 | } | ||
167 | |||
168 | dev_info(&spi->dev, "chip found, driver version " DRV_VERSION "\n"); | ||
169 | dev_info(&spi->dev, "spiclk %u KHz.\n", | ||
170 | (spi->max_speed_hz + 500) / 1000); | ||
171 | |||
172 | /* turn RTC on if it was not on */ | ||
173 | ret = spi_w8r8(spi, RS5C348_CMD_R(RS5C348_REG_CTL2)); | ||
174 | if (ret < 0) | ||
175 | goto kfree_exit; | ||
176 | if (ret & (RS5C348_BIT_XSTP | RS5C348_BIT_VDET)) { | ||
177 | u8 buf[2]; | ||
178 | if (ret & RS5C348_BIT_VDET) | ||
179 | dev_warn(&spi->dev, "voltage-low detected.\n"); | ||
180 | buf[0] = RS5C348_CMD_W(RS5C348_REG_CTL2); | ||
181 | buf[1] = 0; | ||
182 | ret = spi_write_then_read(spi, buf, sizeof(buf), NULL, 0); | ||
183 | if (ret < 0) | ||
184 | goto kfree_exit; | ||
185 | } | ||
186 | |||
187 | ret = spi_w8r8(spi, RS5C348_CMD_R(RS5C348_REG_CTL1)); | ||
188 | if (ret < 0) | ||
189 | goto kfree_exit; | ||
190 | if (ret & RS5C348_BIT_24H) | ||
191 | pdata->rtc_24h = 1; | ||
192 | |||
193 | rtc = rtc_device_register(rs5c348_driver.driver.name, &spi->dev, | ||
194 | &rs5c348_rtc_ops, THIS_MODULE); | ||
195 | |||
196 | if (IS_ERR(rtc)) { | ||
197 | ret = PTR_ERR(rtc); | ||
198 | goto kfree_exit; | ||
199 | } | ||
200 | |||
201 | pdata->rtc = rtc; | ||
202 | |||
203 | return 0; | ||
204 | kfree_exit: | ||
205 | kfree(pdata); | ||
206 | return ret; | ||
207 | } | ||
208 | |||
209 | static int __devexit rs5c348_remove(struct spi_device *spi) | ||
210 | { | ||
211 | struct rs5c348_plat_data *pdata = spi->dev.platform_data; | ||
212 | struct rtc_device *rtc = pdata->rtc; | ||
213 | |||
214 | if (rtc) | ||
215 | rtc_device_unregister(rtc); | ||
216 | kfree(pdata); | ||
217 | return 0; | ||
218 | } | ||
219 | |||
220 | static struct spi_driver rs5c348_driver = { | ||
221 | .driver = { | ||
222 | .name = "rs5c348", | ||
223 | .bus = &spi_bus_type, | ||
224 | .owner = THIS_MODULE, | ||
225 | }, | ||
226 | .probe = rs5c348_probe, | ||
227 | .remove = __devexit_p(rs5c348_remove), | ||
228 | }; | ||
229 | |||
230 | static __init int rs5c348_init(void) | ||
231 | { | ||
232 | return spi_register_driver(&rs5c348_driver); | ||
233 | } | ||
234 | |||
235 | static __exit void rs5c348_exit(void) | ||
236 | { | ||
237 | spi_unregister_driver(&rs5c348_driver); | ||
238 | } | ||
239 | |||
240 | module_init(rs5c348_init); | ||
241 | module_exit(rs5c348_exit); | ||
242 | |||
243 | MODULE_AUTHOR("Atsushi Nemoto <anemo@mba.ocn.ne.jp>"); | ||
244 | MODULE_DESCRIPTION("Ricoh RS5C348 RTC driver"); | ||
245 | MODULE_LICENSE("GPL"); | ||
246 | MODULE_VERSION(DRV_VERSION); | ||
diff --git a/drivers/rtc/rtc-sa1100.c b/drivers/rtc/rtc-sa1100.c index ab486fbc828d..9cd1cb304bb2 100644 --- a/drivers/rtc/rtc-sa1100.c +++ b/drivers/rtc/rtc-sa1100.c | |||
@@ -45,7 +45,7 @@ | |||
45 | 45 | ||
46 | static unsigned long rtc_freq = 1024; | 46 | static unsigned long rtc_freq = 1024; |
47 | static struct rtc_time rtc_alarm; | 47 | static struct rtc_time rtc_alarm; |
48 | static spinlock_t sa1100_rtc_lock = SPIN_LOCK_UNLOCKED; | 48 | static DEFINE_SPINLOCK(sa1100_rtc_lock); |
49 | 49 | ||
50 | static int rtc_update_alarm(struct rtc_time *alrm) | 50 | static int rtc_update_alarm(struct rtc_time *alrm) |
51 | { | 51 | { |
diff --git a/drivers/rtc/rtc-vr41xx.c b/drivers/rtc/rtc-vr41xx.c index 33e029207e26..4b9291dd4443 100644 --- a/drivers/rtc/rtc-vr41xx.c +++ b/drivers/rtc/rtc-vr41xx.c | |||
@@ -93,7 +93,7 @@ static void __iomem *rtc2_base; | |||
93 | 93 | ||
94 | static unsigned long epoch = 1970; /* Jan 1 1970 00:00:00 */ | 94 | static unsigned long epoch = 1970; /* Jan 1 1970 00:00:00 */ |
95 | 95 | ||
96 | static spinlock_t rtc_lock = SPIN_LOCK_UNLOCKED; | 96 | static DEFINE_SPINLOCK(rtc_lock); |
97 | static char rtc_name[] = "RTC"; | 97 | static char rtc_name[] = "RTC"; |
98 | static unsigned long periodic_frequency; | 98 | static unsigned long periodic_frequency; |
99 | static unsigned long periodic_count; | 99 | static unsigned long periodic_count; |
diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c index cfb1fff3787c..2dc179b14ce6 100644 --- a/drivers/s390/block/dasd.c +++ b/drivers/s390/block/dasd.c | |||
@@ -95,7 +95,7 @@ dasd_alloc_device(void) | |||
95 | spin_lock_init(&device->mem_lock); | 95 | spin_lock_init(&device->mem_lock); |
96 | spin_lock_init(&device->request_queue_lock); | 96 | spin_lock_init(&device->request_queue_lock); |
97 | atomic_set (&device->tasklet_scheduled, 0); | 97 | atomic_set (&device->tasklet_scheduled, 0); |
98 | tasklet_init(&device->tasklet, | 98 | tasklet_init(&device->tasklet, |
99 | (void (*)(unsigned long)) dasd_tasklet, | 99 | (void (*)(unsigned long)) dasd_tasklet, |
100 | (unsigned long) device); | 100 | (unsigned long) device); |
101 | INIT_LIST_HEAD(&device->ccw_queue); | 101 | INIT_LIST_HEAD(&device->ccw_queue); |
@@ -128,7 +128,7 @@ dasd_state_new_to_known(struct dasd_device *device) | |||
128 | int rc; | 128 | int rc; |
129 | 129 | ||
130 | /* | 130 | /* |
131 | * As long as the device is not in state DASD_STATE_NEW we want to | 131 | * As long as the device is not in state DASD_STATE_NEW we want to |
132 | * keep the reference count > 0. | 132 | * keep the reference count > 0. |
133 | */ | 133 | */ |
134 | dasd_get_device(device); | 134 | dasd_get_device(device); |
@@ -336,7 +336,7 @@ dasd_decrease_state(struct dasd_device *device) | |||
336 | if (device->state == DASD_STATE_ONLINE && | 336 | if (device->state == DASD_STATE_ONLINE && |
337 | device->target <= DASD_STATE_READY) | 337 | device->target <= DASD_STATE_READY) |
338 | dasd_state_online_to_ready(device); | 338 | dasd_state_online_to_ready(device); |
339 | 339 | ||
340 | if (device->state == DASD_STATE_READY && | 340 | if (device->state == DASD_STATE_READY && |
341 | device->target <= DASD_STATE_BASIC) | 341 | device->target <= DASD_STATE_BASIC) |
342 | dasd_state_ready_to_basic(device); | 342 | dasd_state_ready_to_basic(device); |
@@ -348,7 +348,7 @@ dasd_decrease_state(struct dasd_device *device) | |||
348 | if (device->state == DASD_STATE_BASIC && | 348 | if (device->state == DASD_STATE_BASIC && |
349 | device->target <= DASD_STATE_KNOWN) | 349 | device->target <= DASD_STATE_KNOWN) |
350 | dasd_state_basic_to_known(device); | 350 | dasd_state_basic_to_known(device); |
351 | 351 | ||
352 | if (device->state == DASD_STATE_KNOWN && | 352 | if (device->state == DASD_STATE_KNOWN && |
353 | device->target <= DASD_STATE_NEW) | 353 | device->target <= DASD_STATE_NEW) |
354 | dasd_state_known_to_new(device); | 354 | dasd_state_known_to_new(device); |
@@ -994,7 +994,7 @@ dasd_int_handler(struct ccw_device *cdev, unsigned long intparm, | |||
994 | ((irb->scsw.cstat << 8) | irb->scsw.dstat), cqr); | 994 | ((irb->scsw.cstat << 8) | irb->scsw.dstat), cqr); |
995 | 995 | ||
996 | /* Find out the appropriate era_action. */ | 996 | /* Find out the appropriate era_action. */ |
997 | if (irb->scsw.fctl & SCSW_FCTL_HALT_FUNC) | 997 | if (irb->scsw.fctl & SCSW_FCTL_HALT_FUNC) |
998 | era = dasd_era_fatal; | 998 | era = dasd_era_fatal; |
999 | else if (irb->scsw.dstat == (DEV_STAT_CHN_END | DEV_STAT_DEV_END) && | 999 | else if (irb->scsw.dstat == (DEV_STAT_CHN_END | DEV_STAT_DEV_END) && |
1000 | irb->scsw.cstat == 0 && | 1000 | irb->scsw.cstat == 0 && |
@@ -1004,7 +1004,7 @@ dasd_int_handler(struct ccw_device *cdev, unsigned long intparm, | |||
1004 | era = dasd_era_fatal; /* don't recover this request */ | 1004 | era = dasd_era_fatal; /* don't recover this request */ |
1005 | else if (irb->esw.esw0.erw.cons) | 1005 | else if (irb->esw.esw0.erw.cons) |
1006 | era = device->discipline->examine_error(cqr, irb); | 1006 | era = device->discipline->examine_error(cqr, irb); |
1007 | else | 1007 | else |
1008 | era = dasd_era_recover; | 1008 | era = dasd_era_recover; |
1009 | 1009 | ||
1010 | DBF_DEV_EVENT(DBF_DEBUG, device, "era_code %d", era); | 1010 | DBF_DEV_EVENT(DBF_DEBUG, device, "era_code %d", era); |
@@ -1287,7 +1287,7 @@ __dasd_start_head(struct dasd_device * device) | |||
1287 | } | 1287 | } |
1288 | 1288 | ||
1289 | /* | 1289 | /* |
1290 | * Remove requests from the ccw queue. | 1290 | * Remove requests from the ccw queue. |
1291 | */ | 1291 | */ |
1292 | static void | 1292 | static void |
1293 | dasd_flush_ccw_queue(struct dasd_device * device, int all) | 1293 | dasd_flush_ccw_queue(struct dasd_device * device, int all) |
@@ -1450,23 +1450,23 @@ dasd_sleep_on(struct dasd_ccw_req * cqr) | |||
1450 | wait_queue_head_t wait_q; | 1450 | wait_queue_head_t wait_q; |
1451 | struct dasd_device *device; | 1451 | struct dasd_device *device; |
1452 | int rc; | 1452 | int rc; |
1453 | 1453 | ||
1454 | device = cqr->device; | 1454 | device = cqr->device; |
1455 | spin_lock_irq(get_ccwdev_lock(device->cdev)); | 1455 | spin_lock_irq(get_ccwdev_lock(device->cdev)); |
1456 | 1456 | ||
1457 | init_waitqueue_head (&wait_q); | 1457 | init_waitqueue_head (&wait_q); |
1458 | cqr->callback = dasd_wakeup_cb; | 1458 | cqr->callback = dasd_wakeup_cb; |
1459 | cqr->callback_data = (void *) &wait_q; | 1459 | cqr->callback_data = (void *) &wait_q; |
1460 | cqr->status = DASD_CQR_QUEUED; | 1460 | cqr->status = DASD_CQR_QUEUED; |
1461 | list_add_tail(&cqr->list, &device->ccw_queue); | 1461 | list_add_tail(&cqr->list, &device->ccw_queue); |
1462 | 1462 | ||
1463 | /* let the bh start the request to keep them in order */ | 1463 | /* let the bh start the request to keep them in order */ |
1464 | dasd_schedule_bh(device); | 1464 | dasd_schedule_bh(device); |
1465 | 1465 | ||
1466 | spin_unlock_irq(get_ccwdev_lock(device->cdev)); | 1466 | spin_unlock_irq(get_ccwdev_lock(device->cdev)); |
1467 | 1467 | ||
1468 | wait_event(wait_q, _wait_for_wakeup(cqr)); | 1468 | wait_event(wait_q, _wait_for_wakeup(cqr)); |
1469 | 1469 | ||
1470 | /* Request status is either done or failed. */ | 1470 | /* Request status is either done or failed. */ |
1471 | rc = (cqr->status == DASD_CQR_FAILED) ? -EIO : 0; | 1471 | rc = (cqr->status == DASD_CQR_FAILED) ? -EIO : 0; |
1472 | return rc; | 1472 | return rc; |
@@ -1568,7 +1568,7 @@ dasd_sleep_on_immediatly(struct dasd_ccw_req * cqr) | |||
1568 | wait_queue_head_t wait_q; | 1568 | wait_queue_head_t wait_q; |
1569 | struct dasd_device *device; | 1569 | struct dasd_device *device; |
1570 | int rc; | 1570 | int rc; |
1571 | 1571 | ||
1572 | device = cqr->device; | 1572 | device = cqr->device; |
1573 | spin_lock_irq(get_ccwdev_lock(device->cdev)); | 1573 | spin_lock_irq(get_ccwdev_lock(device->cdev)); |
1574 | rc = _dasd_term_running_cqr(device); | 1574 | rc = _dasd_term_running_cqr(device); |
@@ -1576,20 +1576,20 @@ dasd_sleep_on_immediatly(struct dasd_ccw_req * cqr) | |||
1576 | spin_unlock_irq(get_ccwdev_lock(device->cdev)); | 1576 | spin_unlock_irq(get_ccwdev_lock(device->cdev)); |
1577 | return rc; | 1577 | return rc; |
1578 | } | 1578 | } |
1579 | 1579 | ||
1580 | init_waitqueue_head (&wait_q); | 1580 | init_waitqueue_head (&wait_q); |
1581 | cqr->callback = dasd_wakeup_cb; | 1581 | cqr->callback = dasd_wakeup_cb; |
1582 | cqr->callback_data = (void *) &wait_q; | 1582 | cqr->callback_data = (void *) &wait_q; |
1583 | cqr->status = DASD_CQR_QUEUED; | 1583 | cqr->status = DASD_CQR_QUEUED; |
1584 | list_add(&cqr->list, &device->ccw_queue); | 1584 | list_add(&cqr->list, &device->ccw_queue); |
1585 | 1585 | ||
1586 | /* let the bh start the request to keep them in order */ | 1586 | /* let the bh start the request to keep them in order */ |
1587 | dasd_schedule_bh(device); | 1587 | dasd_schedule_bh(device); |
1588 | 1588 | ||
1589 | spin_unlock_irq(get_ccwdev_lock(device->cdev)); | 1589 | spin_unlock_irq(get_ccwdev_lock(device->cdev)); |
1590 | 1590 | ||
1591 | wait_event(wait_q, _wait_for_wakeup(cqr)); | 1591 | wait_event(wait_q, _wait_for_wakeup(cqr)); |
1592 | 1592 | ||
1593 | /* Request status is either done or failed. */ | 1593 | /* Request status is either done or failed. */ |
1594 | rc = (cqr->status == DASD_CQR_FAILED) ? -EIO : 0; | 1594 | rc = (cqr->status == DASD_CQR_FAILED) ? -EIO : 0; |
1595 | return rc; | 1595 | return rc; |
@@ -1725,7 +1725,7 @@ dasd_flush_request_queue(struct dasd_device * device) | |||
1725 | 1725 | ||
1726 | if (!device->request_queue) | 1726 | if (!device->request_queue) |
1727 | return; | 1727 | return; |
1728 | 1728 | ||
1729 | spin_lock_irq(&device->request_queue_lock); | 1729 | spin_lock_irq(&device->request_queue_lock); |
1730 | while (!list_empty(&device->request_queue->queue_head)) { | 1730 | while (!list_empty(&device->request_queue->queue_head)) { |
1731 | req = elv_next_request(device->request_queue); | 1731 | req = elv_next_request(device->request_queue); |
@@ -1834,7 +1834,6 @@ dasd_exit(void) | |||
1834 | } | 1834 | } |
1835 | dasd_gendisk_exit(); | 1835 | dasd_gendisk_exit(); |
1836 | dasd_devmap_exit(); | 1836 | dasd_devmap_exit(); |
1837 | devfs_remove("dasd"); | ||
1838 | if (dasd_debug_area != NULL) { | 1837 | if (dasd_debug_area != NULL) { |
1839 | debug_unregister(dasd_debug_area); | 1838 | debug_unregister(dasd_debug_area); |
1840 | dasd_debug_area = NULL; | 1839 | dasd_debug_area = NULL; |
@@ -1855,15 +1854,34 @@ dasd_generic_probe (struct ccw_device *cdev, | |||
1855 | { | 1854 | { |
1856 | int ret; | 1855 | int ret; |
1857 | 1856 | ||
1857 | ret = ccw_device_set_options(cdev, CCWDEV_DO_PATHGROUP); | ||
1858 | if (ret) { | ||
1859 | printk(KERN_WARNING | ||
1860 | "dasd_generic_probe: could not set ccw-device options " | ||
1861 | "for %s\n", cdev->dev.bus_id); | ||
1862 | return ret; | ||
1863 | } | ||
1858 | ret = dasd_add_sysfs_files(cdev); | 1864 | ret = dasd_add_sysfs_files(cdev); |
1859 | if (ret) { | 1865 | if (ret) { |
1860 | printk(KERN_WARNING | 1866 | printk(KERN_WARNING |
1861 | "dasd_generic_probe: could not add sysfs entries " | 1867 | "dasd_generic_probe: could not add sysfs entries " |
1862 | "for %s\n", cdev->dev.bus_id); | 1868 | "for %s\n", cdev->dev.bus_id); |
1863 | } else { | 1869 | return ret; |
1864 | cdev->handler = &dasd_int_handler; | ||
1865 | } | 1870 | } |
1871 | cdev->handler = &dasd_int_handler; | ||
1866 | 1872 | ||
1873 | /* | ||
1874 | * Automatically online either all dasd devices (dasd_autodetect) | ||
1875 | * or all devices specified with dasd= parameters during | ||
1876 | * initial probe. | ||
1877 | */ | ||
1878 | if ((dasd_get_feature(cdev, DASD_FEATURE_INITIAL_ONLINE) > 0 ) || | ||
1879 | (dasd_autodetect && dasd_busid_known(cdev->dev.bus_id) != 0)) | ||
1880 | ret = ccw_device_set_online(cdev); | ||
1881 | if (ret) | ||
1882 | printk(KERN_WARNING | ||
1883 | "dasd_generic_probe: could not initially online " | ||
1884 | "ccw-device %s\n", cdev->dev.bus_id); | ||
1867 | return ret; | 1885 | return ret; |
1868 | } | 1886 | } |
1869 | 1887 | ||
@@ -1911,6 +1929,8 @@ dasd_generic_set_online (struct ccw_device *cdev, | |||
1911 | struct dasd_device *device; | 1929 | struct dasd_device *device; |
1912 | int rc; | 1930 | int rc; |
1913 | 1931 | ||
1932 | /* first online clears initial online feature flag */ | ||
1933 | dasd_set_feature(cdev, DASD_FEATURE_INITIAL_ONLINE, 0); | ||
1914 | device = dasd_create_device(cdev); | 1934 | device = dasd_create_device(cdev); |
1915 | if (IS_ERR(device)) | 1935 | if (IS_ERR(device)) |
1916 | return PTR_ERR(device); | 1936 | return PTR_ERR(device); |
@@ -2065,31 +2085,6 @@ dasd_generic_notify(struct ccw_device *cdev, int event) | |||
2065 | return ret; | 2085 | return ret; |
2066 | } | 2086 | } |
2067 | 2087 | ||
2068 | /* | ||
2069 | * Automatically online either all dasd devices (dasd_autodetect) or | ||
2070 | * all devices specified with dasd= parameters. | ||
2071 | */ | ||
2072 | static int | ||
2073 | __dasd_auto_online(struct device *dev, void *data) | ||
2074 | { | ||
2075 | struct ccw_device *cdev; | ||
2076 | |||
2077 | cdev = to_ccwdev(dev); | ||
2078 | if (dasd_autodetect || dasd_busid_known(cdev->dev.bus_id) == 0) | ||
2079 | ccw_device_set_online(cdev); | ||
2080 | return 0; | ||
2081 | } | ||
2082 | |||
2083 | void | ||
2084 | dasd_generic_auto_online (struct ccw_driver *dasd_discipline_driver) | ||
2085 | { | ||
2086 | struct device_driver *drv; | ||
2087 | |||
2088 | drv = get_driver(&dasd_discipline_driver->driver); | ||
2089 | driver_for_each_device(drv, NULL, NULL, __dasd_auto_online); | ||
2090 | put_driver(drv); | ||
2091 | } | ||
2092 | |||
2093 | 2088 | ||
2094 | static int __init | 2089 | static int __init |
2095 | dasd_init(void) | 2090 | dasd_init(void) |
@@ -2111,9 +2106,6 @@ dasd_init(void) | |||
2111 | 2106 | ||
2112 | dasd_diag_discipline_pointer = NULL; | 2107 | dasd_diag_discipline_pointer = NULL; |
2113 | 2108 | ||
2114 | rc = devfs_mk_dir("dasd"); | ||
2115 | if (rc) | ||
2116 | goto failed; | ||
2117 | rc = dasd_devmap_init(); | 2109 | rc = dasd_devmap_init(); |
2118 | if (rc) | 2110 | if (rc) |
2119 | goto failed; | 2111 | goto failed; |
@@ -2170,23 +2162,4 @@ EXPORT_SYMBOL_GPL(dasd_generic_remove); | |||
2170 | EXPORT_SYMBOL_GPL(dasd_generic_notify); | 2162 | EXPORT_SYMBOL_GPL(dasd_generic_notify); |
2171 | EXPORT_SYMBOL_GPL(dasd_generic_set_online); | 2163 | EXPORT_SYMBOL_GPL(dasd_generic_set_online); |
2172 | EXPORT_SYMBOL_GPL(dasd_generic_set_offline); | 2164 | EXPORT_SYMBOL_GPL(dasd_generic_set_offline); |
2173 | EXPORT_SYMBOL_GPL(dasd_generic_auto_online); | ||
2174 | 2165 | ||
2175 | /* | ||
2176 | * Overrides for Emacs so that we follow Linus's tabbing style. | ||
2177 | * Emacs will notice this stuff at the end of the file and automatically | ||
2178 | * adjust the settings for this buffer only. This must remain at the end | ||
2179 | * of the file. | ||
2180 | * --------------------------------------------------------------------------- | ||
2181 | * Local variables: | ||
2182 | * c-indent-level: 4 | ||
2183 | * c-brace-imaginary-offset: 0 | ||
2184 | * c-brace-offset: -4 | ||
2185 | * c-argdecl-indent: 4 | ||
2186 | * c-label-offset: -4 | ||
2187 | * c-continued-statement-offset: 4 | ||
2188 | * c-continued-brace-offset: 0 | ||
2189 | * indent-tabs-mode: 1 | ||
2190 | * tab-width: 8 | ||
2191 | * End: | ||
2192 | */ | ||
diff --git a/drivers/s390/block/dasd_3370_erp.c b/drivers/s390/block/dasd_3370_erp.c index 1d11c2a9525d..1ddab8991d92 100644 --- a/drivers/s390/block/dasd_3370_erp.c +++ b/drivers/s390/block/dasd_3370_erp.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * File...........: linux/drivers/s390/block/dasd_3370_erp.c | 2 | * File...........: linux/drivers/s390/block/dasd_3370_erp.c |
3 | * Author(s)......: Holger Smolinski <Holger.Smolinski@de.ibm.com> | 3 | * Author(s)......: Holger Smolinski <Holger.Smolinski@de.ibm.com> |
4 | * Bugreports.to..: <Linux390@de.ibm.com> | 4 | * Bugreports.to..: <Linux390@de.ibm.com> |
@@ -12,10 +12,10 @@ | |||
12 | 12 | ||
13 | 13 | ||
14 | /* | 14 | /* |
15 | * DASD_3370_ERP_EXAMINE | 15 | * DASD_3370_ERP_EXAMINE |
16 | * | 16 | * |
17 | * DESCRIPTION | 17 | * DESCRIPTION |
18 | * Checks only for fatal/no/recover error. | 18 | * Checks only for fatal/no/recover error. |
19 | * A detailed examination of the sense data is done later outside | 19 | * A detailed examination of the sense data is done later outside |
20 | * the interrupt handler. | 20 | * the interrupt handler. |
21 | * | 21 | * |
@@ -23,7 +23,7 @@ | |||
23 | * 'Chapter 7. 3370 Sense Data'. | 23 | * 'Chapter 7. 3370 Sense Data'. |
24 | * | 24 | * |
25 | * RETURN VALUES | 25 | * RETURN VALUES |
26 | * dasd_era_none no error | 26 | * dasd_era_none no error |
27 | * dasd_era_fatal for all fatal (unrecoverable errors) | 27 | * dasd_era_fatal for all fatal (unrecoverable errors) |
28 | * dasd_era_recover for all others. | 28 | * dasd_era_recover for all others. |
29 | */ | 29 | */ |
@@ -82,22 +82,3 @@ dasd_3370_erp_examine(struct dasd_ccw_req * cqr, struct irb * irb) | |||
82 | return dasd_era_recover; | 82 | return dasd_era_recover; |
83 | 83 | ||
84 | } /* END dasd_3370_erp_examine */ | 84 | } /* END dasd_3370_erp_examine */ |
85 | |||
86 | /* | ||
87 | * Overrides for Emacs so that we follow Linus's tabbing style. | ||
88 | * Emacs will notice this stuff at the end of the file and automatically | ||
89 | * adjust the settings for this buffer only. This must remain at the end | ||
90 | * of the file. | ||
91 | * --------------------------------------------------------------------------- | ||
92 | * Local variables: | ||
93 | * c-indent-level: 4 | ||
94 | * c-brace-imaginary-offset: 0 | ||
95 | * c-brace-offset: -4 | ||
96 | * c-argdecl-indent: 4 | ||
97 | * c-label-offset: -4 | ||
98 | * c-continued-statement-offset: 4 | ||
99 | * c-continued-brace-offset: 0 | ||
100 | * indent-tabs-mode: 1 | ||
101 | * tab-width: 8 | ||
102 | * End: | ||
103 | */ | ||
diff --git a/drivers/s390/block/dasd_3990_erp.c b/drivers/s390/block/dasd_3990_erp.c index 2ed51562319e..669805d4402d 100644 --- a/drivers/s390/block/dasd_3990_erp.c +++ b/drivers/s390/block/dasd_3990_erp.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * File...........: linux/drivers/s390/block/dasd_3990_erp.c | 2 | * File...........: linux/drivers/s390/block/dasd_3990_erp.c |
3 | * Author(s)......: Horst Hummel <Horst.Hummel@de.ibm.com> | 3 | * Author(s)......: Horst Hummel <Horst.Hummel@de.ibm.com> |
4 | * Holger Smolinski <Holger.Smolinski@de.ibm.com> | 4 | * Holger Smolinski <Holger.Smolinski@de.ibm.com> |
5 | * Bugreports.to..: <Linux390@de.ibm.com> | 5 | * Bugreports.to..: <Linux390@de.ibm.com> |
6 | * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 2000, 2001 | 6 | * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 2000, 2001 |
@@ -25,23 +25,23 @@ struct DCTL_data { | |||
25 | } __attribute__ ((packed)); | 25 | } __attribute__ ((packed)); |
26 | 26 | ||
27 | /* | 27 | /* |
28 | ***************************************************************************** | 28 | ***************************************************************************** |
29 | * SECTION ERP EXAMINATION | 29 | * SECTION ERP EXAMINATION |
30 | ***************************************************************************** | 30 | ***************************************************************************** |
31 | */ | 31 | */ |
32 | 32 | ||
33 | /* | 33 | /* |
34 | * DASD_3990_ERP_EXAMINE_24 | 34 | * DASD_3990_ERP_EXAMINE_24 |
35 | * | 35 | * |
36 | * DESCRIPTION | 36 | * DESCRIPTION |
37 | * Checks only for fatal (unrecoverable) error. | 37 | * Checks only for fatal (unrecoverable) error. |
38 | * A detailed examination of the sense data is done later outside | 38 | * A detailed examination of the sense data is done later outside |
39 | * the interrupt handler. | 39 | * the interrupt handler. |
40 | * | 40 | * |
41 | * Each bit configuration leading to an action code 2 (Exit with | 41 | * Each bit configuration leading to an action code 2 (Exit with |
42 | * programming error or unusual condition indication) | 42 | * programming error or unusual condition indication) |
43 | * are handled as fatal error´s. | 43 | * are handled as fatal error´s. |
44 | * | 44 | * |
45 | * All other configurations are handled as recoverable errors. | 45 | * All other configurations are handled as recoverable errors. |
46 | * | 46 | * |
47 | * RETURN VALUES | 47 | * RETURN VALUES |
@@ -93,15 +93,15 @@ dasd_3990_erp_examine_24(struct dasd_ccw_req * cqr, char *sense) | |||
93 | } /* END dasd_3990_erp_examine_24 */ | 93 | } /* END dasd_3990_erp_examine_24 */ |
94 | 94 | ||
95 | /* | 95 | /* |
96 | * DASD_3990_ERP_EXAMINE_32 | 96 | * DASD_3990_ERP_EXAMINE_32 |
97 | * | 97 | * |
98 | * DESCRIPTION | 98 | * DESCRIPTION |
99 | * Checks only for fatal/no/recoverable error. | 99 | * Checks only for fatal/no/recoverable error. |
100 | * A detailed examination of the sense data is done later outside | 100 | * A detailed examination of the sense data is done later outside |
101 | * the interrupt handler. | 101 | * the interrupt handler. |
102 | * | 102 | * |
103 | * RETURN VALUES | 103 | * RETURN VALUES |
104 | * dasd_era_none no error | 104 | * dasd_era_none no error |
105 | * dasd_era_fatal for all fatal (unrecoverable errors) | 105 | * dasd_era_fatal for all fatal (unrecoverable errors) |
106 | * dasd_era_recover for recoverable others. | 106 | * dasd_era_recover for recoverable others. |
107 | */ | 107 | */ |
@@ -128,10 +128,10 @@ dasd_3990_erp_examine_32(struct dasd_ccw_req * cqr, char *sense) | |||
128 | } /* end dasd_3990_erp_examine_32 */ | 128 | } /* end dasd_3990_erp_examine_32 */ |
129 | 129 | ||
130 | /* | 130 | /* |
131 | * DASD_3990_ERP_EXAMINE | 131 | * DASD_3990_ERP_EXAMINE |
132 | * | 132 | * |
133 | * DESCRIPTION | 133 | * DESCRIPTION |
134 | * Checks only for fatal/no/recover error. | 134 | * Checks only for fatal/no/recover error. |
135 | * A detailed examination of the sense data is done later outside | 135 | * A detailed examination of the sense data is done later outside |
136 | * the interrupt handler. | 136 | * the interrupt handler. |
137 | * | 137 | * |
@@ -139,7 +139,7 @@ dasd_3990_erp_examine_32(struct dasd_ccw_req * cqr, char *sense) | |||
139 | * 'Chapter 7. Error Recovery Procedures'. | 139 | * 'Chapter 7. Error Recovery Procedures'. |
140 | * | 140 | * |
141 | * RETURN VALUES | 141 | * RETURN VALUES |
142 | * dasd_era_none no error | 142 | * dasd_era_none no error |
143 | * dasd_era_fatal for all fatal (unrecoverable errors) | 143 | * dasd_era_fatal for all fatal (unrecoverable errors) |
144 | * dasd_era_recover for all others. | 144 | * dasd_era_recover for all others. |
145 | */ | 145 | */ |
@@ -178,18 +178,18 @@ dasd_3990_erp_examine(struct dasd_ccw_req * cqr, struct irb * irb) | |||
178 | } /* END dasd_3990_erp_examine */ | 178 | } /* END dasd_3990_erp_examine */ |
179 | 179 | ||
180 | /* | 180 | /* |
181 | ***************************************************************************** | 181 | ***************************************************************************** |
182 | * SECTION ERP HANDLING | 182 | * SECTION ERP HANDLING |
183 | ***************************************************************************** | 183 | ***************************************************************************** |
184 | */ | 184 | */ |
185 | /* | 185 | /* |
186 | ***************************************************************************** | 186 | ***************************************************************************** |
187 | * 24 and 32 byte sense ERP functions | 187 | * 24 and 32 byte sense ERP functions |
188 | ***************************************************************************** | 188 | ***************************************************************************** |
189 | */ | 189 | */ |
190 | 190 | ||
191 | /* | 191 | /* |
192 | * DASD_3990_ERP_CLEANUP | 192 | * DASD_3990_ERP_CLEANUP |
193 | * | 193 | * |
194 | * DESCRIPTION | 194 | * DESCRIPTION |
195 | * Removes the already build but not necessary ERP request and sets | 195 | * Removes the already build but not necessary ERP request and sets |
@@ -197,10 +197,10 @@ dasd_3990_erp_examine(struct dasd_ccw_req * cqr, struct irb * irb) | |||
197 | * | 197 | * |
198 | * PARAMETER | 198 | * PARAMETER |
199 | * erp request to be blocked | 199 | * erp request to be blocked |
200 | * final_status either DASD_CQR_DONE or DASD_CQR_FAILED | 200 | * final_status either DASD_CQR_DONE or DASD_CQR_FAILED |
201 | * | 201 | * |
202 | * RETURN VALUES | 202 | * RETURN VALUES |
203 | * cqr original cqr | 203 | * cqr original cqr |
204 | */ | 204 | */ |
205 | static struct dasd_ccw_req * | 205 | static struct dasd_ccw_req * |
206 | dasd_3990_erp_cleanup(struct dasd_ccw_req * erp, char final_status) | 206 | dasd_3990_erp_cleanup(struct dasd_ccw_req * erp, char final_status) |
@@ -214,7 +214,7 @@ dasd_3990_erp_cleanup(struct dasd_ccw_req * erp, char final_status) | |||
214 | } /* end dasd_3990_erp_cleanup */ | 214 | } /* end dasd_3990_erp_cleanup */ |
215 | 215 | ||
216 | /* | 216 | /* |
217 | * DASD_3990_ERP_BLOCK_QUEUE | 217 | * DASD_3990_ERP_BLOCK_QUEUE |
218 | * | 218 | * |
219 | * DESCRIPTION | 219 | * DESCRIPTION |
220 | * Block the given device request queue to prevent from further | 220 | * Block the given device request queue to prevent from further |
@@ -237,7 +237,7 @@ dasd_3990_erp_block_queue(struct dasd_ccw_req * erp, int expires) | |||
237 | } | 237 | } |
238 | 238 | ||
239 | /* | 239 | /* |
240 | * DASD_3990_ERP_INT_REQ | 240 | * DASD_3990_ERP_INT_REQ |
241 | * | 241 | * |
242 | * DESCRIPTION | 242 | * DESCRIPTION |
243 | * Handles 'Intervention Required' error. | 243 | * Handles 'Intervention Required' error. |
@@ -277,7 +277,7 @@ dasd_3990_erp_int_req(struct dasd_ccw_req * erp) | |||
277 | } /* end dasd_3990_erp_int_req */ | 277 | } /* end dasd_3990_erp_int_req */ |
278 | 278 | ||
279 | /* | 279 | /* |
280 | * DASD_3990_ERP_ALTERNATE_PATH | 280 | * DASD_3990_ERP_ALTERNATE_PATH |
281 | * | 281 | * |
282 | * DESCRIPTION | 282 | * DESCRIPTION |
283 | * Repeat the operation on a different channel path. | 283 | * Repeat the operation on a different channel path. |
@@ -330,15 +330,15 @@ dasd_3990_erp_alternate_path(struct dasd_ccw_req * erp) | |||
330 | * DASD_3990_ERP_DCTL | 330 | * DASD_3990_ERP_DCTL |
331 | * | 331 | * |
332 | * DESCRIPTION | 332 | * DESCRIPTION |
333 | * Setup cqr to do the Diagnostic Control (DCTL) command with an | 333 | * Setup cqr to do the Diagnostic Control (DCTL) command with an |
334 | * Inhibit Write subcommand (0x20) and the given modifier. | 334 | * Inhibit Write subcommand (0x20) and the given modifier. |
335 | * | 335 | * |
336 | * PARAMETER | 336 | * PARAMETER |
337 | * erp pointer to the current (failed) ERP | 337 | * erp pointer to the current (failed) ERP |
338 | * modifier subcommand modifier | 338 | * modifier subcommand modifier |
339 | * | 339 | * |
340 | * RETURN VALUES | 340 | * RETURN VALUES |
341 | * dctl_cqr pointer to NEW dctl_cqr | 341 | * dctl_cqr pointer to NEW dctl_cqr |
342 | * | 342 | * |
343 | */ | 343 | */ |
344 | static struct dasd_ccw_req * | 344 | static struct dasd_ccw_req * |
@@ -386,7 +386,7 @@ dasd_3990_erp_DCTL(struct dasd_ccw_req * erp, char modifier) | |||
386 | } /* end dasd_3990_erp_DCTL */ | 386 | } /* end dasd_3990_erp_DCTL */ |
387 | 387 | ||
388 | /* | 388 | /* |
389 | * DASD_3990_ERP_ACTION_1 | 389 | * DASD_3990_ERP_ACTION_1 |
390 | * | 390 | * |
391 | * DESCRIPTION | 391 | * DESCRIPTION |
392 | * Setup ERP to do the ERP action 1 (see Reference manual). | 392 | * Setup ERP to do the ERP action 1 (see Reference manual). |
@@ -415,7 +415,7 @@ dasd_3990_erp_action_1(struct dasd_ccw_req * erp) | |||
415 | } /* end dasd_3990_erp_action_1 */ | 415 | } /* end dasd_3990_erp_action_1 */ |
416 | 416 | ||
417 | /* | 417 | /* |
418 | * DASD_3990_ERP_ACTION_4 | 418 | * DASD_3990_ERP_ACTION_4 |
419 | * | 419 | * |
420 | * DESCRIPTION | 420 | * DESCRIPTION |
421 | * Setup ERP to do the ERP action 4 (see Reference manual). | 421 | * Setup ERP to do the ERP action 4 (see Reference manual). |
@@ -453,11 +453,11 @@ dasd_3990_erp_action_4(struct dasd_ccw_req * erp, char *sense) | |||
453 | 453 | ||
454 | if (sense[25] == 0x1D) { /* state change pending */ | 454 | if (sense[25] == 0x1D) { /* state change pending */ |
455 | 455 | ||
456 | DEV_MESSAGE(KERN_INFO, device, | 456 | DEV_MESSAGE(KERN_INFO, device, |
457 | "waiting for state change pending " | 457 | "waiting for state change pending " |
458 | "interrupt, %d retries left", | 458 | "interrupt, %d retries left", |
459 | erp->retries); | 459 | erp->retries); |
460 | 460 | ||
461 | dasd_3990_erp_block_queue(erp, 30*HZ); | 461 | dasd_3990_erp_block_queue(erp, 30*HZ); |
462 | 462 | ||
463 | } else if (sense[25] == 0x1E) { /* busy */ | 463 | } else if (sense[25] == 0x1E) { /* busy */ |
@@ -469,9 +469,9 @@ dasd_3990_erp_action_4(struct dasd_ccw_req * erp, char *sense) | |||
469 | } else { | 469 | } else { |
470 | 470 | ||
471 | /* no state change pending - retry */ | 471 | /* no state change pending - retry */ |
472 | DEV_MESSAGE (KERN_INFO, device, | 472 | DEV_MESSAGE (KERN_INFO, device, |
473 | "redriving request immediately, " | 473 | "redriving request immediately, " |
474 | "%d retries left", | 474 | "%d retries left", |
475 | erp->retries); | 475 | erp->retries); |
476 | erp->status = DASD_CQR_QUEUED; | 476 | erp->status = DASD_CQR_QUEUED; |
477 | } | 477 | } |
@@ -482,13 +482,13 @@ dasd_3990_erp_action_4(struct dasd_ccw_req * erp, char *sense) | |||
482 | } /* end dasd_3990_erp_action_4 */ | 482 | } /* end dasd_3990_erp_action_4 */ |
483 | 483 | ||
484 | /* | 484 | /* |
485 | ***************************************************************************** | 485 | ***************************************************************************** |
486 | * 24 byte sense ERP functions (only) | 486 | * 24 byte sense ERP functions (only) |
487 | ***************************************************************************** | 487 | ***************************************************************************** |
488 | */ | 488 | */ |
489 | 489 | ||
490 | /* | 490 | /* |
491 | * DASD_3990_ERP_ACTION_5 | 491 | * DASD_3990_ERP_ACTION_5 |
492 | * | 492 | * |
493 | * DESCRIPTION | 493 | * DESCRIPTION |
494 | * Setup ERP to do the ERP action 5 (see Reference manual). | 494 | * Setup ERP to do the ERP action 5 (see Reference manual). |
@@ -523,7 +523,7 @@ dasd_3990_erp_action_5(struct dasd_ccw_req * erp) | |||
523 | * | 523 | * |
524 | * PARAMETER | 524 | * PARAMETER |
525 | * sense current sense data | 525 | * sense current sense data |
526 | * | 526 | * |
527 | * RETURN VALUES | 527 | * RETURN VALUES |
528 | * void | 528 | * void |
529 | */ | 529 | */ |
@@ -1150,9 +1150,9 @@ dasd_3990_handle_env_data(struct dasd_ccw_req * erp, char *sense) | |||
1150 | * PARAMETER | 1150 | * PARAMETER |
1151 | * erp current erp_head | 1151 | * erp current erp_head |
1152 | * sense current sense data | 1152 | * sense current sense data |
1153 | * | 1153 | * |
1154 | * RETURN VALUES | 1154 | * RETURN VALUES |
1155 | * erp 'new' erp_head - pointer to new ERP | 1155 | * erp 'new' erp_head - pointer to new ERP |
1156 | */ | 1156 | */ |
1157 | static struct dasd_ccw_req * | 1157 | static struct dasd_ccw_req * |
1158 | dasd_3990_erp_com_rej(struct dasd_ccw_req * erp, char *sense) | 1158 | dasd_3990_erp_com_rej(struct dasd_ccw_req * erp, char *sense) |
@@ -1185,7 +1185,7 @@ dasd_3990_erp_com_rej(struct dasd_ccw_req * erp, char *sense) | |||
1185 | } /* end dasd_3990_erp_com_rej */ | 1185 | } /* end dasd_3990_erp_com_rej */ |
1186 | 1186 | ||
1187 | /* | 1187 | /* |
1188 | * DASD_3990_ERP_BUS_OUT | 1188 | * DASD_3990_ERP_BUS_OUT |
1189 | * | 1189 | * |
1190 | * DESCRIPTION | 1190 | * DESCRIPTION |
1191 | * Handles 24 byte 'Bus Out Parity Check' error. | 1191 | * Handles 24 byte 'Bus Out Parity Check' error. |
@@ -1483,7 +1483,7 @@ dasd_3990_erp_env_data(struct dasd_ccw_req * erp, char *sense) | |||
1483 | * | 1483 | * |
1484 | * PARAMETER | 1484 | * PARAMETER |
1485 | * erp already added default ERP | 1485 | * erp already added default ERP |
1486 | * | 1486 | * |
1487 | * RETURN VALUES | 1487 | * RETURN VALUES |
1488 | * erp new erp_head - pointer to new ERP | 1488 | * erp new erp_head - pointer to new ERP |
1489 | */ | 1489 | */ |
@@ -1527,11 +1527,11 @@ dasd_3990_erp_file_prot(struct dasd_ccw_req * erp) | |||
1527 | } /* end dasd_3990_erp_file_prot */ | 1527 | } /* end dasd_3990_erp_file_prot */ |
1528 | 1528 | ||
1529 | /* | 1529 | /* |
1530 | * DASD_3990_ERP_INSPECT_24 | 1530 | * DASD_3990_ERP_INSPECT_24 |
1531 | * | 1531 | * |
1532 | * DESCRIPTION | 1532 | * DESCRIPTION |
1533 | * Does a detailed inspection of the 24 byte sense data | 1533 | * Does a detailed inspection of the 24 byte sense data |
1534 | * and sets up a related error recovery action. | 1534 | * and sets up a related error recovery action. |
1535 | * | 1535 | * |
1536 | * PARAMETER | 1536 | * PARAMETER |
1537 | * sense sense data of the actual error | 1537 | * sense sense data of the actual error |
@@ -1602,13 +1602,13 @@ dasd_3990_erp_inspect_24(struct dasd_ccw_req * erp, char *sense) | |||
1602 | } /* END dasd_3990_erp_inspect_24 */ | 1602 | } /* END dasd_3990_erp_inspect_24 */ |
1603 | 1603 | ||
1604 | /* | 1604 | /* |
1605 | ***************************************************************************** | 1605 | ***************************************************************************** |
1606 | * 32 byte sense ERP functions (only) | 1606 | * 32 byte sense ERP functions (only) |
1607 | ***************************************************************************** | 1607 | ***************************************************************************** |
1608 | */ | 1608 | */ |
1609 | 1609 | ||
1610 | /* | 1610 | /* |
1611 | * DASD_3990_ERPACTION_10_32 | 1611 | * DASD_3990_ERPACTION_10_32 |
1612 | * | 1612 | * |
1613 | * DESCRIPTION | 1613 | * DESCRIPTION |
1614 | * Handles 32 byte 'Action 10' of Single Program Action Codes. | 1614 | * Handles 32 byte 'Action 10' of Single Program Action Codes. |
@@ -1616,7 +1616,7 @@ dasd_3990_erp_inspect_24(struct dasd_ccw_req * erp, char *sense) | |||
1616 | * | 1616 | * |
1617 | * PARAMETER | 1617 | * PARAMETER |
1618 | * erp current erp_head | 1618 | * erp current erp_head |
1619 | * sense current sense data | 1619 | * sense current sense data |
1620 | * RETURN VALUES | 1620 | * RETURN VALUES |
1621 | * erp modified erp_head | 1621 | * erp modified erp_head |
1622 | */ | 1622 | */ |
@@ -1640,18 +1640,18 @@ dasd_3990_erp_action_10_32(struct dasd_ccw_req * erp, char *sense) | |||
1640 | * | 1640 | * |
1641 | * DESCRIPTION | 1641 | * DESCRIPTION |
1642 | * Handles 32 byte 'Action 1B' of Single Program Action Codes. | 1642 | * Handles 32 byte 'Action 1B' of Single Program Action Codes. |
1643 | * A write operation could not be finished because of an unexpected | 1643 | * A write operation could not be finished because of an unexpected |
1644 | * condition. | 1644 | * condition. |
1645 | * The already created 'default erp' is used to get the link to | 1645 | * The already created 'default erp' is used to get the link to |
1646 | * the erp chain, but it can not be used for this recovery | 1646 | * the erp chain, but it can not be used for this recovery |
1647 | * action because it contains no DE/LO data space. | 1647 | * action because it contains no DE/LO data space. |
1648 | * | 1648 | * |
1649 | * PARAMETER | 1649 | * PARAMETER |
1650 | * default_erp already added default erp. | 1650 | * default_erp already added default erp. |
1651 | * sense current sense data | 1651 | * sense current sense data |
1652 | * | 1652 | * |
1653 | * RETURN VALUES | 1653 | * RETURN VALUES |
1654 | * erp new erp or | 1654 | * erp new erp or |
1655 | * default_erp in case of imprecise ending or error | 1655 | * default_erp in case of imprecise ending or error |
1656 | */ | 1656 | */ |
1657 | static struct dasd_ccw_req * | 1657 | static struct dasd_ccw_req * |
@@ -1789,16 +1789,16 @@ dasd_3990_erp_action_1B_32(struct dasd_ccw_req * default_erp, char *sense) | |||
1789 | * DASD_3990_UPDATE_1B | 1789 | * DASD_3990_UPDATE_1B |
1790 | * | 1790 | * |
1791 | * DESCRIPTION | 1791 | * DESCRIPTION |
1792 | * Handles the update to the 32 byte 'Action 1B' of Single Program | 1792 | * Handles the update to the 32 byte 'Action 1B' of Single Program |
1793 | * Action Codes in case the first action was not successful. | 1793 | * Action Codes in case the first action was not successful. |
1794 | * The already created 'previous_erp' is the currently not successful | 1794 | * The already created 'previous_erp' is the currently not successful |
1795 | * ERP. | 1795 | * ERP. |
1796 | * | 1796 | * |
1797 | * PARAMETER | 1797 | * PARAMETER |
1798 | * previous_erp already created previous erp. | 1798 | * previous_erp already created previous erp. |
1799 | * sense current sense data | 1799 | * sense current sense data |
1800 | * RETURN VALUES | 1800 | * RETURN VALUES |
1801 | * erp modified erp | 1801 | * erp modified erp |
1802 | */ | 1802 | */ |
1803 | static struct dasd_ccw_req * | 1803 | static struct dasd_ccw_req * |
1804 | dasd_3990_update_1B(struct dasd_ccw_req * previous_erp, char *sense) | 1804 | dasd_3990_update_1B(struct dasd_ccw_req * previous_erp, char *sense) |
@@ -1897,7 +1897,7 @@ dasd_3990_update_1B(struct dasd_ccw_req * previous_erp, char *sense) | |||
1897 | } /* end dasd_3990_update_1B */ | 1897 | } /* end dasd_3990_update_1B */ |
1898 | 1898 | ||
1899 | /* | 1899 | /* |
1900 | * DASD_3990_ERP_COMPOUND_RETRY | 1900 | * DASD_3990_ERP_COMPOUND_RETRY |
1901 | * | 1901 | * |
1902 | * DESCRIPTION | 1902 | * DESCRIPTION |
1903 | * Handles the compound ERP action retry code. | 1903 | * Handles the compound ERP action retry code. |
@@ -1943,7 +1943,7 @@ dasd_3990_erp_compound_retry(struct dasd_ccw_req * erp, char *sense) | |||
1943 | } /* end dasd_3990_erp_compound_retry */ | 1943 | } /* end dasd_3990_erp_compound_retry */ |
1944 | 1944 | ||
1945 | /* | 1945 | /* |
1946 | * DASD_3990_ERP_COMPOUND_PATH | 1946 | * DASD_3990_ERP_COMPOUND_PATH |
1947 | * | 1947 | * |
1948 | * DESCRIPTION | 1948 | * DESCRIPTION |
1949 | * Handles the compound ERP action for retry on alternate | 1949 | * Handles the compound ERP action for retry on alternate |
@@ -1965,7 +1965,7 @@ dasd_3990_erp_compound_path(struct dasd_ccw_req * erp, char *sense) | |||
1965 | dasd_3990_erp_alternate_path(erp); | 1965 | dasd_3990_erp_alternate_path(erp); |
1966 | 1966 | ||
1967 | if (erp->status == DASD_CQR_FAILED) { | 1967 | if (erp->status == DASD_CQR_FAILED) { |
1968 | /* reset the lpm and the status to be able to | 1968 | /* reset the lpm and the status to be able to |
1969 | * try further actions. */ | 1969 | * try further actions. */ |
1970 | 1970 | ||
1971 | erp->lpm = 0; | 1971 | erp->lpm = 0; |
@@ -1980,7 +1980,7 @@ dasd_3990_erp_compound_path(struct dasd_ccw_req * erp, char *sense) | |||
1980 | } /* end dasd_3990_erp_compound_path */ | 1980 | } /* end dasd_3990_erp_compound_path */ |
1981 | 1981 | ||
1982 | /* | 1982 | /* |
1983 | * DASD_3990_ERP_COMPOUND_CODE | 1983 | * DASD_3990_ERP_COMPOUND_CODE |
1984 | * | 1984 | * |
1985 | * DESCRIPTION | 1985 | * DESCRIPTION |
1986 | * Handles the compound ERP action for retry code. | 1986 | * Handles the compound ERP action for retry code. |
@@ -2001,18 +2001,18 @@ dasd_3990_erp_compound_code(struct dasd_ccw_req * erp, char *sense) | |||
2001 | 2001 | ||
2002 | switch (sense[28]) { | 2002 | switch (sense[28]) { |
2003 | case 0x17: | 2003 | case 0x17: |
2004 | /* issue a Diagnostic Control command with an | 2004 | /* issue a Diagnostic Control command with an |
2005 | * Inhibit Write subcommand and controler modifier */ | 2005 | * Inhibit Write subcommand and controler modifier */ |
2006 | erp = dasd_3990_erp_DCTL(erp, 0x20); | 2006 | erp = dasd_3990_erp_DCTL(erp, 0x20); |
2007 | break; | 2007 | break; |
2008 | 2008 | ||
2009 | case 0x25: | 2009 | case 0x25: |
2010 | /* wait for 5 seconds and retry again */ | 2010 | /* wait for 5 seconds and retry again */ |
2011 | erp->retries = 1; | 2011 | erp->retries = 1; |
2012 | 2012 | ||
2013 | dasd_3990_erp_block_queue (erp, 5*HZ); | 2013 | dasd_3990_erp_block_queue (erp, 5*HZ); |
2014 | break; | 2014 | break; |
2015 | 2015 | ||
2016 | default: | 2016 | default: |
2017 | /* should not happen - continue */ | 2017 | /* should not happen - continue */ |
2018 | break; | 2018 | break; |
@@ -2026,7 +2026,7 @@ dasd_3990_erp_compound_code(struct dasd_ccw_req * erp, char *sense) | |||
2026 | } /* end dasd_3990_erp_compound_code */ | 2026 | } /* end dasd_3990_erp_compound_code */ |
2027 | 2027 | ||
2028 | /* | 2028 | /* |
2029 | * DASD_3990_ERP_COMPOUND_CONFIG | 2029 | * DASD_3990_ERP_COMPOUND_CONFIG |
2030 | * | 2030 | * |
2031 | * DESCRIPTION | 2031 | * DESCRIPTION |
2032 | * Handles the compound ERP action for configruation | 2032 | * Handles the compound ERP action for configruation |
@@ -2063,10 +2063,10 @@ dasd_3990_erp_compound_config(struct dasd_ccw_req * erp, char *sense) | |||
2063 | } /* end dasd_3990_erp_compound_config */ | 2063 | } /* end dasd_3990_erp_compound_config */ |
2064 | 2064 | ||
2065 | /* | 2065 | /* |
2066 | * DASD_3990_ERP_COMPOUND | 2066 | * DASD_3990_ERP_COMPOUND |
2067 | * | 2067 | * |
2068 | * DESCRIPTION | 2068 | * DESCRIPTION |
2069 | * Does the further compound program action if | 2069 | * Does the further compound program action if |
2070 | * compound retry was not successful. | 2070 | * compound retry was not successful. |
2071 | * | 2071 | * |
2072 | * PARAMETER | 2072 | * PARAMETER |
@@ -2110,11 +2110,11 @@ dasd_3990_erp_compound(struct dasd_ccw_req * erp, char *sense) | |||
2110 | } /* end dasd_3990_erp_compound */ | 2110 | } /* end dasd_3990_erp_compound */ |
2111 | 2111 | ||
2112 | /* | 2112 | /* |
2113 | * DASD_3990_ERP_INSPECT_32 | 2113 | * DASD_3990_ERP_INSPECT_32 |
2114 | * | 2114 | * |
2115 | * DESCRIPTION | 2115 | * DESCRIPTION |
2116 | * Does a detailed inspection of the 32 byte sense data | 2116 | * Does a detailed inspection of the 32 byte sense data |
2117 | * and sets up a related error recovery action. | 2117 | * and sets up a related error recovery action. |
2118 | * | 2118 | * |
2119 | * PARAMETER | 2119 | * PARAMETER |
2120 | * sense sense data of the actual error | 2120 | * sense sense data of the actual error |
@@ -2228,9 +2228,9 @@ dasd_3990_erp_inspect_32(struct dasd_ccw_req * erp, char *sense) | |||
2228 | } /* end dasd_3990_erp_inspect_32 */ | 2228 | } /* end dasd_3990_erp_inspect_32 */ |
2229 | 2229 | ||
2230 | /* | 2230 | /* |
2231 | ***************************************************************************** | 2231 | ***************************************************************************** |
2232 | * main ERP control fuctions (24 and 32 byte sense) | 2232 | * main ERP control fuctions (24 and 32 byte sense) |
2233 | ***************************************************************************** | 2233 | ***************************************************************************** |
2234 | */ | 2234 | */ |
2235 | 2235 | ||
2236 | /* | 2236 | /* |
@@ -2243,7 +2243,7 @@ dasd_3990_erp_inspect_32(struct dasd_ccw_req * erp, char *sense) | |||
2243 | * PARAMETER | 2243 | * PARAMETER |
2244 | * erp pointer to the currently created default ERP | 2244 | * erp pointer to the currently created default ERP |
2245 | * RETURN VALUES | 2245 | * RETURN VALUES |
2246 | * erp_new contens was possibly modified | 2246 | * erp_new contens was possibly modified |
2247 | */ | 2247 | */ |
2248 | static struct dasd_ccw_req * | 2248 | static struct dasd_ccw_req * |
2249 | dasd_3990_erp_inspect(struct dasd_ccw_req * erp) | 2249 | dasd_3990_erp_inspect(struct dasd_ccw_req * erp) |
@@ -2272,14 +2272,14 @@ dasd_3990_erp_inspect(struct dasd_ccw_req * erp) | |||
2272 | 2272 | ||
2273 | /* | 2273 | /* |
2274 | * DASD_3990_ERP_ADD_ERP | 2274 | * DASD_3990_ERP_ADD_ERP |
2275 | * | 2275 | * |
2276 | * DESCRIPTION | 2276 | * DESCRIPTION |
2277 | * This funtion adds an additional request block (ERP) to the head of | 2277 | * This funtion adds an additional request block (ERP) to the head of |
2278 | * the given cqr (or erp). | 2278 | * the given cqr (or erp). |
2279 | * This erp is initialized as an default erp (retry TIC) | 2279 | * This erp is initialized as an default erp (retry TIC) |
2280 | * | 2280 | * |
2281 | * PARAMETER | 2281 | * PARAMETER |
2282 | * cqr head of the current ERP-chain (or single cqr if | 2282 | * cqr head of the current ERP-chain (or single cqr if |
2283 | * first error) | 2283 | * first error) |
2284 | * RETURN VALUES | 2284 | * RETURN VALUES |
2285 | * erp pointer to new ERP-chain head | 2285 | * erp pointer to new ERP-chain head |
@@ -2332,15 +2332,15 @@ dasd_3990_erp_add_erp(struct dasd_ccw_req * cqr) | |||
2332 | } | 2332 | } |
2333 | 2333 | ||
2334 | /* | 2334 | /* |
2335 | * DASD_3990_ERP_ADDITIONAL_ERP | 2335 | * DASD_3990_ERP_ADDITIONAL_ERP |
2336 | * | 2336 | * |
2337 | * DESCRIPTION | 2337 | * DESCRIPTION |
2338 | * An additional ERP is needed to handle the current error. | 2338 | * An additional ERP is needed to handle the current error. |
2339 | * Add ERP to the head of the ERP-chain containing the ERP processing | 2339 | * Add ERP to the head of the ERP-chain containing the ERP processing |
2340 | * determined based on the sense data. | 2340 | * determined based on the sense data. |
2341 | * | 2341 | * |
2342 | * PARAMETER | 2342 | * PARAMETER |
2343 | * cqr head of the current ERP-chain (or single cqr if | 2343 | * cqr head of the current ERP-chain (or single cqr if |
2344 | * first error) | 2344 | * first error) |
2345 | * | 2345 | * |
2346 | * RETURN VALUES | 2346 | * RETURN VALUES |
@@ -2376,7 +2376,7 @@ dasd_3990_erp_additional_erp(struct dasd_ccw_req * cqr) | |||
2376 | * 24 byte sense byte 25 and 27 is set as well. | 2376 | * 24 byte sense byte 25 and 27 is set as well. |
2377 | * | 2377 | * |
2378 | * PARAMETER | 2378 | * PARAMETER |
2379 | * cqr1 first cqr, which will be compared with the | 2379 | * cqr1 first cqr, which will be compared with the |
2380 | * cqr2 second cqr. | 2380 | * cqr2 second cqr. |
2381 | * | 2381 | * |
2382 | * RETURN VALUES | 2382 | * RETURN VALUES |
@@ -2415,7 +2415,7 @@ dasd_3990_erp_error_match(struct dasd_ccw_req *cqr1, struct dasd_ccw_req *cqr2) | |||
2415 | * cqr failed cqr (either original cqr or already an erp) | 2415 | * cqr failed cqr (either original cqr or already an erp) |
2416 | * | 2416 | * |
2417 | * RETURN VALUES | 2417 | * RETURN VALUES |
2418 | * erp erp-pointer to the already defined error | 2418 | * erp erp-pointer to the already defined error |
2419 | * recovery procedure OR | 2419 | * recovery procedure OR |
2420 | * NULL if a 'new' error occurred. | 2420 | * NULL if a 'new' error occurred. |
2421 | */ | 2421 | */ |
@@ -2451,10 +2451,10 @@ dasd_3990_erp_in_erp(struct dasd_ccw_req *cqr) | |||
2451 | * DASD_3990_ERP_FURTHER_ERP (24 & 32 byte sense) | 2451 | * DASD_3990_ERP_FURTHER_ERP (24 & 32 byte sense) |
2452 | * | 2452 | * |
2453 | * DESCRIPTION | 2453 | * DESCRIPTION |
2454 | * No retry is left for the current ERP. Check what has to be done | 2454 | * No retry is left for the current ERP. Check what has to be done |
2455 | * with the ERP. | 2455 | * with the ERP. |
2456 | * - do further defined ERP action or | 2456 | * - do further defined ERP action or |
2457 | * - wait for interrupt or | 2457 | * - wait for interrupt or |
2458 | * - exit with permanent error | 2458 | * - exit with permanent error |
2459 | * | 2459 | * |
2460 | * PARAMETER | 2460 | * PARAMETER |
@@ -2485,7 +2485,7 @@ dasd_3990_erp_further_erp(struct dasd_ccw_req *erp) | |||
2485 | 2485 | ||
2486 | if (!(sense[2] & DASD_SENSE_BIT_0)) { | 2486 | if (!(sense[2] & DASD_SENSE_BIT_0)) { |
2487 | 2487 | ||
2488 | /* issue a Diagnostic Control command with an | 2488 | /* issue a Diagnostic Control command with an |
2489 | * Inhibit Write subcommand */ | 2489 | * Inhibit Write subcommand */ |
2490 | 2490 | ||
2491 | switch (sense[25]) { | 2491 | switch (sense[25]) { |
@@ -2535,14 +2535,14 @@ dasd_3990_erp_further_erp(struct dasd_ccw_req *erp) | |||
2535 | } /* end dasd_3990_erp_further_erp */ | 2535 | } /* end dasd_3990_erp_further_erp */ |
2536 | 2536 | ||
2537 | /* | 2537 | /* |
2538 | * DASD_3990_ERP_HANDLE_MATCH_ERP | 2538 | * DASD_3990_ERP_HANDLE_MATCH_ERP |
2539 | * | 2539 | * |
2540 | * DESCRIPTION | 2540 | * DESCRIPTION |
2541 | * An error occurred again and an ERP has been detected which is already | 2541 | * An error occurred again and an ERP has been detected which is already |
2542 | * used to handle this error (e.g. retries). | 2542 | * used to handle this error (e.g. retries). |
2543 | * All prior ERP's are asumed to be successful and therefore removed | 2543 | * All prior ERP's are asumed to be successful and therefore removed |
2544 | * from queue. | 2544 | * from queue. |
2545 | * If retry counter of matching erp is already 0, it is checked if further | 2545 | * If retry counter of matching erp is already 0, it is checked if further |
2546 | * action is needed (besides retry) or if the ERP has failed. | 2546 | * action is needed (besides retry) or if the ERP has failed. |
2547 | * | 2547 | * |
2548 | * PARAMETER | 2548 | * PARAMETER |
@@ -2631,7 +2631,7 @@ dasd_3990_erp_handle_match_erp(struct dasd_ccw_req *erp_head, | |||
2631 | * erp erp-pointer to the head of the ERP action chain. | 2631 | * erp erp-pointer to the head of the ERP action chain. |
2632 | * This means: | 2632 | * This means: |
2633 | * - either a ptr to an additional ERP cqr or | 2633 | * - either a ptr to an additional ERP cqr or |
2634 | * - the original given cqr (which's status might | 2634 | * - the original given cqr (which's status might |
2635 | * be modified) | 2635 | * be modified) |
2636 | */ | 2636 | */ |
2637 | struct dasd_ccw_req * | 2637 | struct dasd_ccw_req * |
@@ -2723,22 +2723,3 @@ dasd_3990_erp_action(struct dasd_ccw_req * cqr) | |||
2723 | return erp; | 2723 | return erp; |
2724 | 2724 | ||
2725 | } /* end dasd_3990_erp_action */ | 2725 | } /* end dasd_3990_erp_action */ |
2726 | |||
2727 | /* | ||
2728 | * Overrides for Emacs so that we follow Linus's tabbing style. | ||
2729 | * Emacs will notice this stuff at the end of the file and automatically | ||
2730 | * adjust the settings for this buffer only. This must remain at the end | ||
2731 | * of the file. | ||
2732 | * --------------------------------------------------------------------------- | ||
2733 | * Local variables: | ||
2734 | * c-indent-level: 4 | ||
2735 | * c-brace-imaginary-offset: 0 | ||
2736 | * c-brace-offset: -4 | ||
2737 | * c-argdecl-indent: 4 | ||
2738 | * c-label-offset: -4 | ||
2739 | * c-continued-statement-offset: 4 | ||
2740 | * c-continued-brace-offset: 0 | ||
2741 | * indent-tabs-mode: 1 | ||
2742 | * tab-width: 8 | ||
2743 | * End: | ||
2744 | */ | ||
diff --git a/drivers/s390/block/dasd_9336_erp.c b/drivers/s390/block/dasd_9336_erp.c index dc861446d056..6e082688475a 100644 --- a/drivers/s390/block/dasd_9336_erp.c +++ b/drivers/s390/block/dasd_9336_erp.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * File...........: linux/drivers/s390/block/dasd_9336_erp.c | 2 | * File...........: linux/drivers/s390/block/dasd_9336_erp.c |
3 | * Author(s)......: Holger Smolinski <Holger.Smolinski@de.ibm.com> | 3 | * Author(s)......: Holger Smolinski <Holger.Smolinski@de.ibm.com> |
4 | * Bugreports.to..: <Linux390@de.ibm.com> | 4 | * Bugreports.to..: <Linux390@de.ibm.com> |
@@ -12,10 +12,10 @@ | |||
12 | 12 | ||
13 | 13 | ||
14 | /* | 14 | /* |
15 | * DASD_9336_ERP_EXAMINE | 15 | * DASD_9336_ERP_EXAMINE |
16 | * | 16 | * |
17 | * DESCRIPTION | 17 | * DESCRIPTION |
18 | * Checks only for fatal/no/recover error. | 18 | * Checks only for fatal/no/recover error. |
19 | * A detailed examination of the sense data is done later outside | 19 | * A detailed examination of the sense data is done later outside |
20 | * the interrupt handler. | 20 | * the interrupt handler. |
21 | * | 21 | * |
@@ -23,7 +23,7 @@ | |||
23 | * 'Chapter 7. 9336 Sense Data'. | 23 | * 'Chapter 7. 9336 Sense Data'. |
24 | * | 24 | * |
25 | * RETURN VALUES | 25 | * RETURN VALUES |
26 | * dasd_era_none no error | 26 | * dasd_era_none no error |
27 | * dasd_era_fatal for all fatal (unrecoverable errors) | 27 | * dasd_era_fatal for all fatal (unrecoverable errors) |
28 | * dasd_era_recover for all others. | 28 | * dasd_era_recover for all others. |
29 | */ | 29 | */ |
@@ -39,22 +39,3 @@ dasd_9336_erp_examine(struct dasd_ccw_req * cqr, struct irb * irb) | |||
39 | return dasd_era_recover; | 39 | return dasd_era_recover; |
40 | 40 | ||
41 | } /* END dasd_9336_erp_examine */ | 41 | } /* END dasd_9336_erp_examine */ |
42 | |||
43 | /* | ||
44 | * Overrides for Emacs so that we follow Linus's tabbing style. | ||
45 | * Emacs will notice this stuff at the end of the file and automatically | ||
46 | * adjust the settings for this buffer only. This must remain at the end | ||
47 | * of the file. | ||
48 | * --------------------------------------------------------------------------- | ||
49 | * Local variables: | ||
50 | * c-indent-level: 4 | ||
51 | * c-brace-imaginary-offset: 0 | ||
52 | * c-brace-offset: -4 | ||
53 | * c-argdecl-indent: 4 | ||
54 | * c-label-offset: -4 | ||
55 | * c-continued-statement-offset: 4 | ||
56 | * c-continued-brace-offset: 0 | ||
57 | * indent-tabs-mode: 1 | ||
58 | * tab-width: 8 | ||
59 | * End: | ||
60 | */ | ||
diff --git a/drivers/s390/block/dasd_9343_erp.c b/drivers/s390/block/dasd_9343_erp.c index 4a5b79569aaa..ddecb9808ed4 100644 --- a/drivers/s390/block/dasd_9343_erp.c +++ b/drivers/s390/block/dasd_9343_erp.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * File...........: linux/drivers/s390/block/dasd_9345_erp.c | 2 | * File...........: linux/drivers/s390/block/dasd_9345_erp.c |
3 | * Author(s)......: Holger Smolinski <Holger.Smolinski@de.ibm.com> | 3 | * Author(s)......: Holger Smolinski <Holger.Smolinski@de.ibm.com> |
4 | * Bugreports.to..: <Linux390@de.ibm.com> | 4 | * Bugreports.to..: <Linux390@de.ibm.com> |
diff --git a/drivers/s390/block/dasd_devmap.c b/drivers/s390/block/dasd_devmap.c index 216bc4fba199..9e9ae7179602 100644 --- a/drivers/s390/block/dasd_devmap.c +++ b/drivers/s390/block/dasd_devmap.c | |||
@@ -27,7 +27,7 @@ | |||
27 | #include "dasd_int.h" | 27 | #include "dasd_int.h" |
28 | 28 | ||
29 | kmem_cache_t *dasd_page_cache; | 29 | kmem_cache_t *dasd_page_cache; |
30 | EXPORT_SYMBOL(dasd_page_cache); | 30 | EXPORT_SYMBOL_GPL(dasd_page_cache); |
31 | 31 | ||
32 | /* | 32 | /* |
33 | * dasd_devmap_t is used to store the features and the relation | 33 | * dasd_devmap_t is used to store the features and the relation |
@@ -49,6 +49,20 @@ struct dasd_devmap { | |||
49 | }; | 49 | }; |
50 | 50 | ||
51 | /* | 51 | /* |
52 | * dasd_servermap is used to store the server_id of all storage servers | ||
53 | * accessed by DASD device driver. | ||
54 | */ | ||
55 | struct dasd_servermap { | ||
56 | struct list_head list; | ||
57 | struct server_id { | ||
58 | char vendor[4]; | ||
59 | char serial[15]; | ||
60 | } sid; | ||
61 | }; | ||
62 | |||
63 | static struct list_head dasd_serverlist; | ||
64 | |||
65 | /* | ||
52 | * Parameter parsing functions for dasd= parameter. The syntax is: | 66 | * Parameter parsing functions for dasd= parameter. The syntax is: |
53 | * <devno> : (0x)?[0-9a-fA-F]+ | 67 | * <devno> : (0x)?[0-9a-fA-F]+ |
54 | * <busid> : [0-0a-f]\.[0-9a-f]\.(0x)?[0-9a-fA-F]+ | 68 | * <busid> : [0-0a-f]\.[0-9a-f]\.(0x)?[0-9a-fA-F]+ |
@@ -64,6 +78,8 @@ struct dasd_devmap { | |||
64 | 78 | ||
65 | int dasd_probeonly = 0; /* is true, when probeonly mode is active */ | 79 | int dasd_probeonly = 0; /* is true, when probeonly mode is active */ |
66 | int dasd_autodetect = 0; /* is true, when autodetection is active */ | 80 | int dasd_autodetect = 0; /* is true, when autodetection is active */ |
81 | int dasd_nopav = 0; /* is true, when PAV is disabled */ | ||
82 | EXPORT_SYMBOL_GPL(dasd_nopav); | ||
67 | 83 | ||
68 | /* | 84 | /* |
69 | * char *dasd[] is intended to hold the ranges supplied by the dasd= statement | 85 | * char *dasd[] is intended to hold the ranges supplied by the dasd= statement |
@@ -123,7 +139,7 @@ static inline int | |||
123 | dasd_busid(char **str, int *id0, int *id1, int *devno) | 139 | dasd_busid(char **str, int *id0, int *id1, int *devno) |
124 | { | 140 | { |
125 | int val, old_style; | 141 | int val, old_style; |
126 | 142 | ||
127 | /* check for leading '0x' */ | 143 | /* check for leading '0x' */ |
128 | old_style = 0; | 144 | old_style = 0; |
129 | if ((*str)[0] == '0' && (*str)[1] == 'x') { | 145 | if ((*str)[0] == '0' && (*str)[1] == 'x') { |
@@ -179,7 +195,7 @@ dasd_feature_list(char *str, char **endp) | |||
179 | features = 0; | 195 | features = 0; |
180 | 196 | ||
181 | while (1) { | 197 | while (1) { |
182 | for (len = 0; | 198 | for (len = 0; |
183 | str[len] && str[len] != ':' && str[len] != ')'; len++); | 199 | str[len] && str[len] != ':' && str[len] != ')'; len++); |
184 | if (len == 2 && !strncmp(str, "ro", 2)) | 200 | if (len == 2 && !strncmp(str, "ro", 2)) |
185 | features |= DASD_FEATURE_READONLY; | 201 | features |= DASD_FEATURE_READONLY; |
@@ -228,19 +244,24 @@ dasd_parse_keyword( char *parsestring ) { | |||
228 | length = strlen(parsestring); | 244 | length = strlen(parsestring); |
229 | residual_str = parsestring + length; | 245 | residual_str = parsestring + length; |
230 | } | 246 | } |
231 | if (strncmp ("autodetect", parsestring, length) == 0) { | 247 | if (strncmp("autodetect", parsestring, length) == 0) { |
232 | dasd_autodetect = 1; | 248 | dasd_autodetect = 1; |
233 | MESSAGE (KERN_INFO, "%s", | 249 | MESSAGE (KERN_INFO, "%s", |
234 | "turning to autodetection mode"); | 250 | "turning to autodetection mode"); |
235 | return residual_str; | 251 | return residual_str; |
236 | } | 252 | } |
237 | if (strncmp ("probeonly", parsestring, length) == 0) { | 253 | if (strncmp("probeonly", parsestring, length) == 0) { |
238 | dasd_probeonly = 1; | 254 | dasd_probeonly = 1; |
239 | MESSAGE(KERN_INFO, "%s", | 255 | MESSAGE(KERN_INFO, "%s", |
240 | "turning to probeonly mode"); | 256 | "turning to probeonly mode"); |
241 | return residual_str; | 257 | return residual_str; |
242 | } | 258 | } |
243 | if (strncmp ("fixedbuffers", parsestring, length) == 0) { | 259 | if (strncmp("nopav", parsestring, length) == 0) { |
260 | dasd_nopav = 1; | ||
261 | MESSAGE(KERN_INFO, "%s", "disable PAV mode"); | ||
262 | return residual_str; | ||
263 | } | ||
264 | if (strncmp("fixedbuffers", parsestring, length) == 0) { | ||
244 | if (dasd_page_cache) | 265 | if (dasd_page_cache) |
245 | return residual_str; | 266 | return residual_str; |
246 | dasd_page_cache = | 267 | dasd_page_cache = |
@@ -294,6 +315,8 @@ dasd_parse_range( char *parsestring ) { | |||
294 | features = dasd_feature_list(str, &str); | 315 | features = dasd_feature_list(str, &str); |
295 | if (features < 0) | 316 | if (features < 0) |
296 | return ERR_PTR(-EINVAL); | 317 | return ERR_PTR(-EINVAL); |
318 | /* each device in dasd= parameter should be set initially online */ | ||
319 | features |= DASD_FEATURE_INITIAL_ONLINE; | ||
297 | while (from <= to) { | 320 | while (from <= to) { |
298 | sprintf(bus_id, "%01x.%01x.%04x", | 321 | sprintf(bus_id, "%01x.%01x.%04x", |
299 | from_id0, from_id1, from++); | 322 | from_id0, from_id1, from++); |
@@ -359,7 +382,7 @@ dasd_parse(void) | |||
359 | * Add a devmap for the device specified by busid. It is possible that | 382 | * Add a devmap for the device specified by busid. It is possible that |
360 | * the devmap already exists (dasd= parameter). The order of the devices | 383 | * the devmap already exists (dasd= parameter). The order of the devices |
361 | * added through this function will define the kdevs for the individual | 384 | * added through this function will define the kdevs for the individual |
362 | * devices. | 385 | * devices. |
363 | */ | 386 | */ |
364 | static struct dasd_devmap * | 387 | static struct dasd_devmap * |
365 | dasd_add_busid(char *bus_id, int features) | 388 | dasd_add_busid(char *bus_id, int features) |
@@ -368,7 +391,7 @@ dasd_add_busid(char *bus_id, int features) | |||
368 | int hash; | 391 | int hash; |
369 | 392 | ||
370 | new = (struct dasd_devmap *) | 393 | new = (struct dasd_devmap *) |
371 | kmalloc(sizeof(struct dasd_devmap), GFP_KERNEL); | 394 | kzalloc(sizeof(struct dasd_devmap), GFP_KERNEL); |
372 | if (!new) | 395 | if (!new) |
373 | return ERR_PTR(-ENOMEM); | 396 | return ERR_PTR(-ENOMEM); |
374 | spin_lock(&dasd_devmap_lock); | 397 | spin_lock(&dasd_devmap_lock); |
@@ -630,7 +653,8 @@ dasd_ro_show(struct device *dev, struct device_attribute *attr, char *buf) | |||
630 | } | 653 | } |
631 | 654 | ||
632 | static ssize_t | 655 | static ssize_t |
633 | dasd_ro_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) | 656 | dasd_ro_store(struct device *dev, struct device_attribute *attr, |
657 | const char *buf, size_t count) | ||
634 | { | 658 | { |
635 | struct dasd_devmap *devmap; | 659 | struct dasd_devmap *devmap; |
636 | int ro_flag; | 660 | int ro_flag; |
@@ -658,7 +682,7 @@ static DEVICE_ATTR(readonly, 0644, dasd_ro_show, dasd_ro_store); | |||
658 | * use_diag controls whether the driver should use diag rather than ssch | 682 | * use_diag controls whether the driver should use diag rather than ssch |
659 | * to talk to the device | 683 | * to talk to the device |
660 | */ | 684 | */ |
661 | static ssize_t | 685 | static ssize_t |
662 | dasd_use_diag_show(struct device *dev, struct device_attribute *attr, char *buf) | 686 | dasd_use_diag_show(struct device *dev, struct device_attribute *attr, char *buf) |
663 | { | 687 | { |
664 | struct dasd_devmap *devmap; | 688 | struct dasd_devmap *devmap; |
@@ -673,7 +697,8 @@ dasd_use_diag_show(struct device *dev, struct device_attribute *attr, char *buf) | |||
673 | } | 697 | } |
674 | 698 | ||
675 | static ssize_t | 699 | static ssize_t |
676 | dasd_use_diag_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) | 700 | dasd_use_diag_store(struct device *dev, struct device_attribute *attr, |
701 | const char *buf, size_t count) | ||
677 | { | 702 | { |
678 | struct dasd_devmap *devmap; | 703 | struct dasd_devmap *devmap; |
679 | ssize_t rc; | 704 | ssize_t rc; |
@@ -697,11 +722,11 @@ dasd_use_diag_store(struct device *dev, struct device_attribute *attr, const cha | |||
697 | return rc; | 722 | return rc; |
698 | } | 723 | } |
699 | 724 | ||
700 | static | 725 | static DEVICE_ATTR(use_diag, 0644, dasd_use_diag_show, dasd_use_diag_store); |
701 | DEVICE_ATTR(use_diag, 0644, dasd_use_diag_show, dasd_use_diag_store); | ||
702 | 726 | ||
703 | static ssize_t | 727 | static ssize_t |
704 | dasd_discipline_show(struct device *dev, struct device_attribute *attr, char *buf) | 728 | dasd_discipline_show(struct device *dev, struct device_attribute *attr, |
729 | char *buf) | ||
705 | { | 730 | { |
706 | struct dasd_devmap *devmap; | 731 | struct dasd_devmap *devmap; |
707 | char *dname; | 732 | char *dname; |
@@ -834,6 +859,38 @@ static struct attribute_group dasd_attr_group = { | |||
834 | .attrs = dasd_attrs, | 859 | .attrs = dasd_attrs, |
835 | }; | 860 | }; |
836 | 861 | ||
862 | /* | ||
863 | * Check if the related storage server is already contained in the | ||
864 | * dasd_serverlist. If server is not contained, create new entry. | ||
865 | * Return 0 if server was already in serverlist, | ||
866 | * 1 if the server was added successfully | ||
867 | * <0 in case of error. | ||
868 | */ | ||
869 | static int | ||
870 | dasd_add_server(struct dasd_uid *uid) | ||
871 | { | ||
872 | struct dasd_servermap *new, *tmp; | ||
873 | |||
874 | /* check if server is already contained */ | ||
875 | list_for_each_entry(tmp, &dasd_serverlist, list) | ||
876 | // normale cmp? | ||
877 | if (strncmp(tmp->sid.vendor, uid->vendor, | ||
878 | sizeof(tmp->sid.vendor)) == 0 | ||
879 | && strncmp(tmp->sid.serial, uid->serial, | ||
880 | sizeof(tmp->sid.serial)) == 0) | ||
881 | return 0; | ||
882 | |||
883 | new = (struct dasd_servermap *) | ||
884 | kzalloc(sizeof(struct dasd_servermap), GFP_KERNEL); | ||
885 | if (!new) | ||
886 | return -ENOMEM; | ||
887 | |||
888 | strncpy(new->sid.vendor, uid->vendor, sizeof(new->sid.vendor)); | ||
889 | strncpy(new->sid.serial, uid->serial, sizeof(new->sid.serial)); | ||
890 | list_add(&new->list, &dasd_serverlist); | ||
891 | return 1; | ||
892 | } | ||
893 | |||
837 | 894 | ||
838 | /* | 895 | /* |
839 | * Return copy of the device unique identifier. | 896 | * Return copy of the device unique identifier. |
@@ -854,21 +911,26 @@ dasd_get_uid(struct ccw_device *cdev, struct dasd_uid *uid) | |||
854 | 911 | ||
855 | /* | 912 | /* |
856 | * Register the given device unique identifier into devmap struct. | 913 | * Register the given device unique identifier into devmap struct. |
914 | * Return 0 if server was already in serverlist, | ||
915 | * 1 if the server was added successful | ||
916 | * <0 in case of error. | ||
857 | */ | 917 | */ |
858 | int | 918 | int |
859 | dasd_set_uid(struct ccw_device *cdev, struct dasd_uid *uid) | 919 | dasd_set_uid(struct ccw_device *cdev, struct dasd_uid *uid) |
860 | { | 920 | { |
861 | struct dasd_devmap *devmap; | 921 | struct dasd_devmap *devmap; |
922 | int rc; | ||
862 | 923 | ||
863 | devmap = dasd_find_busid(cdev->dev.bus_id); | 924 | devmap = dasd_find_busid(cdev->dev.bus_id); |
864 | if (IS_ERR(devmap)) | 925 | if (IS_ERR(devmap)) |
865 | return PTR_ERR(devmap); | 926 | return PTR_ERR(devmap); |
866 | spin_lock(&dasd_devmap_lock); | 927 | spin_lock(&dasd_devmap_lock); |
867 | devmap->uid = *uid; | 928 | devmap->uid = *uid; |
929 | rc = dasd_add_server(uid); | ||
868 | spin_unlock(&dasd_devmap_lock); | 930 | spin_unlock(&dasd_devmap_lock); |
869 | return 0; | 931 | return rc; |
870 | } | 932 | } |
871 | EXPORT_SYMBOL(dasd_set_uid); | 933 | EXPORT_SYMBOL_GPL(dasd_set_uid); |
872 | 934 | ||
873 | /* | 935 | /* |
874 | * Return value of the specified feature. | 936 | * Return value of the specified feature. |
@@ -880,7 +942,7 @@ dasd_get_feature(struct ccw_device *cdev, int feature) | |||
880 | 942 | ||
881 | devmap = dasd_find_busid(cdev->dev.bus_id); | 943 | devmap = dasd_find_busid(cdev->dev.bus_id); |
882 | if (IS_ERR(devmap)) | 944 | if (IS_ERR(devmap)) |
883 | return (int) PTR_ERR(devmap); | 945 | return PTR_ERR(devmap); |
884 | 946 | ||
885 | return ((devmap->features & feature) != 0); | 947 | return ((devmap->features & feature) != 0); |
886 | } | 948 | } |
@@ -896,7 +958,7 @@ dasd_set_feature(struct ccw_device *cdev, int feature, int flag) | |||
896 | 958 | ||
897 | devmap = dasd_find_busid(cdev->dev.bus_id); | 959 | devmap = dasd_find_busid(cdev->dev.bus_id); |
898 | if (IS_ERR(devmap)) | 960 | if (IS_ERR(devmap)) |
899 | return (int) PTR_ERR(devmap); | 961 | return PTR_ERR(devmap); |
900 | 962 | ||
901 | spin_lock(&dasd_devmap_lock); | 963 | spin_lock(&dasd_devmap_lock); |
902 | if (flag) | 964 | if (flag) |
@@ -932,8 +994,10 @@ dasd_devmap_init(void) | |||
932 | dasd_max_devindex = 0; | 994 | dasd_max_devindex = 0; |
933 | for (i = 0; i < 256; i++) | 995 | for (i = 0; i < 256; i++) |
934 | INIT_LIST_HEAD(&dasd_hashlists[i]); | 996 | INIT_LIST_HEAD(&dasd_hashlists[i]); |
935 | return 0; | ||
936 | 997 | ||
998 | /* Initialize servermap structure. */ | ||
999 | INIT_LIST_HEAD(&dasd_serverlist); | ||
1000 | return 0; | ||
937 | } | 1001 | } |
938 | 1002 | ||
939 | void | 1003 | void |
diff --git a/drivers/s390/block/dasd_diag.c b/drivers/s390/block/dasd_diag.c index 3f9d704d2657..4002f6c1c1b3 100644 --- a/drivers/s390/block/dasd_diag.c +++ b/drivers/s390/block/dasd_diag.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * File...........: linux/drivers/s390/block/dasd_diag.c | 2 | * File...........: linux/drivers/s390/block/dasd_diag.c |
3 | * Author(s)......: Holger Smolinski <Holger.Smolinski@de.ibm.com> | 3 | * Author(s)......: Holger Smolinski <Holger.Smolinski@de.ibm.com> |
4 | * Based on.......: linux/drivers/s390/block/mdisk.c | 4 | * Based on.......: linux/drivers/s390/block/mdisk.c |
@@ -336,7 +336,7 @@ dasd_diag_check_device(struct dasd_device *device) | |||
336 | 336 | ||
337 | private = (struct dasd_diag_private *) device->private; | 337 | private = (struct dasd_diag_private *) device->private; |
338 | if (private == NULL) { | 338 | if (private == NULL) { |
339 | private = kmalloc(sizeof(struct dasd_diag_private),GFP_KERNEL); | 339 | private = kzalloc(sizeof(struct dasd_diag_private),GFP_KERNEL); |
340 | if (private == NULL) { | 340 | if (private == NULL) { |
341 | DEV_MESSAGE(KERN_WARNING, device, "%s", | 341 | DEV_MESSAGE(KERN_WARNING, device, "%s", |
342 | "memory allocation failed for private data"); | 342 | "memory allocation failed for private data"); |
@@ -527,7 +527,7 @@ dasd_diag_build_cp(struct dasd_device * device, struct request *req) | |||
527 | datasize, device); | 527 | datasize, device); |
528 | if (IS_ERR(cqr)) | 528 | if (IS_ERR(cqr)) |
529 | return cqr; | 529 | return cqr; |
530 | 530 | ||
531 | dreq = (struct dasd_diag_req *) cqr->data; | 531 | dreq = (struct dasd_diag_req *) cqr->data; |
532 | dreq->block_count = count; | 532 | dreq->block_count = count; |
533 | dbio = dreq->bio; | 533 | dbio = dreq->bio; |
diff --git a/drivers/s390/block/dasd_diag.h b/drivers/s390/block/dasd_diag.h index 38a4e55f8953..b8c78267ff3e 100644 --- a/drivers/s390/block/dasd_diag.h +++ b/drivers/s390/block/dasd_diag.h | |||
@@ -1,4 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * File...........: linux/drivers/s390/block/dasd_diag.h | 2 | * File...........: linux/drivers/s390/block/dasd_diag.h |
3 | * Author(s)......: Holger Smolinski <Holger.Smolinski@de.ibm.com> | 3 | * Author(s)......: Holger Smolinski <Holger.Smolinski@de.ibm.com> |
4 | * Based on.......: linux/drivers/s390/block/mdisk.h | 4 | * Based on.......: linux/drivers/s390/block/mdisk.h |
diff --git a/drivers/s390/block/dasd_eckd.c b/drivers/s390/block/dasd_eckd.c index 7d5a6cee4bd8..0dfab30e8089 100644 --- a/drivers/s390/block/dasd_eckd.c +++ b/drivers/s390/block/dasd_eckd.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * File...........: linux/drivers/s390/block/dasd_eckd.c | 2 | * File...........: linux/drivers/s390/block/dasd_eckd.c |
3 | * Author(s)......: Holger Smolinski <Holger.Smolinski@de.ibm.com> | 3 | * Author(s)......: Holger Smolinski <Holger.Smolinski@de.ibm.com> |
4 | * Horst Hummel <Horst.Hummel@de.ibm.com> | 4 | * Horst Hummel <Horst.Hummel@de.ibm.com> |
5 | * Carsten Otte <Cotte@de.ibm.com> | 5 | * Carsten Otte <Cotte@de.ibm.com> |
6 | * Martin Schwidefsky <schwidefsky@de.ibm.com> | 6 | * Martin Schwidefsky <schwidefsky@de.ibm.com> |
7 | * Bugreports.to..: <Linux390@de.ibm.com> | 7 | * Bugreports.to..: <Linux390@de.ibm.com> |
@@ -24,6 +24,7 @@ | |||
24 | #include <asm/io.h> | 24 | #include <asm/io.h> |
25 | #include <asm/todclk.h> | 25 | #include <asm/todclk.h> |
26 | #include <asm/uaccess.h> | 26 | #include <asm/uaccess.h> |
27 | #include <asm/cio.h> | ||
27 | #include <asm/ccwdev.h> | 28 | #include <asm/ccwdev.h> |
28 | 29 | ||
29 | #include "dasd_int.h" | 30 | #include "dasd_int.h" |
@@ -89,17 +90,22 @@ dasd_eckd_probe (struct ccw_device *cdev) | |||
89 | { | 90 | { |
90 | int ret; | 91 | int ret; |
91 | 92 | ||
92 | ret = dasd_generic_probe (cdev, &dasd_eckd_discipline); | 93 | /* set ECKD specific ccw-device options */ |
93 | if (ret) | 94 | ret = ccw_device_set_options(cdev, CCWDEV_ALLOW_FORCE); |
95 | if (ret) { | ||
96 | printk(KERN_WARNING | ||
97 | "dasd_eckd_probe: could not set ccw-device options " | ||
98 | "for %s\n", cdev->dev.bus_id); | ||
94 | return ret; | 99 | return ret; |
95 | ccw_device_set_options(cdev, CCWDEV_DO_PATHGROUP | CCWDEV_ALLOW_FORCE); | 100 | } |
96 | return 0; | 101 | ret = dasd_generic_probe(cdev, &dasd_eckd_discipline); |
102 | return ret; | ||
97 | } | 103 | } |
98 | 104 | ||
99 | static int | 105 | static int |
100 | dasd_eckd_set_online(struct ccw_device *cdev) | 106 | dasd_eckd_set_online(struct ccw_device *cdev) |
101 | { | 107 | { |
102 | return dasd_generic_set_online (cdev, &dasd_eckd_discipline); | 108 | return dasd_generic_set_online(cdev, &dasd_eckd_discipline); |
103 | } | 109 | } |
104 | 110 | ||
105 | static struct ccw_driver dasd_eckd_driver = { | 111 | static struct ccw_driver dasd_eckd_driver = { |
@@ -210,14 +216,14 @@ check_XRC (struct ccw1 *de_ccw, | |||
210 | 216 | ||
211 | /* switch on System Time Stamp - needed for XRC Support */ | 217 | /* switch on System Time Stamp - needed for XRC Support */ |
212 | if (private->rdc_data.facilities.XRC_supported) { | 218 | if (private->rdc_data.facilities.XRC_supported) { |
213 | 219 | ||
214 | data->ga_extended |= 0x08; /* switch on 'Time Stamp Valid' */ | 220 | data->ga_extended |= 0x08; /* switch on 'Time Stamp Valid' */ |
215 | data->ga_extended |= 0x02; /* switch on 'Extended Parameter' */ | 221 | data->ga_extended |= 0x02; /* switch on 'Extended Parameter' */ |
216 | 222 | ||
217 | data->ep_sys_time = get_clock (); | 223 | data->ep_sys_time = get_clock (); |
218 | 224 | ||
219 | de_ccw->count = sizeof (struct DE_eckd_data); | 225 | de_ccw->count = sizeof (struct DE_eckd_data); |
220 | de_ccw->flags |= CCW_FLAG_SLI; | 226 | de_ccw->flags |= CCW_FLAG_SLI; |
221 | } | 227 | } |
222 | 228 | ||
223 | return; | 229 | return; |
@@ -296,8 +302,8 @@ define_extent(struct ccw1 * ccw, struct DE_eckd_data * data, int trk, | |||
296 | /* check for sequential prestage - enhance cylinder range */ | 302 | /* check for sequential prestage - enhance cylinder range */ |
297 | if (data->attributes.operation == DASD_SEQ_PRESTAGE || | 303 | if (data->attributes.operation == DASD_SEQ_PRESTAGE || |
298 | data->attributes.operation == DASD_SEQ_ACCESS) { | 304 | data->attributes.operation == DASD_SEQ_ACCESS) { |
299 | 305 | ||
300 | if (end.cyl + private->attrib.nr_cyl < geo.cyl) | 306 | if (end.cyl + private->attrib.nr_cyl < geo.cyl) |
301 | end.cyl += private->attrib.nr_cyl; | 307 | end.cyl += private->attrib.nr_cyl; |
302 | else | 308 | else |
303 | end.cyl = (geo.cyl - 1); | 309 | end.cyl = (geo.cyl - 1); |
@@ -317,7 +323,7 @@ locate_record(struct ccw1 *ccw, struct LO_eckd_data *data, int trk, | |||
317 | struct dasd_eckd_private *private; | 323 | struct dasd_eckd_private *private; |
318 | int sector; | 324 | int sector; |
319 | int dn, d; | 325 | int dn, d; |
320 | 326 | ||
321 | private = (struct dasd_eckd_private *) device->private; | 327 | private = (struct dasd_eckd_private *) device->private; |
322 | 328 | ||
323 | DBF_DEV_EVENT(DBF_INFO, device, | 329 | DBF_DEV_EVENT(DBF_INFO, device, |
@@ -541,6 +547,86 @@ dasd_eckd_read_conf(struct dasd_device *device) | |||
541 | } | 547 | } |
542 | 548 | ||
543 | /* | 549 | /* |
550 | * Build CP for Perform Subsystem Function - SSC. | ||
551 | */ | ||
552 | struct dasd_ccw_req * | ||
553 | dasd_eckd_build_psf_ssc(struct dasd_device *device) | ||
554 | { | ||
555 | struct dasd_ccw_req *cqr; | ||
556 | struct dasd_psf_ssc_data *psf_ssc_data; | ||
557 | struct ccw1 *ccw; | ||
558 | |||
559 | cqr = dasd_smalloc_request("ECKD", 1 /* PSF */ , | ||
560 | sizeof(struct dasd_psf_ssc_data), | ||
561 | device); | ||
562 | |||
563 | if (IS_ERR(cqr)) { | ||
564 | DEV_MESSAGE(KERN_WARNING, device, "%s", | ||
565 | "Could not allocate PSF-SSC request"); | ||
566 | return cqr; | ||
567 | } | ||
568 | psf_ssc_data = (struct dasd_psf_ssc_data *)cqr->data; | ||
569 | psf_ssc_data->order = PSF_ORDER_SSC; | ||
570 | psf_ssc_data->suborder = 0x08; | ||
571 | |||
572 | ccw = cqr->cpaddr; | ||
573 | ccw->cmd_code = DASD_ECKD_CCW_PSF; | ||
574 | ccw->cda = (__u32)(addr_t)psf_ssc_data; | ||
575 | ccw->count = 66; | ||
576 | |||
577 | cqr->device = device; | ||
578 | cqr->expires = 10*HZ; | ||
579 | cqr->buildclk = get_clock(); | ||
580 | cqr->status = DASD_CQR_FILLED; | ||
581 | return cqr; | ||
582 | } | ||
583 | |||
584 | /* | ||
585 | * Perform Subsystem Function. | ||
586 | * It is necessary to trigger CIO for channel revalidation since this | ||
587 | * call might change behaviour of DASD devices. | ||
588 | */ | ||
589 | static int | ||
590 | dasd_eckd_psf_ssc(struct dasd_device *device) | ||
591 | { | ||
592 | struct dasd_ccw_req *cqr; | ||
593 | int rc; | ||
594 | |||
595 | cqr = dasd_eckd_build_psf_ssc(device); | ||
596 | if (IS_ERR(cqr)) | ||
597 | return PTR_ERR(cqr); | ||
598 | |||
599 | rc = dasd_sleep_on(cqr); | ||
600 | if (!rc) | ||
601 | /* trigger CIO to reprobe devices */ | ||
602 | css_schedule_reprobe(); | ||
603 | dasd_sfree_request(cqr, cqr->device); | ||
604 | return rc; | ||
605 | } | ||
606 | |||
607 | /* | ||
608 | * Valide storage server of current device. | ||
609 | */ | ||
610 | static int | ||
611 | dasd_eckd_validate_server(struct dasd_device *device) | ||
612 | { | ||
613 | int rc; | ||
614 | |||
615 | /* Currently PAV is the only reason to 'validate' server on LPAR */ | ||
616 | if (dasd_nopav || MACHINE_IS_VM) | ||
617 | return 0; | ||
618 | |||
619 | rc = dasd_eckd_psf_ssc(device); | ||
620 | if (rc) | ||
621 | /* may be requested feature is not available on server, | ||
622 | * therefore just report error and go ahead */ | ||
623 | DEV_MESSAGE(KERN_INFO, device, | ||
624 | "Perform Subsystem Function returned rc=%d", rc); | ||
625 | /* RE-Read Configuration Data */ | ||
626 | return dasd_eckd_read_conf(device); | ||
627 | } | ||
628 | |||
629 | /* | ||
544 | * Check device characteristics. | 630 | * Check device characteristics. |
545 | * If the device is accessible using ECKD discipline, the device is enabled. | 631 | * If the device is accessible using ECKD discipline, the device is enabled. |
546 | */ | 632 | */ |
@@ -554,7 +640,7 @@ dasd_eckd_check_characteristics(struct dasd_device *device) | |||
554 | 640 | ||
555 | private = (struct dasd_eckd_private *) device->private; | 641 | private = (struct dasd_eckd_private *) device->private; |
556 | if (private == NULL) { | 642 | if (private == NULL) { |
557 | private = kmalloc(sizeof(struct dasd_eckd_private), | 643 | private = kzalloc(sizeof(struct dasd_eckd_private), |
558 | GFP_KERNEL | GFP_DMA); | 644 | GFP_KERNEL | GFP_DMA); |
559 | if (private == NULL) { | 645 | if (private == NULL) { |
560 | DEV_MESSAGE(KERN_WARNING, device, "%s", | 646 | DEV_MESSAGE(KERN_WARNING, device, "%s", |
@@ -562,7 +648,6 @@ dasd_eckd_check_characteristics(struct dasd_device *device) | |||
562 | "data"); | 648 | "data"); |
563 | return -ENOMEM; | 649 | return -ENOMEM; |
564 | } | 650 | } |
565 | memset(private, 0, sizeof(struct dasd_eckd_private)); | ||
566 | device->private = (void *) private; | 651 | device->private = (void *) private; |
567 | } | 652 | } |
568 | /* Invalidate status of initial analysis. */ | 653 | /* Invalidate status of initial analysis. */ |
@@ -571,16 +656,29 @@ dasd_eckd_check_characteristics(struct dasd_device *device) | |||
571 | private->attrib.operation = DASD_NORMAL_CACHE; | 656 | private->attrib.operation = DASD_NORMAL_CACHE; |
572 | private->attrib.nr_cyl = 0; | 657 | private->attrib.nr_cyl = 0; |
573 | 658 | ||
659 | /* Read Configuration Data */ | ||
660 | rc = dasd_eckd_read_conf(device); | ||
661 | if (rc) | ||
662 | return rc; | ||
663 | |||
664 | /* Generate device unique id and register in devmap */ | ||
665 | rc = dasd_eckd_generate_uid(device, &uid); | ||
666 | if (rc) | ||
667 | return rc; | ||
668 | rc = dasd_set_uid(device->cdev, &uid); | ||
669 | if (rc == 1) /* new server found */ | ||
670 | rc = dasd_eckd_validate_server(device); | ||
671 | if (rc) | ||
672 | return rc; | ||
673 | |||
574 | /* Read Device Characteristics */ | 674 | /* Read Device Characteristics */ |
575 | rdc_data = (void *) &(private->rdc_data); | 675 | rdc_data = (void *) &(private->rdc_data); |
576 | memset(rdc_data, 0, sizeof(rdc_data)); | 676 | memset(rdc_data, 0, sizeof(rdc_data)); |
577 | rc = read_dev_chars(device->cdev, &rdc_data, 64); | 677 | rc = read_dev_chars(device->cdev, &rdc_data, 64); |
578 | if (rc) { | 678 | if (rc) |
579 | DEV_MESSAGE(KERN_WARNING, device, | 679 | DEV_MESSAGE(KERN_WARNING, device, |
580 | "Read device characteristics returned error %d", | 680 | "Read device characteristics returned " |
581 | rc); | 681 | "rc=%d", rc); |
582 | return rc; | ||
583 | } | ||
584 | 682 | ||
585 | DEV_MESSAGE(KERN_INFO, device, | 683 | DEV_MESSAGE(KERN_INFO, device, |
586 | "%04X/%02X(CU:%04X/%02X) Cyl:%d Head:%d Sec:%d", | 684 | "%04X/%02X(CU:%04X/%02X) Cyl:%d Head:%d Sec:%d", |
@@ -591,19 +689,6 @@ dasd_eckd_check_characteristics(struct dasd_device *device) | |||
591 | private->rdc_data.no_cyl, | 689 | private->rdc_data.no_cyl, |
592 | private->rdc_data.trk_per_cyl, | 690 | private->rdc_data.trk_per_cyl, |
593 | private->rdc_data.sec_per_trk); | 691 | private->rdc_data.sec_per_trk); |
594 | |||
595 | /* Read Configuration Data */ | ||
596 | rc = dasd_eckd_read_conf (device); | ||
597 | if (rc) | ||
598 | return rc; | ||
599 | |||
600 | /* Generate device unique id and register in devmap */ | ||
601 | rc = dasd_eckd_generate_uid(device, &uid); | ||
602 | if (rc) | ||
603 | return rc; | ||
604 | |||
605 | rc = dasd_set_uid(device->cdev, &uid); | ||
606 | |||
607 | return rc; | 692 | return rc; |
608 | } | 693 | } |
609 | 694 | ||
@@ -773,7 +858,7 @@ dasd_eckd_end_analysis(struct dasd_device *device) | |||
773 | ((private->rdc_data.no_cyl * | 858 | ((private->rdc_data.no_cyl * |
774 | private->rdc_data.trk_per_cyl * | 859 | private->rdc_data.trk_per_cyl * |
775 | blk_per_trk * (device->bp_block >> 9)) >> 1), | 860 | blk_per_trk * (device->bp_block >> 9)) >> 1), |
776 | ((blk_per_trk * device->bp_block) >> 10), | 861 | ((blk_per_trk * device->bp_block) >> 10), |
777 | private->uses_cdl ? | 862 | private->uses_cdl ? |
778 | "compatible disk layout" : "linux disk layout"); | 863 | "compatible disk layout" : "linux disk layout"); |
779 | 864 | ||
@@ -970,7 +1055,7 @@ dasd_eckd_format_device(struct dasd_device * device, | |||
970 | if (i < 3) { | 1055 | if (i < 3) { |
971 | ect->kl = 4; | 1056 | ect->kl = 4; |
972 | ect->dl = sizes_trk0[i] - 4; | 1057 | ect->dl = sizes_trk0[i] - 4; |
973 | } | 1058 | } |
974 | } | 1059 | } |
975 | if ((fdata->intensity & 0x08) && | 1060 | if ((fdata->intensity & 0x08) && |
976 | fdata->start_unit == 1) { | 1061 | fdata->start_unit == 1) { |
@@ -1270,7 +1355,7 @@ dasd_eckd_fill_info(struct dasd_device * device, | |||
1270 | 1355 | ||
1271 | /* | 1356 | /* |
1272 | * Release device ioctl. | 1357 | * Release device ioctl. |
1273 | * Buils a channel programm to releases a prior reserved | 1358 | * Buils a channel programm to releases a prior reserved |
1274 | * (see dasd_eckd_reserve) device. | 1359 | * (see dasd_eckd_reserve) device. |
1275 | */ | 1360 | */ |
1276 | static int | 1361 | static int |
@@ -1310,8 +1395,8 @@ dasd_eckd_release(struct dasd_device *device) | |||
1310 | /* | 1395 | /* |
1311 | * Reserve device ioctl. | 1396 | * Reserve device ioctl. |
1312 | * Options are set to 'synchronous wait for interrupt' and | 1397 | * Options are set to 'synchronous wait for interrupt' and |
1313 | * 'timeout the request'. This leads to a terminate IO if | 1398 | * 'timeout the request'. This leads to a terminate IO if |
1314 | * the interrupt is outstanding for a certain time. | 1399 | * the interrupt is outstanding for a certain time. |
1315 | */ | 1400 | */ |
1316 | static int | 1401 | static int |
1317 | dasd_eckd_reserve(struct dasd_device *device) | 1402 | dasd_eckd_reserve(struct dasd_device *device) |
@@ -1349,7 +1434,7 @@ dasd_eckd_reserve(struct dasd_device *device) | |||
1349 | 1434 | ||
1350 | /* | 1435 | /* |
1351 | * Steal lock ioctl - unconditional reserve device. | 1436 | * Steal lock ioctl - unconditional reserve device. |
1352 | * Buils a channel programm to break a device's reservation. | 1437 | * Buils a channel programm to break a device's reservation. |
1353 | * (unconditional reserve) | 1438 | * (unconditional reserve) |
1354 | */ | 1439 | */ |
1355 | static int | 1440 | static int |
@@ -1522,6 +1607,40 @@ dasd_eckd_ioctl(struct dasd_device *device, unsigned int cmd, void __user *argp) | |||
1522 | } | 1607 | } |
1523 | 1608 | ||
1524 | /* | 1609 | /* |
1610 | * Dump the range of CCWs into 'page' buffer | ||
1611 | * and return number of printed chars. | ||
1612 | */ | ||
1613 | static inline int | ||
1614 | dasd_eckd_dump_ccw_range(struct ccw1 *from, struct ccw1 *to, char *page) | ||
1615 | { | ||
1616 | int len, count; | ||
1617 | char *datap; | ||
1618 | |||
1619 | len = 0; | ||
1620 | while (from <= to) { | ||
1621 | len += sprintf(page + len, KERN_ERR PRINTK_HEADER | ||
1622 | " CCW %p: %08X %08X DAT:", | ||
1623 | from, ((int *) from)[0], ((int *) from)[1]); | ||
1624 | |||
1625 | /* get pointer to data (consider IDALs) */ | ||
1626 | if (from->flags & CCW_FLAG_IDA) | ||
1627 | datap = (char *) *((addr_t *) (addr_t) from->cda); | ||
1628 | else | ||
1629 | datap = (char *) ((addr_t) from->cda); | ||
1630 | |||
1631 | /* dump data (max 32 bytes) */ | ||
1632 | for (count = 0; count < from->count && count < 32; count++) { | ||
1633 | if (count % 8 == 0) len += sprintf(page + len, " "); | ||
1634 | if (count % 4 == 0) len += sprintf(page + len, " "); | ||
1635 | len += sprintf(page + len, "%02x", datap[count]); | ||
1636 | } | ||
1637 | len += sprintf(page + len, "\n"); | ||
1638 | from++; | ||
1639 | } | ||
1640 | return len; | ||
1641 | } | ||
1642 | |||
1643 | /* | ||
1525 | * Print sense data and related channel program. | 1644 | * Print sense data and related channel program. |
1526 | * Parts are printed because printk buffer is only 1024 bytes. | 1645 | * Parts are printed because printk buffer is only 1024 bytes. |
1527 | */ | 1646 | */ |
@@ -1530,8 +1649,8 @@ dasd_eckd_dump_sense(struct dasd_device *device, struct dasd_ccw_req * req, | |||
1530 | struct irb *irb) | 1649 | struct irb *irb) |
1531 | { | 1650 | { |
1532 | char *page; | 1651 | char *page; |
1533 | struct ccw1 *act, *end, *last; | 1652 | struct ccw1 *first, *last, *fail, *from, *to; |
1534 | int len, sl, sct, count; | 1653 | int len, sl, sct; |
1535 | 1654 | ||
1536 | page = (char *) get_zeroed_page(GFP_ATOMIC); | 1655 | page = (char *) get_zeroed_page(GFP_ATOMIC); |
1537 | if (page == NULL) { | 1656 | if (page == NULL) { |
@@ -1539,7 +1658,8 @@ dasd_eckd_dump_sense(struct dasd_device *device, struct dasd_ccw_req * req, | |||
1539 | "No memory to dump sense data"); | 1658 | "No memory to dump sense data"); |
1540 | return; | 1659 | return; |
1541 | } | 1660 | } |
1542 | len = sprintf(page, KERN_ERR PRINTK_HEADER | 1661 | /* dump the sense data */ |
1662 | len = sprintf(page, KERN_ERR PRINTK_HEADER | ||
1543 | " I/O status report for device %s:\n", | 1663 | " I/O status report for device %s:\n", |
1544 | device->cdev->dev.bus_id); | 1664 | device->cdev->dev.bus_id); |
1545 | len += sprintf(page + len, KERN_ERR PRINTK_HEADER | 1665 | len += sprintf(page + len, KERN_ERR PRINTK_HEADER |
@@ -1564,87 +1684,55 @@ dasd_eckd_dump_sense(struct dasd_device *device, struct dasd_ccw_req * req, | |||
1564 | 1684 | ||
1565 | if (irb->ecw[27] & DASD_SENSE_BIT_0) { | 1685 | if (irb->ecw[27] & DASD_SENSE_BIT_0) { |
1566 | /* 24 Byte Sense Data */ | 1686 | /* 24 Byte Sense Data */ |
1567 | len += sprintf(page + len, KERN_ERR PRINTK_HEADER | 1687 | sprintf(page + len, KERN_ERR PRINTK_HEADER |
1568 | " 24 Byte: %x MSG %x, " | 1688 | " 24 Byte: %x MSG %x, " |
1569 | "%s MSGb to SYSOP\n", | 1689 | "%s MSGb to SYSOP\n", |
1570 | irb->ecw[7] >> 4, irb->ecw[7] & 0x0f, | 1690 | irb->ecw[7] >> 4, irb->ecw[7] & 0x0f, |
1571 | irb->ecw[1] & 0x10 ? "" : "no"); | 1691 | irb->ecw[1] & 0x10 ? "" : "no"); |
1572 | } else { | 1692 | } else { |
1573 | /* 32 Byte Sense Data */ | 1693 | /* 32 Byte Sense Data */ |
1574 | len += sprintf(page + len, KERN_ERR PRINTK_HEADER | 1694 | sprintf(page + len, KERN_ERR PRINTK_HEADER |
1575 | " 32 Byte: Format: %x " | 1695 | " 32 Byte: Format: %x " |
1576 | "Exception class %x\n", | 1696 | "Exception class %x\n", |
1577 | irb->ecw[6] & 0x0f, irb->ecw[22] >> 4); | 1697 | irb->ecw[6] & 0x0f, irb->ecw[22] >> 4); |
1578 | } | 1698 | } |
1579 | } else { | 1699 | } else { |
1580 | len += sprintf(page + len, KERN_ERR PRINTK_HEADER | 1700 | sprintf(page + len, KERN_ERR PRINTK_HEADER |
1581 | " SORRY - NO VALID SENSE AVAILABLE\n"); | 1701 | " SORRY - NO VALID SENSE AVAILABLE\n"); |
1582 | } | 1702 | } |
1583 | MESSAGE_LOG(KERN_ERR, "%s", | 1703 | printk("%s", page); |
1584 | page + sizeof(KERN_ERR PRINTK_HEADER)); | 1704 | |
1585 | 1705 | /* dump the Channel Program (max 140 Bytes per line) */ | |
1586 | /* dump the Channel Program */ | 1706 | /* Count CCW and print first CCWs (maximum 1024 % 140 = 7) */ |
1587 | /* print first CCWs (maximum 8) */ | 1707 | first = req->cpaddr; |
1588 | act = req->cpaddr; | 1708 | for (last = first; last->flags & (CCW_FLAG_CC | CCW_FLAG_DC); last++); |
1589 | for (last = act; last->flags & (CCW_FLAG_CC | CCW_FLAG_DC); last++); | 1709 | to = min(first + 6, last); |
1590 | end = min(act + 8, last); | 1710 | len = sprintf(page, KERN_ERR PRINTK_HEADER |
1591 | len = sprintf(page, KERN_ERR PRINTK_HEADER | ||
1592 | " Related CP in req: %p\n", req); | 1711 | " Related CP in req: %p\n", req); |
1593 | while (act <= end) { | 1712 | dasd_eckd_dump_ccw_range(first, to, page + len); |
1594 | len += sprintf(page + len, KERN_ERR PRINTK_HEADER | 1713 | printk("%s", page); |
1595 | " CCW %p: %08X %08X DAT:", | ||
1596 | act, ((int *) act)[0], ((int *) act)[1]); | ||
1597 | for (count = 0; count < 32 && count < act->count; | ||
1598 | count += sizeof(int)) | ||
1599 | len += sprintf(page + len, " %08X", | ||
1600 | ((int *) (addr_t) act->cda) | ||
1601 | [(count>>2)]); | ||
1602 | len += sprintf(page + len, "\n"); | ||
1603 | act++; | ||
1604 | } | ||
1605 | MESSAGE_LOG(KERN_ERR, "%s", | ||
1606 | page + sizeof(KERN_ERR PRINTK_HEADER)); | ||
1607 | 1714 | ||
1608 | /* print failing CCW area */ | 1715 | /* print failing CCW area (maximum 4) */ |
1716 | /* scsw->cda is either valid or zero */ | ||
1609 | len = 0; | 1717 | len = 0; |
1610 | if (act < ((struct ccw1 *)(addr_t) irb->scsw.cpa) - 2) { | 1718 | from = ++to; |
1611 | act = ((struct ccw1 *)(addr_t) irb->scsw.cpa) - 2; | 1719 | fail = (struct ccw1 *)(addr_t) irb->scsw.cpa; /* failing CCW */ |
1612 | len += sprintf(page + len, KERN_ERR PRINTK_HEADER "......\n"); | 1720 | if (from < fail - 2) { |
1613 | } | 1721 | from = fail - 2; /* there is a gap - print header */ |
1614 | end = min((struct ccw1 *)(addr_t) irb->scsw.cpa + 2, last); | 1722 | len += sprintf(page, KERN_ERR PRINTK_HEADER "......\n"); |
1615 | while (act <= end) { | ||
1616 | len += sprintf(page + len, KERN_ERR PRINTK_HEADER | ||
1617 | " CCW %p: %08X %08X DAT:", | ||
1618 | act, ((int *) act)[0], ((int *) act)[1]); | ||
1619 | for (count = 0; count < 32 && count < act->count; | ||
1620 | count += sizeof(int)) | ||
1621 | len += sprintf(page + len, " %08X", | ||
1622 | ((int *) (addr_t) act->cda) | ||
1623 | [(count>>2)]); | ||
1624 | len += sprintf(page + len, "\n"); | ||
1625 | act++; | ||
1626 | } | 1723 | } |
1724 | to = min(fail + 1, last); | ||
1725 | len += dasd_eckd_dump_ccw_range(from, to, page + len); | ||
1627 | 1726 | ||
1628 | /* print last CCWs */ | 1727 | /* print last CCWs (maximum 2) */ |
1629 | if (act < last - 2) { | 1728 | from = max(from, ++to); |
1630 | act = last - 2; | 1729 | if (from < last - 1) { |
1730 | from = last - 1; /* there is a gap - print header */ | ||
1631 | len += sprintf(page + len, KERN_ERR PRINTK_HEADER "......\n"); | 1731 | len += sprintf(page + len, KERN_ERR PRINTK_HEADER "......\n"); |
1632 | } | 1732 | } |
1633 | while (act <= last) { | 1733 | len += dasd_eckd_dump_ccw_range(from, last, page + len); |
1634 | len += sprintf(page + len, KERN_ERR PRINTK_HEADER | ||
1635 | " CCW %p: %08X %08X DAT:", | ||
1636 | act, ((int *) act)[0], ((int *) act)[1]); | ||
1637 | for (count = 0; count < 32 && count < act->count; | ||
1638 | count += sizeof(int)) | ||
1639 | len += sprintf(page + len, " %08X", | ||
1640 | ((int *) (addr_t) act->cda) | ||
1641 | [(count>>2)]); | ||
1642 | len += sprintf(page + len, "\n"); | ||
1643 | act++; | ||
1644 | } | ||
1645 | if (len > 0) | 1734 | if (len > 0) |
1646 | MESSAGE_LOG(KERN_ERR, "%s", | 1735 | printk("%s", page); |
1647 | page + sizeof(KERN_ERR PRINTK_HEADER)); | ||
1648 | free_page((unsigned long) page); | 1736 | free_page((unsigned long) page); |
1649 | } | 1737 | } |
1650 | 1738 | ||
@@ -1685,14 +1773,8 @@ static struct dasd_discipline dasd_eckd_discipline = { | |||
1685 | static int __init | 1773 | static int __init |
1686 | dasd_eckd_init(void) | 1774 | dasd_eckd_init(void) |
1687 | { | 1775 | { |
1688 | int ret; | ||
1689 | |||
1690 | ASCEBC(dasd_eckd_discipline.ebcname, 4); | 1776 | ASCEBC(dasd_eckd_discipline.ebcname, 4); |
1691 | 1777 | return ccw_driver_register(&dasd_eckd_driver); | |
1692 | ret = ccw_driver_register(&dasd_eckd_driver); | ||
1693 | if (!ret) | ||
1694 | dasd_generic_auto_online(&dasd_eckd_driver); | ||
1695 | return ret; | ||
1696 | } | 1778 | } |
1697 | 1779 | ||
1698 | static void __exit | 1780 | static void __exit |
@@ -1703,22 +1785,3 @@ dasd_eckd_cleanup(void) | |||
1703 | 1785 | ||
1704 | module_init(dasd_eckd_init); | 1786 | module_init(dasd_eckd_init); |
1705 | module_exit(dasd_eckd_cleanup); | 1787 | module_exit(dasd_eckd_cleanup); |
1706 | |||
1707 | /* | ||
1708 | * Overrides for Emacs so that we follow Linus's tabbing style. | ||
1709 | * Emacs will notice this stuff at the end of the file and automatically | ||
1710 | * adjust the settings for this buffer only. This must remain at the end | ||
1711 | * of the file. | ||
1712 | * --------------------------------------------------------------------------- | ||
1713 | * Local variables: | ||
1714 | * c-indent-level: 4 | ||
1715 | * c-brace-imaginary-offset: 0 | ||
1716 | * c-brace-offset: -4 | ||
1717 | * c-argdecl-indent: 4 | ||
1718 | * c-label-offset: -4 | ||
1719 | * c-continued-statement-offset: 4 | ||
1720 | * c-continued-brace-offset: 0 | ||
1721 | * indent-tabs-mode: 1 | ||
1722 | * tab-width: 8 | ||
1723 | * End: | ||
1724 | */ | ||
diff --git a/drivers/s390/block/dasd_eckd.h b/drivers/s390/block/dasd_eckd.h index d5734e976e1c..712ff1650134 100644 --- a/drivers/s390/block/dasd_eckd.h +++ b/drivers/s390/block/dasd_eckd.h | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * File...........: linux/drivers/s390/block/dasd_eckd.h | 2 | * File...........: linux/drivers/s390/block/dasd_eckd.h |
3 | * Author(s)......: Holger Smolinski <Holger.Smolinski@de.ibm.com> | 3 | * Author(s)......: Holger Smolinski <Holger.Smolinski@de.ibm.com> |
4 | * Horst Hummel <Horst.Hummel@de.ibm.com> | 4 | * Horst Hummel <Horst.Hummel@de.ibm.com> |
5 | * Bugreports.to..: <Linux390@de.ibm.com> | 5 | * Bugreports.to..: <Linux390@de.ibm.com> |
6 | * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999,2000 | 6 | * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999,2000 |
7 | * | 7 | * |
@@ -41,9 +41,10 @@ | |||
41 | #define DASD_ECKD_CCW_RESERVE 0xB4 | 41 | #define DASD_ECKD_CCW_RESERVE 0xB4 |
42 | 42 | ||
43 | /* | 43 | /* |
44 | *Perform Subsystem Function / Sub-Orders | 44 | * Perform Subsystem Function / Sub-Orders |
45 | */ | 45 | */ |
46 | #define PSF_ORDER_PRSSD 0x18 | 46 | #define PSF_ORDER_PRSSD 0x18 |
47 | #define PSF_ORDER_SSC 0x1D | ||
47 | 48 | ||
48 | /***************************************************************************** | 49 | /***************************************************************************** |
49 | * SECTION: Type Definitions | 50 | * SECTION: Type Definitions |
@@ -155,7 +156,7 @@ struct dasd_eckd_characteristics { | |||
155 | unsigned char reserved2:4; | 156 | unsigned char reserved2:4; |
156 | unsigned char reserved3:8; | 157 | unsigned char reserved3:8; |
157 | unsigned char defect_wr:1; | 158 | unsigned char defect_wr:1; |
158 | unsigned char XRC_supported:1; | 159 | unsigned char XRC_supported:1; |
159 | unsigned char reserved4:1; | 160 | unsigned char reserved4:1; |
160 | unsigned char striping:1; | 161 | unsigned char striping:1; |
161 | unsigned char reserved5:4; | 162 | unsigned char reserved5:4; |
@@ -343,7 +344,7 @@ struct dasd_eckd_path { | |||
343 | }; | 344 | }; |
344 | 345 | ||
345 | /* | 346 | /* |
346 | * Perform Subsystem Function - Prepare for Read Subsystem Data | 347 | * Perform Subsystem Function - Prepare for Read Subsystem Data |
347 | */ | 348 | */ |
348 | struct dasd_psf_prssd_data { | 349 | struct dasd_psf_prssd_data { |
349 | unsigned char order; | 350 | unsigned char order; |
@@ -353,4 +354,15 @@ struct dasd_psf_prssd_data { | |||
353 | unsigned char varies[9]; | 354 | unsigned char varies[9]; |
354 | } __attribute__ ((packed)); | 355 | } __attribute__ ((packed)); |
355 | 356 | ||
357 | /* | ||
358 | * Perform Subsystem Function - Set Subsystem Characteristics | ||
359 | */ | ||
360 | struct dasd_psf_ssc_data { | ||
361 | unsigned char order; | ||
362 | unsigned char flags; | ||
363 | unsigned char cu_type[4]; | ||
364 | unsigned char suborder; | ||
365 | unsigned char reserved[59]; | ||
366 | } __attribute__((packed)); | ||
367 | |||
356 | #endif /* DASD_ECKD_H */ | 368 | #endif /* DASD_ECKD_H */ |
diff --git a/drivers/s390/block/dasd_eer.c b/drivers/s390/block/dasd_eer.c index 2d946b6ca074..da65f1b032f5 100644 --- a/drivers/s390/block/dasd_eer.c +++ b/drivers/s390/block/dasd_eer.c | |||
@@ -89,7 +89,7 @@ struct eerbuffer { | |||
89 | }; | 89 | }; |
90 | 90 | ||
91 | static LIST_HEAD(bufferlist); | 91 | static LIST_HEAD(bufferlist); |
92 | static spinlock_t bufferlock = SPIN_LOCK_UNLOCKED; | 92 | static DEFINE_SPINLOCK(bufferlock); |
93 | static DECLARE_WAIT_QUEUE_HEAD(dasd_eer_read_wait_queue); | 93 | static DECLARE_WAIT_QUEUE_HEAD(dasd_eer_read_wait_queue); |
94 | 94 | ||
95 | /* | 95 | /* |
@@ -276,7 +276,7 @@ struct dasd_eer_header { | |||
276 | __u64 tv_sec; | 276 | __u64 tv_sec; |
277 | __u64 tv_usec; | 277 | __u64 tv_usec; |
278 | char busid[DASD_EER_BUSID_SIZE]; | 278 | char busid[DASD_EER_BUSID_SIZE]; |
279 | }; | 279 | } __attribute__ ((packed)); |
280 | 280 | ||
281 | /* | 281 | /* |
282 | * The following function can be used for those triggers that have | 282 | * The following function can be used for those triggers that have |
@@ -521,6 +521,8 @@ static int dasd_eer_open(struct inode *inp, struct file *filp) | |||
521 | unsigned long flags; | 521 | unsigned long flags; |
522 | 522 | ||
523 | eerb = kzalloc(sizeof(struct eerbuffer), GFP_KERNEL); | 523 | eerb = kzalloc(sizeof(struct eerbuffer), GFP_KERNEL); |
524 | if (!eerb) | ||
525 | return -ENOMEM; | ||
524 | eerb->buffer_page_count = eer_pages; | 526 | eerb->buffer_page_count = eer_pages; |
525 | if (eerb->buffer_page_count < 1 || | 527 | if (eerb->buffer_page_count < 1 || |
526 | eerb->buffer_page_count > INT_MAX / PAGE_SIZE) { | 528 | eerb->buffer_page_count > INT_MAX / PAGE_SIZE) { |
diff --git a/drivers/s390/block/dasd_erp.c b/drivers/s390/block/dasd_erp.c index b842377cb0c6..4108d96f6a5a 100644 --- a/drivers/s390/block/dasd_erp.c +++ b/drivers/s390/block/dasd_erp.c | |||
@@ -90,7 +90,7 @@ dasd_default_erp_action(struct dasd_ccw_req * cqr) | |||
90 | 90 | ||
91 | /* just retry - there is nothing to save ... I got no sense data.... */ | 91 | /* just retry - there is nothing to save ... I got no sense data.... */ |
92 | if (cqr->retries > 0) { | 92 | if (cqr->retries > 0) { |
93 | DEV_MESSAGE (KERN_DEBUG, device, | 93 | DEV_MESSAGE (KERN_DEBUG, device, |
94 | "default ERP called (%i retries left)", | 94 | "default ERP called (%i retries left)", |
95 | cqr->retries); | 95 | cqr->retries); |
96 | cqr->lpm = LPM_ANYPATH; | 96 | cqr->lpm = LPM_ANYPATH; |
@@ -155,7 +155,7 @@ dasd_default_erp_postaction(struct dasd_ccw_req * cqr) | |||
155 | 155 | ||
156 | /* | 156 | /* |
157 | * Print the hex dump of the memory used by a request. This includes | 157 | * Print the hex dump of the memory used by a request. This includes |
158 | * all error recovery ccws that have been chained in from of the | 158 | * all error recovery ccws that have been chained in from of the |
159 | * real request. | 159 | * real request. |
160 | */ | 160 | */ |
161 | static inline void | 161 | static inline void |
@@ -227,12 +227,12 @@ dasd_log_ccw(struct dasd_ccw_req * cqr, int caller, __u32 cpa) | |||
227 | /* | 227 | /* |
228 | * Log bytes arround failed CCW but only if we did | 228 | * Log bytes arround failed CCW but only if we did |
229 | * not log the whole CP of the CCW is outside the | 229 | * not log the whole CP of the CCW is outside the |
230 | * logged CP. | 230 | * logged CP. |
231 | */ | 231 | */ |
232 | if (cplength > 40 || | 232 | if (cplength > 40 || |
233 | ((addr_t) cpa < (addr_t) lcqr->cpaddr && | 233 | ((addr_t) cpa < (addr_t) lcqr->cpaddr && |
234 | (addr_t) cpa > (addr_t) (lcqr->cpaddr + cplength + 4))) { | 234 | (addr_t) cpa > (addr_t) (lcqr->cpaddr + cplength + 4))) { |
235 | 235 | ||
236 | DEV_MESSAGE(KERN_ERR, device, | 236 | DEV_MESSAGE(KERN_ERR, device, |
237 | "Failed CCW (%p) (area):", | 237 | "Failed CCW (%p) (area):", |
238 | (void *) (long) cpa); | 238 | (void *) (long) cpa); |
diff --git a/drivers/s390/block/dasd_fba.c b/drivers/s390/block/dasd_fba.c index 91145698f8e9..bb7755b9b19d 100644 --- a/drivers/s390/block/dasd_fba.c +++ b/drivers/s390/block/dasd_fba.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * File...........: linux/drivers/s390/block/dasd_fba.c | 2 | * File...........: linux/drivers/s390/block/dasd_fba.c |
3 | * Author(s)......: Holger Smolinski <Holger.Smolinski@de.ibm.com> | 3 | * Author(s)......: Holger Smolinski <Holger.Smolinski@de.ibm.com> |
4 | * Bugreports.to..: <Linux390@de.ibm.com> | 4 | * Bugreports.to..: <Linux390@de.ibm.com> |
@@ -56,19 +56,13 @@ static struct ccw_driver dasd_fba_driver; /* see below */ | |||
56 | static int | 56 | static int |
57 | dasd_fba_probe(struct ccw_device *cdev) | 57 | dasd_fba_probe(struct ccw_device *cdev) |
58 | { | 58 | { |
59 | int ret; | 59 | return dasd_generic_probe(cdev, &dasd_fba_discipline); |
60 | |||
61 | ret = dasd_generic_probe (cdev, &dasd_fba_discipline); | ||
62 | if (ret) | ||
63 | return ret; | ||
64 | ccw_device_set_options(cdev, CCWDEV_DO_PATHGROUP); | ||
65 | return 0; | ||
66 | } | 60 | } |
67 | 61 | ||
68 | static int | 62 | static int |
69 | dasd_fba_set_online(struct ccw_device *cdev) | 63 | dasd_fba_set_online(struct ccw_device *cdev) |
70 | { | 64 | { |
71 | return dasd_generic_set_online (cdev, &dasd_fba_discipline); | 65 | return dasd_generic_set_online(cdev, &dasd_fba_discipline); |
72 | } | 66 | } |
73 | 67 | ||
74 | static struct ccw_driver dasd_fba_driver = { | 68 | static struct ccw_driver dasd_fba_driver = { |
@@ -125,13 +119,13 @@ static int | |||
125 | dasd_fba_check_characteristics(struct dasd_device *device) | 119 | dasd_fba_check_characteristics(struct dasd_device *device) |
126 | { | 120 | { |
127 | struct dasd_fba_private *private; | 121 | struct dasd_fba_private *private; |
128 | struct ccw_device *cdev = device->cdev; | 122 | struct ccw_device *cdev = device->cdev; |
129 | void *rdc_data; | 123 | void *rdc_data; |
130 | int rc; | 124 | int rc; |
131 | 125 | ||
132 | private = (struct dasd_fba_private *) device->private; | 126 | private = (struct dasd_fba_private *) device->private; |
133 | if (private == NULL) { | 127 | if (private == NULL) { |
134 | private = kmalloc(sizeof(struct dasd_fba_private), GFP_KERNEL); | 128 | private = kzalloc(sizeof(struct dasd_fba_private), GFP_KERNEL); |
135 | if (private == NULL) { | 129 | if (private == NULL) { |
136 | DEV_MESSAGE(KERN_WARNING, device, "%s", | 130 | DEV_MESSAGE(KERN_WARNING, device, "%s", |
137 | "memory allocation failed for private " | 131 | "memory allocation failed for private " |
@@ -204,7 +198,7 @@ dasd_fba_examine_error(struct dasd_ccw_req * cqr, struct irb * irb) | |||
204 | if (irb->scsw.cstat == 0x00 && | 198 | if (irb->scsw.cstat == 0x00 && |
205 | irb->scsw.dstat == (DEV_STAT_CHN_END | DEV_STAT_DEV_END)) | 199 | irb->scsw.dstat == (DEV_STAT_CHN_END | DEV_STAT_DEV_END)) |
206 | return dasd_era_none; | 200 | return dasd_era_none; |
207 | 201 | ||
208 | cdev = device->cdev; | 202 | cdev = device->cdev; |
209 | switch (cdev->id.dev_type) { | 203 | switch (cdev->id.dev_type) { |
210 | case 0x3370: | 204 | case 0x3370: |
@@ -539,7 +533,7 @@ dasd_fba_dump_sense(struct dasd_device *device, struct dasd_ccw_req * req, | |||
539 | * 8192 bytes (=2 pages). For 64 bit one dasd_mchunkt_t structure has | 533 | * 8192 bytes (=2 pages). For 64 bit one dasd_mchunkt_t structure has |
540 | * 24 bytes, the struct dasd_ccw_req has 136 bytes and each block can use | 534 | * 24 bytes, the struct dasd_ccw_req has 136 bytes and each block can use |
541 | * up to 16 bytes (8 for the ccw and 8 for the idal pointer). In | 535 | * up to 16 bytes (8 for the ccw and 8 for the idal pointer). In |
542 | * addition we have one define extent ccw + 16 bytes of data and a | 536 | * addition we have one define extent ccw + 16 bytes of data and a |
543 | * locate record ccw for each block (stupid devices!) + 16 bytes of data. | 537 | * locate record ccw for each block (stupid devices!) + 16 bytes of data. |
544 | * That makes: | 538 | * That makes: |
545 | * (8192 - 24 - 136 - 8 - 16) / 40 = 200.2 blocks at maximum. | 539 | * (8192 - 24 - 136 - 8 - 16) / 40 = 200.2 blocks at maximum. |
@@ -569,16 +563,8 @@ static struct dasd_discipline dasd_fba_discipline = { | |||
569 | static int __init | 563 | static int __init |
570 | dasd_fba_init(void) | 564 | dasd_fba_init(void) |
571 | { | 565 | { |
572 | int ret; | ||
573 | |||
574 | ASCEBC(dasd_fba_discipline.ebcname, 4); | 566 | ASCEBC(dasd_fba_discipline.ebcname, 4); |
575 | 567 | return ccw_driver_register(&dasd_fba_driver); | |
576 | ret = ccw_driver_register(&dasd_fba_driver); | ||
577 | if (ret) | ||
578 | return ret; | ||
579 | |||
580 | dasd_generic_auto_online(&dasd_fba_driver); | ||
581 | return 0; | ||
582 | } | 568 | } |
583 | 569 | ||
584 | static void __exit | 570 | static void __exit |
@@ -589,22 +575,3 @@ dasd_fba_cleanup(void) | |||
589 | 575 | ||
590 | module_init(dasd_fba_init); | 576 | module_init(dasd_fba_init); |
591 | module_exit(dasd_fba_cleanup); | 577 | module_exit(dasd_fba_cleanup); |
592 | |||
593 | /* | ||
594 | * Overrides for Emacs so that we follow Linus's tabbing style. | ||
595 | * Emacs will notice this stuff at the end of the file and automatically | ||
596 | * adjust the settings for this buffer only. This must remain at the end | ||
597 | * of the file. | ||
598 | * --------------------------------------------------------------------------- | ||
599 | * Local variables: | ||
600 | * c-indent-level: 4 | ||
601 | * c-brace-imaginary-offset: 0 | ||
602 | * c-brace-offset: -4 | ||
603 | * c-argdecl-indent: 4 | ||
604 | * c-label-offset: -4 | ||
605 | * c-continued-statement-offset: 4 | ||
606 | * c-continued-brace-offset: 0 | ||
607 | * indent-tabs-mode: 1 | ||
608 | * tab-width: 8 | ||
609 | * End: | ||
610 | */ | ||
diff --git a/drivers/s390/block/dasd_fba.h b/drivers/s390/block/dasd_fba.h index da1fa91fc01d..14c910baa5fe 100644 --- a/drivers/s390/block/dasd_fba.h +++ b/drivers/s390/block/dasd_fba.h | |||
@@ -1,4 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * File...........: linux/drivers/s390/block/dasd_fba.h | 2 | * File...........: linux/drivers/s390/block/dasd_fba.h |
3 | * Author(s)......: Holger Smolinski <Holger.Smolinski@de.ibm.com> | 3 | * Author(s)......: Holger Smolinski <Holger.Smolinski@de.ibm.com> |
4 | * Bugreports.to..: <Linux390@de.ibm.com> | 4 | * Bugreports.to..: <Linux390@de.ibm.com> |
diff --git a/drivers/s390/block/dasd_genhd.c b/drivers/s390/block/dasd_genhd.c index fce2835e7d19..61ffde718a7a 100644 --- a/drivers/s390/block/dasd_genhd.c +++ b/drivers/s390/block/dasd_genhd.c | |||
@@ -68,8 +68,6 @@ dasd_gendisk_alloc(struct dasd_device *device) | |||
68 | } | 68 | } |
69 | len += sprintf(gdp->disk_name + len, "%c", 'a'+(device->devindex%26)); | 69 | len += sprintf(gdp->disk_name + len, "%c", 'a'+(device->devindex%26)); |
70 | 70 | ||
71 | sprintf(gdp->devfs_name, "dasd/%s", device->cdev->dev.bus_id); | ||
72 | |||
73 | if (device->features & DASD_FEATURE_READONLY) | 71 | if (device->features & DASD_FEATURE_READONLY) |
74 | set_disk_ro(gdp, 1); | 72 | set_disk_ro(gdp, 1); |
75 | gdp->private_data = device; | 73 | gdp->private_data = device; |
diff --git a/drivers/s390/block/dasd_int.h b/drivers/s390/block/dasd_int.h index d4b13e300a76..3ccf06d28ba1 100644 --- a/drivers/s390/block/dasd_int.h +++ b/drivers/s390/block/dasd_int.h | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * File...........: linux/drivers/s390/block/dasd_int.h | 2 | * File...........: linux/drivers/s390/block/dasd_int.h |
3 | * Author(s)......: Holger Smolinski <Holger.Smolinski@de.ibm.com> | 3 | * Author(s)......: Holger Smolinski <Holger.Smolinski@de.ibm.com> |
4 | * Horst Hummel <Horst.Hummel@de.ibm.com> | 4 | * Horst Hummel <Horst.Hummel@de.ibm.com> |
5 | * Martin Schwidefsky <schwidefsky@de.ibm.com> | 5 | * Martin Schwidefsky <schwidefsky@de.ibm.com> |
6 | * Bugreports.to..: <Linux390@de.ibm.com> | 6 | * Bugreports.to..: <Linux390@de.ibm.com> |
7 | * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999,2000 | 7 | * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999,2000 |
@@ -54,7 +54,6 @@ | |||
54 | #include <linux/module.h> | 54 | #include <linux/module.h> |
55 | #include <linux/wait.h> | 55 | #include <linux/wait.h> |
56 | #include <linux/blkdev.h> | 56 | #include <linux/blkdev.h> |
57 | #include <linux/devfs_fs_kernel.h> | ||
58 | #include <linux/genhd.h> | 57 | #include <linux/genhd.h> |
59 | #include <linux/hdreg.h> | 58 | #include <linux/hdreg.h> |
60 | #include <linux/interrupt.h> | 59 | #include <linux/interrupt.h> |
@@ -186,7 +185,7 @@ struct dasd_ccw_req { | |||
186 | void *callback_data; | 185 | void *callback_data; |
187 | }; | 186 | }; |
188 | 187 | ||
189 | /* | 188 | /* |
190 | * dasd_ccw_req -> status can be: | 189 | * dasd_ccw_req -> status can be: |
191 | */ | 190 | */ |
192 | #define DASD_CQR_FILLED 0x00 /* request is ready to be processed */ | 191 | #define DASD_CQR_FILLED 0x00 /* request is ready to be processed */ |
@@ -248,7 +247,7 @@ struct dasd_discipline { | |||
248 | /* | 247 | /* |
249 | * Error recovery functions. examine_error() returns a value that | 248 | * Error recovery functions. examine_error() returns a value that |
250 | * indicates what to do for an error condition. If examine_error() | 249 | * indicates what to do for an error condition. If examine_error() |
251 | * returns 'dasd_era_recover' erp_action() is called to create a | 250 | * returns 'dasd_era_recover' erp_action() is called to create a |
252 | * special error recovery ccw. erp_postaction() is called after | 251 | * special error recovery ccw. erp_postaction() is called after |
253 | * an error recovery ccw has finished its execution. dump_sense | 252 | * an error recovery ccw has finished its execution. dump_sense |
254 | * is called for every error condition to print the sense data | 253 | * is called for every error condition to print the sense data |
@@ -302,11 +301,11 @@ struct dasd_device { | |||
302 | spinlock_t request_queue_lock; | 301 | spinlock_t request_queue_lock; |
303 | struct block_device *bdev; | 302 | struct block_device *bdev; |
304 | unsigned int devindex; | 303 | unsigned int devindex; |
305 | unsigned long blocks; /* size of volume in blocks */ | 304 | unsigned long blocks; /* size of volume in blocks */ |
306 | unsigned int bp_block; /* bytes per block */ | 305 | unsigned int bp_block; /* bytes per block */ |
307 | unsigned int s2b_shift; /* log2 (bp_block/512) */ | 306 | unsigned int s2b_shift; /* log2 (bp_block/512) */ |
308 | unsigned long flags; /* per device flags */ | 307 | unsigned long flags; /* per device flags */ |
309 | unsigned short features; /* copy of devmap-features (read-only!) */ | 308 | unsigned short features; /* copy of devmap-features (read-only!) */ |
310 | 309 | ||
311 | /* extended error reporting stuff (eer) */ | 310 | /* extended error reporting stuff (eer) */ |
312 | struct dasd_ccw_req *eer_cqr; | 311 | struct dasd_ccw_req *eer_cqr; |
@@ -513,12 +512,12 @@ void dasd_generic_remove (struct ccw_device *cdev); | |||
513 | int dasd_generic_set_online(struct ccw_device *, struct dasd_discipline *); | 512 | int dasd_generic_set_online(struct ccw_device *, struct dasd_discipline *); |
514 | int dasd_generic_set_offline (struct ccw_device *cdev); | 513 | int dasd_generic_set_offline (struct ccw_device *cdev); |
515 | int dasd_generic_notify(struct ccw_device *, int); | 514 | int dasd_generic_notify(struct ccw_device *, int); |
516 | void dasd_generic_auto_online (struct ccw_driver *); | ||
517 | 515 | ||
518 | /* externals in dasd_devmap.c */ | 516 | /* externals in dasd_devmap.c */ |
519 | extern int dasd_max_devindex; | 517 | extern int dasd_max_devindex; |
520 | extern int dasd_probeonly; | 518 | extern int dasd_probeonly; |
521 | extern int dasd_autodetect; | 519 | extern int dasd_autodetect; |
520 | extern int dasd_nopav; | ||
522 | 521 | ||
523 | int dasd_devmap_init(void); | 522 | int dasd_devmap_init(void); |
524 | void dasd_devmap_exit(void); | 523 | void dasd_devmap_exit(void); |
@@ -606,22 +605,3 @@ static inline int dasd_eer_enabled(struct dasd_device *device) | |||
606 | #endif /* __KERNEL__ */ | 605 | #endif /* __KERNEL__ */ |
607 | 606 | ||
608 | #endif /* DASD_H */ | 607 | #endif /* DASD_H */ |
609 | |||
610 | /* | ||
611 | * Overrides for Emacs so that we follow Linus's tabbing style. | ||
612 | * Emacs will notice this stuff at the end of the file and automatically | ||
613 | * adjust the settings for this buffer only. This must remain at the end | ||
614 | * of the file. | ||
615 | * --------------------------------------------------------------------------- | ||
616 | * Local variables: | ||
617 | * c-indent-level: 4 | ||
618 | * c-brace-imaginary-offset: 0 | ||
619 | * c-brace-offset: -4 | ||
620 | * c-argdecl-indent: 4 | ||
621 | * c-label-offset: -4 | ||
622 | * c-continued-statement-offset: 4 | ||
623 | * c-continued-brace-offset: 0 | ||
624 | * indent-tabs-mode: 1 | ||
625 | * tab-width: 8 | ||
626 | * End: | ||
627 | */ | ||
diff --git a/drivers/s390/block/dasd_ioctl.c b/drivers/s390/block/dasd_ioctl.c index b8c80d28df41..302bcd0f28be 100644 --- a/drivers/s390/block/dasd_ioctl.c +++ b/drivers/s390/block/dasd_ioctl.c | |||
@@ -90,10 +90,10 @@ static int | |||
90 | dasd_ioctl_quiesce(struct dasd_device *device) | 90 | dasd_ioctl_quiesce(struct dasd_device *device) |
91 | { | 91 | { |
92 | unsigned long flags; | 92 | unsigned long flags; |
93 | 93 | ||
94 | if (!capable (CAP_SYS_ADMIN)) | 94 | if (!capable (CAP_SYS_ADMIN)) |
95 | return -EACCES; | 95 | return -EACCES; |
96 | 96 | ||
97 | DEV_MESSAGE (KERN_DEBUG, device, "%s", | 97 | DEV_MESSAGE (KERN_DEBUG, device, "%s", |
98 | "Quiesce IO on device"); | 98 | "Quiesce IO on device"); |
99 | spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags); | 99 | spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags); |
@@ -110,13 +110,13 @@ static int | |||
110 | dasd_ioctl_resume(struct dasd_device *device) | 110 | dasd_ioctl_resume(struct dasd_device *device) |
111 | { | 111 | { |
112 | unsigned long flags; | 112 | unsigned long flags; |
113 | 113 | ||
114 | if (!capable (CAP_SYS_ADMIN)) | 114 | if (!capable (CAP_SYS_ADMIN)) |
115 | return -EACCES; | 115 | return -EACCES; |
116 | 116 | ||
117 | DEV_MESSAGE (KERN_DEBUG, device, "%s", | 117 | DEV_MESSAGE (KERN_DEBUG, device, "%s", |
118 | "resume IO on device"); | 118 | "resume IO on device"); |
119 | 119 | ||
120 | spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags); | 120 | spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags); |
121 | device->stopped &= ~DASD_STOPPED_QUIESCE; | 121 | device->stopped &= ~DASD_STOPPED_QUIESCE; |
122 | spin_unlock_irqrestore(get_ccwdev_lock(device->cdev), flags); | 122 | spin_unlock_irqrestore(get_ccwdev_lock(device->cdev), flags); |
@@ -287,7 +287,7 @@ dasd_ioctl_information(struct dasd_device *device, | |||
287 | dasd_info->open_count = atomic_read(&device->open_count); | 287 | dasd_info->open_count = atomic_read(&device->open_count); |
288 | if (!device->bdev) | 288 | if (!device->bdev) |
289 | dasd_info->open_count++; | 289 | dasd_info->open_count++; |
290 | 290 | ||
291 | /* | 291 | /* |
292 | * check if device is really formatted | 292 | * check if device is really formatted |
293 | * LDL / CDL was returned by 'fill_info' | 293 | * LDL / CDL was returned by 'fill_info' |
diff --git a/drivers/s390/block/xpram.c b/drivers/s390/block/xpram.c index 54ecd548c318..4c1e56b9b98d 100644 --- a/drivers/s390/block/xpram.c +++ b/drivers/s390/block/xpram.c | |||
@@ -36,7 +36,6 @@ | |||
36 | #include <linux/hdreg.h> /* HDIO_GETGEO */ | 36 | #include <linux/hdreg.h> /* HDIO_GETGEO */ |
37 | #include <linux/sysdev.h> | 37 | #include <linux/sysdev.h> |
38 | #include <linux/bio.h> | 38 | #include <linux/bio.h> |
39 | #include <linux/devfs_fs_kernel.h> | ||
40 | #include <asm/uaccess.h> | 39 | #include <asm/uaccess.h> |
41 | 40 | ||
42 | #define XPRAM_NAME "xpram" | 41 | #define XPRAM_NAME "xpram" |
@@ -439,8 +438,6 @@ static int __init xpram_setup_blkdev(void) | |||
439 | if (rc < 0) | 438 | if (rc < 0) |
440 | goto out; | 439 | goto out; |
441 | 440 | ||
442 | devfs_mk_dir("slram"); | ||
443 | |||
444 | /* | 441 | /* |
445 | * Assign the other needed values: make request function, sizes and | 442 | * Assign the other needed values: make request function, sizes and |
446 | * hardsect size. All the minor devices feature the same value. | 443 | * hardsect size. All the minor devices feature the same value. |
@@ -469,14 +466,12 @@ static int __init xpram_setup_blkdev(void) | |||
469 | disk->private_data = &xpram_devices[i]; | 466 | disk->private_data = &xpram_devices[i]; |
470 | disk->queue = xpram_queue; | 467 | disk->queue = xpram_queue; |
471 | sprintf(disk->disk_name, "slram%d", i); | 468 | sprintf(disk->disk_name, "slram%d", i); |
472 | sprintf(disk->devfs_name, "slram/%d", i); | ||
473 | set_capacity(disk, xpram_sizes[i] << 1); | 469 | set_capacity(disk, xpram_sizes[i] << 1); |
474 | add_disk(disk); | 470 | add_disk(disk); |
475 | } | 471 | } |
476 | 472 | ||
477 | return 0; | 473 | return 0; |
478 | out_unreg: | 474 | out_unreg: |
479 | devfs_remove("slram"); | ||
480 | unregister_blkdev(XPRAM_MAJOR, XPRAM_NAME); | 475 | unregister_blkdev(XPRAM_MAJOR, XPRAM_NAME); |
481 | out: | 476 | out: |
482 | while (i--) | 477 | while (i--) |
@@ -495,7 +490,6 @@ static void __exit xpram_exit(void) | |||
495 | put_disk(xpram_disks[i]); | 490 | put_disk(xpram_disks[i]); |
496 | } | 491 | } |
497 | unregister_blkdev(XPRAM_MAJOR, XPRAM_NAME); | 492 | unregister_blkdev(XPRAM_MAJOR, XPRAM_NAME); |
498 | devfs_remove("slram"); | ||
499 | blk_cleanup_queue(xpram_queue); | 493 | blk_cleanup_queue(xpram_queue); |
500 | sysdev_unregister(&xpram_sys_device); | 494 | sysdev_unregister(&xpram_sys_device); |
501 | sysdev_class_unregister(&xpram_sysclass); | 495 | sysdev_class_unregister(&xpram_sysclass); |
diff --git a/drivers/s390/char/monreader.c b/drivers/s390/char/monreader.c index fb7bc9e5eebc..a138b1510093 100644 --- a/drivers/s390/char/monreader.c +++ b/drivers/s390/char/monreader.c | |||
@@ -586,7 +586,6 @@ static struct file_operations mon_fops = { | |||
586 | 586 | ||
587 | static struct miscdevice mon_dev = { | 587 | static struct miscdevice mon_dev = { |
588 | .name = "monreader", | 588 | .name = "monreader", |
589 | .devfs_name = "monreader", | ||
590 | .fops = &mon_fops, | 589 | .fops = &mon_fops, |
591 | .minor = MISC_DYNAMIC_MINOR, | 590 | .minor = MISC_DYNAMIC_MINOR, |
592 | }; | 591 | }; |
diff --git a/drivers/s390/char/raw3270.c b/drivers/s390/char/raw3270.c index eecb2afad5c2..3c1314b7391b 100644 --- a/drivers/s390/char/raw3270.c +++ b/drivers/s390/char/raw3270.c | |||
@@ -50,6 +50,9 @@ struct raw3270 { | |||
50 | unsigned char *ascebc; /* ascii -> ebcdic table */ | 50 | unsigned char *ascebc; /* ascii -> ebcdic table */ |
51 | struct class_device *clttydev; /* 3270-class tty device ptr */ | 51 | struct class_device *clttydev; /* 3270-class tty device ptr */ |
52 | struct class_device *cltubdev; /* 3270-class tub device ptr */ | 52 | struct class_device *cltubdev; /* 3270-class tub device ptr */ |
53 | |||
54 | struct raw3270_request init_request; | ||
55 | unsigned char init_data[256]; | ||
53 | }; | 56 | }; |
54 | 57 | ||
55 | /* raw3270->flags */ | 58 | /* raw3270->flags */ |
@@ -484,8 +487,6 @@ struct raw3270_ua { /* Query Reply structure for Usable Area */ | |||
484 | } __attribute__ ((packed)) aua; | 487 | } __attribute__ ((packed)) aua; |
485 | } __attribute__ ((packed)); | 488 | } __attribute__ ((packed)); |
486 | 489 | ||
487 | static unsigned char raw3270_init_data[256]; | ||
488 | static struct raw3270_request raw3270_init_request; | ||
489 | static struct diag210 raw3270_init_diag210; | 490 | static struct diag210 raw3270_init_diag210; |
490 | static DECLARE_MUTEX(raw3270_init_sem); | 491 | static DECLARE_MUTEX(raw3270_init_sem); |
491 | 492 | ||
@@ -644,17 +645,17 @@ __raw3270_size_device(struct raw3270 *rp) | |||
644 | * required (3270 device switched to 'stand-by') and command | 645 | * required (3270 device switched to 'stand-by') and command |
645 | * rejects (old devices that can't do 'read partition'). | 646 | * rejects (old devices that can't do 'read partition'). |
646 | */ | 647 | */ |
647 | memset(&raw3270_init_request, 0, sizeof(raw3270_init_request)); | 648 | memset(&rp->init_request, 0, sizeof(rp->init_request)); |
648 | memset(raw3270_init_data, 0, sizeof(raw3270_init_data)); | 649 | memset(&rp->init_data, 0, 256); |
649 | /* Store 'read partition' data stream to raw3270_init_data */ | 650 | /* Store 'read partition' data stream to init_data */ |
650 | memcpy(raw3270_init_data, wbuf, sizeof(wbuf)); | 651 | memcpy(&rp->init_data, wbuf, sizeof(wbuf)); |
651 | INIT_LIST_HEAD(&raw3270_init_request.list); | 652 | INIT_LIST_HEAD(&rp->init_request.list); |
652 | raw3270_init_request.ccw.cmd_code = TC_WRITESF; | 653 | rp->init_request.ccw.cmd_code = TC_WRITESF; |
653 | raw3270_init_request.ccw.flags = CCW_FLAG_SLI; | 654 | rp->init_request.ccw.flags = CCW_FLAG_SLI; |
654 | raw3270_init_request.ccw.count = sizeof(wbuf); | 655 | rp->init_request.ccw.count = sizeof(wbuf); |
655 | raw3270_init_request.ccw.cda = (__u32) __pa(raw3270_init_data); | 656 | rp->init_request.ccw.cda = (__u32) __pa(&rp->init_data); |
656 | 657 | ||
657 | rc = raw3270_start_init(rp, &raw3270_init_view, &raw3270_init_request); | 658 | rc = raw3270_start_init(rp, &raw3270_init_view, &rp->init_request); |
658 | if (rc) | 659 | if (rc) |
659 | /* Check error cases: -ERESTARTSYS, -EIO and -EOPNOTSUPP */ | 660 | /* Check error cases: -ERESTARTSYS, -EIO and -EOPNOTSUPP */ |
660 | return rc; | 661 | return rc; |
@@ -679,18 +680,18 @@ __raw3270_size_device(struct raw3270 *rp) | |||
679 | * The device accepted the 'read partition' command. Now | 680 | * The device accepted the 'read partition' command. Now |
680 | * set up a read ccw and issue it. | 681 | * set up a read ccw and issue it. |
681 | */ | 682 | */ |
682 | raw3270_init_request.ccw.cmd_code = TC_READMOD; | 683 | rp->init_request.ccw.cmd_code = TC_READMOD; |
683 | raw3270_init_request.ccw.flags = CCW_FLAG_SLI; | 684 | rp->init_request.ccw.flags = CCW_FLAG_SLI; |
684 | raw3270_init_request.ccw.count = sizeof(raw3270_init_data); | 685 | rp->init_request.ccw.count = sizeof(rp->init_data); |
685 | raw3270_init_request.ccw.cda = (__u32) __pa(raw3270_init_data); | 686 | rp->init_request.ccw.cda = (__u32) __pa(rp->init_data); |
686 | rc = raw3270_start_init(rp, &raw3270_init_view, &raw3270_init_request); | 687 | rc = raw3270_start_init(rp, &raw3270_init_view, &rp->init_request); |
687 | if (rc) | 688 | if (rc) |
688 | return rc; | 689 | return rc; |
689 | /* Got a Query Reply */ | 690 | /* Got a Query Reply */ |
690 | count = sizeof(raw3270_init_data) - raw3270_init_request.rescnt; | 691 | count = sizeof(rp->init_data) - rp->init_request.rescnt; |
691 | uap = (struct raw3270_ua *) (raw3270_init_data + 1); | 692 | uap = (struct raw3270_ua *) (rp->init_data + 1); |
692 | /* Paranoia check. */ | 693 | /* Paranoia check. */ |
693 | if (raw3270_init_data[0] != 0x88 || uap->uab.qcode != 0x81) | 694 | if (rp->init_data[0] != 0x88 || uap->uab.qcode != 0x81) |
694 | return -EOPNOTSUPP; | 695 | return -EOPNOTSUPP; |
695 | /* Copy rows/columns of default Usable Area */ | 696 | /* Copy rows/columns of default Usable Area */ |
696 | rp->rows = uap->uab.h; | 697 | rp->rows = uap->uab.h; |
@@ -749,18 +750,18 @@ raw3270_reset_device(struct raw3270 *rp) | |||
749 | int rc; | 750 | int rc; |
750 | 751 | ||
751 | down(&raw3270_init_sem); | 752 | down(&raw3270_init_sem); |
752 | memset(&raw3270_init_request, 0, sizeof(raw3270_init_request)); | 753 | memset(&rp->init_request, 0, sizeof(rp->init_request)); |
753 | memset(raw3270_init_data, 0, sizeof(raw3270_init_data)); | 754 | memset(&rp->init_data, 0, sizeof(rp->init_data)); |
754 | /* Store reset data stream to raw3270_init_data/raw3270_init_request */ | 755 | /* Store reset data stream to init_data/init_request */ |
755 | raw3270_init_data[0] = TW_KR; | 756 | rp->init_data[0] = TW_KR; |
756 | INIT_LIST_HEAD(&raw3270_init_request.list); | 757 | INIT_LIST_HEAD(&rp->init_request.list); |
757 | raw3270_init_request.ccw.cmd_code = TC_EWRITEA; | 758 | rp->init_request.ccw.cmd_code = TC_EWRITEA; |
758 | raw3270_init_request.ccw.flags = CCW_FLAG_SLI; | 759 | rp->init_request.ccw.flags = CCW_FLAG_SLI; |
759 | raw3270_init_request.ccw.count = 1; | 760 | rp->init_request.ccw.count = 1; |
760 | raw3270_init_request.ccw.cda = (__u32) __pa(raw3270_init_data); | 761 | rp->init_request.ccw.cda = (__u32) __pa(rp->init_data); |
761 | rp->view = &raw3270_init_view; | 762 | rp->view = &raw3270_init_view; |
762 | raw3270_init_view.dev = rp; | 763 | raw3270_init_view.dev = rp; |
763 | rc = raw3270_start_init(rp, &raw3270_init_view, &raw3270_init_request); | 764 | rc = raw3270_start_init(rp, &raw3270_init_view, &rp->init_request); |
764 | raw3270_init_view.dev = 0; | 765 | raw3270_init_view.dev = 0; |
765 | rp->view = 0; | 766 | rp->view = 0; |
766 | up(&raw3270_init_sem); | 767 | up(&raw3270_init_sem); |
@@ -854,7 +855,7 @@ raw3270_setup_console(struct ccw_device *cdev) | |||
854 | char *ascebc; | 855 | char *ascebc; |
855 | int rc; | 856 | int rc; |
856 | 857 | ||
857 | rp = (struct raw3270 *) alloc_bootmem(sizeof(struct raw3270)); | 858 | rp = (struct raw3270 *) alloc_bootmem_low(sizeof(struct raw3270)); |
858 | ascebc = (char *) alloc_bootmem(256); | 859 | ascebc = (char *) alloc_bootmem(256); |
859 | rc = raw3270_setup_device(cdev, rp, ascebc); | 860 | rc = raw3270_setup_device(cdev, rp, ascebc); |
860 | if (rc) | 861 | if (rc) |
@@ -895,7 +896,7 @@ raw3270_create_device(struct ccw_device *cdev) | |||
895 | char *ascebc; | 896 | char *ascebc; |
896 | int rc; | 897 | int rc; |
897 | 898 | ||
898 | rp = kmalloc(sizeof(struct raw3270), GFP_KERNEL); | 899 | rp = kmalloc(sizeof(struct raw3270), GFP_KERNEL | GFP_DMA); |
899 | if (!rp) | 900 | if (!rp) |
900 | return ERR_PTR(-ENOMEM); | 901 | return ERR_PTR(-ENOMEM); |
901 | ascebc = kmalloc(256, GFP_KERNEL); | 902 | ascebc = kmalloc(256, GFP_KERNEL); |
diff --git a/drivers/s390/char/tty3270.c b/drivers/s390/char/tty3270.c index 9a141776873f..7d26a3e4cb80 100644 --- a/drivers/s390/char/tty3270.c +++ b/drivers/s390/char/tty3270.c | |||
@@ -1785,7 +1785,6 @@ tty3270_init(void) | |||
1785 | * proc_entry, set_termios, flush_buffer, set_ldisc, write_proc | 1785 | * proc_entry, set_termios, flush_buffer, set_ldisc, write_proc |
1786 | */ | 1786 | */ |
1787 | driver->owner = THIS_MODULE; | 1787 | driver->owner = THIS_MODULE; |
1788 | driver->devfs_name = "ttyTUB/"; | ||
1789 | driver->driver_name = "ttyTUB"; | 1788 | driver->driver_name = "ttyTUB"; |
1790 | driver->name = "ttyTUB"; | 1789 | driver->name = "ttyTUB"; |
1791 | driver->major = IBM_TTY3270_MAJOR; | 1790 | driver->major = IBM_TTY3270_MAJOR; |
@@ -1793,7 +1792,7 @@ tty3270_init(void) | |||
1793 | driver->type = TTY_DRIVER_TYPE_SYSTEM; | 1792 | driver->type = TTY_DRIVER_TYPE_SYSTEM; |
1794 | driver->subtype = SYSTEM_TYPE_TTY; | 1793 | driver->subtype = SYSTEM_TYPE_TTY; |
1795 | driver->init_termios = tty_std_termios; | 1794 | driver->init_termios = tty_std_termios; |
1796 | driver->flags = TTY_DRIVER_RESET_TERMIOS | TTY_DRIVER_NO_DEVFS; | 1795 | driver->flags = TTY_DRIVER_RESET_TERMIOS | TTY_DRIVER_DYNAMIC_DEV; |
1797 | tty_set_operations(driver, &tty3270_ops); | 1796 | tty_set_operations(driver, &tty3270_ops); |
1798 | ret = tty_register_driver(driver); | 1797 | ret = tty_register_driver(driver); |
1799 | if (ret) { | 1798 | if (ret) { |
diff --git a/drivers/s390/cio/blacklist.c b/drivers/s390/cio/blacklist.c index 0960bef7b199..15b895496a45 100644 --- a/drivers/s390/cio/blacklist.c +++ b/drivers/s390/cio/blacklist.c | |||
@@ -224,39 +224,6 @@ is_blacklisted (int ssid, int devno) | |||
224 | } | 224 | } |
225 | 225 | ||
226 | #ifdef CONFIG_PROC_FS | 226 | #ifdef CONFIG_PROC_FS |
227 | static int | ||
228 | __s390_redo_validation(struct subchannel_id schid, void *data) | ||
229 | { | ||
230 | int ret; | ||
231 | struct subchannel *sch; | ||
232 | |||
233 | sch = get_subchannel_by_schid(schid); | ||
234 | if (sch) { | ||
235 | /* Already known. */ | ||
236 | put_device(&sch->dev); | ||
237 | return 0; | ||
238 | } | ||
239 | ret = css_probe_device(schid); | ||
240 | if (ret == -ENXIO) | ||
241 | return ret; /* We're through. */ | ||
242 | if (ret == -ENOMEM) | ||
243 | /* Stop validation for now. Bad, but no need for a panic. */ | ||
244 | return ret; | ||
245 | return 0; | ||
246 | } | ||
247 | |||
248 | /* | ||
249 | * Function: s390_redo_validation | ||
250 | * Look for no longer blacklisted devices | ||
251 | * FIXME: there must be a better way to do this */ | ||
252 | static inline void | ||
253 | s390_redo_validation (void) | ||
254 | { | ||
255 | CIO_TRACE_EVENT (0, "redoval"); | ||
256 | |||
257 | for_each_subchannel(__s390_redo_validation, NULL); | ||
258 | } | ||
259 | |||
260 | /* | 227 | /* |
261 | * Function: blacklist_parse_proc_parameters | 228 | * Function: blacklist_parse_proc_parameters |
262 | * parse the stuff which is piped to /proc/cio_ignore | 229 | * parse the stuff which is piped to /proc/cio_ignore |
@@ -281,7 +248,7 @@ blacklist_parse_proc_parameters (char *buf) | |||
281 | return; | 248 | return; |
282 | } | 249 | } |
283 | 250 | ||
284 | s390_redo_validation (); | 251 | css_schedule_reprobe(); |
285 | } | 252 | } |
286 | 253 | ||
287 | /* Iterator struct for all devices. */ | 254 | /* Iterator struct for all devices. */ |
diff --git a/drivers/s390/cio/ccwgroup.c b/drivers/s390/cio/ccwgroup.c index bdfee7fbaa2e..c7319a07ba35 100644 --- a/drivers/s390/cio/ccwgroup.c +++ b/drivers/s390/cio/ccwgroup.c | |||
@@ -404,21 +404,24 @@ ccwgroup_driver_register (struct ccwgroup_driver *cdriver) | |||
404 | } | 404 | } |
405 | 405 | ||
406 | static int | 406 | static int |
407 | __ccwgroup_driver_unregister_device(struct device *dev, void *data) | 407 | __ccwgroup_match_all(struct device *dev, void *data) |
408 | { | 408 | { |
409 | __ccwgroup_remove_symlinks(to_ccwgroupdev(dev)); | 409 | return 1; |
410 | device_unregister(dev); | ||
411 | put_device(dev); | ||
412 | return 0; | ||
413 | } | 410 | } |
414 | 411 | ||
415 | void | 412 | void |
416 | ccwgroup_driver_unregister (struct ccwgroup_driver *cdriver) | 413 | ccwgroup_driver_unregister (struct ccwgroup_driver *cdriver) |
417 | { | 414 | { |
415 | struct device *dev; | ||
416 | |||
418 | /* We don't want ccwgroup devices to live longer than their driver. */ | 417 | /* We don't want ccwgroup devices to live longer than their driver. */ |
419 | get_driver(&cdriver->driver); | 418 | get_driver(&cdriver->driver); |
420 | driver_for_each_device(&cdriver->driver, NULL, NULL, | 419 | while ((dev = driver_find_device(&cdriver->driver, NULL, NULL, |
421 | __ccwgroup_driver_unregister_device); | 420 | __ccwgroup_match_all))) { |
421 | __ccwgroup_remove_symlinks(to_ccwgroupdev(dev)); | ||
422 | device_unregister(dev); | ||
423 | put_device(dev); | ||
424 | } | ||
422 | put_driver(&cdriver->driver); | 425 | put_driver(&cdriver->driver); |
423 | driver_unregister(&cdriver->driver); | 426 | driver_unregister(&cdriver->driver); |
424 | } | 427 | } |
diff --git a/drivers/s390/cio/chsc.c b/drivers/s390/cio/chsc.c index 72187e54dcac..b00f3ed051a0 100644 --- a/drivers/s390/cio/chsc.c +++ b/drivers/s390/cio/chsc.c | |||
@@ -244,8 +244,7 @@ s390_subchannel_remove_chpid(struct device *dev, void *data) | |||
244 | 244 | ||
245 | if ((sch->schib.scsw.actl & SCSW_ACTL_DEVACT) && | 245 | if ((sch->schib.scsw.actl & SCSW_ACTL_DEVACT) && |
246 | (sch->schib.scsw.actl & SCSW_ACTL_SCHACT) && | 246 | (sch->schib.scsw.actl & SCSW_ACTL_SCHACT) && |
247 | (sch->schib.pmcw.lpum == mask) && | 247 | (sch->schib.pmcw.lpum == mask)) { |
248 | (sch->vpm == 0)) { | ||
249 | int cc; | 248 | int cc; |
250 | 249 | ||
251 | cc = cio_clear(sch); | 250 | cc = cio_clear(sch); |
@@ -918,12 +917,13 @@ chp_measurement_read(struct kobject *kobj, char *buf, loff_t off, size_t count) | |||
918 | chp = to_channelpath(container_of(kobj, struct device, kobj)); | 917 | chp = to_channelpath(container_of(kobj, struct device, kobj)); |
919 | css = to_css(chp->dev.parent); | 918 | css = to_css(chp->dev.parent); |
920 | 919 | ||
921 | size = sizeof(struct cmg_chars); | 920 | size = sizeof(struct cmg_entry); |
922 | 921 | ||
923 | /* Only allow single reads. */ | 922 | /* Only allow single reads. */ |
924 | if (off || count < size) | 923 | if (off || count < size) |
925 | return 0; | 924 | return 0; |
926 | chp_measurement_copy_block((struct cmg_entry *)buf, css, chp->id); | 925 | chp_measurement_copy_block((struct cmg_entry *)buf, css, chp->id); |
926 | count = size; | ||
927 | return count; | 927 | return count; |
928 | } | 928 | } |
929 | 929 | ||
diff --git a/drivers/s390/cio/cmf.c b/drivers/s390/cio/cmf.c index 07ef3f640f4a..1c3e8e9012b0 100644 --- a/drivers/s390/cio/cmf.c +++ b/drivers/s390/cio/cmf.c | |||
@@ -3,9 +3,10 @@ | |||
3 | * | 3 | * |
4 | * Linux on zSeries Channel Measurement Facility support | 4 | * Linux on zSeries Channel Measurement Facility support |
5 | * | 5 | * |
6 | * Copyright 2000,2003 IBM Corporation | 6 | * Copyright 2000,2006 IBM Corporation |
7 | * | 7 | * |
8 | * Author: Arnd Bergmann <arndb@de.ibm.com> | 8 | * Authors: Arnd Bergmann <arndb@de.ibm.com> |
9 | * Cornelia Huck <cornelia.huck@de.ibm.com> | ||
9 | * | 10 | * |
10 | * original idea from Natarajan Krishnaswami <nkrishna@us.ibm.com> | 11 | * original idea from Natarajan Krishnaswami <nkrishna@us.ibm.com> |
11 | * | 12 | * |
@@ -96,9 +97,9 @@ module_param(format, bool, 0444); | |||
96 | /** | 97 | /** |
97 | * struct cmb_operations - functions to use depending on cmb_format | 98 | * struct cmb_operations - functions to use depending on cmb_format |
98 | * | 99 | * |
99 | * all these functions operate on a struct cmf_device. There is only | 100 | * Most of these functions operate on a struct ccw_device. There is only |
100 | * one instance of struct cmb_operations because all cmf_device | 101 | * one instance of struct cmb_operations because the format of the measurement |
101 | * objects are guaranteed to be of the same type. | 102 | * data is guaranteed to be the same for every ccw_device. |
102 | * | 103 | * |
103 | * @alloc: allocate memory for a channel measurement block, | 104 | * @alloc: allocate memory for a channel measurement block, |
104 | * either with the help of a special pool or with kmalloc | 105 | * either with the help of a special pool or with kmalloc |
@@ -107,6 +108,7 @@ module_param(format, bool, 0444); | |||
107 | * @readall: read a measurement block in a common format | 108 | * @readall: read a measurement block in a common format |
108 | * @reset: clear the data in the associated measurement block and | 109 | * @reset: clear the data in the associated measurement block and |
109 | * reset its time stamp | 110 | * reset its time stamp |
111 | * @align: align an allocated block so that the hardware can use it | ||
110 | */ | 112 | */ |
111 | struct cmb_operations { | 113 | struct cmb_operations { |
112 | int (*alloc) (struct ccw_device*); | 114 | int (*alloc) (struct ccw_device*); |
@@ -115,11 +117,19 @@ struct cmb_operations { | |||
115 | u64 (*read) (struct ccw_device*, int); | 117 | u64 (*read) (struct ccw_device*, int); |
116 | int (*readall)(struct ccw_device*, struct cmbdata *); | 118 | int (*readall)(struct ccw_device*, struct cmbdata *); |
117 | void (*reset) (struct ccw_device*); | 119 | void (*reset) (struct ccw_device*); |
120 | void * (*align) (void *); | ||
118 | 121 | ||
119 | struct attribute_group *attr_group; | 122 | struct attribute_group *attr_group; |
120 | }; | 123 | }; |
121 | static struct cmb_operations *cmbops; | 124 | static struct cmb_operations *cmbops; |
122 | 125 | ||
126 | struct cmb_data { | ||
127 | void *hw_block; /* Pointer to block updated by hardware */ | ||
128 | void *last_block; /* Last changed block copied from hardware block */ | ||
129 | int size; /* Size of hw_block and last_block */ | ||
130 | unsigned long long last_update; /* when last_block was updated */ | ||
131 | }; | ||
132 | |||
123 | /* our user interface is designed in terms of nanoseconds, | 133 | /* our user interface is designed in terms of nanoseconds, |
124 | * while the hardware measures total times in its own | 134 | * while the hardware measures total times in its own |
125 | * unit.*/ | 135 | * unit.*/ |
@@ -226,63 +236,229 @@ struct set_schib_struct { | |||
226 | unsigned long address; | 236 | unsigned long address; |
227 | wait_queue_head_t wait; | 237 | wait_queue_head_t wait; |
228 | int ret; | 238 | int ret; |
239 | struct kref kref; | ||
229 | }; | 240 | }; |
230 | 241 | ||
242 | static void cmf_set_schib_release(struct kref *kref) | ||
243 | { | ||
244 | struct set_schib_struct *set_data; | ||
245 | |||
246 | set_data = container_of(kref, struct set_schib_struct, kref); | ||
247 | kfree(set_data); | ||
248 | } | ||
249 | |||
250 | #define CMF_PENDING 1 | ||
251 | |||
231 | static int set_schib_wait(struct ccw_device *cdev, u32 mme, | 252 | static int set_schib_wait(struct ccw_device *cdev, u32 mme, |
232 | int mbfc, unsigned long address) | 253 | int mbfc, unsigned long address) |
233 | { | 254 | { |
234 | struct set_schib_struct s = { | 255 | struct set_schib_struct *set_data; |
235 | .mme = mme, | 256 | int ret; |
236 | .mbfc = mbfc, | ||
237 | .address = address, | ||
238 | .wait = __WAIT_QUEUE_HEAD_INITIALIZER(s.wait), | ||
239 | }; | ||
240 | 257 | ||
241 | spin_lock_irq(cdev->ccwlock); | 258 | spin_lock_irq(cdev->ccwlock); |
242 | s.ret = set_schib(cdev, mme, mbfc, address); | 259 | if (!cdev->private->cmb) { |
243 | if (s.ret != -EBUSY) { | 260 | ret = -ENODEV; |
244 | goto out_nowait; | 261 | goto out; |
245 | } | 262 | } |
263 | set_data = kzalloc(sizeof(struct set_schib_struct), GFP_ATOMIC); | ||
264 | if (!set_data) { | ||
265 | ret = -ENOMEM; | ||
266 | goto out; | ||
267 | } | ||
268 | init_waitqueue_head(&set_data->wait); | ||
269 | kref_init(&set_data->kref); | ||
270 | set_data->mme = mme; | ||
271 | set_data->mbfc = mbfc; | ||
272 | set_data->address = address; | ||
273 | |||
274 | ret = set_schib(cdev, mme, mbfc, address); | ||
275 | if (ret != -EBUSY) | ||
276 | goto out_put; | ||
246 | 277 | ||
247 | if (cdev->private->state != DEV_STATE_ONLINE) { | 278 | if (cdev->private->state != DEV_STATE_ONLINE) { |
248 | s.ret = -EBUSY; | ||
249 | /* if the device is not online, don't even try again */ | 279 | /* if the device is not online, don't even try again */ |
250 | goto out_nowait; | 280 | ret = -EBUSY; |
281 | goto out_put; | ||
251 | } | 282 | } |
283 | |||
252 | cdev->private->state = DEV_STATE_CMFCHANGE; | 284 | cdev->private->state = DEV_STATE_CMFCHANGE; |
253 | cdev->private->cmb_wait = &s; | 285 | set_data->ret = CMF_PENDING; |
254 | s.ret = 1; | 286 | cdev->private->cmb_wait = set_data; |
255 | 287 | ||
256 | spin_unlock_irq(cdev->ccwlock); | 288 | spin_unlock_irq(cdev->ccwlock); |
257 | if (wait_event_interruptible(s.wait, s.ret != 1)) { | 289 | if (wait_event_interruptible(set_data->wait, |
290 | set_data->ret != CMF_PENDING)) { | ||
258 | spin_lock_irq(cdev->ccwlock); | 291 | spin_lock_irq(cdev->ccwlock); |
259 | if (s.ret == 1) { | 292 | if (set_data->ret == CMF_PENDING) { |
260 | s.ret = -ERESTARTSYS; | 293 | set_data->ret = -ERESTARTSYS; |
261 | cdev->private->cmb_wait = 0; | ||
262 | if (cdev->private->state == DEV_STATE_CMFCHANGE) | 294 | if (cdev->private->state == DEV_STATE_CMFCHANGE) |
263 | cdev->private->state = DEV_STATE_ONLINE; | 295 | cdev->private->state = DEV_STATE_ONLINE; |
264 | } | 296 | } |
265 | spin_unlock_irq(cdev->ccwlock); | 297 | spin_unlock_irq(cdev->ccwlock); |
266 | } | 298 | } |
267 | return s.ret; | 299 | spin_lock_irq(cdev->ccwlock); |
268 | 300 | cdev->private->cmb_wait = NULL; | |
269 | out_nowait: | 301 | ret = set_data->ret; |
302 | out_put: | ||
303 | kref_put(&set_data->kref, cmf_set_schib_release); | ||
304 | out: | ||
270 | spin_unlock_irq(cdev->ccwlock); | 305 | spin_unlock_irq(cdev->ccwlock); |
271 | return s.ret; | 306 | return ret; |
272 | } | 307 | } |
273 | 308 | ||
274 | void retry_set_schib(struct ccw_device *cdev) | 309 | void retry_set_schib(struct ccw_device *cdev) |
275 | { | 310 | { |
276 | struct set_schib_struct *s; | 311 | struct set_schib_struct *set_data; |
312 | |||
313 | set_data = cdev->private->cmb_wait; | ||
314 | if (!set_data) { | ||
315 | WARN_ON(1); | ||
316 | return; | ||
317 | } | ||
318 | kref_get(&set_data->kref); | ||
319 | set_data->ret = set_schib(cdev, set_data->mme, set_data->mbfc, | ||
320 | set_data->address); | ||
321 | wake_up(&set_data->wait); | ||
322 | kref_put(&set_data->kref, cmf_set_schib_release); | ||
323 | } | ||
324 | |||
325 | static int cmf_copy_block(struct ccw_device *cdev) | ||
326 | { | ||
327 | struct subchannel *sch; | ||
328 | void *reference_buf; | ||
329 | void *hw_block; | ||
330 | struct cmb_data *cmb_data; | ||
331 | |||
332 | sch = to_subchannel(cdev->dev.parent); | ||
333 | |||
334 | if (stsch(sch->schid, &sch->schib)) | ||
335 | return -ENODEV; | ||
336 | |||
337 | if (sch->schib.scsw.fctl & SCSW_FCTL_START_FUNC) { | ||
338 | /* Don't copy if a start function is in progress. */ | ||
339 | if ((!sch->schib.scsw.actl & SCSW_ACTL_SUSPENDED) && | ||
340 | (sch->schib.scsw.actl & | ||
341 | (SCSW_ACTL_DEVACT | SCSW_ACTL_SCHACT)) && | ||
342 | (!sch->schib.scsw.stctl & SCSW_STCTL_SEC_STATUS)) | ||
343 | return -EBUSY; | ||
344 | } | ||
345 | cmb_data = cdev->private->cmb; | ||
346 | hw_block = cmbops->align(cmb_data->hw_block); | ||
347 | if (!memcmp(cmb_data->last_block, hw_block, cmb_data->size)) | ||
348 | /* No need to copy. */ | ||
349 | return 0; | ||
350 | reference_buf = kzalloc(cmb_data->size, GFP_ATOMIC); | ||
351 | if (!reference_buf) | ||
352 | return -ENOMEM; | ||
353 | /* Ensure consistency of block copied from hardware. */ | ||
354 | do { | ||
355 | memcpy(cmb_data->last_block, hw_block, cmb_data->size); | ||
356 | memcpy(reference_buf, hw_block, cmb_data->size); | ||
357 | } while (memcmp(cmb_data->last_block, reference_buf, cmb_data->size)); | ||
358 | cmb_data->last_update = get_clock(); | ||
359 | kfree(reference_buf); | ||
360 | return 0; | ||
361 | } | ||
362 | |||
363 | struct copy_block_struct { | ||
364 | wait_queue_head_t wait; | ||
365 | int ret; | ||
366 | struct kref kref; | ||
367 | }; | ||
368 | |||
369 | static void cmf_copy_block_release(struct kref *kref) | ||
370 | { | ||
371 | struct copy_block_struct *copy_block; | ||
372 | |||
373 | copy_block = container_of(kref, struct copy_block_struct, kref); | ||
374 | kfree(copy_block); | ||
375 | } | ||
376 | |||
377 | static int cmf_cmb_copy_wait(struct ccw_device *cdev) | ||
378 | { | ||
379 | struct copy_block_struct *copy_block; | ||
380 | int ret; | ||
381 | unsigned long flags; | ||
382 | |||
383 | spin_lock_irqsave(cdev->ccwlock, flags); | ||
384 | if (!cdev->private->cmb) { | ||
385 | ret = -ENODEV; | ||
386 | goto out; | ||
387 | } | ||
388 | copy_block = kzalloc(sizeof(struct copy_block_struct), GFP_ATOMIC); | ||
389 | if (!copy_block) { | ||
390 | ret = -ENOMEM; | ||
391 | goto out; | ||
392 | } | ||
393 | init_waitqueue_head(©_block->wait); | ||
394 | kref_init(©_block->kref); | ||
395 | |||
396 | ret = cmf_copy_block(cdev); | ||
397 | if (ret != -EBUSY) | ||
398 | goto out_put; | ||
399 | |||
400 | if (cdev->private->state != DEV_STATE_ONLINE) { | ||
401 | ret = -EBUSY; | ||
402 | goto out_put; | ||
403 | } | ||
404 | |||
405 | cdev->private->state = DEV_STATE_CMFUPDATE; | ||
406 | copy_block->ret = CMF_PENDING; | ||
407 | cdev->private->cmb_wait = copy_block; | ||
408 | |||
409 | spin_unlock_irqrestore(cdev->ccwlock, flags); | ||
410 | if (wait_event_interruptible(copy_block->wait, | ||
411 | copy_block->ret != CMF_PENDING)) { | ||
412 | spin_lock_irqsave(cdev->ccwlock, flags); | ||
413 | if (copy_block->ret == CMF_PENDING) { | ||
414 | copy_block->ret = -ERESTARTSYS; | ||
415 | if (cdev->private->state == DEV_STATE_CMFUPDATE) | ||
416 | cdev->private->state = DEV_STATE_ONLINE; | ||
417 | } | ||
418 | spin_unlock_irqrestore(cdev->ccwlock, flags); | ||
419 | } | ||
420 | spin_lock_irqsave(cdev->ccwlock, flags); | ||
421 | cdev->private->cmb_wait = NULL; | ||
422 | ret = copy_block->ret; | ||
423 | out_put: | ||
424 | kref_put(©_block->kref, cmf_copy_block_release); | ||
425 | out: | ||
426 | spin_unlock_irqrestore(cdev->ccwlock, flags); | ||
427 | return ret; | ||
428 | } | ||
429 | |||
430 | void cmf_retry_copy_block(struct ccw_device *cdev) | ||
431 | { | ||
432 | struct copy_block_struct *copy_block; | ||
277 | 433 | ||
278 | s = cdev->private->cmb_wait; | 434 | copy_block = cdev->private->cmb_wait; |
279 | cdev->private->cmb_wait = 0; | 435 | if (!copy_block) { |
280 | if (!s) { | ||
281 | WARN_ON(1); | 436 | WARN_ON(1); |
282 | return; | 437 | return; |
283 | } | 438 | } |
284 | s->ret = set_schib(cdev, s->mme, s->mbfc, s->address); | 439 | kref_get(©_block->kref); |
285 | wake_up(&s->wait); | 440 | copy_block->ret = cmf_copy_block(cdev); |
441 | wake_up(©_block->wait); | ||
442 | kref_put(©_block->kref, cmf_copy_block_release); | ||
443 | } | ||
444 | |||
445 | static void cmf_generic_reset(struct ccw_device *cdev) | ||
446 | { | ||
447 | struct cmb_data *cmb_data; | ||
448 | |||
449 | spin_lock_irq(cdev->ccwlock); | ||
450 | cmb_data = cdev->private->cmb; | ||
451 | if (cmb_data) { | ||
452 | memset(cmb_data->last_block, 0, cmb_data->size); | ||
453 | /* | ||
454 | * Need to reset hw block as well to make the hardware start | ||
455 | * from 0 again. | ||
456 | */ | ||
457 | memset(cmbops->align(cmb_data->hw_block), 0, cmb_data->size); | ||
458 | cmb_data->last_update = 0; | ||
459 | } | ||
460 | cdev->private->cmb_start_time = get_clock(); | ||
461 | spin_unlock_irq(cdev->ccwlock); | ||
286 | } | 462 | } |
287 | 463 | ||
288 | /** | 464 | /** |
@@ -343,8 +519,8 @@ struct cmb { | |||
343 | /* insert a single device into the cmb_area list | 519 | /* insert a single device into the cmb_area list |
344 | * called with cmb_area.lock held from alloc_cmb | 520 | * called with cmb_area.lock held from alloc_cmb |
345 | */ | 521 | */ |
346 | static inline int | 522 | static inline int alloc_cmb_single (struct ccw_device *cdev, |
347 | alloc_cmb_single (struct ccw_device *cdev) | 523 | struct cmb_data *cmb_data) |
348 | { | 524 | { |
349 | struct cmb *cmb; | 525 | struct cmb *cmb; |
350 | struct ccw_device_private *node; | 526 | struct ccw_device_private *node; |
@@ -358,10 +534,12 @@ alloc_cmb_single (struct ccw_device *cdev) | |||
358 | 534 | ||
359 | /* find first unused cmb in cmb_area.mem. | 535 | /* find first unused cmb in cmb_area.mem. |
360 | * this is a little tricky: cmb_area.list | 536 | * this is a little tricky: cmb_area.list |
361 | * remains sorted by ->cmb pointers */ | 537 | * remains sorted by ->cmb->hw_data pointers */ |
362 | cmb = cmb_area.mem; | 538 | cmb = cmb_area.mem; |
363 | list_for_each_entry(node, &cmb_area.list, cmb_list) { | 539 | list_for_each_entry(node, &cmb_area.list, cmb_list) { |
364 | if ((struct cmb*)node->cmb > cmb) | 540 | struct cmb_data *data; |
541 | data = node->cmb; | ||
542 | if ((struct cmb*)data->hw_block > cmb) | ||
365 | break; | 543 | break; |
366 | cmb++; | 544 | cmb++; |
367 | } | 545 | } |
@@ -372,7 +550,8 @@ alloc_cmb_single (struct ccw_device *cdev) | |||
372 | 550 | ||
373 | /* insert new cmb */ | 551 | /* insert new cmb */ |
374 | list_add_tail(&cdev->private->cmb_list, &node->cmb_list); | 552 | list_add_tail(&cdev->private->cmb_list, &node->cmb_list); |
375 | cdev->private->cmb = cmb; | 553 | cmb_data->hw_block = cmb; |
554 | cdev->private->cmb = cmb_data; | ||
376 | ret = 0; | 555 | ret = 0; |
377 | out: | 556 | out: |
378 | spin_unlock_irq(cdev->ccwlock); | 557 | spin_unlock_irq(cdev->ccwlock); |
@@ -385,7 +564,19 @@ alloc_cmb (struct ccw_device *cdev) | |||
385 | int ret; | 564 | int ret; |
386 | struct cmb *mem; | 565 | struct cmb *mem; |
387 | ssize_t size; | 566 | ssize_t size; |
567 | struct cmb_data *cmb_data; | ||
568 | |||
569 | /* Allocate private cmb_data. */ | ||
570 | cmb_data = kzalloc(sizeof(struct cmb_data), GFP_KERNEL); | ||
571 | if (!cmb_data) | ||
572 | return -ENOMEM; | ||
388 | 573 | ||
574 | cmb_data->last_block = kzalloc(sizeof(struct cmb), GFP_KERNEL); | ||
575 | if (!cmb_data->last_block) { | ||
576 | kfree(cmb_data); | ||
577 | return -ENOMEM; | ||
578 | } | ||
579 | cmb_data->size = sizeof(struct cmb); | ||
389 | spin_lock(&cmb_area.lock); | 580 | spin_lock(&cmb_area.lock); |
390 | 581 | ||
391 | if (!cmb_area.mem) { | 582 | if (!cmb_area.mem) { |
@@ -414,29 +605,36 @@ alloc_cmb (struct ccw_device *cdev) | |||
414 | } | 605 | } |
415 | 606 | ||
416 | /* do the actual allocation */ | 607 | /* do the actual allocation */ |
417 | ret = alloc_cmb_single(cdev); | 608 | ret = alloc_cmb_single(cdev, cmb_data); |
418 | out: | 609 | out: |
419 | spin_unlock(&cmb_area.lock); | 610 | spin_unlock(&cmb_area.lock); |
420 | 611 | if (ret) { | |
612 | kfree(cmb_data->last_block); | ||
613 | kfree(cmb_data); | ||
614 | } | ||
421 | return ret; | 615 | return ret; |
422 | } | 616 | } |
423 | 617 | ||
424 | static void | 618 | static void free_cmb(struct ccw_device *cdev) |
425 | free_cmb(struct ccw_device *cdev) | ||
426 | { | 619 | { |
427 | struct ccw_device_private *priv; | 620 | struct ccw_device_private *priv; |
428 | 621 | struct cmb_data *cmb_data; | |
429 | priv = cdev->private; | ||
430 | 622 | ||
431 | spin_lock(&cmb_area.lock); | 623 | spin_lock(&cmb_area.lock); |
432 | spin_lock_irq(cdev->ccwlock); | 624 | spin_lock_irq(cdev->ccwlock); |
433 | 625 | ||
626 | priv = cdev->private; | ||
627 | |||
434 | if (list_empty(&priv->cmb_list)) { | 628 | if (list_empty(&priv->cmb_list)) { |
435 | /* already freed */ | 629 | /* already freed */ |
436 | goto out; | 630 | goto out; |
437 | } | 631 | } |
438 | 632 | ||
633 | cmb_data = priv->cmb; | ||
439 | priv->cmb = NULL; | 634 | priv->cmb = NULL; |
635 | if (cmb_data) | ||
636 | kfree(cmb_data->last_block); | ||
637 | kfree(cmb_data); | ||
440 | list_del_init(&priv->cmb_list); | 638 | list_del_init(&priv->cmb_list); |
441 | 639 | ||
442 | if (list_empty(&cmb_area.list)) { | 640 | if (list_empty(&cmb_area.list)) { |
@@ -451,83 +649,97 @@ out: | |||
451 | spin_unlock(&cmb_area.lock); | 649 | spin_unlock(&cmb_area.lock); |
452 | } | 650 | } |
453 | 651 | ||
454 | static int | 652 | static int set_cmb(struct ccw_device *cdev, u32 mme) |
455 | set_cmb(struct ccw_device *cdev, u32 mme) | ||
456 | { | 653 | { |
457 | u16 offset; | 654 | u16 offset; |
655 | struct cmb_data *cmb_data; | ||
656 | unsigned long flags; | ||
458 | 657 | ||
459 | if (!cdev->private->cmb) | 658 | spin_lock_irqsave(cdev->ccwlock, flags); |
659 | if (!cdev->private->cmb) { | ||
660 | spin_unlock_irqrestore(cdev->ccwlock, flags); | ||
460 | return -EINVAL; | 661 | return -EINVAL; |
461 | 662 | } | |
462 | offset = mme ? (struct cmb *)cdev->private->cmb - cmb_area.mem : 0; | 663 | cmb_data = cdev->private->cmb; |
664 | offset = mme ? (struct cmb *)cmb_data->hw_block - cmb_area.mem : 0; | ||
665 | spin_unlock_irqrestore(cdev->ccwlock, flags); | ||
463 | 666 | ||
464 | return set_schib_wait(cdev, mme, 0, offset); | 667 | return set_schib_wait(cdev, mme, 0, offset); |
465 | } | 668 | } |
466 | 669 | ||
467 | static u64 | 670 | static u64 read_cmb (struct ccw_device *cdev, int index) |
468 | read_cmb (struct ccw_device *cdev, int index) | ||
469 | { | 671 | { |
470 | /* yes, we have to put it on the stack | 672 | struct cmb *cmb; |
471 | * because the cmb must only be accessed | ||
472 | * atomically, e.g. with mvc */ | ||
473 | struct cmb cmb; | ||
474 | unsigned long flags; | ||
475 | u32 val; | 673 | u32 val; |
674 | int ret; | ||
675 | unsigned long flags; | ||
676 | |||
677 | ret = cmf_cmb_copy_wait(cdev); | ||
678 | if (ret < 0) | ||
679 | return 0; | ||
476 | 680 | ||
477 | spin_lock_irqsave(cdev->ccwlock, flags); | 681 | spin_lock_irqsave(cdev->ccwlock, flags); |
478 | if (!cdev->private->cmb) { | 682 | if (!cdev->private->cmb) { |
479 | spin_unlock_irqrestore(cdev->ccwlock, flags); | 683 | ret = 0; |
480 | return 0; | 684 | goto out; |
481 | } | 685 | } |
482 | 686 | cmb = ((struct cmb_data *)cdev->private->cmb)->last_block; | |
483 | cmb = *(struct cmb*)cdev->private->cmb; | ||
484 | spin_unlock_irqrestore(cdev->ccwlock, flags); | ||
485 | 687 | ||
486 | switch (index) { | 688 | switch (index) { |
487 | case cmb_ssch_rsch_count: | 689 | case cmb_ssch_rsch_count: |
488 | return cmb.ssch_rsch_count; | 690 | ret = cmb->ssch_rsch_count; |
691 | goto out; | ||
489 | case cmb_sample_count: | 692 | case cmb_sample_count: |
490 | return cmb.sample_count; | 693 | ret = cmb->sample_count; |
694 | goto out; | ||
491 | case cmb_device_connect_time: | 695 | case cmb_device_connect_time: |
492 | val = cmb.device_connect_time; | 696 | val = cmb->device_connect_time; |
493 | break; | 697 | break; |
494 | case cmb_function_pending_time: | 698 | case cmb_function_pending_time: |
495 | val = cmb.function_pending_time; | 699 | val = cmb->function_pending_time; |
496 | break; | 700 | break; |
497 | case cmb_device_disconnect_time: | 701 | case cmb_device_disconnect_time: |
498 | val = cmb.device_disconnect_time; | 702 | val = cmb->device_disconnect_time; |
499 | break; | 703 | break; |
500 | case cmb_control_unit_queuing_time: | 704 | case cmb_control_unit_queuing_time: |
501 | val = cmb.control_unit_queuing_time; | 705 | val = cmb->control_unit_queuing_time; |
502 | break; | 706 | break; |
503 | case cmb_device_active_only_time: | 707 | case cmb_device_active_only_time: |
504 | val = cmb.device_active_only_time; | 708 | val = cmb->device_active_only_time; |
505 | break; | 709 | break; |
506 | default: | 710 | default: |
507 | return 0; | 711 | ret = 0; |
712 | goto out; | ||
508 | } | 713 | } |
509 | return time_to_avg_nsec(val, cmb.sample_count); | 714 | ret = time_to_avg_nsec(val, cmb->sample_count); |
715 | out: | ||
716 | spin_unlock_irqrestore(cdev->ccwlock, flags); | ||
717 | return ret; | ||
510 | } | 718 | } |
511 | 719 | ||
512 | static int | 720 | static int readall_cmb (struct ccw_device *cdev, struct cmbdata *data) |
513 | readall_cmb (struct ccw_device *cdev, struct cmbdata *data) | ||
514 | { | 721 | { |
515 | /* yes, we have to put it on the stack | 722 | struct cmb *cmb; |
516 | * because the cmb must only be accessed | 723 | struct cmb_data *cmb_data; |
517 | * atomically, e.g. with mvc */ | ||
518 | struct cmb cmb; | ||
519 | unsigned long flags; | ||
520 | u64 time; | 724 | u64 time; |
725 | unsigned long flags; | ||
726 | int ret; | ||
521 | 727 | ||
728 | ret = cmf_cmb_copy_wait(cdev); | ||
729 | if (ret < 0) | ||
730 | return ret; | ||
522 | spin_lock_irqsave(cdev->ccwlock, flags); | 731 | spin_lock_irqsave(cdev->ccwlock, flags); |
523 | if (!cdev->private->cmb) { | 732 | cmb_data = cdev->private->cmb; |
524 | spin_unlock_irqrestore(cdev->ccwlock, flags); | 733 | if (!cmb_data) { |
525 | return -ENODEV; | 734 | ret = -ENODEV; |
735 | goto out; | ||
526 | } | 736 | } |
527 | 737 | if (cmb_data->last_update == 0) { | |
528 | cmb = *(struct cmb*)cdev->private->cmb; | 738 | ret = -EAGAIN; |
529 | time = get_clock() - cdev->private->cmb_start_time; | 739 | goto out; |
530 | spin_unlock_irqrestore(cdev->ccwlock, flags); | 740 | } |
741 | cmb = cmb_data->last_block; | ||
742 | time = cmb_data->last_update - cdev->private->cmb_start_time; | ||
531 | 743 | ||
532 | memset(data, 0, sizeof(struct cmbdata)); | 744 | memset(data, 0, sizeof(struct cmbdata)); |
533 | 745 | ||
@@ -538,31 +750,32 @@ readall_cmb (struct ccw_device *cdev, struct cmbdata *data) | |||
538 | data->elapsed_time = (time * 1000) >> 12; | 750 | data->elapsed_time = (time * 1000) >> 12; |
539 | 751 | ||
540 | /* copy data to new structure */ | 752 | /* copy data to new structure */ |
541 | data->ssch_rsch_count = cmb.ssch_rsch_count; | 753 | data->ssch_rsch_count = cmb->ssch_rsch_count; |
542 | data->sample_count = cmb.sample_count; | 754 | data->sample_count = cmb->sample_count; |
543 | 755 | ||
544 | /* time fields are converted to nanoseconds while copying */ | 756 | /* time fields are converted to nanoseconds while copying */ |
545 | data->device_connect_time = time_to_nsec(cmb.device_connect_time); | 757 | data->device_connect_time = time_to_nsec(cmb->device_connect_time); |
546 | data->function_pending_time = time_to_nsec(cmb.function_pending_time); | 758 | data->function_pending_time = time_to_nsec(cmb->function_pending_time); |
547 | data->device_disconnect_time = time_to_nsec(cmb.device_disconnect_time); | 759 | data->device_disconnect_time = |
760 | time_to_nsec(cmb->device_disconnect_time); | ||
548 | data->control_unit_queuing_time | 761 | data->control_unit_queuing_time |
549 | = time_to_nsec(cmb.control_unit_queuing_time); | 762 | = time_to_nsec(cmb->control_unit_queuing_time); |
550 | data->device_active_only_time | 763 | data->device_active_only_time |
551 | = time_to_nsec(cmb.device_active_only_time); | 764 | = time_to_nsec(cmb->device_active_only_time); |
765 | ret = 0; | ||
766 | out: | ||
767 | spin_unlock_irqrestore(cdev->ccwlock, flags); | ||
768 | return ret; | ||
769 | } | ||
552 | 770 | ||
553 | return 0; | 771 | static void reset_cmb(struct ccw_device *cdev) |
772 | { | ||
773 | cmf_generic_reset(cdev); | ||
554 | } | 774 | } |
555 | 775 | ||
556 | static void | 776 | static void * align_cmb(void *area) |
557 | reset_cmb(struct ccw_device *cdev) | ||
558 | { | 777 | { |
559 | struct cmb *cmb; | 778 | return area; |
560 | spin_lock_irq(cdev->ccwlock); | ||
561 | cmb = cdev->private->cmb; | ||
562 | if (cmb) | ||
563 | memset (cmb, 0, sizeof (*cmb)); | ||
564 | cdev->private->cmb_start_time = get_clock(); | ||
565 | spin_unlock_irq(cdev->ccwlock); | ||
566 | } | 779 | } |
567 | 780 | ||
568 | static struct attribute_group cmf_attr_group; | 781 | static struct attribute_group cmf_attr_group; |
@@ -574,6 +787,7 @@ static struct cmb_operations cmbops_basic = { | |||
574 | .read = read_cmb, | 787 | .read = read_cmb, |
575 | .readall = readall_cmb, | 788 | .readall = readall_cmb, |
576 | .reset = reset_cmb, | 789 | .reset = reset_cmb, |
790 | .align = align_cmb, | ||
577 | .attr_group = &cmf_attr_group, | 791 | .attr_group = &cmf_attr_group, |
578 | }; | 792 | }; |
579 | 793 | ||
@@ -610,22 +824,34 @@ static inline struct cmbe* cmbe_align(struct cmbe *c) | |||
610 | return (struct cmbe*)addr; | 824 | return (struct cmbe*)addr; |
611 | } | 825 | } |
612 | 826 | ||
613 | static int | 827 | static int alloc_cmbe (struct ccw_device *cdev) |
614 | alloc_cmbe (struct ccw_device *cdev) | ||
615 | { | 828 | { |
616 | struct cmbe *cmbe; | 829 | struct cmbe *cmbe; |
617 | cmbe = kmalloc (sizeof (*cmbe) * 2, GFP_KERNEL); | 830 | struct cmb_data *cmb_data; |
831 | int ret; | ||
832 | |||
833 | cmbe = kzalloc (sizeof (*cmbe) * 2, GFP_KERNEL); | ||
618 | if (!cmbe) | 834 | if (!cmbe) |
619 | return -ENOMEM; | 835 | return -ENOMEM; |
620 | 836 | cmb_data = kzalloc(sizeof(struct cmb_data), GFP_KERNEL); | |
837 | if (!cmb_data) { | ||
838 | ret = -ENOMEM; | ||
839 | goto out_free; | ||
840 | } | ||
841 | cmb_data->last_block = kzalloc(sizeof(struct cmbe), GFP_KERNEL); | ||
842 | if (!cmb_data->last_block) { | ||
843 | ret = -ENOMEM; | ||
844 | goto out_free; | ||
845 | } | ||
846 | cmb_data->size = sizeof(struct cmbe); | ||
621 | spin_lock_irq(cdev->ccwlock); | 847 | spin_lock_irq(cdev->ccwlock); |
622 | if (cdev->private->cmb) { | 848 | if (cdev->private->cmb) { |
623 | kfree(cmbe); | ||
624 | spin_unlock_irq(cdev->ccwlock); | 849 | spin_unlock_irq(cdev->ccwlock); |
625 | return -EBUSY; | 850 | ret = -EBUSY; |
851 | goto out_free; | ||
626 | } | 852 | } |
627 | 853 | cmb_data->hw_block = cmbe; | |
628 | cdev->private->cmb = cmbe; | 854 | cdev->private->cmb = cmb_data; |
629 | spin_unlock_irq(cdev->ccwlock); | 855 | spin_unlock_irq(cdev->ccwlock); |
630 | 856 | ||
631 | /* activate global measurement if this is the first channel */ | 857 | /* activate global measurement if this is the first channel */ |
@@ -636,14 +862,24 @@ alloc_cmbe (struct ccw_device *cdev) | |||
636 | spin_unlock(&cmb_area.lock); | 862 | spin_unlock(&cmb_area.lock); |
637 | 863 | ||
638 | return 0; | 864 | return 0; |
865 | out_free: | ||
866 | if (cmb_data) | ||
867 | kfree(cmb_data->last_block); | ||
868 | kfree(cmb_data); | ||
869 | kfree(cmbe); | ||
870 | return ret; | ||
639 | } | 871 | } |
640 | 872 | ||
641 | static void | 873 | static void free_cmbe (struct ccw_device *cdev) |
642 | free_cmbe (struct ccw_device *cdev) | ||
643 | { | 874 | { |
875 | struct cmb_data *cmb_data; | ||
876 | |||
644 | spin_lock_irq(cdev->ccwlock); | 877 | spin_lock_irq(cdev->ccwlock); |
645 | kfree(cdev->private->cmb); | 878 | cmb_data = cdev->private->cmb; |
646 | cdev->private->cmb = NULL; | 879 | cdev->private->cmb = NULL; |
880 | if (cmb_data) | ||
881 | kfree(cmb_data->last_block); | ||
882 | kfree(cmb_data); | ||
647 | spin_unlock_irq(cdev->ccwlock); | 883 | spin_unlock_irq(cdev->ccwlock); |
648 | 884 | ||
649 | /* deactivate global measurement if this is the last channel */ | 885 | /* deactivate global measurement if this is the last channel */ |
@@ -654,89 +890,105 @@ free_cmbe (struct ccw_device *cdev) | |||
654 | spin_unlock(&cmb_area.lock); | 890 | spin_unlock(&cmb_area.lock); |
655 | } | 891 | } |
656 | 892 | ||
657 | static int | 893 | static int set_cmbe(struct ccw_device *cdev, u32 mme) |
658 | set_cmbe(struct ccw_device *cdev, u32 mme) | ||
659 | { | 894 | { |
660 | unsigned long mba; | 895 | unsigned long mba; |
896 | struct cmb_data *cmb_data; | ||
897 | unsigned long flags; | ||
661 | 898 | ||
662 | if (!cdev->private->cmb) | 899 | spin_lock_irqsave(cdev->ccwlock, flags); |
900 | if (!cdev->private->cmb) { | ||
901 | spin_unlock_irqrestore(cdev->ccwlock, flags); | ||
663 | return -EINVAL; | 902 | return -EINVAL; |
664 | mba = mme ? (unsigned long) cmbe_align(cdev->private->cmb) : 0; | 903 | } |
904 | cmb_data = cdev->private->cmb; | ||
905 | mba = mme ? (unsigned long) cmbe_align(cmb_data->hw_block) : 0; | ||
906 | spin_unlock_irqrestore(cdev->ccwlock, flags); | ||
665 | 907 | ||
666 | return set_schib_wait(cdev, mme, 1, mba); | 908 | return set_schib_wait(cdev, mme, 1, mba); |
667 | } | 909 | } |
668 | 910 | ||
669 | 911 | ||
670 | u64 | 912 | static u64 read_cmbe (struct ccw_device *cdev, int index) |
671 | read_cmbe (struct ccw_device *cdev, int index) | ||
672 | { | 913 | { |
673 | /* yes, we have to put it on the stack | 914 | struct cmbe *cmb; |
674 | * because the cmb must only be accessed | 915 | struct cmb_data *cmb_data; |
675 | * atomically, e.g. with mvc */ | ||
676 | struct cmbe cmb; | ||
677 | unsigned long flags; | ||
678 | u32 val; | 916 | u32 val; |
917 | int ret; | ||
918 | unsigned long flags; | ||
679 | 919 | ||
680 | spin_lock_irqsave(cdev->ccwlock, flags); | 920 | ret = cmf_cmb_copy_wait(cdev); |
681 | if (!cdev->private->cmb) { | 921 | if (ret < 0) |
682 | spin_unlock_irqrestore(cdev->ccwlock, flags); | ||
683 | return 0; | 922 | return 0; |
684 | } | ||
685 | 923 | ||
686 | cmb = *cmbe_align(cdev->private->cmb); | 924 | spin_lock_irqsave(cdev->ccwlock, flags); |
687 | spin_unlock_irqrestore(cdev->ccwlock, flags); | 925 | cmb_data = cdev->private->cmb; |
926 | if (!cmb_data) { | ||
927 | ret = 0; | ||
928 | goto out; | ||
929 | } | ||
930 | cmb = cmb_data->last_block; | ||
688 | 931 | ||
689 | switch (index) { | 932 | switch (index) { |
690 | case cmb_ssch_rsch_count: | 933 | case cmb_ssch_rsch_count: |
691 | return cmb.ssch_rsch_count; | 934 | ret = cmb->ssch_rsch_count; |
935 | goto out; | ||
692 | case cmb_sample_count: | 936 | case cmb_sample_count: |
693 | return cmb.sample_count; | 937 | ret = cmb->sample_count; |
938 | goto out; | ||
694 | case cmb_device_connect_time: | 939 | case cmb_device_connect_time: |
695 | val = cmb.device_connect_time; | 940 | val = cmb->device_connect_time; |
696 | break; | 941 | break; |
697 | case cmb_function_pending_time: | 942 | case cmb_function_pending_time: |
698 | val = cmb.function_pending_time; | 943 | val = cmb->function_pending_time; |
699 | break; | 944 | break; |
700 | case cmb_device_disconnect_time: | 945 | case cmb_device_disconnect_time: |
701 | val = cmb.device_disconnect_time; | 946 | val = cmb->device_disconnect_time; |
702 | break; | 947 | break; |
703 | case cmb_control_unit_queuing_time: | 948 | case cmb_control_unit_queuing_time: |
704 | val = cmb.control_unit_queuing_time; | 949 | val = cmb->control_unit_queuing_time; |
705 | break; | 950 | break; |
706 | case cmb_device_active_only_time: | 951 | case cmb_device_active_only_time: |
707 | val = cmb.device_active_only_time; | 952 | val = cmb->device_active_only_time; |
708 | break; | 953 | break; |
709 | case cmb_device_busy_time: | 954 | case cmb_device_busy_time: |
710 | val = cmb.device_busy_time; | 955 | val = cmb->device_busy_time; |
711 | break; | 956 | break; |
712 | case cmb_initial_command_response_time: | 957 | case cmb_initial_command_response_time: |
713 | val = cmb.initial_command_response_time; | 958 | val = cmb->initial_command_response_time; |
714 | break; | 959 | break; |
715 | default: | 960 | default: |
716 | return 0; | 961 | ret = 0; |
962 | goto out; | ||
717 | } | 963 | } |
718 | return time_to_avg_nsec(val, cmb.sample_count); | 964 | ret = time_to_avg_nsec(val, cmb->sample_count); |
965 | out: | ||
966 | spin_unlock_irqrestore(cdev->ccwlock, flags); | ||
967 | return ret; | ||
719 | } | 968 | } |
720 | 969 | ||
721 | static int | 970 | static int readall_cmbe (struct ccw_device *cdev, struct cmbdata *data) |
722 | readall_cmbe (struct ccw_device *cdev, struct cmbdata *data) | ||
723 | { | 971 | { |
724 | /* yes, we have to put it on the stack | 972 | struct cmbe *cmb; |
725 | * because the cmb must only be accessed | 973 | struct cmb_data *cmb_data; |
726 | * atomically, e.g. with mvc */ | ||
727 | struct cmbe cmb; | ||
728 | unsigned long flags; | ||
729 | u64 time; | 974 | u64 time; |
975 | unsigned long flags; | ||
976 | int ret; | ||
730 | 977 | ||
978 | ret = cmf_cmb_copy_wait(cdev); | ||
979 | if (ret < 0) | ||
980 | return ret; | ||
731 | spin_lock_irqsave(cdev->ccwlock, flags); | 981 | spin_lock_irqsave(cdev->ccwlock, flags); |
732 | if (!cdev->private->cmb) { | 982 | cmb_data = cdev->private->cmb; |
733 | spin_unlock_irqrestore(cdev->ccwlock, flags); | 983 | if (!cmb_data) { |
734 | return -ENODEV; | 984 | ret = -ENODEV; |
985 | goto out; | ||
735 | } | 986 | } |
736 | 987 | if (cmb_data->last_update == 0) { | |
737 | cmb = *cmbe_align(cdev->private->cmb); | 988 | ret = -EAGAIN; |
738 | time = get_clock() - cdev->private->cmb_start_time; | 989 | goto out; |
739 | spin_unlock_irqrestore(cdev->ccwlock, flags); | 990 | } |
991 | time = cmb_data->last_update - cdev->private->cmb_start_time; | ||
740 | 992 | ||
741 | memset (data, 0, sizeof(struct cmbdata)); | 993 | memset (data, 0, sizeof(struct cmbdata)); |
742 | 994 | ||
@@ -746,35 +998,38 @@ readall_cmbe (struct ccw_device *cdev, struct cmbdata *data) | |||
746 | /* conver to nanoseconds */ | 998 | /* conver to nanoseconds */ |
747 | data->elapsed_time = (time * 1000) >> 12; | 999 | data->elapsed_time = (time * 1000) >> 12; |
748 | 1000 | ||
1001 | cmb = cmb_data->last_block; | ||
749 | /* copy data to new structure */ | 1002 | /* copy data to new structure */ |
750 | data->ssch_rsch_count = cmb.ssch_rsch_count; | 1003 | data->ssch_rsch_count = cmb->ssch_rsch_count; |
751 | data->sample_count = cmb.sample_count; | 1004 | data->sample_count = cmb->sample_count; |
752 | 1005 | ||
753 | /* time fields are converted to nanoseconds while copying */ | 1006 | /* time fields are converted to nanoseconds while copying */ |
754 | data->device_connect_time = time_to_nsec(cmb.device_connect_time); | 1007 | data->device_connect_time = time_to_nsec(cmb->device_connect_time); |
755 | data->function_pending_time = time_to_nsec(cmb.function_pending_time); | 1008 | data->function_pending_time = time_to_nsec(cmb->function_pending_time); |
756 | data->device_disconnect_time = time_to_nsec(cmb.device_disconnect_time); | 1009 | data->device_disconnect_time = |
1010 | time_to_nsec(cmb->device_disconnect_time); | ||
757 | data->control_unit_queuing_time | 1011 | data->control_unit_queuing_time |
758 | = time_to_nsec(cmb.control_unit_queuing_time); | 1012 | = time_to_nsec(cmb->control_unit_queuing_time); |
759 | data->device_active_only_time | 1013 | data->device_active_only_time |
760 | = time_to_nsec(cmb.device_active_only_time); | 1014 | = time_to_nsec(cmb->device_active_only_time); |
761 | data->device_busy_time = time_to_nsec(cmb.device_busy_time); | 1015 | data->device_busy_time = time_to_nsec(cmb->device_busy_time); |
762 | data->initial_command_response_time | 1016 | data->initial_command_response_time |
763 | = time_to_nsec(cmb.initial_command_response_time); | 1017 | = time_to_nsec(cmb->initial_command_response_time); |
764 | 1018 | ||
765 | return 0; | 1019 | ret = 0; |
1020 | out: | ||
1021 | spin_unlock_irqrestore(cdev->ccwlock, flags); | ||
1022 | return ret; | ||
766 | } | 1023 | } |
767 | 1024 | ||
768 | static void | 1025 | static void reset_cmbe(struct ccw_device *cdev) |
769 | reset_cmbe(struct ccw_device *cdev) | ||
770 | { | 1026 | { |
771 | struct cmbe *cmb; | 1027 | cmf_generic_reset(cdev); |
772 | spin_lock_irq(cdev->ccwlock); | 1028 | } |
773 | cmb = cmbe_align(cdev->private->cmb); | 1029 | |
774 | if (cmb) | 1030 | static void * align_cmbe(void *area) |
775 | memset (cmb, 0, sizeof (*cmb)); | 1031 | { |
776 | cdev->private->cmb_start_time = get_clock(); | 1032 | return cmbe_align(area); |
777 | spin_unlock_irq(cdev->ccwlock); | ||
778 | } | 1033 | } |
779 | 1034 | ||
780 | static struct attribute_group cmf_attr_group_ext; | 1035 | static struct attribute_group cmf_attr_group_ext; |
@@ -786,6 +1041,7 @@ static struct cmb_operations cmbops_extended = { | |||
786 | .read = read_cmbe, | 1041 | .read = read_cmbe, |
787 | .readall = readall_cmbe, | 1042 | .readall = readall_cmbe, |
788 | .reset = reset_cmbe, | 1043 | .reset = reset_cmbe, |
1044 | .align = align_cmbe, | ||
789 | .attr_group = &cmf_attr_group_ext, | 1045 | .attr_group = &cmf_attr_group_ext, |
790 | }; | 1046 | }; |
791 | 1047 | ||
@@ -803,14 +1059,19 @@ cmb_show_avg_sample_interval(struct device *dev, struct device_attribute *attr, | |||
803 | struct ccw_device *cdev; | 1059 | struct ccw_device *cdev; |
804 | long interval; | 1060 | long interval; |
805 | unsigned long count; | 1061 | unsigned long count; |
1062 | struct cmb_data *cmb_data; | ||
806 | 1063 | ||
807 | cdev = to_ccwdev(dev); | 1064 | cdev = to_ccwdev(dev); |
808 | interval = get_clock() - cdev->private->cmb_start_time; | ||
809 | count = cmf_read(cdev, cmb_sample_count); | 1065 | count = cmf_read(cdev, cmb_sample_count); |
810 | if (count) | 1066 | spin_lock_irq(cdev->ccwlock); |
1067 | cmb_data = cdev->private->cmb; | ||
1068 | if (count) { | ||
1069 | interval = cmb_data->last_update - | ||
1070 | cdev->private->cmb_start_time; | ||
811 | interval /= count; | 1071 | interval /= count; |
812 | else | 1072 | } else |
813 | interval = -1; | 1073 | interval = -1; |
1074 | spin_unlock_irq(cdev->ccwlock); | ||
814 | return sprintf(buf, "%ld\n", interval); | 1075 | return sprintf(buf, "%ld\n", interval); |
815 | } | 1076 | } |
816 | 1077 | ||
@@ -823,7 +1084,10 @@ cmb_show_avg_utilization(struct device *dev, struct device_attribute *attr, char | |||
823 | int ret; | 1084 | int ret; |
824 | 1085 | ||
825 | ret = cmf_readall(to_ccwdev(dev), &data); | 1086 | ret = cmf_readall(to_ccwdev(dev), &data); |
826 | if (ret) | 1087 | if (ret == -EAGAIN || ret == -ENODEV) |
1088 | /* No data (yet/currently) available to use for calculation. */ | ||
1089 | return sprintf(buf, "n/a\n"); | ||
1090 | else if (ret) | ||
827 | return ret; | 1091 | return ret; |
828 | 1092 | ||
829 | utilization = data.device_connect_time + | 1093 | utilization = data.device_connect_time + |
@@ -982,6 +1246,13 @@ cmf_readall(struct ccw_device *cdev, struct cmbdata *data) | |||
982 | return cmbops->readall(cdev, data); | 1246 | return cmbops->readall(cdev, data); |
983 | } | 1247 | } |
984 | 1248 | ||
1249 | /* Reenable cmf when a disconnected device becomes available again. */ | ||
1250 | int cmf_reenable(struct ccw_device *cdev) | ||
1251 | { | ||
1252 | cmbops->reset(cdev); | ||
1253 | return cmbops->set(cdev, 2); | ||
1254 | } | ||
1255 | |||
985 | static int __init | 1256 | static int __init |
986 | init_cmf(void) | 1257 | init_cmf(void) |
987 | { | 1258 | { |
diff --git a/drivers/s390/cio/css.c b/drivers/s390/cio/css.c index 74ea8aac4b7d..1d3be80797f8 100644 --- a/drivers/s390/cio/css.c +++ b/drivers/s390/cio/css.c | |||
@@ -19,9 +19,11 @@ | |||
19 | #include "cio_debug.h" | 19 | #include "cio_debug.h" |
20 | #include "ioasm.h" | 20 | #include "ioasm.h" |
21 | #include "chsc.h" | 21 | #include "chsc.h" |
22 | #include "device.h" | ||
22 | 23 | ||
23 | int need_rescan = 0; | 24 | int need_rescan = 0; |
24 | int css_init_done = 0; | 25 | int css_init_done = 0; |
26 | static int need_reprobe = 0; | ||
25 | static int max_ssid = 0; | 27 | static int max_ssid = 0; |
26 | 28 | ||
27 | struct channel_subsystem *css[__MAX_CSSID + 1]; | 29 | struct channel_subsystem *css[__MAX_CSSID + 1]; |
@@ -339,6 +341,67 @@ typedef void (*workfunc)(void *); | |||
339 | DECLARE_WORK(slow_path_work, (workfunc)css_trigger_slow_path, NULL); | 341 | DECLARE_WORK(slow_path_work, (workfunc)css_trigger_slow_path, NULL); |
340 | struct workqueue_struct *slow_path_wq; | 342 | struct workqueue_struct *slow_path_wq; |
341 | 343 | ||
344 | /* Reprobe subchannel if unregistered. */ | ||
345 | static int reprobe_subchannel(struct subchannel_id schid, void *data) | ||
346 | { | ||
347 | struct subchannel *sch; | ||
348 | int ret; | ||
349 | |||
350 | CIO_DEBUG(KERN_INFO, 6, "cio: reprobe 0.%x.%04x\n", | ||
351 | schid.ssid, schid.sch_no); | ||
352 | if (need_reprobe) | ||
353 | return -EAGAIN; | ||
354 | |||
355 | sch = get_subchannel_by_schid(schid); | ||
356 | if (sch) { | ||
357 | /* Already known. */ | ||
358 | put_device(&sch->dev); | ||
359 | return 0; | ||
360 | } | ||
361 | |||
362 | ret = css_probe_device(schid); | ||
363 | switch (ret) { | ||
364 | case 0: | ||
365 | break; | ||
366 | case -ENXIO: | ||
367 | case -ENOMEM: | ||
368 | /* These should abort looping */ | ||
369 | break; | ||
370 | default: | ||
371 | ret = 0; | ||
372 | } | ||
373 | |||
374 | return ret; | ||
375 | } | ||
376 | |||
377 | /* Work function used to reprobe all unregistered subchannels. */ | ||
378 | static void reprobe_all(void *data) | ||
379 | { | ||
380 | int ret; | ||
381 | |||
382 | CIO_MSG_EVENT(2, "reprobe start\n"); | ||
383 | |||
384 | need_reprobe = 0; | ||
385 | /* Make sure initial subchannel scan is done. */ | ||
386 | wait_event(ccw_device_init_wq, | ||
387 | atomic_read(&ccw_device_init_count) == 0); | ||
388 | ret = for_each_subchannel(reprobe_subchannel, NULL); | ||
389 | |||
390 | CIO_MSG_EVENT(2, "reprobe done (rc=%d, need_reprobe=%d)\n", ret, | ||
391 | need_reprobe); | ||
392 | } | ||
393 | |||
394 | DECLARE_WORK(css_reprobe_work, reprobe_all, NULL); | ||
395 | |||
396 | /* Schedule reprobing of all unregistered subchannels. */ | ||
397 | void css_schedule_reprobe(void) | ||
398 | { | ||
399 | need_reprobe = 1; | ||
400 | queue_work(ccw_device_work, &css_reprobe_work); | ||
401 | } | ||
402 | |||
403 | EXPORT_SYMBOL_GPL(css_schedule_reprobe); | ||
404 | |||
342 | /* | 405 | /* |
343 | * Rescan for new devices. FIXME: This is slow. | 406 | * Rescan for new devices. FIXME: This is slow. |
344 | * This function is called when we have lost CRWs due to overflows and we have | 407 | * This function is called when we have lost CRWs due to overflows and we have |
diff --git a/drivers/s390/cio/device.c b/drivers/s390/cio/device.c index 8e3053c2a451..eafde43e8410 100644 --- a/drivers/s390/cio/device.c +++ b/drivers/s390/cio/device.c | |||
@@ -133,8 +133,8 @@ struct css_driver io_subchannel_driver = { | |||
133 | 133 | ||
134 | struct workqueue_struct *ccw_device_work; | 134 | struct workqueue_struct *ccw_device_work; |
135 | struct workqueue_struct *ccw_device_notify_work; | 135 | struct workqueue_struct *ccw_device_notify_work; |
136 | static wait_queue_head_t ccw_device_init_wq; | 136 | wait_queue_head_t ccw_device_init_wq; |
137 | static atomic_t ccw_device_init_count; | 137 | atomic_t ccw_device_init_count; |
138 | 138 | ||
139 | static int __init | 139 | static int __init |
140 | init_ccw_bus_type (void) | 140 | init_ccw_bus_type (void) |
diff --git a/drivers/s390/cio/device.h b/drivers/s390/cio/device.h index 11587ebb7289..00be9a5b4acd 100644 --- a/drivers/s390/cio/device.h +++ b/drivers/s390/cio/device.h | |||
@@ -1,6 +1,10 @@ | |||
1 | #ifndef S390_DEVICE_H | 1 | #ifndef S390_DEVICE_H |
2 | #define S390_DEVICE_H | 2 | #define S390_DEVICE_H |
3 | 3 | ||
4 | #include <asm/ccwdev.h> | ||
5 | #include <asm/atomic.h> | ||
6 | #include <linux/wait.h> | ||
7 | |||
4 | /* | 8 | /* |
5 | * states of the device statemachine | 9 | * states of the device statemachine |
6 | */ | 10 | */ |
@@ -23,6 +27,7 @@ enum dev_state { | |||
23 | DEV_STATE_DISCONNECTED, | 27 | DEV_STATE_DISCONNECTED, |
24 | DEV_STATE_DISCONNECTED_SENSE_ID, | 28 | DEV_STATE_DISCONNECTED_SENSE_ID, |
25 | DEV_STATE_CMFCHANGE, | 29 | DEV_STATE_CMFCHANGE, |
30 | DEV_STATE_CMFUPDATE, | ||
26 | /* last element! */ | 31 | /* last element! */ |
27 | NR_DEV_STATES | 32 | NR_DEV_STATES |
28 | }; | 33 | }; |
@@ -67,6 +72,8 @@ dev_fsm_final_state(struct ccw_device *cdev) | |||
67 | 72 | ||
68 | extern struct workqueue_struct *ccw_device_work; | 73 | extern struct workqueue_struct *ccw_device_work; |
69 | extern struct workqueue_struct *ccw_device_notify_work; | 74 | extern struct workqueue_struct *ccw_device_notify_work; |
75 | extern wait_queue_head_t ccw_device_init_wq; | ||
76 | extern atomic_t ccw_device_init_count; | ||
70 | 77 | ||
71 | void io_subchannel_recog_done(struct ccw_device *cdev); | 78 | void io_subchannel_recog_done(struct ccw_device *cdev); |
72 | 79 | ||
@@ -112,5 +119,8 @@ int ccw_device_stlck(struct ccw_device *); | |||
112 | void ccw_device_set_timeout(struct ccw_device *, int); | 119 | void ccw_device_set_timeout(struct ccw_device *, int); |
113 | extern struct subchannel_id ccw_device_get_subchannel_id(struct ccw_device *); | 120 | extern struct subchannel_id ccw_device_get_subchannel_id(struct ccw_device *); |
114 | 121 | ||
122 | /* Channel measurement facility related */ | ||
115 | void retry_set_schib(struct ccw_device *cdev); | 123 | void retry_set_schib(struct ccw_device *cdev); |
124 | void cmf_retry_copy_block(struct ccw_device *); | ||
125 | int cmf_reenable(struct ccw_device *); | ||
116 | #endif | 126 | #endif |
diff --git a/drivers/s390/cio/device_fsm.c b/drivers/s390/cio/device_fsm.c index 49ec562d7f60..7d0dd72635eb 100644 --- a/drivers/s390/cio/device_fsm.c +++ b/drivers/s390/cio/device_fsm.c | |||
@@ -336,8 +336,11 @@ ccw_device_oper_notify(void *data) | |||
336 | if (!ret) | 336 | if (!ret) |
337 | /* Driver doesn't want device back. */ | 337 | /* Driver doesn't want device back. */ |
338 | ccw_device_do_unreg_rereg((void *)cdev); | 338 | ccw_device_do_unreg_rereg((void *)cdev); |
339 | else | 339 | else { |
340 | /* Reenable channel measurements, if needed. */ | ||
341 | cmf_reenable(cdev); | ||
340 | wake_up(&cdev->private->wait_q); | 342 | wake_up(&cdev->private->wait_q); |
343 | } | ||
341 | } | 344 | } |
342 | 345 | ||
343 | /* | 346 | /* |
@@ -861,6 +864,8 @@ ccw_device_clear_verify(struct ccw_device *cdev, enum dev_event dev_event) | |||
861 | irb = (struct irb *) __LC_IRB; | 864 | irb = (struct irb *) __LC_IRB; |
862 | /* Accumulate status. We don't do basic sense. */ | 865 | /* Accumulate status. We don't do basic sense. */ |
863 | ccw_device_accumulate_irb(cdev, irb); | 866 | ccw_device_accumulate_irb(cdev, irb); |
867 | /* Remember to clear irb to avoid residuals. */ | ||
868 | memset(&cdev->private->irb, 0, sizeof(struct irb)); | ||
864 | /* Try to start delayed device verification. */ | 869 | /* Try to start delayed device verification. */ |
865 | ccw_device_online_verify(cdev, 0); | 870 | ccw_device_online_verify(cdev, 0); |
866 | /* Note: Don't call handler for cio initiated clear! */ | 871 | /* Note: Don't call handler for cio initiated clear! */ |
@@ -1093,6 +1098,13 @@ ccw_device_change_cmfstate(struct ccw_device *cdev, enum dev_event dev_event) | |||
1093 | dev_fsm_event(cdev, dev_event); | 1098 | dev_fsm_event(cdev, dev_event); |
1094 | } | 1099 | } |
1095 | 1100 | ||
1101 | static void ccw_device_update_cmfblock(struct ccw_device *cdev, | ||
1102 | enum dev_event dev_event) | ||
1103 | { | ||
1104 | cmf_retry_copy_block(cdev); | ||
1105 | cdev->private->state = DEV_STATE_ONLINE; | ||
1106 | dev_fsm_event(cdev, dev_event); | ||
1107 | } | ||
1096 | 1108 | ||
1097 | static void | 1109 | static void |
1098 | ccw_device_quiesce_done(struct ccw_device *cdev, enum dev_event dev_event) | 1110 | ccw_device_quiesce_done(struct ccw_device *cdev, enum dev_event dev_event) |
@@ -1247,6 +1259,12 @@ fsm_func_t *dev_jumptable[NR_DEV_STATES][NR_DEV_EVENTS] = { | |||
1247 | [DEV_EVENT_TIMEOUT] = ccw_device_change_cmfstate, | 1259 | [DEV_EVENT_TIMEOUT] = ccw_device_change_cmfstate, |
1248 | [DEV_EVENT_VERIFY] = ccw_device_change_cmfstate, | 1260 | [DEV_EVENT_VERIFY] = ccw_device_change_cmfstate, |
1249 | }, | 1261 | }, |
1262 | [DEV_STATE_CMFUPDATE] = { | ||
1263 | [DEV_EVENT_NOTOPER] = ccw_device_update_cmfblock, | ||
1264 | [DEV_EVENT_INTERRUPT] = ccw_device_update_cmfblock, | ||
1265 | [DEV_EVENT_TIMEOUT] = ccw_device_update_cmfblock, | ||
1266 | [DEV_EVENT_VERIFY] = ccw_device_update_cmfblock, | ||
1267 | }, | ||
1250 | }; | 1268 | }; |
1251 | 1269 | ||
1252 | /* | 1270 | /* |
diff --git a/drivers/s390/cio/device_ops.c b/drivers/s390/cio/device_ops.c index 795abb5a65ba..b266ad8e14ff 100644 --- a/drivers/s390/cio/device_ops.c +++ b/drivers/s390/cio/device_ops.c | |||
@@ -78,7 +78,8 @@ ccw_device_start_key(struct ccw_device *cdev, struct ccw1 *cpa, | |||
78 | return -ENODEV; | 78 | return -ENODEV; |
79 | if (cdev->private->state == DEV_STATE_NOT_OPER) | 79 | if (cdev->private->state == DEV_STATE_NOT_OPER) |
80 | return -ENODEV; | 80 | return -ENODEV; |
81 | if (cdev->private->state == DEV_STATE_VERIFY) { | 81 | if (cdev->private->state == DEV_STATE_VERIFY || |
82 | cdev->private->state == DEV_STATE_CLEAR_VERIFY) { | ||
82 | /* Remember to fake irb when finished. */ | 83 | /* Remember to fake irb when finished. */ |
83 | if (!cdev->private->flags.fake_irb) { | 84 | if (!cdev->private->flags.fake_irb) { |
84 | cdev->private->flags.fake_irb = 1; | 85 | cdev->private->flags.fake_irb = 1; |
@@ -270,7 +271,8 @@ ccw_device_wake_up(struct ccw_device *cdev, unsigned long ip, struct irb *irb) | |||
270 | * We didn't get channel end / device end. Check if path | 271 | * We didn't get channel end / device end. Check if path |
271 | * verification has been started; we can retry after it has | 272 | * verification has been started; we can retry after it has |
272 | * finished. We also retry unit checks except for command reject | 273 | * finished. We also retry unit checks except for command reject |
273 | * or intervention required. | 274 | * or intervention required. Also check for long busy |
275 | * conditions. | ||
274 | */ | 276 | */ |
275 | if (cdev->private->flags.doverify || | 277 | if (cdev->private->flags.doverify || |
276 | cdev->private->state == DEV_STATE_VERIFY) | 278 | cdev->private->state == DEV_STATE_VERIFY) |
@@ -279,6 +281,10 @@ ccw_device_wake_up(struct ccw_device *cdev, unsigned long ip, struct irb *irb) | |||
279 | !(irb->ecw[0] & | 281 | !(irb->ecw[0] & |
280 | (SNS0_CMD_REJECT | SNS0_INTERVENTION_REQ))) | 282 | (SNS0_CMD_REJECT | SNS0_INTERVENTION_REQ))) |
281 | cdev->private->intparm = -EAGAIN; | 283 | cdev->private->intparm = -EAGAIN; |
284 | else if ((irb->scsw.dstat & DEV_STAT_ATTENTION) && | ||
285 | (irb->scsw.dstat & DEV_STAT_DEV_END) && | ||
286 | (irb->scsw.dstat & DEV_STAT_UNIT_EXCEP)) | ||
287 | cdev->private->intparm = -EAGAIN; | ||
282 | else | 288 | else |
283 | cdev->private->intparm = -EIO; | 289 | cdev->private->intparm = -EIO; |
284 | 290 | ||
diff --git a/drivers/s390/crypto/z90main.c b/drivers/s390/crypto/z90main.c index 982acc7303ea..b2f20ab8431a 100644 --- a/drivers/s390/crypto/z90main.c +++ b/drivers/s390/crypto/z90main.c | |||
@@ -411,7 +411,6 @@ static struct miscdevice z90crypt_misc_device = { | |||
411 | .minor = Z90CRYPT_MINOR, | 411 | .minor = Z90CRYPT_MINOR, |
412 | .name = DEV_NAME, | 412 | .name = DEV_NAME, |
413 | .fops = &z90crypt_fops, | 413 | .fops = &z90crypt_fops, |
414 | .devfs_name = DEV_NAME | ||
415 | }; | 414 | }; |
416 | 415 | ||
417 | /** | 416 | /** |
diff --git a/drivers/s390/s390mach.c b/drivers/s390/s390mach.c index f99e55308b32..8dc75002acbe 100644 --- a/drivers/s390/s390mach.c +++ b/drivers/s390/s390mach.c | |||
@@ -14,6 +14,7 @@ | |||
14 | #include <linux/errno.h> | 14 | #include <linux/errno.h> |
15 | #include <linux/workqueue.h> | 15 | #include <linux/workqueue.h> |
16 | #include <linux/time.h> | 16 | #include <linux/time.h> |
17 | #include <linux/kthread.h> | ||
17 | 18 | ||
18 | #include <asm/lowcore.h> | 19 | #include <asm/lowcore.h> |
19 | 20 | ||
@@ -56,8 +57,6 @@ s390_collect_crw_info(void *param) | |||
56 | unsigned int chain; | 57 | unsigned int chain; |
57 | 58 | ||
58 | sem = (struct semaphore *)param; | 59 | sem = (struct semaphore *)param; |
59 | /* Set a nice name. */ | ||
60 | daemonize("kmcheck"); | ||
61 | repeat: | 60 | repeat: |
62 | down_interruptible(sem); | 61 | down_interruptible(sem); |
63 | slow = 0; | 62 | slow = 0; |
@@ -516,7 +515,7 @@ arch_initcall(machine_check_init); | |||
516 | static int __init | 515 | static int __init |
517 | machine_check_crw_init (void) | 516 | machine_check_crw_init (void) |
518 | { | 517 | { |
519 | kernel_thread(s390_collect_crw_info, &m_sem, CLONE_FS|CLONE_FILES); | 518 | kthread_run(s390_collect_crw_info, &m_sem, "kmcheck"); |
520 | ctl_set_bit(14, 28); /* enable channel report MCH */ | 519 | ctl_set_bit(14, 28); /* enable channel report MCH */ |
521 | return 0; | 520 | return 0; |
522 | } | 521 | } |
diff --git a/drivers/sbus/char/bpp.c b/drivers/sbus/char/bpp.c index ccb20a6f5f36..385f4f768311 100644 --- a/drivers/sbus/char/bpp.c +++ b/drivers/sbus/char/bpp.c | |||
@@ -20,7 +20,6 @@ | |||
20 | #include <linux/timer.h> | 20 | #include <linux/timer.h> |
21 | #include <linux/ioport.h> | 21 | #include <linux/ioport.h> |
22 | #include <linux/major.h> | 22 | #include <linux/major.h> |
23 | #include <linux/devfs_fs_kernel.h> | ||
24 | 23 | ||
25 | #include <asm/uaccess.h> | 24 | #include <asm/uaccess.h> |
26 | #include <asm/io.h> | 25 | #include <asm/io.h> |
@@ -1031,11 +1030,6 @@ static int __init bpp_init(void) | |||
1031 | instances[idx].opened = 0; | 1030 | instances[idx].opened = 0; |
1032 | probeLptPort(idx); | 1031 | probeLptPort(idx); |
1033 | } | 1032 | } |
1034 | devfs_mk_dir("bpp"); | ||
1035 | for (idx = 0; idx < BPP_NO; idx++) { | ||
1036 | devfs_mk_cdev(MKDEV(BPP_MAJOR, idx), | ||
1037 | S_IFCHR | S_IRUSR | S_IWUSR, "bpp/%d", idx); | ||
1038 | } | ||
1039 | 1033 | ||
1040 | return 0; | 1034 | return 0; |
1041 | } | 1035 | } |
@@ -1044,9 +1038,6 @@ static void __exit bpp_cleanup(void) | |||
1044 | { | 1038 | { |
1045 | unsigned idx; | 1039 | unsigned idx; |
1046 | 1040 | ||
1047 | for (idx = 0; idx < BPP_NO; idx++) | ||
1048 | devfs_remove("bpp/%d", idx); | ||
1049 | devfs_remove("bpp"); | ||
1050 | unregister_chrdev(BPP_MAJOR, dev_name); | 1041 | unregister_chrdev(BPP_MAJOR, dev_name); |
1051 | 1042 | ||
1052 | for (idx = 0; idx < BPP_NO; idx++) { | 1043 | for (idx = 0; idx < BPP_NO; idx++) { |
diff --git a/drivers/sbus/char/vfc.h b/drivers/sbus/char/vfc.h index 8045cd5e7cb3..63941a259b92 100644 --- a/drivers/sbus/char/vfc.h +++ b/drivers/sbus/char/vfc.h | |||
@@ -1,8 +1,6 @@ | |||
1 | #ifndef _LINUX_VFC_H_ | 1 | #ifndef _LINUX_VFC_H_ |
2 | #define _LINUX_VFC_H_ | 2 | #define _LINUX_VFC_H_ |
3 | 3 | ||
4 | #include <linux/devfs_fs_kernel.h> | ||
5 | |||
6 | /* | 4 | /* |
7 | * The control register for the vfc is at offset 0x4000 | 5 | * The control register for the vfc is at offset 0x4000 |
8 | * The first field ram bank is located at offset 0x5000 | 6 | * The first field ram bank is located at offset 0x5000 |
diff --git a/drivers/sbus/char/vfc_dev.c b/drivers/sbus/char/vfc_dev.c index ddcd330b9e89..55b2b31bd7ab 100644 --- a/drivers/sbus/char/vfc_dev.c +++ b/drivers/sbus/char/vfc_dev.c | |||
@@ -164,10 +164,6 @@ int init_vfc_device(struct sbus_dev *sdev,struct vfc_dev *dev, int instance) | |||
164 | return -EINVAL; | 164 | return -EINVAL; |
165 | if (init_vfc_hw(dev)) | 165 | if (init_vfc_hw(dev)) |
166 | return -EIO; | 166 | return -EIO; |
167 | |||
168 | devfs_mk_cdev(MKDEV(VFC_MAJOR, instance), | ||
169 | S_IFCHR | S_IRUSR | S_IWUSR, | ||
170 | "vfc/%d", instance); | ||
171 | return 0; | 167 | return 0; |
172 | } | 168 | } |
173 | 169 | ||
@@ -677,7 +673,6 @@ static int vfc_probe(void) | |||
677 | kfree(vfc_dev_lst); | 673 | kfree(vfc_dev_lst); |
678 | return -EIO; | 674 | return -EIO; |
679 | } | 675 | } |
680 | devfs_mk_dir("vfc"); | ||
681 | instance = 0; | 676 | instance = 0; |
682 | for_all_sbusdev(sdev, sbus) { | 677 | for_all_sbusdev(sdev, sbus) { |
683 | if (strcmp(sdev->prom_name, "vfc") == 0) { | 678 | if (strcmp(sdev->prom_name, "vfc") == 0) { |
@@ -717,7 +712,6 @@ static void deinit_vfc_device(struct vfc_dev *dev) | |||
717 | { | 712 | { |
718 | if(dev == NULL) | 713 | if(dev == NULL) |
719 | return; | 714 | return; |
720 | devfs_remove("vfc/%d", dev->instance); | ||
721 | sbus_iounmap(dev->regs, sizeof(struct vfc_regs)); | 715 | sbus_iounmap(dev->regs, sizeof(struct vfc_regs)); |
722 | kfree(dev); | 716 | kfree(dev); |
723 | } | 717 | } |
@@ -731,7 +725,6 @@ void cleanup_module(void) | |||
731 | for (devp = vfc_dev_lst; *devp; devp++) | 725 | for (devp = vfc_dev_lst; *devp; devp++) |
732 | deinit_vfc_device(*devp); | 726 | deinit_vfc_device(*devp); |
733 | 727 | ||
734 | devfs_remove("vfc"); | ||
735 | kfree(vfc_dev_lst); | 728 | kfree(vfc_dev_lst); |
736 | return; | 729 | return; |
737 | } | 730 | } |
diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig index c84b02aec1f3..96a81cd17617 100644 --- a/drivers/scsi/Kconfig +++ b/drivers/scsi/Kconfig | |||
@@ -501,7 +501,7 @@ config SCSI_ATA_PIIX | |||
501 | tristate "Intel PIIX/ICH SATA support" | 501 | tristate "Intel PIIX/ICH SATA support" |
502 | depends on SCSI_SATA && PCI | 502 | depends on SCSI_SATA && PCI |
503 | help | 503 | help |
504 | This option enables support for ICH5 Serial ATA. | 504 | This option enables support for ICH5/6/7/8 Serial ATA. |
505 | If PATA support was enabled previously, this enables | 505 | If PATA support was enabled previously, this enables |
506 | support for select Intel PIIX/ICH PATA host controllers. | 506 | support for select Intel PIIX/ICH PATA host controllers. |
507 | 507 | ||
diff --git a/drivers/scsi/ahci.c b/drivers/scsi/ahci.c index 4bb77f62b3b9..f05946777718 100644 --- a/drivers/scsi/ahci.c +++ b/drivers/scsi/ahci.c | |||
@@ -48,7 +48,7 @@ | |||
48 | #include <asm/io.h> | 48 | #include <asm/io.h> |
49 | 49 | ||
50 | #define DRV_NAME "ahci" | 50 | #define DRV_NAME "ahci" |
51 | #define DRV_VERSION "1.3" | 51 | #define DRV_VERSION "2.0" |
52 | 52 | ||
53 | 53 | ||
54 | enum { | 54 | enum { |
diff --git a/drivers/scsi/ata_piix.c b/drivers/scsi/ata_piix.c index 521b718763f6..94b1261a259d 100644 --- a/drivers/scsi/ata_piix.c +++ b/drivers/scsi/ata_piix.c | |||
@@ -93,7 +93,7 @@ | |||
93 | #include <linux/libata.h> | 93 | #include <linux/libata.h> |
94 | 94 | ||
95 | #define DRV_NAME "ata_piix" | 95 | #define DRV_NAME "ata_piix" |
96 | #define DRV_VERSION "1.10" | 96 | #define DRV_VERSION "2.00" |
97 | 97 | ||
98 | enum { | 98 | enum { |
99 | PIIX_IOCFG = 0x54, /* IDE I/O configuration register */ | 99 | PIIX_IOCFG = 0x54, /* IDE I/O configuration register */ |
diff --git a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c index 6c66877be2bf..d1c1c30d123f 100644 --- a/drivers/scsi/libata-core.c +++ b/drivers/scsi/libata-core.c | |||
@@ -88,6 +88,10 @@ int libata_fua = 0; | |||
88 | module_param_named(fua, libata_fua, int, 0444); | 88 | module_param_named(fua, libata_fua, int, 0444); |
89 | MODULE_PARM_DESC(fua, "FUA support (0=off, 1=on)"); | 89 | MODULE_PARM_DESC(fua, "FUA support (0=off, 1=on)"); |
90 | 90 | ||
91 | static int ata_probe_timeout = ATA_TMOUT_INTERNAL / HZ; | ||
92 | module_param(ata_probe_timeout, int, 0444); | ||
93 | MODULE_PARM_DESC(ata_probe_timeout, "Set ATA probing timeout (seconds)"); | ||
94 | |||
91 | MODULE_AUTHOR("Jeff Garzik"); | 95 | MODULE_AUTHOR("Jeff Garzik"); |
92 | MODULE_DESCRIPTION("Library module for ATA devices"); | 96 | MODULE_DESCRIPTION("Library module for ATA devices"); |
93 | MODULE_LICENSE("GPL"); | 97 | MODULE_LICENSE("GPL"); |
@@ -777,11 +781,9 @@ void ata_std_dev_select (struct ata_port *ap, unsigned int device) | |||
777 | void ata_dev_select(struct ata_port *ap, unsigned int device, | 781 | void ata_dev_select(struct ata_port *ap, unsigned int device, |
778 | unsigned int wait, unsigned int can_sleep) | 782 | unsigned int wait, unsigned int can_sleep) |
779 | { | 783 | { |
780 | if (ata_msg_probe(ap)) { | 784 | if (ata_msg_probe(ap)) |
781 | ata_port_printk(ap, KERN_INFO, "ata_dev_select: ENTER, ata%u: " | 785 | ata_port_printk(ap, KERN_INFO, "ata_dev_select: ENTER, ata%u: " |
782 | "device %u, wait %u\n", | 786 | "device %u, wait %u\n", ap->id, device, wait); |
783 | ap->id, device, wait); | ||
784 | } | ||
785 | 787 | ||
786 | if (wait) | 788 | if (wait) |
787 | ata_wait_idle(ap); | 789 | ata_wait_idle(ap); |
@@ -950,7 +952,8 @@ void ata_port_flush_task(struct ata_port *ap) | |||
950 | */ | 952 | */ |
951 | if (!cancel_delayed_work(&ap->port_task)) { | 953 | if (!cancel_delayed_work(&ap->port_task)) { |
952 | if (ata_msg_ctl(ap)) | 954 | if (ata_msg_ctl(ap)) |
953 | ata_port_printk(ap, KERN_DEBUG, "%s: flush #2\n", __FUNCTION__); | 955 | ata_port_printk(ap, KERN_DEBUG, "%s: flush #2\n", |
956 | __FUNCTION__); | ||
954 | flush_workqueue(ata_wq); | 957 | flush_workqueue(ata_wq); |
955 | } | 958 | } |
956 | 959 | ||
@@ -1059,7 +1062,7 @@ unsigned ata_exec_internal(struct ata_device *dev, | |||
1059 | 1062 | ||
1060 | spin_unlock_irqrestore(ap->lock, flags); | 1063 | spin_unlock_irqrestore(ap->lock, flags); |
1061 | 1064 | ||
1062 | rc = wait_for_completion_timeout(&wait, ATA_TMOUT_INTERNAL); | 1065 | rc = wait_for_completion_timeout(&wait, ata_probe_timeout); |
1063 | 1066 | ||
1064 | ata_port_flush_task(ap); | 1067 | ata_port_flush_task(ap); |
1065 | 1068 | ||
@@ -1081,7 +1084,7 @@ unsigned ata_exec_internal(struct ata_device *dev, | |||
1081 | 1084 | ||
1082 | if (ata_msg_warn(ap)) | 1085 | if (ata_msg_warn(ap)) |
1083 | ata_dev_printk(dev, KERN_WARNING, | 1086 | ata_dev_printk(dev, KERN_WARNING, |
1084 | "qc timeout (cmd 0x%x)\n", command); | 1087 | "qc timeout (cmd 0x%x)\n", command); |
1085 | } | 1088 | } |
1086 | 1089 | ||
1087 | spin_unlock_irqrestore(ap->lock, flags); | 1090 | spin_unlock_irqrestore(ap->lock, flags); |
@@ -1093,9 +1096,9 @@ unsigned ata_exec_internal(struct ata_device *dev, | |||
1093 | 1096 | ||
1094 | if (qc->flags & ATA_QCFLAG_FAILED && !qc->err_mask) { | 1097 | if (qc->flags & ATA_QCFLAG_FAILED && !qc->err_mask) { |
1095 | if (ata_msg_warn(ap)) | 1098 | if (ata_msg_warn(ap)) |
1096 | ata_dev_printk(dev, KERN_WARNING, | 1099 | ata_dev_printk(dev, KERN_WARNING, |
1097 | "zero err_mask for failed " | 1100 | "zero err_mask for failed " |
1098 | "internal command, assuming AC_ERR_OTHER\n"); | 1101 | "internal command, assuming AC_ERR_OTHER\n"); |
1099 | qc->err_mask |= AC_ERR_OTHER; | 1102 | qc->err_mask |= AC_ERR_OTHER; |
1100 | } | 1103 | } |
1101 | 1104 | ||
@@ -1132,6 +1135,33 @@ unsigned ata_exec_internal(struct ata_device *dev, | |||
1132 | } | 1135 | } |
1133 | 1136 | ||
1134 | /** | 1137 | /** |
1138 | * ata_do_simple_cmd - execute simple internal command | ||
1139 | * @dev: Device to which the command is sent | ||
1140 | * @cmd: Opcode to execute | ||
1141 | * | ||
1142 | * Execute a 'simple' command, that only consists of the opcode | ||
1143 | * 'cmd' itself, without filling any other registers | ||
1144 | * | ||
1145 | * LOCKING: | ||
1146 | * Kernel thread context (may sleep). | ||
1147 | * | ||
1148 | * RETURNS: | ||
1149 | * Zero on success, AC_ERR_* mask on failure | ||
1150 | */ | ||
1151 | unsigned int ata_do_simple_cmd(struct ata_device *dev, u8 cmd) | ||
1152 | { | ||
1153 | struct ata_taskfile tf; | ||
1154 | |||
1155 | ata_tf_init(dev, &tf); | ||
1156 | |||
1157 | tf.command = cmd; | ||
1158 | tf.flags |= ATA_TFLAG_DEVICE; | ||
1159 | tf.protocol = ATA_PROT_NODATA; | ||
1160 | |||
1161 | return ata_exec_internal(dev, &tf, NULL, DMA_NONE, NULL, 0); | ||
1162 | } | ||
1163 | |||
1164 | /** | ||
1135 | * ata_pio_need_iordy - check if iordy needed | 1165 | * ata_pio_need_iordy - check if iordy needed |
1136 | * @adev: ATA device | 1166 | * @adev: ATA device |
1137 | * | 1167 | * |
@@ -1193,8 +1223,8 @@ int ata_dev_read_id(struct ata_device *dev, unsigned int *p_class, | |||
1193 | int rc; | 1223 | int rc; |
1194 | 1224 | ||
1195 | if (ata_msg_ctl(ap)) | 1225 | if (ata_msg_ctl(ap)) |
1196 | ata_dev_printk(dev, KERN_DEBUG, "%s: ENTER, host %u, dev %u\n", | 1226 | ata_dev_printk(dev, KERN_DEBUG, "%s: ENTER, host %u, dev %u\n", |
1197 | __FUNCTION__, ap->id, dev->devno); | 1227 | __FUNCTION__, ap->id, dev->devno); |
1198 | 1228 | ||
1199 | ata_dev_select(ap, dev->devno, 1, 1); /* select device 0/1 */ | 1229 | ata_dev_select(ap, dev->devno, 1, 1); /* select device 0/1 */ |
1200 | 1230 | ||
@@ -1263,9 +1293,9 @@ int ata_dev_read_id(struct ata_device *dev, unsigned int *p_class, | |||
1263 | return 0; | 1293 | return 0; |
1264 | 1294 | ||
1265 | err_out: | 1295 | err_out: |
1266 | if (ata_msg_warn(ap)) | 1296 | if (ata_msg_warn(ap)) |
1267 | ata_dev_printk(dev, KERN_WARNING, "failed to IDENTIFY " | 1297 | ata_dev_printk(dev, KERN_WARNING, "failed to IDENTIFY " |
1268 | "(%s, err_mask=0x%x)\n", reason, err_mask); | 1298 | "(%s, err_mask=0x%x)\n", reason, err_mask); |
1269 | return rc; | 1299 | return rc; |
1270 | } | 1300 | } |
1271 | 1301 | ||
@@ -1318,19 +1348,21 @@ int ata_dev_configure(struct ata_device *dev, int print_info) | |||
1318 | int i, rc; | 1348 | int i, rc; |
1319 | 1349 | ||
1320 | if (!ata_dev_enabled(dev) && ata_msg_info(ap)) { | 1350 | if (!ata_dev_enabled(dev) && ata_msg_info(ap)) { |
1321 | ata_dev_printk(dev, KERN_INFO, "%s: ENTER/EXIT (host %u, dev %u) -- nodev\n", | 1351 | ata_dev_printk(dev, KERN_INFO, |
1322 | __FUNCTION__, ap->id, dev->devno); | 1352 | "%s: ENTER/EXIT (host %u, dev %u) -- nodev\n", |
1353 | __FUNCTION__, ap->id, dev->devno); | ||
1323 | return 0; | 1354 | return 0; |
1324 | } | 1355 | } |
1325 | 1356 | ||
1326 | if (ata_msg_probe(ap)) | 1357 | if (ata_msg_probe(ap)) |
1327 | ata_dev_printk(dev, KERN_DEBUG, "%s: ENTER, host %u, dev %u\n", | 1358 | ata_dev_printk(dev, KERN_DEBUG, "%s: ENTER, host %u, dev %u\n", |
1328 | __FUNCTION__, ap->id, dev->devno); | 1359 | __FUNCTION__, ap->id, dev->devno); |
1329 | 1360 | ||
1330 | /* print device capabilities */ | 1361 | /* print device capabilities */ |
1331 | if (ata_msg_probe(ap)) | 1362 | if (ata_msg_probe(ap)) |
1332 | ata_dev_printk(dev, KERN_DEBUG, "%s: cfg 49:%04x 82:%04x 83:%04x " | 1363 | ata_dev_printk(dev, KERN_DEBUG, |
1333 | "84:%04x 85:%04x 86:%04x 87:%04x 88:%04x\n", | 1364 | "%s: cfg 49:%04x 82:%04x 83:%04x 84:%04x " |
1365 | "85:%04x 86:%04x 87:%04x 88:%04x\n", | ||
1334 | __FUNCTION__, | 1366 | __FUNCTION__, |
1335 | id[49], id[82], id[83], id[84], | 1367 | id[49], id[82], id[83], id[84], |
1336 | id[85], id[86], id[87], id[88]); | 1368 | id[85], id[86], id[87], id[88]); |
@@ -1402,14 +1434,16 @@ int ata_dev_configure(struct ata_device *dev, int print_info) | |||
1402 | ata_id_major_version(id), | 1434 | ata_id_major_version(id), |
1403 | ata_mode_string(xfer_mask), | 1435 | ata_mode_string(xfer_mask), |
1404 | (unsigned long long)dev->n_sectors, | 1436 | (unsigned long long)dev->n_sectors, |
1405 | dev->cylinders, dev->heads, dev->sectors); | 1437 | dev->cylinders, dev->heads, |
1438 | dev->sectors); | ||
1406 | } | 1439 | } |
1407 | 1440 | ||
1408 | if (dev->id[59] & 0x100) { | 1441 | if (dev->id[59] & 0x100) { |
1409 | dev->multi_count = dev->id[59] & 0xff; | 1442 | dev->multi_count = dev->id[59] & 0xff; |
1410 | if (ata_msg_info(ap)) | 1443 | if (ata_msg_info(ap)) |
1411 | ata_dev_printk(dev, KERN_INFO, "ata%u: dev %u multi count %u\n", | 1444 | ata_dev_printk(dev, KERN_INFO, |
1412 | ap->id, dev->devno, dev->multi_count); | 1445 | "ata%u: dev %u multi count %u\n", |
1446 | ap->id, dev->devno, dev->multi_count); | ||
1413 | } | 1447 | } |
1414 | 1448 | ||
1415 | dev->cdb_len = 16; | 1449 | dev->cdb_len = 16; |
@@ -1422,8 +1456,8 @@ int ata_dev_configure(struct ata_device *dev, int print_info) | |||
1422 | rc = atapi_cdb_len(id); | 1456 | rc = atapi_cdb_len(id); |
1423 | if ((rc < 12) || (rc > ATAPI_CDB_LEN)) { | 1457 | if ((rc < 12) || (rc > ATAPI_CDB_LEN)) { |
1424 | if (ata_msg_warn(ap)) | 1458 | if (ata_msg_warn(ap)) |
1425 | ata_dev_printk(dev, KERN_WARNING, | 1459 | ata_dev_printk(dev, KERN_WARNING, |
1426 | "unsupported CDB len\n"); | 1460 | "unsupported CDB len\n"); |
1427 | rc = -EINVAL; | 1461 | rc = -EINVAL; |
1428 | goto err_out_nosup; | 1462 | goto err_out_nosup; |
1429 | } | 1463 | } |
@@ -1466,8 +1500,8 @@ int ata_dev_configure(struct ata_device *dev, int print_info) | |||
1466 | 1500 | ||
1467 | err_out_nosup: | 1501 | err_out_nosup: |
1468 | if (ata_msg_probe(ap)) | 1502 | if (ata_msg_probe(ap)) |
1469 | ata_dev_printk(dev, KERN_DEBUG, | 1503 | ata_dev_printk(dev, KERN_DEBUG, |
1470 | "%s: EXIT, err\n", __FUNCTION__); | 1504 | "%s: EXIT, err\n", __FUNCTION__); |
1471 | return rc; | 1505 | return rc; |
1472 | } | 1506 | } |
1473 | 1507 | ||
@@ -3527,7 +3561,7 @@ void swap_buf_le16(u16 *buf, unsigned int buf_words) | |||
3527 | * Inherited from caller. | 3561 | * Inherited from caller. |
3528 | */ | 3562 | */ |
3529 | 3563 | ||
3530 | void ata_mmio_data_xfer(struct ata_device *adev, unsigned char *buf, | 3564 | void ata_mmio_data_xfer(struct ata_device *adev, unsigned char *buf, |
3531 | unsigned int buflen, int write_data) | 3565 | unsigned int buflen, int write_data) |
3532 | { | 3566 | { |
3533 | struct ata_port *ap = adev->ap; | 3567 | struct ata_port *ap = adev->ap; |
@@ -3573,7 +3607,7 @@ void ata_mmio_data_xfer(struct ata_device *adev, unsigned char *buf, | |||
3573 | * Inherited from caller. | 3607 | * Inherited from caller. |
3574 | */ | 3608 | */ |
3575 | 3609 | ||
3576 | void ata_pio_data_xfer(struct ata_device *adev, unsigned char *buf, | 3610 | void ata_pio_data_xfer(struct ata_device *adev, unsigned char *buf, |
3577 | unsigned int buflen, int write_data) | 3611 | unsigned int buflen, int write_data) |
3578 | { | 3612 | { |
3579 | struct ata_port *ap = adev->ap; | 3613 | struct ata_port *ap = adev->ap; |
@@ -3607,7 +3641,7 @@ void ata_pio_data_xfer(struct ata_device *adev, unsigned char *buf, | |||
3607 | * @buflen: buffer length | 3641 | * @buflen: buffer length |
3608 | * @write_data: read/write | 3642 | * @write_data: read/write |
3609 | * | 3643 | * |
3610 | * Transfer data from/to the device data register by PIO. Do the | 3644 | * Transfer data from/to the device data register by PIO. Do the |
3611 | * transfer with interrupts disabled. | 3645 | * transfer with interrupts disabled. |
3612 | * | 3646 | * |
3613 | * LOCKING: | 3647 | * LOCKING: |
@@ -4946,31 +4980,9 @@ int ata_port_offline(struct ata_port *ap) | |||
4946 | return 0; | 4980 | return 0; |
4947 | } | 4981 | } |
4948 | 4982 | ||
4949 | /* | 4983 | int ata_flush_cache(struct ata_device *dev) |
4950 | * Execute a 'simple' command, that only consists of the opcode 'cmd' itself, | ||
4951 | * without filling any other registers | ||
4952 | */ | ||
4953 | static int ata_do_simple_cmd(struct ata_device *dev, u8 cmd) | ||
4954 | { | ||
4955 | struct ata_taskfile tf; | ||
4956 | int err; | ||
4957 | |||
4958 | ata_tf_init(dev, &tf); | ||
4959 | |||
4960 | tf.command = cmd; | ||
4961 | tf.flags |= ATA_TFLAG_DEVICE; | ||
4962 | tf.protocol = ATA_PROT_NODATA; | ||
4963 | |||
4964 | err = ata_exec_internal(dev, &tf, NULL, DMA_NONE, NULL, 0); | ||
4965 | if (err) | ||
4966 | ata_dev_printk(dev, KERN_ERR, "%s: ata command failed: %d\n", | ||
4967 | __FUNCTION__, err); | ||
4968 | |||
4969 | return err; | ||
4970 | } | ||
4971 | |||
4972 | static int ata_flush_cache(struct ata_device *dev) | ||
4973 | { | 4984 | { |
4985 | unsigned int err_mask; | ||
4974 | u8 cmd; | 4986 | u8 cmd; |
4975 | 4987 | ||
4976 | if (!ata_try_flush_cache(dev)) | 4988 | if (!ata_try_flush_cache(dev)) |
@@ -4981,17 +4993,41 @@ static int ata_flush_cache(struct ata_device *dev) | |||
4981 | else | 4993 | else |
4982 | cmd = ATA_CMD_FLUSH; | 4994 | cmd = ATA_CMD_FLUSH; |
4983 | 4995 | ||
4984 | return ata_do_simple_cmd(dev, cmd); | 4996 | err_mask = ata_do_simple_cmd(dev, cmd); |
4997 | if (err_mask) { | ||
4998 | ata_dev_printk(dev, KERN_ERR, "failed to flush cache\n"); | ||
4999 | return -EIO; | ||
5000 | } | ||
5001 | |||
5002 | return 0; | ||
4985 | } | 5003 | } |
4986 | 5004 | ||
4987 | static int ata_standby_drive(struct ata_device *dev) | 5005 | static int ata_standby_drive(struct ata_device *dev) |
4988 | { | 5006 | { |
4989 | return ata_do_simple_cmd(dev, ATA_CMD_STANDBYNOW1); | 5007 | unsigned int err_mask; |
5008 | |||
5009 | err_mask = ata_do_simple_cmd(dev, ATA_CMD_STANDBYNOW1); | ||
5010 | if (err_mask) { | ||
5011 | ata_dev_printk(dev, KERN_ERR, "failed to standby drive " | ||
5012 | "(err_mask=0x%x)\n", err_mask); | ||
5013 | return -EIO; | ||
5014 | } | ||
5015 | |||
5016 | return 0; | ||
4990 | } | 5017 | } |
4991 | 5018 | ||
4992 | static int ata_start_drive(struct ata_device *dev) | 5019 | static int ata_start_drive(struct ata_device *dev) |
4993 | { | 5020 | { |
4994 | return ata_do_simple_cmd(dev, ATA_CMD_IDLEIMMEDIATE); | 5021 | unsigned int err_mask; |
5022 | |||
5023 | err_mask = ata_do_simple_cmd(dev, ATA_CMD_IDLEIMMEDIATE); | ||
5024 | if (err_mask) { | ||
5025 | ata_dev_printk(dev, KERN_ERR, "failed to start drive " | ||
5026 | "(err_mask=0x%x)\n", err_mask); | ||
5027 | return -EIO; | ||
5028 | } | ||
5029 | |||
5030 | return 0; | ||
4995 | } | 5031 | } |
4996 | 5032 | ||
4997 | /** | 5033 | /** |
@@ -5212,7 +5248,7 @@ static void ata_host_init(struct ata_port *ap, struct Scsi_Host *host, | |||
5212 | ap->msg_enable = 0x00FF; | 5248 | ap->msg_enable = 0x00FF; |
5213 | #elif defined(ATA_DEBUG) | 5249 | #elif defined(ATA_DEBUG) |
5214 | ap->msg_enable = ATA_MSG_DRV | ATA_MSG_INFO | ATA_MSG_CTL | ATA_MSG_WARN | ATA_MSG_ERR; | 5250 | ap->msg_enable = ATA_MSG_DRV | ATA_MSG_INFO | ATA_MSG_CTL | ATA_MSG_WARN | ATA_MSG_ERR; |
5215 | #else | 5251 | #else |
5216 | ap->msg_enable = ATA_MSG_DRV | ATA_MSG_ERR | ATA_MSG_WARN; | 5252 | ap->msg_enable = ATA_MSG_DRV | ATA_MSG_ERR | ATA_MSG_WARN; |
5217 | #endif | 5253 | #endif |
5218 | 5254 | ||
@@ -5709,6 +5745,7 @@ int ata_pci_device_resume(struct pci_dev *pdev) | |||
5709 | 5745 | ||
5710 | static int __init ata_init(void) | 5746 | static int __init ata_init(void) |
5711 | { | 5747 | { |
5748 | ata_probe_timeout *= HZ; | ||
5712 | ata_wq = create_workqueue("ata"); | 5749 | ata_wq = create_workqueue("ata"); |
5713 | if (!ata_wq) | 5750 | if (!ata_wq) |
5714 | return -ENOMEM; | 5751 | return -ENOMEM; |
@@ -5733,7 +5770,7 @@ module_init(ata_init); | |||
5733 | module_exit(ata_exit); | 5770 | module_exit(ata_exit); |
5734 | 5771 | ||
5735 | static unsigned long ratelimit_time; | 5772 | static unsigned long ratelimit_time; |
5736 | static spinlock_t ata_ratelimit_lock = SPIN_LOCK_UNLOCKED; | 5773 | static DEFINE_SPINLOCK(ata_ratelimit_lock); |
5737 | 5774 | ||
5738 | int ata_ratelimit(void) | 5775 | int ata_ratelimit(void) |
5739 | { | 5776 | { |
diff --git a/drivers/scsi/libata-eh.c b/drivers/scsi/libata-eh.c index 823385981a7a..bf5a72aca8a4 100644 --- a/drivers/scsi/libata-eh.c +++ b/drivers/scsi/libata-eh.c | |||
@@ -93,6 +93,38 @@ static int ata_ering_map(struct ata_ering *ering, | |||
93 | return rc; | 93 | return rc; |
94 | } | 94 | } |
95 | 95 | ||
96 | static unsigned int ata_eh_dev_action(struct ata_device *dev) | ||
97 | { | ||
98 | struct ata_eh_context *ehc = &dev->ap->eh_context; | ||
99 | |||
100 | return ehc->i.action | ehc->i.dev_action[dev->devno]; | ||
101 | } | ||
102 | |||
103 | static void ata_eh_clear_action(struct ata_device *dev, | ||
104 | struct ata_eh_info *ehi, unsigned int action) | ||
105 | { | ||
106 | int i; | ||
107 | |||
108 | if (!dev) { | ||
109 | ehi->action &= ~action; | ||
110 | for (i = 0; i < ATA_MAX_DEVICES; i++) | ||
111 | ehi->dev_action[i] &= ~action; | ||
112 | } else { | ||
113 | /* doesn't make sense for port-wide EH actions */ | ||
114 | WARN_ON(!(action & ATA_EH_PERDEV_MASK)); | ||
115 | |||
116 | /* break ehi->action into ehi->dev_action */ | ||
117 | if (ehi->action & action) { | ||
118 | for (i = 0; i < ATA_MAX_DEVICES; i++) | ||
119 | ehi->dev_action[i] |= ehi->action & action; | ||
120 | ehi->action &= ~action; | ||
121 | } | ||
122 | |||
123 | /* turn off the specified per-dev action */ | ||
124 | ehi->dev_action[dev->devno] &= ~action; | ||
125 | } | ||
126 | } | ||
127 | |||
96 | /** | 128 | /** |
97 | * ata_scsi_timed_out - SCSI layer time out callback | 129 | * ata_scsi_timed_out - SCSI layer time out callback |
98 | * @cmd: timed out SCSI command | 130 | * @cmd: timed out SCSI command |
@@ -702,32 +734,11 @@ static void ata_eh_detach_dev(struct ata_device *dev) | |||
702 | ap->flags |= ATA_FLAG_SCSI_HOTPLUG; | 734 | ap->flags |= ATA_FLAG_SCSI_HOTPLUG; |
703 | } | 735 | } |
704 | 736 | ||
705 | spin_unlock_irqrestore(ap->lock, flags); | 737 | /* clear per-dev EH actions */ |
706 | } | 738 | ata_eh_clear_action(dev, &ap->eh_info, ATA_EH_PERDEV_MASK); |
707 | 739 | ata_eh_clear_action(dev, &ap->eh_context.i, ATA_EH_PERDEV_MASK); | |
708 | static void ata_eh_clear_action(struct ata_device *dev, | ||
709 | struct ata_eh_info *ehi, unsigned int action) | ||
710 | { | ||
711 | int i; | ||
712 | 740 | ||
713 | if (!dev) { | 741 | spin_unlock_irqrestore(ap->lock, flags); |
714 | ehi->action &= ~action; | ||
715 | for (i = 0; i < ATA_MAX_DEVICES; i++) | ||
716 | ehi->dev_action[i] &= ~action; | ||
717 | } else { | ||
718 | /* doesn't make sense for port-wide EH actions */ | ||
719 | WARN_ON(!(action & ATA_EH_PERDEV_MASK)); | ||
720 | |||
721 | /* break ehi->action into ehi->dev_action */ | ||
722 | if (ehi->action & action) { | ||
723 | for (i = 0; i < ATA_MAX_DEVICES; i++) | ||
724 | ehi->dev_action[i] |= ehi->action & action; | ||
725 | ehi->action &= ~action; | ||
726 | } | ||
727 | |||
728 | /* turn off the specified per-dev action */ | ||
729 | ehi->dev_action[dev->devno] &= ~action; | ||
730 | } | ||
731 | } | 742 | } |
732 | 743 | ||
733 | /** | 744 | /** |
@@ -1592,7 +1603,7 @@ static int ata_eh_revalidate_and_attach(struct ata_port *ap, | |||
1592 | unsigned int action; | 1603 | unsigned int action; |
1593 | 1604 | ||
1594 | dev = &ap->device[i]; | 1605 | dev = &ap->device[i]; |
1595 | action = ehc->i.action | ehc->i.dev_action[dev->devno]; | 1606 | action = ata_eh_dev_action(dev); |
1596 | 1607 | ||
1597 | if (action & ATA_EH_REVALIDATE && ata_dev_enabled(dev)) { | 1608 | if (action & ATA_EH_REVALIDATE && ata_dev_enabled(dev)) { |
1598 | if (ata_port_offline(ap)) { | 1609 | if (ata_port_offline(ap)) { |
diff --git a/drivers/scsi/libata-scsi.c b/drivers/scsi/libata-scsi.c index 93d18a74c401..2915bca691e8 100644 --- a/drivers/scsi/libata-scsi.c +++ b/drivers/scsi/libata-scsi.c | |||
@@ -222,9 +222,7 @@ int ata_cmd_ioctl(struct scsi_device *scsidev, void __user *arg) | |||
222 | && copy_to_user(arg + sizeof(args), argbuf, argsize)) | 222 | && copy_to_user(arg + sizeof(args), argbuf, argsize)) |
223 | rc = -EFAULT; | 223 | rc = -EFAULT; |
224 | error: | 224 | error: |
225 | if (argbuf) | 225 | kfree(argbuf); |
226 | kfree(argbuf); | ||
227 | |||
228 | return rc; | 226 | return rc; |
229 | } | 227 | } |
230 | 228 | ||
diff --git a/drivers/scsi/libata.h b/drivers/scsi/libata.h index bdd488897096..c325679d9b54 100644 --- a/drivers/scsi/libata.h +++ b/drivers/scsi/libata.h | |||
@@ -29,7 +29,7 @@ | |||
29 | #define __LIBATA_H__ | 29 | #define __LIBATA_H__ |
30 | 30 | ||
31 | #define DRV_NAME "libata" | 31 | #define DRV_NAME "libata" |
32 | #define DRV_VERSION "1.30" /* must be exactly four chars */ | 32 | #define DRV_VERSION "2.00" /* must be exactly four chars */ |
33 | 33 | ||
34 | struct ata_scsi_args { | 34 | struct ata_scsi_args { |
35 | struct ata_device *dev; | 35 | struct ata_device *dev; |
@@ -50,6 +50,7 @@ extern void ata_port_flush_task(struct ata_port *ap); | |||
50 | extern unsigned ata_exec_internal(struct ata_device *dev, | 50 | extern unsigned ata_exec_internal(struct ata_device *dev, |
51 | struct ata_taskfile *tf, const u8 *cdb, | 51 | struct ata_taskfile *tf, const u8 *cdb, |
52 | int dma_dir, void *buf, unsigned int buflen); | 52 | int dma_dir, void *buf, unsigned int buflen); |
53 | extern unsigned int ata_do_simple_cmd(struct ata_device *dev, u8 cmd); | ||
53 | extern int ata_dev_read_id(struct ata_device *dev, unsigned int *p_class, | 54 | extern int ata_dev_read_id(struct ata_device *dev, unsigned int *p_class, |
54 | int post_reset, u16 *id); | 55 | int post_reset, u16 *id); |
55 | extern int ata_dev_configure(struct ata_device *dev, int print_info); | 56 | extern int ata_dev_configure(struct ata_device *dev, int print_info); |
@@ -64,6 +65,7 @@ extern int ata_check_atapi_dma(struct ata_queued_cmd *qc); | |||
64 | extern void ata_dev_select(struct ata_port *ap, unsigned int device, | 65 | extern void ata_dev_select(struct ata_port *ap, unsigned int device, |
65 | unsigned int wait, unsigned int can_sleep); | 66 | unsigned int wait, unsigned int can_sleep); |
66 | extern void swap_buf_le16(u16 *buf, unsigned int buf_words); | 67 | extern void swap_buf_le16(u16 *buf, unsigned int buf_words); |
68 | extern int ata_flush_cache(struct ata_device *dev); | ||
67 | extern void ata_dev_init(struct ata_device *dev); | 69 | extern void ata_dev_init(struct ata_device *dev); |
68 | extern int ata_task_ioctl(struct scsi_device *scsidev, void __user *arg); | 70 | extern int ata_task_ioctl(struct scsi_device *scsidev, void __user *arg); |
69 | extern int ata_cmd_ioctl(struct scsi_device *scsidev, void __user *arg); | 71 | extern int ata_cmd_ioctl(struct scsi_device *scsidev, void __user *arg); |
diff --git a/drivers/scsi/sata_nv.c b/drivers/scsi/sata_nv.c index d18e7e0932ef..5cc42c6054eb 100644 --- a/drivers/scsi/sata_nv.c +++ b/drivers/scsi/sata_nv.c | |||
@@ -44,7 +44,7 @@ | |||
44 | #include <linux/libata.h> | 44 | #include <linux/libata.h> |
45 | 45 | ||
46 | #define DRV_NAME "sata_nv" | 46 | #define DRV_NAME "sata_nv" |
47 | #define DRV_VERSION "0.9" | 47 | #define DRV_VERSION "2.0" |
48 | 48 | ||
49 | enum { | 49 | enum { |
50 | NV_PORTS = 2, | 50 | NV_PORTS = 2, |
diff --git a/drivers/scsi/sata_sil.c b/drivers/scsi/sata_sil.c index bc9f918a7f28..51d86d750e84 100644 --- a/drivers/scsi/sata_sil.c +++ b/drivers/scsi/sata_sil.c | |||
@@ -46,12 +46,13 @@ | |||
46 | #include <linux/libata.h> | 46 | #include <linux/libata.h> |
47 | 47 | ||
48 | #define DRV_NAME "sata_sil" | 48 | #define DRV_NAME "sata_sil" |
49 | #define DRV_VERSION "1.0" | 49 | #define DRV_VERSION "2.0" |
50 | 50 | ||
51 | enum { | 51 | enum { |
52 | /* | 52 | /* |
53 | * host flags | 53 | * host flags |
54 | */ | 54 | */ |
55 | SIL_FLAG_NO_SATA_IRQ = (1 << 28), | ||
55 | SIL_FLAG_RERR_ON_DMA_ACT = (1 << 29), | 56 | SIL_FLAG_RERR_ON_DMA_ACT = (1 << 29), |
56 | SIL_FLAG_MOD15WRITE = (1 << 30), | 57 | SIL_FLAG_MOD15WRITE = (1 << 30), |
57 | 58 | ||
@@ -62,8 +63,9 @@ enum { | |||
62 | * Controller IDs | 63 | * Controller IDs |
63 | */ | 64 | */ |
64 | sil_3112 = 0, | 65 | sil_3112 = 0, |
65 | sil_3512 = 1, | 66 | sil_3112_no_sata_irq = 1, |
66 | sil_3114 = 2, | 67 | sil_3512 = 2, |
68 | sil_3114 = 3, | ||
67 | 69 | ||
68 | /* | 70 | /* |
69 | * Register offsets | 71 | * Register offsets |
@@ -123,8 +125,8 @@ static const struct pci_device_id sil_pci_tbl[] = { | |||
123 | { 0x1095, 0x3512, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3512 }, | 125 | { 0x1095, 0x3512, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3512 }, |
124 | { 0x1095, 0x3114, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3114 }, | 126 | { 0x1095, 0x3114, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3114 }, |
125 | { 0x1002, 0x436e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3112 }, | 127 | { 0x1002, 0x436e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3112 }, |
126 | { 0x1002, 0x4379, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3112 }, | 128 | { 0x1002, 0x4379, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3112_no_sata_irq }, |
127 | { 0x1002, 0x437a, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3112 }, | 129 | { 0x1002, 0x437a, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3112_no_sata_irq }, |
128 | { } /* terminate list */ | 130 | { } /* terminate list */ |
129 | }; | 131 | }; |
130 | 132 | ||
@@ -217,6 +219,16 @@ static const struct ata_port_info sil_port_info[] = { | |||
217 | .udma_mask = 0x3f, /* udma0-5 */ | 219 | .udma_mask = 0x3f, /* udma0-5 */ |
218 | .port_ops = &sil_ops, | 220 | .port_ops = &sil_ops, |
219 | }, | 221 | }, |
222 | /* sil_3112_no_sata_irq */ | ||
223 | { | ||
224 | .sht = &sil_sht, | ||
225 | .host_flags = SIL_DFL_HOST_FLAGS | SIL_FLAG_MOD15WRITE | | ||
226 | SIL_FLAG_NO_SATA_IRQ, | ||
227 | .pio_mask = 0x1f, /* pio0-4 */ | ||
228 | .mwdma_mask = 0x07, /* mwdma0-2 */ | ||
229 | .udma_mask = 0x3f, /* udma0-5 */ | ||
230 | .port_ops = &sil_ops, | ||
231 | }, | ||
220 | /* sil_3512 */ | 232 | /* sil_3512 */ |
221 | { | 233 | { |
222 | .sht = &sil_sht, | 234 | .sht = &sil_sht, |
@@ -437,6 +449,10 @@ static irqreturn_t sil_interrupt(int irq, void *dev_instance, | |||
437 | if (unlikely(!ap || ap->flags & ATA_FLAG_DISABLED)) | 449 | if (unlikely(!ap || ap->flags & ATA_FLAG_DISABLED)) |
438 | continue; | 450 | continue; |
439 | 451 | ||
452 | /* turn off SATA_IRQ if not supported */ | ||
453 | if (ap->flags & SIL_FLAG_NO_SATA_IRQ) | ||
454 | bmdma2 &= ~SIL_DMA_SATA_IRQ; | ||
455 | |||
440 | if (bmdma2 == 0xffffffff || | 456 | if (bmdma2 == 0xffffffff || |
441 | !(bmdma2 & (SIL_DMA_COMPLETE | SIL_DMA_SATA_IRQ))) | 457 | !(bmdma2 & (SIL_DMA_COMPLETE | SIL_DMA_SATA_IRQ))) |
442 | continue; | 458 | continue; |
@@ -474,8 +490,9 @@ static void sil_thaw(struct ata_port *ap) | |||
474 | ata_chk_status(ap); | 490 | ata_chk_status(ap); |
475 | ata_bmdma_irq_clear(ap); | 491 | ata_bmdma_irq_clear(ap); |
476 | 492 | ||
477 | /* turn on SATA IRQ */ | 493 | /* turn on SATA IRQ if supported */ |
478 | writel(SIL_SIEN_N, mmio_base + sil_port[ap->port_no].sien); | 494 | if (!(ap->flags & SIL_FLAG_NO_SATA_IRQ)) |
495 | writel(SIL_SIEN_N, mmio_base + sil_port[ap->port_no].sien); | ||
479 | 496 | ||
480 | /* turn on IRQ */ | 497 | /* turn on IRQ */ |
481 | tmp = readl(mmio_base + SIL_SYSCFG); | 498 | tmp = readl(mmio_base + SIL_SYSCFG); |
diff --git a/drivers/scsi/sata_sil24.c b/drivers/scsi/sata_sil24.c index c8b477c67247..b5f8fa955679 100644 --- a/drivers/scsi/sata_sil24.c +++ b/drivers/scsi/sata_sil24.c | |||
@@ -31,7 +31,7 @@ | |||
31 | #include <asm/io.h> | 31 | #include <asm/io.h> |
32 | 32 | ||
33 | #define DRV_NAME "sata_sil24" | 33 | #define DRV_NAME "sata_sil24" |
34 | #define DRV_VERSION "0.24" | 34 | #define DRV_VERSION "0.3" |
35 | 35 | ||
36 | /* | 36 | /* |
37 | * Port request block (PRB) 32 bytes | 37 | * Port request block (PRB) 32 bytes |
diff --git a/drivers/scsi/sata_svw.c b/drivers/scsi/sata_svw.c index c94b870cf378..7566c2cabaf7 100644 --- a/drivers/scsi/sata_svw.c +++ b/drivers/scsi/sata_svw.c | |||
@@ -54,7 +54,7 @@ | |||
54 | #endif /* CONFIG_PPC_OF */ | 54 | #endif /* CONFIG_PPC_OF */ |
55 | 55 | ||
56 | #define DRV_NAME "sata_svw" | 56 | #define DRV_NAME "sata_svw" |
57 | #define DRV_VERSION "1.8" | 57 | #define DRV_VERSION "2.0" |
58 | 58 | ||
59 | enum { | 59 | enum { |
60 | /* Taskfile registers offsets */ | 60 | /* Taskfile registers offsets */ |
diff --git a/drivers/scsi/sata_uli.c b/drivers/scsi/sata_uli.c index f668c997e9af..64f3c1aeed21 100644 --- a/drivers/scsi/sata_uli.c +++ b/drivers/scsi/sata_uli.c | |||
@@ -37,7 +37,7 @@ | |||
37 | #include <linux/libata.h> | 37 | #include <linux/libata.h> |
38 | 38 | ||
39 | #define DRV_NAME "sata_uli" | 39 | #define DRV_NAME "sata_uli" |
40 | #define DRV_VERSION "0.6" | 40 | #define DRV_VERSION "1.0" |
41 | 41 | ||
42 | enum { | 42 | enum { |
43 | uli_5289 = 0, | 43 | uli_5289 = 0, |
diff --git a/drivers/scsi/sata_via.c b/drivers/scsi/sata_via.c index 322890b400a6..501ce1791782 100644 --- a/drivers/scsi/sata_via.c +++ b/drivers/scsi/sata_via.c | |||
@@ -47,7 +47,7 @@ | |||
47 | #include <asm/io.h> | 47 | #include <asm/io.h> |
48 | 48 | ||
49 | #define DRV_NAME "sata_via" | 49 | #define DRV_NAME "sata_via" |
50 | #define DRV_VERSION "1.2" | 50 | #define DRV_VERSION "2.0" |
51 | 51 | ||
52 | enum board_ids_enum { | 52 | enum board_ids_enum { |
53 | vt6420, | 53 | vt6420, |
@@ -335,10 +335,10 @@ static int svia_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) | |||
335 | if ((pci_resource_start(pdev, i) == 0) || | 335 | if ((pci_resource_start(pdev, i) == 0) || |
336 | (pci_resource_len(pdev, i) < bar_sizes[i])) { | 336 | (pci_resource_len(pdev, i) < bar_sizes[i])) { |
337 | dev_printk(KERN_ERR, &pdev->dev, | 337 | dev_printk(KERN_ERR, &pdev->dev, |
338 | "invalid PCI BAR %u (sz 0x%lx, val 0x%lx)\n", | 338 | "invalid PCI BAR %u (sz 0x%llx, val 0x%llx)\n", |
339 | i, | 339 | i, |
340 | pci_resource_start(pdev, i), | 340 | (unsigned long long)pci_resource_start(pdev, i), |
341 | pci_resource_len(pdev, i)); | 341 | (unsigned long long)pci_resource_len(pdev, i)); |
342 | rc = -ENODEV; | 342 | rc = -ENODEV; |
343 | goto err_out_regions; | 343 | goto err_out_regions; |
344 | } | 344 | } |
diff --git a/drivers/scsi/sata_vsc.c b/drivers/scsi/sata_vsc.c index 6d0c4f18e652..616fd9634b4b 100644 --- a/drivers/scsi/sata_vsc.c +++ b/drivers/scsi/sata_vsc.c | |||
@@ -47,7 +47,7 @@ | |||
47 | #include <linux/libata.h> | 47 | #include <linux/libata.h> |
48 | 48 | ||
49 | #define DRV_NAME "sata_vsc" | 49 | #define DRV_NAME "sata_vsc" |
50 | #define DRV_VERSION "1.2" | 50 | #define DRV_VERSION "2.0" |
51 | 51 | ||
52 | enum { | 52 | enum { |
53 | /* Interrupt register offsets (from chip base address) */ | 53 | /* Interrupt register offsets (from chip base address) */ |
@@ -443,16 +443,12 @@ err_out: | |||
443 | } | 443 | } |
444 | 444 | ||
445 | 445 | ||
446 | /* | ||
447 | * Intel 31244 is supposed to be identical. | ||
448 | * Compatibility is untested as of yet. | ||
449 | */ | ||
450 | static const struct pci_device_id vsc_sata_pci_tbl[] = { | 446 | static const struct pci_device_id vsc_sata_pci_tbl[] = { |
451 | { PCI_VENDOR_ID_VITESSE, PCI_DEVICE_ID_VITESSE_VSC7174, | 447 | { PCI_VENDOR_ID_VITESSE, 0x7174, |
452 | PCI_ANY_ID, PCI_ANY_ID, 0x10600, 0xFFFFFF, 0 }, | 448 | PCI_ANY_ID, PCI_ANY_ID, 0x10600, 0xFFFFFF, 0 }, |
453 | { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_GD31244, | 449 | { PCI_VENDOR_ID_INTEL, 0x3200, |
454 | PCI_ANY_ID, PCI_ANY_ID, 0x10600, 0xFFFFFF, 0 }, | 450 | PCI_ANY_ID, PCI_ANY_ID, 0x10600, 0xFFFFFF, 0 }, |
455 | { } | 451 | { } /* terminate list */ |
456 | }; | 452 | }; |
457 | 453 | ||
458 | 454 | ||
diff --git a/drivers/serial/21285.c b/drivers/serial/21285.c index 7572665a8855..9fd0de4b7afd 100644 --- a/drivers/serial/21285.c +++ b/drivers/serial/21285.c | |||
@@ -479,7 +479,6 @@ static struct uart_driver serial21285_reg = { | |||
479 | .owner = THIS_MODULE, | 479 | .owner = THIS_MODULE, |
480 | .driver_name = "ttyFB", | 480 | .driver_name = "ttyFB", |
481 | .dev_name = "ttyFB", | 481 | .dev_name = "ttyFB", |
482 | .devfs_name = "ttyFB", | ||
483 | .major = SERIAL_21285_MAJOR, | 482 | .major = SERIAL_21285_MAJOR, |
484 | .minor = SERIAL_21285_MINOR, | 483 | .minor = SERIAL_21285_MINOR, |
485 | .nr = 1, | 484 | .nr = 1, |
diff --git a/drivers/serial/68328serial.c b/drivers/serial/68328serial.c index b88a7c1158af..bff94541991c 100644 --- a/drivers/serial/68328serial.c +++ b/drivers/serial/68328serial.c | |||
@@ -131,17 +131,6 @@ static int m68328_console_baud = CONSOLE_BAUD_RATE; | |||
131 | static int m68328_console_cbaud = DEFAULT_CBAUD; | 131 | static int m68328_console_cbaud = DEFAULT_CBAUD; |
132 | 132 | ||
133 | 133 | ||
134 | /* | ||
135 | * tmp_buf is used as a temporary buffer by serial_write. We need to | ||
136 | * lock it in case the memcpy_fromfs blocks while swapping in a page, | ||
137 | * and some other program tries to do a serial write at the same time. | ||
138 | * Since the lock will only come under contention when the system is | ||
139 | * swapping and available memory is low, it makes sense to share one | ||
140 | * buffer across all the serial ports, since it significantly saves | ||
141 | * memory if large numbers of serial ports are open. | ||
142 | */ | ||
143 | static unsigned char tmp_buf[SERIAL_XMIT_SIZE]; /* This is cheating */ | ||
144 | |||
145 | static inline int serial_paranoia_check(struct m68k_serial *info, | 134 | static inline int serial_paranoia_check(struct m68k_serial *info, |
146 | char *name, const char *routine) | 135 | char *name, const char *routine) |
147 | { | 136 | { |
@@ -211,16 +200,16 @@ static void rs_stop(struct tty_struct *tty) | |||
211 | if (serial_paranoia_check(info, tty->name, "rs_stop")) | 200 | if (serial_paranoia_check(info, tty->name, "rs_stop")) |
212 | return; | 201 | return; |
213 | 202 | ||
214 | save_flags(flags); cli(); | 203 | local_irq_save(flags); |
215 | uart->ustcnt &= ~USTCNT_TXEN; | 204 | uart->ustcnt &= ~USTCNT_TXEN; |
216 | restore_flags(flags); | 205 | local_irq_restore(flags); |
217 | } | 206 | } |
218 | 207 | ||
219 | static void rs_put_char(char ch) | 208 | static void rs_put_char(char ch) |
220 | { | 209 | { |
221 | int flags, loops = 0; | 210 | int flags, loops = 0; |
222 | 211 | ||
223 | save_flags(flags); cli(); | 212 | local_irq_save(flags); |
224 | 213 | ||
225 | while (!(UTX & UTX_TX_AVAIL) && (loops < 1000)) { | 214 | while (!(UTX & UTX_TX_AVAIL) && (loops < 1000)) { |
226 | loops++; | 215 | loops++; |
@@ -229,7 +218,7 @@ static void rs_put_char(char ch) | |||
229 | 218 | ||
230 | UTX_TXDATA = ch; | 219 | UTX_TXDATA = ch; |
231 | udelay(5); | 220 | udelay(5); |
232 | restore_flags(flags); | 221 | local_irq_restore(flags); |
233 | } | 222 | } |
234 | 223 | ||
235 | static void rs_start(struct tty_struct *tty) | 224 | static void rs_start(struct tty_struct *tty) |
@@ -241,7 +230,7 @@ static void rs_start(struct tty_struct *tty) | |||
241 | if (serial_paranoia_check(info, tty->name, "rs_start")) | 230 | if (serial_paranoia_check(info, tty->name, "rs_start")) |
242 | return; | 231 | return; |
243 | 232 | ||
244 | save_flags(flags); cli(); | 233 | local_irq_save(flags); |
245 | if (info->xmit_cnt && info->xmit_buf && !(uart->ustcnt & USTCNT_TXEN)) { | 234 | if (info->xmit_cnt && info->xmit_buf && !(uart->ustcnt & USTCNT_TXEN)) { |
246 | #ifdef USE_INTS | 235 | #ifdef USE_INTS |
247 | uart->ustcnt |= USTCNT_TXEN | USTCNT_TX_INTR_MASK; | 236 | uart->ustcnt |= USTCNT_TXEN | USTCNT_TX_INTR_MASK; |
@@ -249,7 +238,7 @@ static void rs_start(struct tty_struct *tty) | |||
249 | uart->ustcnt |= USTCNT_TXEN; | 238 | uart->ustcnt |= USTCNT_TXEN; |
250 | #endif | 239 | #endif |
251 | } | 240 | } |
252 | restore_flags(flags); | 241 | local_irq_restore(flags); |
253 | } | 242 | } |
254 | 243 | ||
255 | /* Drop into either the boot monitor or kadb upon receiving a break | 244 | /* Drop into either the boot monitor or kadb upon receiving a break |
@@ -327,14 +316,6 @@ static void receive_chars(struct m68k_serial *info, struct pt_regs *regs, | |||
327 | if(!tty) | 316 | if(!tty) |
328 | goto clear_and_exit; | 317 | goto clear_and_exit; |
329 | 318 | ||
330 | /* | ||
331 | * Make sure that we do not overflow the buffer | ||
332 | */ | ||
333 | if (tty_request_buffer_room(tty, 1) == 0) { | ||
334 | tty_schedule_flip(tty); | ||
335 | return; | ||
336 | } | ||
337 | |||
338 | flag = TTY_NORMAL; | 319 | flag = TTY_NORMAL; |
339 | 320 | ||
340 | if(rx & URX_PARITY_ERROR) { | 321 | if(rx & URX_PARITY_ERROR) { |
@@ -473,7 +454,7 @@ static int startup(struct m68k_serial * info) | |||
473 | return -ENOMEM; | 454 | return -ENOMEM; |
474 | } | 455 | } |
475 | 456 | ||
476 | save_flags(flags); cli(); | 457 | local_irq_save(flags); |
477 | 458 | ||
478 | /* | 459 | /* |
479 | * Clear the FIFO buffers and disable them | 460 | * Clear the FIFO buffers and disable them |
@@ -506,7 +487,7 @@ static int startup(struct m68k_serial * info) | |||
506 | change_speed(info); | 487 | change_speed(info); |
507 | 488 | ||
508 | info->flags |= S_INITIALIZED; | 489 | info->flags |= S_INITIALIZED; |
509 | restore_flags(flags); | 490 | local_irq_restore(flags); |
510 | return 0; | 491 | return 0; |
511 | } | 492 | } |
512 | 493 | ||
@@ -523,7 +504,7 @@ static void shutdown(struct m68k_serial * info) | |||
523 | if (!(info->flags & S_INITIALIZED)) | 504 | if (!(info->flags & S_INITIALIZED)) |
524 | return; | 505 | return; |
525 | 506 | ||
526 | save_flags(flags); cli(); /* Disable interrupts */ | 507 | local_irq_save(flags); |
527 | 508 | ||
528 | if (info->xmit_buf) { | 509 | if (info->xmit_buf) { |
529 | free_page((unsigned long) info->xmit_buf); | 510 | free_page((unsigned long) info->xmit_buf); |
@@ -534,7 +515,7 @@ static void shutdown(struct m68k_serial * info) | |||
534 | set_bit(TTY_IO_ERROR, &info->tty->flags); | 515 | set_bit(TTY_IO_ERROR, &info->tty->flags); |
535 | 516 | ||
536 | info->flags &= ~S_INITIALIZED; | 517 | info->flags &= ~S_INITIALIZED; |
537 | restore_flags(flags); | 518 | local_irq_restore(flags); |
538 | } | 519 | } |
539 | 520 | ||
540 | struct { | 521 | struct { |
@@ -655,24 +636,24 @@ static void rs_fair_output(void) | |||
655 | if (info == 0) return; | 636 | if (info == 0) return; |
656 | if (info->xmit_buf == 0) return; | 637 | if (info->xmit_buf == 0) return; |
657 | 638 | ||
658 | save_flags(flags); cli(); | 639 | local_irq_save(flags); |
659 | left = info->xmit_cnt; | 640 | left = info->xmit_cnt; |
660 | while (left != 0) { | 641 | while (left != 0) { |
661 | c = info->xmit_buf[info->xmit_tail]; | 642 | c = info->xmit_buf[info->xmit_tail]; |
662 | info->xmit_tail = (info->xmit_tail+1) & (SERIAL_XMIT_SIZE-1); | 643 | info->xmit_tail = (info->xmit_tail+1) & (SERIAL_XMIT_SIZE-1); |
663 | info->xmit_cnt--; | 644 | info->xmit_cnt--; |
664 | restore_flags(flags); | 645 | local_irq_restore(flags); |
665 | 646 | ||
666 | rs_put_char(c); | 647 | rs_put_char(c); |
667 | 648 | ||
668 | save_flags(flags); cli(); | 649 | local_irq_save(flags); |
669 | left = min(info->xmit_cnt, left-1); | 650 | left = min(info->xmit_cnt, left-1); |
670 | } | 651 | } |
671 | 652 | ||
672 | /* Last character is being transmitted now (hopefully). */ | 653 | /* Last character is being transmitted now (hopefully). */ |
673 | udelay(5); | 654 | udelay(5); |
674 | 655 | ||
675 | restore_flags(flags); | 656 | local_irq_restore(flags); |
676 | return; | 657 | return; |
677 | } | 658 | } |
678 | 659 | ||
@@ -720,11 +701,11 @@ static void rs_flush_chars(struct tty_struct *tty) | |||
720 | #endif | 701 | #endif |
721 | 702 | ||
722 | /* Enable transmitter */ | 703 | /* Enable transmitter */ |
723 | save_flags(flags); cli(); | 704 | local_irq_save(flags); |
724 | 705 | ||
725 | if (info->xmit_cnt <= 0 || tty->stopped || tty->hw_stopped || | 706 | if (info->xmit_cnt <= 0 || tty->stopped || tty->hw_stopped || |
726 | !info->xmit_buf) { | 707 | !info->xmit_buf) { |
727 | restore_flags(flags); | 708 | local_irq_restore(flags); |
728 | return; | 709 | return; |
729 | } | 710 | } |
730 | 711 | ||
@@ -749,7 +730,7 @@ static void rs_flush_chars(struct tty_struct *tty) | |||
749 | while (!(uart->utx.w & UTX_TX_AVAIL)) udelay(5); | 730 | while (!(uart->utx.w & UTX_TX_AVAIL)) udelay(5); |
750 | } | 731 | } |
751 | #endif | 732 | #endif |
752 | restore_flags(flags); | 733 | local_irq_restore(flags); |
753 | } | 734 | } |
754 | 735 | ||
755 | extern void console_printn(const char * b, int count); | 736 | extern void console_printn(const char * b, int count); |
@@ -768,18 +749,22 @@ static int rs_write(struct tty_struct * tty, | |||
768 | if (!tty || !info->xmit_buf) | 749 | if (!tty || !info->xmit_buf) |
769 | return 0; | 750 | return 0; |
770 | 751 | ||
771 | save_flags(flags); | 752 | local_save_flags(flags); |
772 | while (1) { | 753 | while (1) { |
773 | cli(); | 754 | local_irq_disable(); |
774 | c = min_t(int, count, min(SERIAL_XMIT_SIZE - info->xmit_cnt - 1, | 755 | c = min_t(int, count, min(SERIAL_XMIT_SIZE - info->xmit_cnt - 1, |
775 | SERIAL_XMIT_SIZE - info->xmit_head)); | 756 | SERIAL_XMIT_SIZE - info->xmit_head)); |
757 | local_irq_restore(flags); | ||
758 | |||
776 | if (c <= 0) | 759 | if (c <= 0) |
777 | break; | 760 | break; |
778 | 761 | ||
779 | memcpy(info->xmit_buf + info->xmit_head, buf, c); | 762 | memcpy(info->xmit_buf + info->xmit_head, buf, c); |
763 | |||
764 | local_irq_disable(); | ||
780 | info->xmit_head = (info->xmit_head + c) & (SERIAL_XMIT_SIZE-1); | 765 | info->xmit_head = (info->xmit_head + c) & (SERIAL_XMIT_SIZE-1); |
781 | info->xmit_cnt += c; | 766 | info->xmit_cnt += c; |
782 | restore_flags(flags); | 767 | local_irq_restore(flags); |
783 | buf += c; | 768 | buf += c; |
784 | count -= c; | 769 | count -= c; |
785 | total += c; | 770 | total += c; |
@@ -787,7 +772,7 @@ static int rs_write(struct tty_struct * tty, | |||
787 | 772 | ||
788 | if (info->xmit_cnt && !tty->stopped && !tty->hw_stopped) { | 773 | if (info->xmit_cnt && !tty->stopped && !tty->hw_stopped) { |
789 | /* Enable transmitter */ | 774 | /* Enable transmitter */ |
790 | cli(); | 775 | local_irq_disable(); |
791 | #ifndef USE_INTS | 776 | #ifndef USE_INTS |
792 | while(info->xmit_cnt) { | 777 | while(info->xmit_cnt) { |
793 | #endif | 778 | #endif |
@@ -807,9 +792,9 @@ static int rs_write(struct tty_struct * tty, | |||
807 | #ifndef USE_INTS | 792 | #ifndef USE_INTS |
808 | } | 793 | } |
809 | #endif | 794 | #endif |
810 | restore_flags(flags); | 795 | local_irq_restore(flags); |
811 | } | 796 | } |
812 | restore_flags(flags); | 797 | |
813 | return total; | 798 | return total; |
814 | } | 799 | } |
815 | 800 | ||
@@ -838,12 +823,13 @@ static int rs_chars_in_buffer(struct tty_struct *tty) | |||
838 | static void rs_flush_buffer(struct tty_struct *tty) | 823 | static void rs_flush_buffer(struct tty_struct *tty) |
839 | { | 824 | { |
840 | struct m68k_serial *info = (struct m68k_serial *)tty->driver_data; | 825 | struct m68k_serial *info = (struct m68k_serial *)tty->driver_data; |
826 | unsigned long flags; | ||
841 | 827 | ||
842 | if (serial_paranoia_check(info, tty->name, "rs_flush_buffer")) | 828 | if (serial_paranoia_check(info, tty->name, "rs_flush_buffer")) |
843 | return; | 829 | return; |
844 | cli(); | 830 | local_irq_save(flags); |
845 | info->xmit_cnt = info->xmit_head = info->xmit_tail = 0; | 831 | info->xmit_cnt = info->xmit_head = info->xmit_tail = 0; |
846 | sti(); | 832 | local_irq_restore(flags); |
847 | tty_wakeup(tty); | 833 | tty_wakeup(tty); |
848 | } | 834 | } |
849 | 835 | ||
@@ -973,14 +959,15 @@ static int get_lsr_info(struct m68k_serial * info, unsigned int *value) | |||
973 | m68328_uart *uart = &uart_addr[info->line]; | 959 | m68328_uart *uart = &uart_addr[info->line]; |
974 | #endif | 960 | #endif |
975 | unsigned char status; | 961 | unsigned char status; |
962 | unsigned long flags; | ||
976 | 963 | ||
977 | cli(); | 964 | local_irq_save(flags); |
978 | #ifdef CONFIG_SERIAL_68328_RTS_CTS | 965 | #ifdef CONFIG_SERIAL_68328_RTS_CTS |
979 | status = (uart->utx.w & UTX_CTS_STAT) ? 1 : 0; | 966 | status = (uart->utx.w & UTX_CTS_STAT) ? 1 : 0; |
980 | #else | 967 | #else |
981 | status = 0; | 968 | status = 0; |
982 | #endif | 969 | #endif |
983 | sti(); | 970 | local_irq_restore(flags); |
984 | put_user(status,value); | 971 | put_user(status,value); |
985 | return 0; | 972 | return 0; |
986 | } | 973 | } |
@@ -994,14 +981,13 @@ static void send_break(struct m68k_serial * info, unsigned int duration) | |||
994 | unsigned long flags; | 981 | unsigned long flags; |
995 | if (!info->port) | 982 | if (!info->port) |
996 | return; | 983 | return; |
997 | save_flags(flags); | 984 | local_irq_save(flags); |
998 | cli(); | ||
999 | #ifdef USE_INTS | 985 | #ifdef USE_INTS |
1000 | uart->utx.w |= UTX_SEND_BREAK; | 986 | uart->utx.w |= UTX_SEND_BREAK; |
1001 | msleep_interruptible(duration); | 987 | msleep_interruptible(duration); |
1002 | uart->utx.w &= ~UTX_SEND_BREAK; | 988 | uart->utx.w &= ~UTX_SEND_BREAK; |
1003 | #endif | 989 | #endif |
1004 | restore_flags(flags); | 990 | local_irq_restore(flags); |
1005 | } | 991 | } |
1006 | 992 | ||
1007 | static int rs_ioctl(struct tty_struct *tty, struct file * file, | 993 | static int rs_ioctl(struct tty_struct *tty, struct file * file, |
@@ -1060,7 +1046,7 @@ static int rs_ioctl(struct tty_struct *tty, struct file * file, | |||
1060 | (struct serial_struct *) arg); | 1046 | (struct serial_struct *) arg); |
1061 | case TIOCSERGETLSR: /* Get line status register */ | 1047 | case TIOCSERGETLSR: /* Get line status register */ |
1062 | if (access_ok(VERIFY_WRITE, (void *) arg, | 1048 | if (access_ok(VERIFY_WRITE, (void *) arg, |
1063 | sizeof(unsigned int)); | 1049 | sizeof(unsigned int))) |
1064 | return get_lsr_info(info, (unsigned int *) arg); | 1050 | return get_lsr_info(info, (unsigned int *) arg); |
1065 | return -EFAULT; | 1051 | return -EFAULT; |
1066 | case TIOCSERGSTRUCT: | 1052 | case TIOCSERGSTRUCT: |
@@ -1113,10 +1099,10 @@ static void rs_close(struct tty_struct *tty, struct file * filp) | |||
1113 | if (!info || serial_paranoia_check(info, tty->name, "rs_close")) | 1099 | if (!info || serial_paranoia_check(info, tty->name, "rs_close")) |
1114 | return; | 1100 | return; |
1115 | 1101 | ||
1116 | save_flags(flags); cli(); | 1102 | local_irq_save(flags); |
1117 | 1103 | ||
1118 | if (tty_hung_up_p(filp)) { | 1104 | if (tty_hung_up_p(filp)) { |
1119 | restore_flags(flags); | 1105 | local_irq_restore(flags); |
1120 | return; | 1106 | return; |
1121 | } | 1107 | } |
1122 | 1108 | ||
@@ -1138,7 +1124,7 @@ static void rs_close(struct tty_struct *tty, struct file * filp) | |||
1138 | info->count = 0; | 1124 | info->count = 0; |
1139 | } | 1125 | } |
1140 | if (info->count) { | 1126 | if (info->count) { |
1141 | restore_flags(flags); | 1127 | local_irq_restore(flags); |
1142 | return; | 1128 | return; |
1143 | } | 1129 | } |
1144 | info->flags |= S_CLOSING; | 1130 | info->flags |= S_CLOSING; |
@@ -1186,7 +1172,7 @@ static void rs_close(struct tty_struct *tty, struct file * filp) | |||
1186 | } | 1172 | } |
1187 | info->flags &= ~(S_NORMAL_ACTIVE|S_CLOSING); | 1173 | info->flags &= ~(S_NORMAL_ACTIVE|S_CLOSING); |
1188 | wake_up_interruptible(&info->close_wait); | 1174 | wake_up_interruptible(&info->close_wait); |
1189 | restore_flags(flags); | 1175 | local_irq_restore(flags); |
1190 | } | 1176 | } |
1191 | 1177 | ||
1192 | /* | 1178 | /* |
@@ -1262,9 +1248,9 @@ static int block_til_ready(struct tty_struct *tty, struct file * filp, | |||
1262 | info->count--; | 1248 | info->count--; |
1263 | info->blocked_open++; | 1249 | info->blocked_open++; |
1264 | while (1) { | 1250 | while (1) { |
1265 | cli(); | 1251 | local_irq_disable(); |
1266 | m68k_rtsdtr(info, 1); | 1252 | m68k_rtsdtr(info, 1); |
1267 | sti(); | 1253 | local_irq_enable(); |
1268 | current->state = TASK_INTERRUPTIBLE; | 1254 | current->state = TASK_INTERRUPTIBLE; |
1269 | if (tty_hung_up_p(filp) || | 1255 | if (tty_hung_up_p(filp) || |
1270 | !(info->flags & S_INITIALIZED)) { | 1256 | !(info->flags & S_INITIALIZED)) { |
@@ -1444,7 +1430,7 @@ rs68328_init(void) | |||
1444 | return -ENOMEM; | 1430 | return -ENOMEM; |
1445 | } | 1431 | } |
1446 | 1432 | ||
1447 | save_flags(flags); cli(); | 1433 | local_irq_save(flags); |
1448 | 1434 | ||
1449 | for(i=0;i<NR_PORTS;i++) { | 1435 | for(i=0;i<NR_PORTS;i++) { |
1450 | 1436 | ||
@@ -1489,7 +1475,7 @@ rs68328_init(void) | |||
1489 | serial_pm[i]->data = info; | 1475 | serial_pm[i]->data = info; |
1490 | #endif | 1476 | #endif |
1491 | } | 1477 | } |
1492 | restore_flags(flags); | 1478 | local_irq_restore(flags); |
1493 | return 0; | 1479 | return 0; |
1494 | } | 1480 | } |
1495 | 1481 | ||
diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c index bbf78aaf9e01..f361b356bd1d 100644 --- a/drivers/serial/8250.c +++ b/drivers/serial/8250.c | |||
@@ -2354,7 +2354,6 @@ int __init serial8250_start_console(struct uart_port *port, char *options) | |||
2354 | static struct uart_driver serial8250_reg = { | 2354 | static struct uart_driver serial8250_reg = { |
2355 | .owner = THIS_MODULE, | 2355 | .owner = THIS_MODULE, |
2356 | .driver_name = "serial", | 2356 | .driver_name = "serial", |
2357 | .devfs_name = "tts/", | ||
2358 | .dev_name = "ttyS", | 2357 | .dev_name = "ttyS", |
2359 | .major = TTY_MAJOR, | 2358 | .major = TTY_MAJOR, |
2360 | .minor = 64, | 2359 | .minor = 64, |
diff --git a/drivers/serial/8250_pci.c b/drivers/serial/8250_pci.c index 94886c000d2a..864ef859be56 100644 --- a/drivers/serial/8250_pci.c +++ b/drivers/serial/8250_pci.c | |||
@@ -594,8 +594,8 @@ pci_default_setup(struct serial_private *priv, struct pciserial_board *board, | |||
594 | else | 594 | else |
595 | offset += idx * board->uart_offset; | 595 | offset += idx * board->uart_offset; |
596 | 596 | ||
597 | maxnr = (pci_resource_len(priv->dev, bar) - board->first_offset) / | 597 | maxnr = (pci_resource_len(priv->dev, bar) - board->first_offset) >> |
598 | (8 << board->reg_shift); | 598 | (board->reg_shift + 3); |
599 | 599 | ||
600 | if (board->flags & FL_REGION_SZ_CAP && idx >= maxnr) | 600 | if (board->flags & FL_REGION_SZ_CAP && idx >= maxnr) |
601 | return 1; | 601 | return 1; |
diff --git a/drivers/serial/at91_serial.c b/drivers/serial/at91_serial.c index db5b25fafed4..df9500bdaded 100644 --- a/drivers/serial/at91_serial.c +++ b/drivers/serial/at91_serial.c | |||
@@ -863,7 +863,6 @@ static struct uart_driver at91_uart = { | |||
863 | .owner = THIS_MODULE, | 863 | .owner = THIS_MODULE, |
864 | .driver_name = "at91_serial", | 864 | .driver_name = "at91_serial", |
865 | .dev_name = AT91_DEVICENAME, | 865 | .dev_name = AT91_DEVICENAME, |
866 | .devfs_name = AT91_DEVICENAME, | ||
867 | .major = SERIAL_AT91_MAJOR, | 866 | .major = SERIAL_AT91_MAJOR, |
868 | .minor = MINOR_START, | 867 | .minor = MINOR_START, |
869 | .nr = AT91_NR_UART, | 868 | .nr = AT91_NR_UART, |
diff --git a/drivers/serial/crisv10.c b/drivers/serial/crisv10.c index 89700141f87e..b84137cdeb2b 100644 --- a/drivers/serial/crisv10.c +++ b/drivers/serial/crisv10.c | |||
@@ -2573,12 +2573,6 @@ static void flush_to_flip_buffer(struct e100_serial *info) | |||
2573 | 2573 | ||
2574 | DFLIP( | 2574 | DFLIP( |
2575 | if (1) { | 2575 | if (1) { |
2576 | |||
2577 | if (test_bit(TTY_DONT_FLIP, &tty->flags)) { | ||
2578 | DEBUG_LOG(info->line, "*** TTY_DONT_FLIP set flip.count %i ***\n", tty->flip.count); | ||
2579 | DEBUG_LOG(info->line, "*** recv_cnt %i\n", info->recv_cnt); | ||
2580 | } else { | ||
2581 | } | ||
2582 | DEBUG_LOG(info->line, "*** rxtot %i\n", info->icount.rx); | 2576 | DEBUG_LOG(info->line, "*** rxtot %i\n", info->icount.rx); |
2583 | DEBUG_LOG(info->line, "ldisc %lu\n", tty->ldisc.chars_in_buffer(tty)); | 2577 | DEBUG_LOG(info->line, "ldisc %lu\n", tty->ldisc.chars_in_buffer(tty)); |
2584 | DEBUG_LOG(info->line, "room %lu\n", tty->ldisc.receive_room(tty)); | 2578 | DEBUG_LOG(info->line, "room %lu\n", tty->ldisc.receive_room(tty)); |
@@ -4884,7 +4878,7 @@ rs_init(void) | |||
4884 | driver->init_termios = tty_std_termios; | 4878 | driver->init_termios = tty_std_termios; |
4885 | driver->init_termios.c_cflag = | 4879 | driver->init_termios.c_cflag = |
4886 | B115200 | CS8 | CREAD | HUPCL | CLOCAL; /* is normally B9600 default... */ | 4880 | B115200 | CS8 | CREAD | HUPCL | CLOCAL; /* is normally B9600 default... */ |
4887 | driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_NO_DEVFS; | 4881 | driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV; |
4888 | driver->termios = serial_termios; | 4882 | driver->termios = serial_termios; |
4889 | driver->termios_locked = serial_termios_locked; | 4883 | driver->termios_locked = serial_termios_locked; |
4890 | 4884 | ||
diff --git a/drivers/serial/dz.c b/drivers/serial/dz.c index bf71bad5c34f..466d06cc7d37 100644 --- a/drivers/serial/dz.c +++ b/drivers/serial/dz.c | |||
@@ -768,11 +768,7 @@ void __init dz_serial_console_init(void) | |||
768 | static struct uart_driver dz_reg = { | 768 | static struct uart_driver dz_reg = { |
769 | .owner = THIS_MODULE, | 769 | .owner = THIS_MODULE, |
770 | .driver_name = "serial", | 770 | .driver_name = "serial", |
771 | #ifdef CONFIG_DEVFS | ||
772 | .dev_name = "tts/%d", | ||
773 | #else | ||
774 | .dev_name = "ttyS%d", | 771 | .dev_name = "ttyS%d", |
775 | #endif | ||
776 | .major = TTY_MAJOR, | 772 | .major = TTY_MAJOR, |
777 | .minor = 64, | 773 | .minor = 64, |
778 | .nr = DZ_NB_PORT, | 774 | .nr = DZ_NB_PORT, |
diff --git a/drivers/serial/imx.c b/drivers/serial/imx.c index d202eb4f3848..da85bafa0942 100644 --- a/drivers/serial/imx.c +++ b/drivers/serial/imx.c | |||
@@ -888,7 +888,6 @@ static struct uart_driver imx_reg = { | |||
888 | .owner = THIS_MODULE, | 888 | .owner = THIS_MODULE, |
889 | .driver_name = DRIVER_NAME, | 889 | .driver_name = DRIVER_NAME, |
890 | .dev_name = "ttySMX", | 890 | .dev_name = "ttySMX", |
891 | .devfs_name = "ttsmx/", | ||
892 | .major = SERIAL_IMX_MAJOR, | 891 | .major = SERIAL_IMX_MAJOR, |
893 | .minor = MINOR_START, | 892 | .minor = MINOR_START, |
894 | .nr = ARRAY_SIZE(imx_ports), | 893 | .nr = ARRAY_SIZE(imx_ports), |
diff --git a/drivers/serial/ip22zilog.c b/drivers/serial/ip22zilog.c index 651772474ac1..56b093ecd779 100644 --- a/drivers/serial/ip22zilog.c +++ b/drivers/serial/ip22zilog.c | |||
@@ -1085,7 +1085,6 @@ static struct console ip22zilog_console = { | |||
1085 | static struct uart_driver ip22zilog_reg = { | 1085 | static struct uart_driver ip22zilog_reg = { |
1086 | .owner = THIS_MODULE, | 1086 | .owner = THIS_MODULE, |
1087 | .driver_name = "serial", | 1087 | .driver_name = "serial", |
1088 | .devfs_name = "tts/", | ||
1089 | .dev_name = "ttyS", | 1088 | .dev_name = "ttyS", |
1090 | .major = TTY_MAJOR, | 1089 | .major = TTY_MAJOR, |
1091 | .minor = 64, | 1090 | .minor = 64, |
diff --git a/drivers/serial/jsm/jsm_tty.c b/drivers/serial/jsm/jsm_tty.c index 7d823705193c..f8262e6ad8d3 100644 --- a/drivers/serial/jsm/jsm_tty.c +++ b/drivers/serial/jsm/jsm_tty.c | |||
@@ -589,13 +589,6 @@ void jsm_input(struct jsm_channel *ch) | |||
589 | ld = tty_ldisc_ref(tp); | 589 | ld = tty_ldisc_ref(tp); |
590 | 590 | ||
591 | /* | 591 | /* |
592 | * If the DONT_FLIP flag is on, don't flush our buffer, and act | ||
593 | * like the ld doesn't have any space to put the data right now. | ||
594 | */ | ||
595 | if (test_bit(TTY_DONT_FLIP, &tp->flags)) | ||
596 | len = 0; | ||
597 | |||
598 | /* | ||
599 | * If we were unable to get a reference to the ld, | 592 | * If we were unable to get a reference to the ld, |
600 | * don't flush our buffer, and act like the ld doesn't | 593 | * don't flush our buffer, and act like the ld doesn't |
601 | * have any space to put the data right now. | 594 | * have any space to put the data right now. |
diff --git a/drivers/serial/m32r_sio.c b/drivers/serial/m32r_sio.c index 321a40f33b50..6a2a25d9b596 100644 --- a/drivers/serial/m32r_sio.c +++ b/drivers/serial/m32r_sio.c | |||
@@ -1131,7 +1131,6 @@ console_initcall(m32r_sio_console_init); | |||
1131 | static struct uart_driver m32r_sio_reg = { | 1131 | static struct uart_driver m32r_sio_reg = { |
1132 | .owner = THIS_MODULE, | 1132 | .owner = THIS_MODULE, |
1133 | .driver_name = "sio", | 1133 | .driver_name = "sio", |
1134 | .devfs_name = "tts/", | ||
1135 | .dev_name = "ttyS", | 1134 | .dev_name = "ttyS", |
1136 | .major = TTY_MAJOR, | 1135 | .major = TTY_MAJOR, |
1137 | .minor = 64, | 1136 | .minor = 64, |
diff --git a/drivers/serial/mcfserial.c b/drivers/serial/mcfserial.c index 8ad242934368..29c0630e3e64 100644 --- a/drivers/serial/mcfserial.c +++ b/drivers/serial/mcfserial.c | |||
@@ -1713,7 +1713,6 @@ mcfrs_init(void) | |||
1713 | /* Initialize the tty_driver structure */ | 1713 | /* Initialize the tty_driver structure */ |
1714 | mcfrs_serial_driver->owner = THIS_MODULE; | 1714 | mcfrs_serial_driver->owner = THIS_MODULE; |
1715 | mcfrs_serial_driver->name = "ttyS"; | 1715 | mcfrs_serial_driver->name = "ttyS"; |
1716 | mcfrs_serial_driver->devfs_name = "ttys/"; | ||
1717 | mcfrs_serial_driver->driver_name = "serial"; | 1716 | mcfrs_serial_driver->driver_name = "serial"; |
1718 | mcfrs_serial_driver->major = TTY_MAJOR; | 1717 | mcfrs_serial_driver->major = TTY_MAJOR; |
1719 | mcfrs_serial_driver->minor_start = 64; | 1718 | mcfrs_serial_driver->minor_start = 64; |
diff --git a/drivers/serial/mpc52xx_uart.c b/drivers/serial/mpc52xx_uart.c index 6459edc7f5c5..1aa34844218c 100644 --- a/drivers/serial/mpc52xx_uart.c +++ b/drivers/serial/mpc52xx_uart.c | |||
@@ -693,7 +693,6 @@ static struct uart_driver mpc52xx_uart_driver = { | |||
693 | .owner = THIS_MODULE, | 693 | .owner = THIS_MODULE, |
694 | .driver_name = "mpc52xx_psc_uart", | 694 | .driver_name = "mpc52xx_psc_uart", |
695 | .dev_name = "ttyPSC", | 695 | .dev_name = "ttyPSC", |
696 | .devfs_name = "ttyPSC", | ||
697 | .major = SERIAL_PSC_MAJOR, | 696 | .major = SERIAL_PSC_MAJOR, |
698 | .minor = SERIAL_PSC_MINOR, | 697 | .minor = SERIAL_PSC_MINOR, |
699 | .nr = MPC52xx_PSC_MAXNUM, | 698 | .nr = MPC52xx_PSC_MAXNUM, |
diff --git a/drivers/serial/mpsc.c b/drivers/serial/mpsc.c index 94681922ea0a..1cd102f84bfa 100644 --- a/drivers/serial/mpsc.c +++ b/drivers/serial/mpsc.c | |||
@@ -315,7 +315,6 @@ struct mpsc_port_info *mpsc_device_remove(int index); | |||
315 | #define MPSC_MAJOR 204 | 315 | #define MPSC_MAJOR 204 |
316 | #define MPSC_MINOR_START 44 | 316 | #define MPSC_MINOR_START 44 |
317 | #define MPSC_DRIVER_NAME "MPSC" | 317 | #define MPSC_DRIVER_NAME "MPSC" |
318 | #define MPSC_DEVFS_NAME "ttymm/" | ||
319 | #define MPSC_DEV_NAME "ttyMM" | 318 | #define MPSC_DEV_NAME "ttyMM" |
320 | #define MPSC_VERSION "1.00" | 319 | #define MPSC_VERSION "1.00" |
321 | 320 | ||
@@ -1863,7 +1862,6 @@ static struct platform_driver mpsc_shared_driver = { | |||
1863 | static struct uart_driver mpsc_reg = { | 1862 | static struct uart_driver mpsc_reg = { |
1864 | .owner = THIS_MODULE, | 1863 | .owner = THIS_MODULE, |
1865 | .driver_name = MPSC_DRIVER_NAME, | 1864 | .driver_name = MPSC_DRIVER_NAME, |
1866 | .devfs_name = MPSC_DEVFS_NAME, | ||
1867 | .dev_name = MPSC_DEV_NAME, | 1865 | .dev_name = MPSC_DEV_NAME, |
1868 | .major = MPSC_MAJOR, | 1866 | .major = MPSC_MAJOR, |
1869 | .minor = MPSC_MINOR_START, | 1867 | .minor = MPSC_MINOR_START, |
diff --git a/drivers/serial/pmac_zilog.c b/drivers/serial/pmac_zilog.c index 513ff8597707..e3ba7e17a240 100644 --- a/drivers/serial/pmac_zilog.c +++ b/drivers/serial/pmac_zilog.c | |||
@@ -101,7 +101,6 @@ static DEFINE_MUTEX(pmz_irq_mutex); | |||
101 | static struct uart_driver pmz_uart_reg = { | 101 | static struct uart_driver pmz_uart_reg = { |
102 | .owner = THIS_MODULE, | 102 | .owner = THIS_MODULE, |
103 | .driver_name = "ttyS", | 103 | .driver_name = "ttyS", |
104 | .devfs_name = "tts/", | ||
105 | .dev_name = "ttyS", | 104 | .dev_name = "ttyS", |
106 | .major = TTY_MAJOR, | 105 | .major = TTY_MAJOR, |
107 | }; | 106 | }; |
diff --git a/drivers/serial/pxa.c b/drivers/serial/pxa.c index ae3649568541..0fa0ccc9ed27 100644 --- a/drivers/serial/pxa.c +++ b/drivers/serial/pxa.c | |||
@@ -780,7 +780,6 @@ static struct uart_pxa_port serial_pxa_ports[] = { | |||
780 | static struct uart_driver serial_pxa_reg = { | 780 | static struct uart_driver serial_pxa_reg = { |
781 | .owner = THIS_MODULE, | 781 | .owner = THIS_MODULE, |
782 | .driver_name = "PXA serial", | 782 | .driver_name = "PXA serial", |
783 | .devfs_name = "tts/", | ||
784 | .dev_name = "ttyS", | 783 | .dev_name = "ttyS", |
785 | .major = TTY_MAJOR, | 784 | .major = TTY_MAJOR, |
786 | .minor = 64, | 785 | .minor = 64, |
diff --git a/drivers/serial/s3c2410.c b/drivers/serial/s3c2410.c index 837b6da520b3..4c62ab949ecc 100644 --- a/drivers/serial/s3c2410.c +++ b/drivers/serial/s3c2410.c | |||
@@ -149,7 +149,6 @@ s3c24xx_serial_dbg(const char *fmt, ...) | |||
149 | /* UART name and device definitions */ | 149 | /* UART name and device definitions */ |
150 | 150 | ||
151 | #define S3C24XX_SERIAL_NAME "ttySAC" | 151 | #define S3C24XX_SERIAL_NAME "ttySAC" |
152 | #define S3C24XX_SERIAL_DEVFS "tts/" | ||
153 | #define S3C24XX_SERIAL_MAJOR 204 | 152 | #define S3C24XX_SERIAL_MAJOR 204 |
154 | #define S3C24XX_SERIAL_MINOR 64 | 153 | #define S3C24XX_SERIAL_MINOR 64 |
155 | 154 | ||
@@ -952,7 +951,6 @@ static struct uart_driver s3c24xx_uart_drv = { | |||
952 | .nr = 3, | 951 | .nr = 3, |
953 | .cons = S3C24XX_SERIAL_CONSOLE, | 952 | .cons = S3C24XX_SERIAL_CONSOLE, |
954 | .driver_name = S3C24XX_SERIAL_NAME, | 953 | .driver_name = S3C24XX_SERIAL_NAME, |
955 | .devfs_name = S3C24XX_SERIAL_DEVFS, | ||
956 | .major = S3C24XX_SERIAL_MAJOR, | 954 | .major = S3C24XX_SERIAL_MAJOR, |
957 | .minor = S3C24XX_SERIAL_MINOR, | 955 | .minor = S3C24XX_SERIAL_MINOR, |
958 | }; | 956 | }; |
diff --git a/drivers/serial/sa1100.c b/drivers/serial/sa1100.c index c2d9068b491d..8bbd8567669c 100644 --- a/drivers/serial/sa1100.c +++ b/drivers/serial/sa1100.c | |||
@@ -816,7 +816,6 @@ static struct uart_driver sa1100_reg = { | |||
816 | .owner = THIS_MODULE, | 816 | .owner = THIS_MODULE, |
817 | .driver_name = "ttySA", | 817 | .driver_name = "ttySA", |
818 | .dev_name = "ttySA", | 818 | .dev_name = "ttySA", |
819 | .devfs_name = "ttySA", | ||
820 | .major = SERIAL_SA1100_MAJOR, | 819 | .major = SERIAL_SA1100_MAJOR, |
821 | .minor = MINOR_START, | 820 | .minor = MINOR_START, |
822 | .nr = NR_PORTS, | 821 | .nr = NR_PORTS, |
diff --git a/drivers/serial/serial_core.c b/drivers/serial/serial_core.c index 17839e753e4c..7dc1e67b6851 100644 --- a/drivers/serial/serial_core.c +++ b/drivers/serial/serial_core.c | |||
@@ -2153,7 +2153,6 @@ int uart_register_driver(struct uart_driver *drv) | |||
2153 | 2153 | ||
2154 | normal->owner = drv->owner; | 2154 | normal->owner = drv->owner; |
2155 | normal->driver_name = drv->driver_name; | 2155 | normal->driver_name = drv->driver_name; |
2156 | normal->devfs_name = drv->devfs_name; | ||
2157 | normal->name = drv->dev_name; | 2156 | normal->name = drv->dev_name; |
2158 | normal->major = drv->major; | 2157 | normal->major = drv->major; |
2159 | normal->minor_start = drv->minor; | 2158 | normal->minor_start = drv->minor; |
@@ -2161,7 +2160,7 @@ int uart_register_driver(struct uart_driver *drv) | |||
2161 | normal->subtype = SERIAL_TYPE_NORMAL; | 2160 | normal->subtype = SERIAL_TYPE_NORMAL; |
2162 | normal->init_termios = tty_std_termios; | 2161 | normal->init_termios = tty_std_termios; |
2163 | normal->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL; | 2162 | normal->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL; |
2164 | normal->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_NO_DEVFS; | 2163 | normal->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV; |
2165 | normal->driver_state = drv; | 2164 | normal->driver_state = drv; |
2166 | tty_set_operations(normal, &uart_ops); | 2165 | tty_set_operations(normal, &uart_ops); |
2167 | 2166 | ||
@@ -2312,7 +2311,7 @@ int uart_remove_one_port(struct uart_driver *drv, struct uart_port *port) | |||
2312 | mutex_unlock(&state->mutex); | 2311 | mutex_unlock(&state->mutex); |
2313 | 2312 | ||
2314 | /* | 2313 | /* |
2315 | * Remove the devices from devfs | 2314 | * Remove the devices from the tty layer |
2316 | */ | 2315 | */ |
2317 | tty_unregister_device(drv->tty_driver, port->line); | 2316 | tty_unregister_device(drv->tty_driver, port->line); |
2318 | 2317 | ||
diff --git a/drivers/serial/serial_txx9.c b/drivers/serial/serial_txx9.c index 3bdee64d1a99..a901a7e446f3 100644 --- a/drivers/serial/serial_txx9.c +++ b/drivers/serial/serial_txx9.c | |||
@@ -69,12 +69,10 @@ static char *serial_name = "TX39/49 Serial driver"; | |||
69 | #if !defined(CONFIG_SERIAL_TXX9_STDSERIAL) | 69 | #if !defined(CONFIG_SERIAL_TXX9_STDSERIAL) |
70 | /* "ttyS" is used for standard serial driver */ | 70 | /* "ttyS" is used for standard serial driver */ |
71 | #define TXX9_TTY_NAME "ttyTX" | 71 | #define TXX9_TTY_NAME "ttyTX" |
72 | #define TXX9_TTY_DEVFS_NAME "tttx/" | ||
73 | #define TXX9_TTY_MINOR_START (64 + 64) /* ttyTX0(128), ttyTX1(129) */ | 72 | #define TXX9_TTY_MINOR_START (64 + 64) /* ttyTX0(128), ttyTX1(129) */ |
74 | #else | 73 | #else |
75 | /* acts like standard serial driver */ | 74 | /* acts like standard serial driver */ |
76 | #define TXX9_TTY_NAME "ttyS" | 75 | #define TXX9_TTY_NAME "ttyS" |
77 | #define TXX9_TTY_DEVFS_NAME "tts/" | ||
78 | #define TXX9_TTY_MINOR_START 64 | 76 | #define TXX9_TTY_MINOR_START 64 |
79 | #endif | 77 | #endif |
80 | #define TXX9_TTY_MAJOR TTY_MAJOR | 78 | #define TXX9_TTY_MAJOR TTY_MAJOR |
@@ -971,7 +969,6 @@ console_initcall(serial_txx9_console_init); | |||
971 | static struct uart_driver serial_txx9_reg = { | 969 | static struct uart_driver serial_txx9_reg = { |
972 | .owner = THIS_MODULE, | 970 | .owner = THIS_MODULE, |
973 | .driver_name = "serial_txx9", | 971 | .driver_name = "serial_txx9", |
974 | .devfs_name = TXX9_TTY_DEVFS_NAME, | ||
975 | .dev_name = TXX9_TTY_NAME, | 972 | .dev_name = TXX9_TTY_NAME, |
976 | .major = TXX9_TTY_MAJOR, | 973 | .major = TXX9_TTY_MAJOR, |
977 | .minor = TXX9_TTY_MINOR_START, | 974 | .minor = TXX9_TTY_MINOR_START, |
diff --git a/drivers/serial/sh-sci.c b/drivers/serial/sh-sci.c index 44f6bf79bbe1..d97f3ca6cc29 100644 --- a/drivers/serial/sh-sci.c +++ b/drivers/serial/sh-sci.c | |||
@@ -1699,9 +1699,6 @@ static char banner[] __initdata = | |||
1699 | static struct uart_driver sci_uart_driver = { | 1699 | static struct uart_driver sci_uart_driver = { |
1700 | .owner = THIS_MODULE, | 1700 | .owner = THIS_MODULE, |
1701 | .driver_name = "sci", | 1701 | .driver_name = "sci", |
1702 | #ifdef CONFIG_DEVFS_FS | ||
1703 | .devfs_name = "ttsc/", | ||
1704 | #endif | ||
1705 | .dev_name = "ttySC", | 1702 | .dev_name = "ttySC", |
1706 | .major = SCI_MAJOR, | 1703 | .major = SCI_MAJOR, |
1707 | .minor = SCI_MINOR_START, | 1704 | .minor = SCI_MINOR_START, |
diff --git a/drivers/serial/sunhv.c b/drivers/serial/sunhv.c index ba22e256c6f7..d36bc4003399 100644 --- a/drivers/serial/sunhv.c +++ b/drivers/serial/sunhv.c | |||
@@ -353,7 +353,6 @@ static struct uart_ops sunhv_pops = { | |||
353 | static struct uart_driver sunhv_reg = { | 353 | static struct uart_driver sunhv_reg = { |
354 | .owner = THIS_MODULE, | 354 | .owner = THIS_MODULE, |
355 | .driver_name = "serial", | 355 | .driver_name = "serial", |
356 | .devfs_name = "tts/", | ||
357 | .dev_name = "ttyS", | 356 | .dev_name = "ttyS", |
358 | .major = TTY_MAJOR, | 357 | .major = TTY_MAJOR, |
359 | }; | 358 | }; |
diff --git a/drivers/serial/sunsab.c b/drivers/serial/sunsab.c index e4c0fd2d6a9d..7da02d11c364 100644 --- a/drivers/serial/sunsab.c +++ b/drivers/serial/sunsab.c | |||
@@ -851,7 +851,6 @@ static struct uart_ops sunsab_pops = { | |||
851 | static struct uart_driver sunsab_reg = { | 851 | static struct uart_driver sunsab_reg = { |
852 | .owner = THIS_MODULE, | 852 | .owner = THIS_MODULE, |
853 | .driver_name = "serial", | 853 | .driver_name = "serial", |
854 | .devfs_name = "tts/", | ||
855 | .dev_name = "ttyS", | 854 | .dev_name = "ttyS", |
856 | .major = TTY_MAJOR, | 855 | .major = TTY_MAJOR, |
857 | }; | 856 | }; |
diff --git a/drivers/serial/sunsu.c b/drivers/serial/sunsu.c index 0268b307c01e..6e28c25138cf 100644 --- a/drivers/serial/sunsu.c +++ b/drivers/serial/sunsu.c | |||
@@ -1265,7 +1265,6 @@ out: | |||
1265 | static struct uart_driver sunsu_reg = { | 1265 | static struct uart_driver sunsu_reg = { |
1266 | .owner = THIS_MODULE, | 1266 | .owner = THIS_MODULE, |
1267 | .driver_name = "serial", | 1267 | .driver_name = "serial", |
1268 | .devfs_name = "tts/", | ||
1269 | .dev_name = "ttyS", | 1268 | .dev_name = "ttyS", |
1270 | .major = TTY_MAJOR, | 1269 | .major = TTY_MAJOR, |
1271 | }; | 1270 | }; |
diff --git a/drivers/serial/sunzilog.c b/drivers/serial/sunzilog.c index 76c9bac9271f..9f42677287ad 100644 --- a/drivers/serial/sunzilog.c +++ b/drivers/serial/sunzilog.c | |||
@@ -1017,7 +1017,6 @@ static int zilog_irq = -1; | |||
1017 | static struct uart_driver sunzilog_reg = { | 1017 | static struct uart_driver sunzilog_reg = { |
1018 | .owner = THIS_MODULE, | 1018 | .owner = THIS_MODULE, |
1019 | .driver_name = "ttyS", | 1019 | .driver_name = "ttyS", |
1020 | .devfs_name = "tts/", | ||
1021 | .dev_name = "ttyS", | 1020 | .dev_name = "ttyS", |
1022 | .major = TTY_MAJOR, | 1021 | .major = TTY_MAJOR, |
1023 | }; | 1022 | }; |
diff --git a/drivers/serial/v850e_uart.c b/drivers/serial/v850e_uart.c index df705fda4243..a0da2aaf71c4 100644 --- a/drivers/serial/v850e_uart.c +++ b/drivers/serial/v850e_uart.c | |||
@@ -468,7 +468,6 @@ static struct uart_ops v850e_uart_ops = { | |||
468 | static struct uart_driver v850e_uart_driver = { | 468 | static struct uart_driver v850e_uart_driver = { |
469 | .owner = THIS_MODULE, | 469 | .owner = THIS_MODULE, |
470 | .driver_name = "v850e_uart", | 470 | .driver_name = "v850e_uart", |
471 | .devfs_name = "tts/", | ||
472 | .dev_name = "ttyS", | 471 | .dev_name = "ttyS", |
473 | .major = TTY_MAJOR, | 472 | .major = TTY_MAJOR, |
474 | .minor = V850E_UART_MINOR_BASE, | 473 | .minor = V850E_UART_MINOR_BASE, |
diff --git a/drivers/serial/vr41xx_siu.c b/drivers/serial/vr41xx_siu.c index df5e8713fa31..017571ffa19c 100644 --- a/drivers/serial/vr41xx_siu.c +++ b/drivers/serial/vr41xx_siu.c | |||
@@ -911,7 +911,6 @@ static struct uart_driver siu_uart_driver = { | |||
911 | .owner = THIS_MODULE, | 911 | .owner = THIS_MODULE, |
912 | .driver_name = "SIU", | 912 | .driver_name = "SIU", |
913 | .dev_name = "ttyVR", | 913 | .dev_name = "ttyVR", |
914 | .devfs_name = "ttvr/", | ||
915 | .major = SIU_MAJOR, | 914 | .major = SIU_MAJOR, |
916 | .minor = SIU_MINOR_BASE, | 915 | .minor = SIU_MINOR_BASE, |
917 | .cons = SERIAL_VR41XX_CONSOLE, | 916 | .cons = SERIAL_VR41XX_CONSOLE, |
diff --git a/drivers/sn/ioc3.c b/drivers/sn/ioc3.c index 501316b198e5..ed946311d3a4 100644 --- a/drivers/sn/ioc3.c +++ b/drivers/sn/ioc3.c | |||
@@ -26,7 +26,7 @@ static DECLARE_RWSEM(ioc3_devices_rwsem); | |||
26 | 26 | ||
27 | static struct ioc3_submodule *ioc3_submodules[IOC3_MAX_SUBMODULES]; | 27 | static struct ioc3_submodule *ioc3_submodules[IOC3_MAX_SUBMODULES]; |
28 | static struct ioc3_submodule *ioc3_ethernet; | 28 | static struct ioc3_submodule *ioc3_ethernet; |
29 | static rwlock_t ioc3_submodules_lock = RW_LOCK_UNLOCKED; | 29 | static DEFINE_RWLOCK(ioc3_submodules_lock); |
30 | 30 | ||
31 | /* NIC probing code */ | 31 | /* NIC probing code */ |
32 | 32 | ||
diff --git a/drivers/sn/ioc4.c b/drivers/sn/ioc4.c index 8256a97eb508..8562821e6498 100644 --- a/drivers/sn/ioc4.c +++ b/drivers/sn/ioc4.c | |||
@@ -438,7 +438,7 @@ static struct pci_device_id ioc4_id_table[] = { | |||
438 | {0} | 438 | {0} |
439 | }; | 439 | }; |
440 | 440 | ||
441 | static struct pci_driver __devinitdata ioc4_driver = { | 441 | static struct pci_driver ioc4_driver = { |
442 | .name = "IOC4", | 442 | .name = "IOC4", |
443 | .id_table = ioc4_id_table, | 443 | .id_table = ioc4_id_table, |
444 | .probe = ioc4_probe, | 444 | .probe = ioc4_probe, |
diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index 1cea4a6799fe..ed1cdf6ac8f3 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c | |||
@@ -210,6 +210,7 @@ spi_new_device(struct spi_master *master, struct spi_board_info *chip) | |||
210 | proxy->master = master; | 210 | proxy->master = master; |
211 | proxy->chip_select = chip->chip_select; | 211 | proxy->chip_select = chip->chip_select; |
212 | proxy->max_speed_hz = chip->max_speed_hz; | 212 | proxy->max_speed_hz = chip->max_speed_hz; |
213 | proxy->mode = chip->mode; | ||
213 | proxy->irq = chip->irq; | 214 | proxy->irq = chip->irq; |
214 | proxy->modalias = chip->modalias; | 215 | proxy->modalias = chip->modalias; |
215 | 216 | ||
diff --git a/drivers/tc/zs.c b/drivers/tc/zs.c index 2dffa8e303b2..7f27b356eaf7 100644 --- a/drivers/tc/zs.c +++ b/drivers/tc/zs.c | |||
@@ -1745,7 +1745,6 @@ int __init zs_init(void) | |||
1745 | /* Not all of this is exactly right for us. */ | 1745 | /* Not all of this is exactly right for us. */ |
1746 | 1746 | ||
1747 | serial_driver->owner = THIS_MODULE; | 1747 | serial_driver->owner = THIS_MODULE; |
1748 | serial_driver->devfs_name = "tts/"; | ||
1749 | serial_driver->name = "ttyS"; | 1748 | serial_driver->name = "ttyS"; |
1750 | serial_driver->major = TTY_MAJOR; | 1749 | serial_driver->major = TTY_MAJOR; |
1751 | serial_driver->minor_start = 64; | 1750 | serial_driver->minor_start = 64; |
@@ -1754,7 +1753,7 @@ int __init zs_init(void) | |||
1754 | serial_driver->init_termios = tty_std_termios; | 1753 | serial_driver->init_termios = tty_std_termios; |
1755 | serial_driver->init_termios.c_cflag = | 1754 | serial_driver->init_termios.c_cflag = |
1756 | B9600 | CS8 | CREAD | HUPCL | CLOCAL; | 1755 | B9600 | CS8 | CREAD | HUPCL | CLOCAL; |
1757 | serial_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_NO_DEVFS; | 1756 | serial_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV; |
1758 | tty_set_operations(serial_driver, &serial_ops); | 1757 | tty_set_operations(serial_driver, &serial_ops); |
1759 | 1758 | ||
1760 | if (tty_register_driver(serial_driver)) | 1759 | if (tty_register_driver(serial_driver)) |
diff --git a/drivers/telephony/phonedev.c b/drivers/telephony/phonedev.c index e166fffea86b..e41f49afd0f4 100644 --- a/drivers/telephony/phonedev.c +++ b/drivers/telephony/phonedev.c | |||
@@ -28,7 +28,6 @@ | |||
28 | 28 | ||
29 | #include <linux/kmod.h> | 29 | #include <linux/kmod.h> |
30 | #include <linux/sem.h> | 30 | #include <linux/sem.h> |
31 | #include <linux/devfs_fs_kernel.h> | ||
32 | #include <linux/mutex.h> | 31 | #include <linux/mutex.h> |
33 | 32 | ||
34 | #define PHONE_NUM_DEVICES 256 | 33 | #define PHONE_NUM_DEVICES 256 |
@@ -106,8 +105,6 @@ int phone_register_device(struct phone_device *p, int unit) | |||
106 | if (phone_device[i] == NULL) { | 105 | if (phone_device[i] == NULL) { |
107 | phone_device[i] = p; | 106 | phone_device[i] = p; |
108 | p->minor = i; | 107 | p->minor = i; |
109 | devfs_mk_cdev(MKDEV(PHONE_MAJOR,i), | ||
110 | S_IFCHR|S_IRUSR|S_IWUSR, "phone/%d", i); | ||
111 | mutex_unlock(&phone_lock); | 108 | mutex_unlock(&phone_lock); |
112 | return 0; | 109 | return 0; |
113 | } | 110 | } |
@@ -125,7 +122,6 @@ void phone_unregister_device(struct phone_device *pfd) | |||
125 | mutex_lock(&phone_lock); | 122 | mutex_lock(&phone_lock); |
126 | if (phone_device[pfd->minor] != pfd) | 123 | if (phone_device[pfd->minor] != pfd) |
127 | panic("phone: bad unregister"); | 124 | panic("phone: bad unregister"); |
128 | devfs_remove("phone/%d", pfd->minor); | ||
129 | phone_device[pfd->minor] = NULL; | 125 | phone_device[pfd->minor] = NULL; |
130 | mutex_unlock(&phone_lock); | 126 | mutex_unlock(&phone_lock); |
131 | } | 127 | } |
diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c index d41dc67ba4cc..3670d77e912c 100644 --- a/drivers/usb/class/cdc-acm.c +++ b/drivers/usb/class/cdc-acm.c | |||
@@ -1145,12 +1145,11 @@ static int __init acm_init(void) | |||
1145 | acm_tty_driver->owner = THIS_MODULE, | 1145 | acm_tty_driver->owner = THIS_MODULE, |
1146 | acm_tty_driver->driver_name = "acm", | 1146 | acm_tty_driver->driver_name = "acm", |
1147 | acm_tty_driver->name = "ttyACM", | 1147 | acm_tty_driver->name = "ttyACM", |
1148 | acm_tty_driver->devfs_name = "usb/acm/", | ||
1149 | acm_tty_driver->major = ACM_TTY_MAJOR, | 1148 | acm_tty_driver->major = ACM_TTY_MAJOR, |
1150 | acm_tty_driver->minor_start = 0, | 1149 | acm_tty_driver->minor_start = 0, |
1151 | acm_tty_driver->type = TTY_DRIVER_TYPE_SERIAL, | 1150 | acm_tty_driver->type = TTY_DRIVER_TYPE_SERIAL, |
1152 | acm_tty_driver->subtype = SERIAL_TYPE_NORMAL, | 1151 | acm_tty_driver->subtype = SERIAL_TYPE_NORMAL, |
1153 | acm_tty_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_NO_DEVFS, | 1152 | acm_tty_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV; |
1154 | acm_tty_driver->init_termios = tty_std_termios; | 1153 | acm_tty_driver->init_termios = tty_std_termios; |
1155 | acm_tty_driver->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL; | 1154 | acm_tty_driver->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL; |
1156 | tty_set_operations(acm_tty_driver, &acm_ops); | 1155 | tty_set_operations(acm_tty_driver, &acm_ops); |
diff --git a/drivers/usb/gadget/pxa2xx_udc.c b/drivers/usb/gadget/pxa2xx_udc.c index 269ce7f4ad66..735e9dbd39fd 100644 --- a/drivers/usb/gadget/pxa2xx_udc.c +++ b/drivers/usb/gadget/pxa2xx_udc.c | |||
@@ -60,7 +60,7 @@ | |||
60 | #include <linux/usb_ch9.h> | 60 | #include <linux/usb_ch9.h> |
61 | #include <linux/usb_gadget.h> | 61 | #include <linux/usb_gadget.h> |
62 | 62 | ||
63 | #include <asm/arch/hardware/intel_udc.h> | 63 | #include <asm/arch/udc.h> |
64 | 64 | ||
65 | 65 | ||
66 | /* | 66 | /* |
diff --git a/drivers/usb/gadget/serial.c b/drivers/usb/gadget/serial.c index 9d6e1d295528..416acac879df 100644 --- a/drivers/usb/gadget/serial.c +++ b/drivers/usb/gadget/serial.c | |||
@@ -588,12 +588,11 @@ static int __init gs_module_init(void) | |||
588 | gs_tty_driver->owner = THIS_MODULE; | 588 | gs_tty_driver->owner = THIS_MODULE; |
589 | gs_tty_driver->driver_name = GS_SHORT_NAME; | 589 | gs_tty_driver->driver_name = GS_SHORT_NAME; |
590 | gs_tty_driver->name = "ttygs"; | 590 | gs_tty_driver->name = "ttygs"; |
591 | gs_tty_driver->devfs_name = "usb/ttygs/"; | ||
592 | gs_tty_driver->major = GS_MAJOR; | 591 | gs_tty_driver->major = GS_MAJOR; |
593 | gs_tty_driver->minor_start = GS_MINOR_START; | 592 | gs_tty_driver->minor_start = GS_MINOR_START; |
594 | gs_tty_driver->type = TTY_DRIVER_TYPE_SERIAL; | 593 | gs_tty_driver->type = TTY_DRIVER_TYPE_SERIAL; |
595 | gs_tty_driver->subtype = SERIAL_TYPE_NORMAL; | 594 | gs_tty_driver->subtype = SERIAL_TYPE_NORMAL; |
596 | gs_tty_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_NO_DEVFS; | 595 | gs_tty_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV; |
597 | gs_tty_driver->init_termios = tty_std_termios; | 596 | gs_tty_driver->init_termios = tty_std_termios; |
598 | gs_tty_driver->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL; | 597 | gs_tty_driver->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL; |
599 | tty_set_operations(gs_tty_driver, &gs_tty_ops); | 598 | tty_set_operations(gs_tty_driver, &gs_tty_ops); |
diff --git a/drivers/usb/host/sl811-hcd.c b/drivers/usb/host/sl811-hcd.c index 6b4bc3f2bd86..89bcda5a3298 100644 --- a/drivers/usb/host/sl811-hcd.c +++ b/drivers/usb/host/sl811-hcd.c | |||
@@ -1684,9 +1684,13 @@ sl811h_probe(struct platform_device *dev) | |||
1684 | if (!addr || !data) | 1684 | if (!addr || !data) |
1685 | return -ENODEV; | 1685 | return -ENODEV; |
1686 | ioaddr = 1; | 1686 | ioaddr = 1; |
1687 | 1687 | /* | |
1688 | addr_reg = (void __iomem *) addr->start; | 1688 | * NOTE: 64-bit resource->start is getting truncated |
1689 | data_reg = (void __iomem *) data->start; | 1689 | * to avoid compiler warning, assuming that ->start |
1690 | * is always 32-bit for this case | ||
1691 | */ | ||
1692 | addr_reg = (void __iomem *) (unsigned long) addr->start; | ||
1693 | data_reg = (void __iomem *) (unsigned long) data->start; | ||
1690 | } else { | 1694 | } else { |
1691 | addr_reg = ioremap(addr->start, 1); | 1695 | addr_reg = ioremap(addr->start, 1); |
1692 | if (addr_reg == NULL) { | 1696 | if (addr_reg == NULL) { |
diff --git a/drivers/usb/serial/ir-usb.c b/drivers/usb/serial/ir-usb.c index 9432c7302275..d7f3f736a692 100644 --- a/drivers/usb/serial/ir-usb.c +++ b/drivers/usb/serial/ir-usb.c | |||
@@ -453,8 +453,7 @@ static void ir_read_bulk_callback (struct urb *urb, struct pt_regs *regs) | |||
453 | tty = port->tty; | 453 | tty = port->tty; |
454 | 454 | ||
455 | /* | 455 | /* |
456 | * FIXME: must not do this in IRQ context, | 456 | * FIXME: must not do this in IRQ context |
457 | * must honour TTY_DONT_FLIP | ||
458 | */ | 457 | */ |
459 | tty->ldisc.receive_buf( | 458 | tty->ldisc.receive_buf( |
460 | tty, | 459 | tty, |
diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c index a30135c7cfe6..f466f89eeb6d 100644 --- a/drivers/usb/serial/usb-serial.c +++ b/drivers/usb/serial/usb-serial.c | |||
@@ -1059,13 +1059,12 @@ static int __init usb_serial_init(void) | |||
1059 | 1059 | ||
1060 | usb_serial_tty_driver->owner = THIS_MODULE; | 1060 | usb_serial_tty_driver->owner = THIS_MODULE; |
1061 | usb_serial_tty_driver->driver_name = "usbserial"; | 1061 | usb_serial_tty_driver->driver_name = "usbserial"; |
1062 | usb_serial_tty_driver->devfs_name = "usb/tts/"; | ||
1063 | usb_serial_tty_driver->name = "ttyUSB"; | 1062 | usb_serial_tty_driver->name = "ttyUSB"; |
1064 | usb_serial_tty_driver->major = SERIAL_TTY_MAJOR; | 1063 | usb_serial_tty_driver->major = SERIAL_TTY_MAJOR; |
1065 | usb_serial_tty_driver->minor_start = 0; | 1064 | usb_serial_tty_driver->minor_start = 0; |
1066 | usb_serial_tty_driver->type = TTY_DRIVER_TYPE_SERIAL; | 1065 | usb_serial_tty_driver->type = TTY_DRIVER_TYPE_SERIAL; |
1067 | usb_serial_tty_driver->subtype = SERIAL_TYPE_NORMAL; | 1066 | usb_serial_tty_driver->subtype = SERIAL_TYPE_NORMAL; |
1068 | usb_serial_tty_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_NO_DEVFS; | 1067 | usb_serial_tty_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV; |
1069 | usb_serial_tty_driver->init_termios = tty_std_termios; | 1068 | usb_serial_tty_driver->init_termios = tty_std_termios; |
1070 | usb_serial_tty_driver->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL; | 1069 | usb_serial_tty_driver->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL; |
1071 | tty_set_operations(usb_serial_tty_driver, &serial_ops); | 1070 | tty_set_operations(usb_serial_tty_driver, &serial_ops); |
diff --git a/drivers/video/aty/radeon_backlight.c b/drivers/video/aty/radeon_backlight.c index 7de66b855d4e..1755dddf1899 100644 --- a/drivers/video/aty/radeon_backlight.c +++ b/drivers/video/aty/radeon_backlight.c | |||
@@ -40,14 +40,14 @@ static int radeon_bl_get_level_brightness(struct radeon_bl_privdata *pdata, | |||
40 | 40 | ||
41 | mutex_unlock(&info->bl_mutex); | 41 | mutex_unlock(&info->bl_mutex); |
42 | 42 | ||
43 | if (pdata->negative) | ||
44 | rlevel = MAX_RADEON_LEVEL - rlevel; | ||
45 | |||
46 | if (rlevel < 0) | 43 | if (rlevel < 0) |
47 | rlevel = 0; | 44 | rlevel = 0; |
48 | else if (rlevel > MAX_RADEON_LEVEL) | 45 | else if (rlevel > MAX_RADEON_LEVEL) |
49 | rlevel = MAX_RADEON_LEVEL; | 46 | rlevel = MAX_RADEON_LEVEL; |
50 | 47 | ||
48 | if (pdata->negative) | ||
49 | rlevel = MAX_RADEON_LEVEL - rlevel; | ||
50 | |||
51 | return rlevel; | 51 | return rlevel; |
52 | } | 52 | } |
53 | 53 | ||
diff --git a/drivers/video/au1100fb.c b/drivers/video/au1100fb.c index d63c3f485853..9ef68cd83bb4 100644 --- a/drivers/video/au1100fb.c +++ b/drivers/video/au1100fb.c | |||
@@ -743,8 +743,7 @@ void __exit au1100fb_cleanup(void) | |||
743 | { | 743 | { |
744 | driver_unregister(&au1100fb_driver); | 744 | driver_unregister(&au1100fb_driver); |
745 | 745 | ||
746 | if (drv_info.opt_mode) | 746 | kfree(drv_info.opt_mode); |
747 | kfree(drv_info.opt_mode); | ||
748 | } | 747 | } |
749 | 748 | ||
750 | module_init(au1100fb_init); | 749 | module_init(au1100fb_init); |
diff --git a/drivers/video/backlight/hp680_bl.c b/drivers/video/backlight/hp680_bl.c index a71e984c93d4..ffc72ae3ada8 100644 --- a/drivers/video/backlight/hp680_bl.c +++ b/drivers/video/backlight/hp680_bl.c | |||
@@ -27,7 +27,7 @@ | |||
27 | 27 | ||
28 | static int hp680bl_suspended; | 28 | static int hp680bl_suspended; |
29 | static int current_intensity = 0; | 29 | static int current_intensity = 0; |
30 | static spinlock_t bl_lock = SPIN_LOCK_UNLOCKED; | 30 | static DEFINE_SPINLOCK(bl_lock); |
31 | static struct backlight_device *hp680_backlight_device; | 31 | static struct backlight_device *hp680_backlight_device; |
32 | 32 | ||
33 | static void hp680bl_send_intensity(struct backlight_device *bd) | 33 | static void hp680bl_send_intensity(struct backlight_device *bd) |
diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c index f32b590730f2..01401cd63ac0 100644 --- a/drivers/video/console/vgacon.c +++ b/drivers/video/console/vgacon.c | |||
@@ -390,7 +390,7 @@ static const char *vgacon_startup(void) | |||
390 | vga_video_port_val = VGA_CRT_DM; | 390 | vga_video_port_val = VGA_CRT_DM; |
391 | if ((ORIG_VIDEO_EGA_BX & 0xff) != 0x10) { | 391 | if ((ORIG_VIDEO_EGA_BX & 0xff) != 0x10) { |
392 | static struct resource ega_console_resource = | 392 | static struct resource ega_console_resource = |
393 | { "ega", 0x3B0, 0x3BF }; | 393 | { .name = "ega", .start = 0x3B0, .end = 0x3BF }; |
394 | vga_video_type = VIDEO_TYPE_EGAM; | 394 | vga_video_type = VIDEO_TYPE_EGAM; |
395 | vga_vram_size = 0x8000; | 395 | vga_vram_size = 0x8000; |
396 | display_desc = "EGA+"; | 396 | display_desc = "EGA+"; |
@@ -398,9 +398,9 @@ static const char *vgacon_startup(void) | |||
398 | &ega_console_resource); | 398 | &ega_console_resource); |
399 | } else { | 399 | } else { |
400 | static struct resource mda1_console_resource = | 400 | static struct resource mda1_console_resource = |
401 | { "mda", 0x3B0, 0x3BB }; | 401 | { .name = "mda", .start = 0x3B0, .end = 0x3BB }; |
402 | static struct resource mda2_console_resource = | 402 | static struct resource mda2_console_resource = |
403 | { "mda", 0x3BF, 0x3BF }; | 403 | { .name = "mda", .start = 0x3BF, .end = 0x3BF }; |
404 | vga_video_type = VIDEO_TYPE_MDA; | 404 | vga_video_type = VIDEO_TYPE_MDA; |
405 | vga_vram_size = 0x2000; | 405 | vga_vram_size = 0x2000; |
406 | display_desc = "*MDA"; | 406 | display_desc = "*MDA"; |
@@ -423,14 +423,14 @@ static const char *vgacon_startup(void) | |||
423 | 423 | ||
424 | if (!ORIG_VIDEO_ISVGA) { | 424 | if (!ORIG_VIDEO_ISVGA) { |
425 | static struct resource ega_console_resource | 425 | static struct resource ega_console_resource |
426 | = { "ega", 0x3C0, 0x3DF }; | 426 | = { .name = "ega", .start = 0x3C0, .end = 0x3DF }; |
427 | vga_video_type = VIDEO_TYPE_EGAC; | 427 | vga_video_type = VIDEO_TYPE_EGAC; |
428 | display_desc = "EGA"; | 428 | display_desc = "EGA"; |
429 | request_resource(&ioport_resource, | 429 | request_resource(&ioport_resource, |
430 | &ega_console_resource); | 430 | &ega_console_resource); |
431 | } else { | 431 | } else { |
432 | static struct resource vga_console_resource | 432 | static struct resource vga_console_resource |
433 | = { "vga+", 0x3C0, 0x3DF }; | 433 | = { .name = "vga+", .start = 0x3C0, .end = 0x3DF }; |
434 | vga_video_type = VIDEO_TYPE_VGAC; | 434 | vga_video_type = VIDEO_TYPE_VGAC; |
435 | display_desc = "VGA+"; | 435 | display_desc = "VGA+"; |
436 | request_resource(&ioport_resource, | 436 | request_resource(&ioport_resource, |
@@ -474,7 +474,7 @@ static const char *vgacon_startup(void) | |||
474 | } | 474 | } |
475 | } else { | 475 | } else { |
476 | static struct resource cga_console_resource = | 476 | static struct resource cga_console_resource = |
477 | { "cga", 0x3D4, 0x3D5 }; | 477 | { .name = "cga", .start = 0x3D4, .end = 0x3D5 }; |
478 | vga_video_type = VIDEO_TYPE_CGA; | 478 | vga_video_type = VIDEO_TYPE_CGA; |
479 | vga_vram_size = 0x2000; | 479 | vga_vram_size = 0x2000; |
480 | display_desc = "*CGA"; | 480 | display_desc = "*CGA"; |
diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c index 31143afe7c95..a171daab0ad0 100644 --- a/drivers/video/fbmem.c +++ b/drivers/video/fbmem.c | |||
@@ -32,7 +32,6 @@ | |||
32 | #ifdef CONFIG_KMOD | 32 | #ifdef CONFIG_KMOD |
33 | #include <linux/kmod.h> | 33 | #include <linux/kmod.h> |
34 | #endif | 34 | #endif |
35 | #include <linux/devfs_fs_kernel.h> | ||
36 | #include <linux/err.h> | 35 | #include <linux/err.h> |
37 | #include <linux/device.h> | 36 | #include <linux/device.h> |
38 | #include <linux/efi.h> | 37 | #include <linux/efi.h> |
@@ -1331,8 +1330,6 @@ register_framebuffer(struct fb_info *fb_info) | |||
1331 | fb_add_videomode(&mode, &fb_info->modelist); | 1330 | fb_add_videomode(&mode, &fb_info->modelist); |
1332 | registered_fb[i] = fb_info; | 1331 | registered_fb[i] = fb_info; |
1333 | 1332 | ||
1334 | devfs_mk_cdev(MKDEV(FB_MAJOR, i), | ||
1335 | S_IFCHR | S_IRUGO | S_IWUGO, "fb/%d", i); | ||
1336 | event.info = fb_info; | 1333 | event.info = fb_info; |
1337 | blocking_notifier_call_chain(&fb_notifier_list, | 1334 | blocking_notifier_call_chain(&fb_notifier_list, |
1338 | FB_EVENT_FB_REGISTERED, &event); | 1335 | FB_EVENT_FB_REGISTERED, &event); |
@@ -1359,7 +1356,6 @@ unregister_framebuffer(struct fb_info *fb_info) | |||
1359 | i = fb_info->node; | 1356 | i = fb_info->node; |
1360 | if (!registered_fb[i]) | 1357 | if (!registered_fb[i]) |
1361 | return -EINVAL; | 1358 | return -EINVAL; |
1362 | devfs_remove("fb/%d", i); | ||
1363 | 1359 | ||
1364 | if (fb_info->pixmap.addr && | 1360 | if (fb_info->pixmap.addr && |
1365 | (fb_info->pixmap.flags & FB_PIXMAP_DEFAULT)) | 1361 | (fb_info->pixmap.flags & FB_PIXMAP_DEFAULT)) |
@@ -1432,7 +1428,6 @@ fbmem_init(void) | |||
1432 | { | 1428 | { |
1433 | create_proc_read_entry("fb", 0, NULL, fbmem_read_proc, NULL); | 1429 | create_proc_read_entry("fb", 0, NULL, fbmem_read_proc, NULL); |
1434 | 1430 | ||
1435 | devfs_mk_dir("fb"); | ||
1436 | if (register_chrdev(FB_MAJOR,"fb",&fb_fops)) | 1431 | if (register_chrdev(FB_MAJOR,"fb",&fb_fops)) |
1437 | printk("unable to get major %d for fb devs\n", FB_MAJOR); | 1432 | printk("unable to get major %d for fb devs\n", FB_MAJOR); |
1438 | 1433 | ||
diff --git a/drivers/video/sgivwfb.c b/drivers/video/sgivwfb.c index 2e6df1fcb2b9..c0cc5e3ba7b5 100644 --- a/drivers/video/sgivwfb.c +++ b/drivers/video/sgivwfb.c | |||
@@ -23,6 +23,8 @@ | |||
23 | #include <asm/io.h> | 23 | #include <asm/io.h> |
24 | #include <asm/mtrr.h> | 24 | #include <asm/mtrr.h> |
25 | 25 | ||
26 | #include <setup_arch.h> | ||
27 | |||
26 | #define INCLUDE_TIMING_TABLE_DATA | 28 | #define INCLUDE_TIMING_TABLE_DATA |
27 | #define DBE_REG_BASE par->regs | 29 | #define DBE_REG_BASE par->regs |
28 | #include <video/sgivw.h> | 30 | #include <video/sgivw.h> |
@@ -42,10 +44,6 @@ struct sgivw_par { | |||
42 | * The default can be overridden if the driver is compiled as a module | 44 | * The default can be overridden if the driver is compiled as a module |
43 | */ | 45 | */ |
44 | 46 | ||
45 | /* set by arch/i386/kernel/setup.c */ | ||
46 | extern unsigned long sgivwfb_mem_phys; | ||
47 | extern unsigned long sgivwfb_mem_size; | ||
48 | |||
49 | static int ypan = 0; | 47 | static int ypan = 0; |
50 | static int ywrap = 0; | 48 | static int ywrap = 0; |
51 | 49 | ||