diff options
Diffstat (limited to 'drivers')
40 files changed, 433 insertions, 1490 deletions
diff --git a/drivers/acpi/asus_acpi.c b/drivers/acpi/asus_acpi.c index d25ef961415c..44ad90c03c2e 100644 --- a/drivers/acpi/asus_acpi.c +++ b/drivers/acpi/asus_acpi.c | |||
@@ -610,7 +610,7 @@ write_led(const char __user * buffer, unsigned long count, | |||
610 | (led_out) ? (hotk->status | ledmask) : (hotk->status & ~ledmask); | 610 | (led_out) ? (hotk->status | ledmask) : (hotk->status & ~ledmask); |
611 | 611 | ||
612 | if (invert) /* invert target value */ | 612 | if (invert) /* invert target value */ |
613 | led_out = !led_out & 0x1; | 613 | led_out = !led_out; |
614 | 614 | ||
615 | if (!write_acpi_int(hotk->handle, ledname, led_out, NULL)) | 615 | if (!write_acpi_int(hotk->handle, ledname, led_out, NULL)) |
616 | printk(KERN_WARNING "Asus ACPI: LED (%s) write failed\n", | 616 | printk(KERN_WARNING "Asus ACPI: LED (%s) write failed\n", |
diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c index f6215e809808..d5729d5dc190 100644 --- a/drivers/acpi/battery.c +++ b/drivers/acpi/battery.c | |||
@@ -293,13 +293,12 @@ static int extract_package(struct acpi_battery *battery, | |||
293 | strncpy(ptr, (u8 *)&element->integer.value, | 293 | strncpy(ptr, (u8 *)&element->integer.value, |
294 | sizeof(acpi_integer)); | 294 | sizeof(acpi_integer)); |
295 | ptr[sizeof(acpi_integer)] = 0; | 295 | ptr[sizeof(acpi_integer)] = 0; |
296 | } else return -EFAULT; | 296 | } else |
297 | *ptr = 0; /* don't have value */ | ||
297 | } else { | 298 | } else { |
298 | if (element->type == ACPI_TYPE_INTEGER) { | 299 | int *x = (int *)((u8 *)battery + offsets[i].offset); |
299 | int *x = (int *)((u8 *)battery + | 300 | *x = (element->type == ACPI_TYPE_INTEGER) ? |
300 | offsets[i].offset); | 301 | element->integer.value : -1; |
301 | *x = element->integer.value; | ||
302 | } else return -EFAULT; | ||
303 | } | 302 | } |
304 | } | 303 | } |
305 | return 0; | 304 | return 0; |
diff --git a/drivers/acpi/dock.c b/drivers/acpi/dock.c index 307cef65c247..fa44fb96fc34 100644 --- a/drivers/acpi/dock.c +++ b/drivers/acpi/dock.c | |||
@@ -710,6 +710,7 @@ static ssize_t write_undock(struct device *dev, struct device_attribute *attr, | |||
710 | if (!count) | 710 | if (!count) |
711 | return -EINVAL; | 711 | return -EINVAL; |
712 | 712 | ||
713 | begin_undock(dock_station); | ||
713 | ret = handle_eject_request(dock_station, ACPI_NOTIFY_EJECT_REQUEST); | 714 | ret = handle_eject_request(dock_station, ACPI_NOTIFY_EJECT_REQUEST); |
714 | return ret ? ret: count; | 715 | return ret ? ret: count; |
715 | } | 716 | } |
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c index 6f3b217699e9..e8e2d8869236 100644 --- a/drivers/acpi/processor_idle.c +++ b/drivers/acpi/processor_idle.c | |||
@@ -216,8 +216,10 @@ static void acpi_safe_halt(void) | |||
216 | * test NEED_RESCHED: | 216 | * test NEED_RESCHED: |
217 | */ | 217 | */ |
218 | smp_mb(); | 218 | smp_mb(); |
219 | if (!need_resched()) | 219 | if (!need_resched()) { |
220 | safe_halt(); | 220 | safe_halt(); |
221 | local_irq_disable(); | ||
222 | } | ||
221 | current_thread_info()->status |= TS_POLLING; | 223 | current_thread_info()->status |= TS_POLLING; |
222 | } | 224 | } |
223 | 225 | ||
@@ -421,7 +423,9 @@ static void acpi_processor_idle(void) | |||
421 | else | 423 | else |
422 | acpi_safe_halt(); | 424 | acpi_safe_halt(); |
423 | 425 | ||
424 | local_irq_enable(); | 426 | if (irqs_disabled()) |
427 | local_irq_enable(); | ||
428 | |||
425 | return; | 429 | return; |
426 | } | 430 | } |
427 | 431 | ||
@@ -530,7 +534,9 @@ static void acpi_processor_idle(void) | |||
530 | * skew otherwise. | 534 | * skew otherwise. |
531 | */ | 535 | */ |
532 | sleep_ticks = 0xFFFFFFFF; | 536 | sleep_ticks = 0xFFFFFFFF; |
533 | local_irq_enable(); | 537 | if (irqs_disabled()) |
538 | local_irq_enable(); | ||
539 | |||
534 | break; | 540 | break; |
535 | 541 | ||
536 | case ACPI_STATE_C2: | 542 | case ACPI_STATE_C2: |
diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c index 1bc0c74f2755..12fb44f16766 100644 --- a/drivers/acpi/video.c +++ b/drivers/acpi/video.c | |||
@@ -807,40 +807,11 @@ static void acpi_video_bus_find_cap(struct acpi_video_bus *video) | |||
807 | static int acpi_video_bus_check(struct acpi_video_bus *video) | 807 | static int acpi_video_bus_check(struct acpi_video_bus *video) |
808 | { | 808 | { |
809 | acpi_status status = -ENOENT; | 809 | acpi_status status = -ENOENT; |
810 | long device_id; | 810 | |
811 | struct device *dev; | ||
812 | struct acpi_device *device; | ||
813 | 811 | ||
814 | if (!video) | 812 | if (!video) |
815 | return -EINVAL; | 813 | return -EINVAL; |
816 | 814 | ||
817 | device = video->device; | ||
818 | |||
819 | status = | ||
820 | acpi_evaluate_integer(device->handle, "_ADR", NULL, &device_id); | ||
821 | |||
822 | if (!ACPI_SUCCESS(status)) | ||
823 | return -ENODEV; | ||
824 | |||
825 | /* We need to attempt to determine whether the _ADR refers to a | ||
826 | PCI device or not. There's no terribly good way to do this, | ||
827 | so the best we can hope for is to assume that there'll never | ||
828 | be a video device in the host bridge */ | ||
829 | if (device_id >= 0x10000) { | ||
830 | /* It looks like a PCI device. Does it exist? */ | ||
831 | dev = acpi_get_physical_device(device->handle); | ||
832 | } else { | ||
833 | /* It doesn't look like a PCI device. Does its parent | ||
834 | exist? */ | ||
835 | acpi_handle phandle; | ||
836 | if (acpi_get_parent(device->handle, &phandle)) | ||
837 | return -ENODEV; | ||
838 | dev = acpi_get_physical_device(phandle); | ||
839 | } | ||
840 | if (!dev) | ||
841 | return -ENODEV; | ||
842 | put_device(dev); | ||
843 | |||
844 | /* Since there is no HID, CID and so on for VGA driver, we have | 815 | /* Since there is no HID, CID and so on for VGA driver, we have |
845 | * to check well known required nodes. | 816 | * to check well known required nodes. |
846 | */ | 817 | */ |
@@ -1366,37 +1337,8 @@ acpi_video_bus_write_DOS(struct file *file, | |||
1366 | 1337 | ||
1367 | static int acpi_video_bus_add_fs(struct acpi_device *device) | 1338 | static int acpi_video_bus_add_fs(struct acpi_device *device) |
1368 | { | 1339 | { |
1369 | long device_id; | ||
1370 | int status; | ||
1371 | struct proc_dir_entry *entry = NULL; | 1340 | struct proc_dir_entry *entry = NULL; |
1372 | struct acpi_video_bus *video; | 1341 | struct acpi_video_bus *video; |
1373 | struct device *dev; | ||
1374 | |||
1375 | status = | ||
1376 | acpi_evaluate_integer(device->handle, "_ADR", NULL, &device_id); | ||
1377 | |||
1378 | if (!ACPI_SUCCESS(status)) | ||
1379 | return -ENODEV; | ||
1380 | |||
1381 | /* We need to attempt to determine whether the _ADR refers to a | ||
1382 | PCI device or not. There's no terribly good way to do this, | ||
1383 | so the best we can hope for is to assume that there'll never | ||
1384 | be a video device in the host bridge */ | ||
1385 | if (device_id >= 0x10000) { | ||
1386 | /* It looks like a PCI device. Does it exist? */ | ||
1387 | dev = acpi_get_physical_device(device->handle); | ||
1388 | } else { | ||
1389 | /* It doesn't look like a PCI device. Does its parent | ||
1390 | exist? */ | ||
1391 | acpi_handle phandle; | ||
1392 | if (acpi_get_parent(device->handle, &phandle)) | ||
1393 | return -ENODEV; | ||
1394 | dev = acpi_get_physical_device(phandle); | ||
1395 | } | ||
1396 | if (!dev) | ||
1397 | return -ENODEV; | ||
1398 | put_device(dev); | ||
1399 | |||
1400 | 1342 | ||
1401 | 1343 | ||
1402 | video = acpi_driver_data(device); | 1344 | video = acpi_driver_data(device); |
diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig index e469647330de..25aba69b59b4 100644 --- a/drivers/ata/Kconfig +++ b/drivers/ata/Kconfig | |||
@@ -30,6 +30,7 @@ config ATA_NONSTANDARD | |||
30 | config ATA_ACPI | 30 | config ATA_ACPI |
31 | bool | 31 | bool |
32 | depends on ACPI && PCI | 32 | depends on ACPI && PCI |
33 | select ACPI_DOCK | ||
33 | default y | 34 | default y |
34 | help | 35 | help |
35 | This option adds support for ATA-related ACPI objects. | 36 | This option adds support for ATA-related ACPI objects. |
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index 6978469eb16d..17ee6ed985d9 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c | |||
@@ -49,6 +49,10 @@ | |||
49 | #define DRV_NAME "ahci" | 49 | #define DRV_NAME "ahci" |
50 | #define DRV_VERSION "3.0" | 50 | #define DRV_VERSION "3.0" |
51 | 51 | ||
52 | static int ahci_skip_host_reset; | ||
53 | module_param_named(skip_host_reset, ahci_skip_host_reset, int, 0444); | ||
54 | MODULE_PARM_DESC(skip_host_reset, "skip global host reset (0=don't skip, 1=skip)"); | ||
55 | |||
52 | static int ahci_enable_alpm(struct ata_port *ap, | 56 | static int ahci_enable_alpm(struct ata_port *ap, |
53 | enum link_pm policy); | 57 | enum link_pm policy); |
54 | static void ahci_disable_alpm(struct ata_port *ap); | 58 | static void ahci_disable_alpm(struct ata_port *ap); |
@@ -587,6 +591,7 @@ static const struct pci_device_id ahci_pci_tbl[] = { | |||
587 | 591 | ||
588 | /* Marvell */ | 592 | /* Marvell */ |
589 | { PCI_VDEVICE(MARVELL, 0x6145), board_ahci_mv }, /* 6145 */ | 593 | { PCI_VDEVICE(MARVELL, 0x6145), board_ahci_mv }, /* 6145 */ |
594 | { PCI_VDEVICE(MARVELL, 0x6121), board_ahci_mv }, /* 6121 */ | ||
590 | 595 | ||
591 | /* Generic, PCI class code for AHCI */ | 596 | /* Generic, PCI class code for AHCI */ |
592 | { PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, | 597 | { PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, |
@@ -661,6 +666,7 @@ static void ahci_save_initial_config(struct pci_dev *pdev, | |||
661 | void __iomem *mmio = pcim_iomap_table(pdev)[AHCI_PCI_BAR]; | 666 | void __iomem *mmio = pcim_iomap_table(pdev)[AHCI_PCI_BAR]; |
662 | u32 cap, port_map; | 667 | u32 cap, port_map; |
663 | int i; | 668 | int i; |
669 | int mv; | ||
664 | 670 | ||
665 | /* make sure AHCI mode is enabled before accessing CAP */ | 671 | /* make sure AHCI mode is enabled before accessing CAP */ |
666 | ahci_enable_ahci(mmio); | 672 | ahci_enable_ahci(mmio); |
@@ -696,12 +702,16 @@ static void ahci_save_initial_config(struct pci_dev *pdev, | |||
696 | * presence register, as bit 4 (counting from 0) | 702 | * presence register, as bit 4 (counting from 0) |
697 | */ | 703 | */ |
698 | if (hpriv->flags & AHCI_HFLAG_MV_PATA) { | 704 | if (hpriv->flags & AHCI_HFLAG_MV_PATA) { |
705 | if (pdev->device == 0x6121) | ||
706 | mv = 0x3; | ||
707 | else | ||
708 | mv = 0xf; | ||
699 | dev_printk(KERN_ERR, &pdev->dev, | 709 | dev_printk(KERN_ERR, &pdev->dev, |
700 | "MV_AHCI HACK: port_map %x -> %x\n", | 710 | "MV_AHCI HACK: port_map %x -> %x\n", |
701 | hpriv->port_map, | 711 | port_map, |
702 | hpriv->port_map & 0xf); | 712 | port_map & mv); |
703 | 713 | ||
704 | port_map &= 0xf; | 714 | port_map &= mv; |
705 | } | 715 | } |
706 | 716 | ||
707 | /* cross check port_map and cap.n_ports */ | 717 | /* cross check port_map and cap.n_ports */ |
@@ -1088,29 +1098,35 @@ static int ahci_reset_controller(struct ata_host *host) | |||
1088 | ahci_enable_ahci(mmio); | 1098 | ahci_enable_ahci(mmio); |
1089 | 1099 | ||
1090 | /* global controller reset */ | 1100 | /* global controller reset */ |
1091 | tmp = readl(mmio + HOST_CTL); | 1101 | if (!ahci_skip_host_reset) { |
1092 | if ((tmp & HOST_RESET) == 0) { | 1102 | tmp = readl(mmio + HOST_CTL); |
1093 | writel(tmp | HOST_RESET, mmio + HOST_CTL); | 1103 | if ((tmp & HOST_RESET) == 0) { |
1094 | readl(mmio + HOST_CTL); /* flush */ | 1104 | writel(tmp | HOST_RESET, mmio + HOST_CTL); |
1095 | } | 1105 | readl(mmio + HOST_CTL); /* flush */ |
1106 | } | ||
1096 | 1107 | ||
1097 | /* reset must complete within 1 second, or | 1108 | /* reset must complete within 1 second, or |
1098 | * the hardware should be considered fried. | 1109 | * the hardware should be considered fried. |
1099 | */ | 1110 | */ |
1100 | ssleep(1); | 1111 | ssleep(1); |
1101 | 1112 | ||
1102 | tmp = readl(mmio + HOST_CTL); | 1113 | tmp = readl(mmio + HOST_CTL); |
1103 | if (tmp & HOST_RESET) { | 1114 | if (tmp & HOST_RESET) { |
1104 | dev_printk(KERN_ERR, host->dev, | 1115 | dev_printk(KERN_ERR, host->dev, |
1105 | "controller reset failed (0x%x)\n", tmp); | 1116 | "controller reset failed (0x%x)\n", tmp); |
1106 | return -EIO; | 1117 | return -EIO; |
1107 | } | 1118 | } |
1108 | 1119 | ||
1109 | /* turn on AHCI mode */ | 1120 | /* turn on AHCI mode */ |
1110 | ahci_enable_ahci(mmio); | 1121 | ahci_enable_ahci(mmio); |
1111 | 1122 | ||
1112 | /* some registers might be cleared on reset. restore initial values */ | 1123 | /* Some registers might be cleared on reset. Restore |
1113 | ahci_restore_initial_config(host); | 1124 | * initial values. |
1125 | */ | ||
1126 | ahci_restore_initial_config(host); | ||
1127 | } else | ||
1128 | dev_printk(KERN_INFO, host->dev, | ||
1129 | "skipping global host reset\n"); | ||
1114 | 1130 | ||
1115 | if (pdev->vendor == PCI_VENDOR_ID_INTEL) { | 1131 | if (pdev->vendor == PCI_VENDOR_ID_INTEL) { |
1116 | u16 tmp16; | 1132 | u16 tmp16; |
@@ -1162,9 +1178,14 @@ static void ahci_init_controller(struct ata_host *host) | |||
1162 | int i; | 1178 | int i; |
1163 | void __iomem *port_mmio; | 1179 | void __iomem *port_mmio; |
1164 | u32 tmp; | 1180 | u32 tmp; |
1181 | int mv; | ||
1165 | 1182 | ||
1166 | if (hpriv->flags & AHCI_HFLAG_MV_PATA) { | 1183 | if (hpriv->flags & AHCI_HFLAG_MV_PATA) { |
1167 | port_mmio = __ahci_port_base(host, 4); | 1184 | if (pdev->device == 0x6121) |
1185 | mv = 2; | ||
1186 | else | ||
1187 | mv = 4; | ||
1188 | port_mmio = __ahci_port_base(host, mv); | ||
1168 | 1189 | ||
1169 | writel(0, port_mmio + PORT_IRQ_MASK); | 1190 | writel(0, port_mmio + PORT_IRQ_MASK); |
1170 | 1191 | ||
@@ -2241,7 +2262,10 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
2241 | if (rc) | 2262 | if (rc) |
2242 | return rc; | 2263 | return rc; |
2243 | 2264 | ||
2244 | rc = pcim_iomap_regions(pdev, 1 << AHCI_PCI_BAR, DRV_NAME); | 2265 | /* AHCI controllers often implement SFF compatible interface. |
2266 | * Grab all PCI BARs just in case. | ||
2267 | */ | ||
2268 | rc = pcim_iomap_regions_request_all(pdev, 1 << AHCI_PCI_BAR, DRV_NAME); | ||
2245 | if (rc == -EBUSY) | 2269 | if (rc == -EBUSY) |
2246 | pcim_pin_device(pdev); | 2270 | pcim_pin_device(pdev); |
2247 | if (rc) | 2271 | if (rc) |
diff --git a/drivers/ata/libata-acpi.c b/drivers/ata/libata-acpi.c index 0770cb7391a4..bf98a566adac 100644 --- a/drivers/ata/libata-acpi.c +++ b/drivers/ata/libata-acpi.c | |||
@@ -118,45 +118,77 @@ static void ata_acpi_associate_ide_port(struct ata_port *ap) | |||
118 | ap->pflags |= ATA_PFLAG_INIT_GTM_VALID; | 118 | ap->pflags |= ATA_PFLAG_INIT_GTM_VALID; |
119 | } | 119 | } |
120 | 120 | ||
121 | static void ata_acpi_handle_hotplug(struct ata_port *ap, struct kobject *kobj, | 121 | static void ata_acpi_handle_hotplug(struct ata_port *ap, struct ata_device *dev, |
122 | u32 event) | 122 | u32 event) |
123 | { | 123 | { |
124 | char event_string[12]; | 124 | char event_string[12]; |
125 | char *envp[] = { event_string, NULL }; | 125 | char *envp[] = { event_string, NULL }; |
126 | struct ata_eh_info *ehi = &ap->link.eh_info; | 126 | struct ata_eh_info *ehi; |
127 | 127 | struct kobject *kobj = NULL; | |
128 | if (event == 0 || event == 1) { | 128 | int wait = 0; |
129 | unsigned long flags; | 129 | unsigned long flags; |
130 | spin_lock_irqsave(ap->lock, flags); | 130 | |
131 | ata_ehi_clear_desc(ehi); | 131 | if (!ap) |
132 | ata_ehi_push_desc(ehi, "ACPI event"); | 132 | ap = dev->link->ap; |
133 | ata_ehi_hotplugged(ehi); | 133 | ehi = &ap->link.eh_info; |
134 | ata_port_freeze(ap); | 134 | |
135 | spin_unlock_irqrestore(ap->lock, flags); | 135 | spin_lock_irqsave(ap->lock, flags); |
136 | |||
137 | switch (event) { | ||
138 | case ACPI_NOTIFY_BUS_CHECK: | ||
139 | case ACPI_NOTIFY_DEVICE_CHECK: | ||
140 | ata_ehi_push_desc(ehi, "ACPI event"); | ||
141 | ata_ehi_hotplugged(ehi); | ||
142 | ata_port_freeze(ap); | ||
143 | break; | ||
144 | |||
145 | case ACPI_NOTIFY_EJECT_REQUEST: | ||
146 | ata_ehi_push_desc(ehi, "ACPI event"); | ||
147 | if (dev) | ||
148 | dev->flags |= ATA_DFLAG_DETACH; | ||
149 | else { | ||
150 | struct ata_link *tlink; | ||
151 | struct ata_device *tdev; | ||
152 | |||
153 | ata_port_for_each_link(tlink, ap) | ||
154 | ata_link_for_each_dev(tdev, tlink) | ||
155 | tdev->flags |= ATA_DFLAG_DETACH; | ||
156 | } | ||
157 | |||
158 | ata_port_schedule_eh(ap); | ||
159 | wait = 1; | ||
160 | break; | ||
136 | } | 161 | } |
137 | 162 | ||
163 | if (dev) { | ||
164 | if (dev->sdev) | ||
165 | kobj = &dev->sdev->sdev_gendev.kobj; | ||
166 | } else | ||
167 | kobj = &ap->dev->kobj; | ||
168 | |||
138 | if (kobj) { | 169 | if (kobj) { |
139 | sprintf(event_string, "BAY_EVENT=%d", event); | 170 | sprintf(event_string, "BAY_EVENT=%d", event); |
140 | kobject_uevent_env(kobj, KOBJ_CHANGE, envp); | 171 | kobject_uevent_env(kobj, KOBJ_CHANGE, envp); |
141 | } | 172 | } |
173 | |||
174 | spin_unlock_irqrestore(ap->lock, flags); | ||
175 | |||
176 | if (wait) | ||
177 | ata_port_wait_eh(ap); | ||
142 | } | 178 | } |
143 | 179 | ||
144 | static void ata_acpi_dev_notify(acpi_handle handle, u32 event, void *data) | 180 | static void ata_acpi_dev_notify(acpi_handle handle, u32 event, void *data) |
145 | { | 181 | { |
146 | struct ata_device *dev = data; | 182 | struct ata_device *dev = data; |
147 | struct kobject *kobj = NULL; | ||
148 | 183 | ||
149 | if (dev->sdev) | 184 | ata_acpi_handle_hotplug(NULL, dev, event); |
150 | kobj = &dev->sdev->sdev_gendev.kobj; | ||
151 | |||
152 | ata_acpi_handle_hotplug(dev->link->ap, kobj, event); | ||
153 | } | 185 | } |
154 | 186 | ||
155 | static void ata_acpi_ap_notify(acpi_handle handle, u32 event, void *data) | 187 | static void ata_acpi_ap_notify(acpi_handle handle, u32 event, void *data) |
156 | { | 188 | { |
157 | struct ata_port *ap = data; | 189 | struct ata_port *ap = data; |
158 | 190 | ||
159 | ata_acpi_handle_hotplug(ap, &ap->dev->kobj, event); | 191 | ata_acpi_handle_hotplug(ap, NULL, event); |
160 | } | 192 | } |
161 | 193 | ||
162 | /** | 194 | /** |
@@ -191,20 +223,30 @@ void ata_acpi_associate(struct ata_host *host) | |||
191 | else | 223 | else |
192 | ata_acpi_associate_ide_port(ap); | 224 | ata_acpi_associate_ide_port(ap); |
193 | 225 | ||
194 | if (ap->acpi_handle) | 226 | if (ap->acpi_handle) { |
195 | acpi_install_notify_handler (ap->acpi_handle, | 227 | acpi_install_notify_handler(ap->acpi_handle, |
196 | ACPI_SYSTEM_NOTIFY, | 228 | ACPI_SYSTEM_NOTIFY, |
197 | ata_acpi_ap_notify, | 229 | ata_acpi_ap_notify, ap); |
198 | ap); | 230 | #if defined(CONFIG_ACPI_DOCK) || defined(CONFIG_ACPI_DOCK_MODULE) |
231 | /* we might be on a docking station */ | ||
232 | register_hotplug_dock_device(ap->acpi_handle, | ||
233 | ata_acpi_ap_notify, ap); | ||
234 | #endif | ||
235 | } | ||
199 | 236 | ||
200 | for (j = 0; j < ata_link_max_devices(&ap->link); j++) { | 237 | for (j = 0; j < ata_link_max_devices(&ap->link); j++) { |
201 | struct ata_device *dev = &ap->link.device[j]; | 238 | struct ata_device *dev = &ap->link.device[j]; |
202 | 239 | ||
203 | if (dev->acpi_handle) | 240 | if (dev->acpi_handle) { |
204 | acpi_install_notify_handler (dev->acpi_handle, | 241 | acpi_install_notify_handler(dev->acpi_handle, |
205 | ACPI_SYSTEM_NOTIFY, | 242 | ACPI_SYSTEM_NOTIFY, |
206 | ata_acpi_dev_notify, | 243 | ata_acpi_dev_notify, dev); |
207 | dev); | 244 | #if defined(CONFIG_ACPI_DOCK) || defined(CONFIG_ACPI_DOCK_MODULE) |
245 | /* we might be on a docking station */ | ||
246 | register_hotplug_dock_device(dev->acpi_handle, | ||
247 | ata_acpi_dev_notify, dev); | ||
248 | #endif | ||
249 | } | ||
208 | } | 250 | } |
209 | } | 251 | } |
210 | } | 252 | } |
diff --git a/drivers/ata/pata_ali.c b/drivers/ata/pata_ali.c index 7e68edf3c0f3..8786455c901d 100644 --- a/drivers/ata/pata_ali.c +++ b/drivers/ata/pata_ali.c | |||
@@ -295,7 +295,7 @@ static void ali_lock_sectors(struct ata_device *adev) | |||
295 | static int ali_check_atapi_dma(struct ata_queued_cmd *qc) | 295 | static int ali_check_atapi_dma(struct ata_queued_cmd *qc) |
296 | { | 296 | { |
297 | /* If its not a media command, its not worth it */ | 297 | /* If its not a media command, its not worth it */ |
298 | if (qc->nbytes < 2048) | 298 | if (atapi_cmd_type(qc->cdb[0]) == ATAPI_MISC) |
299 | return -EOPNOTSUPP; | 299 | return -EOPNOTSUPP; |
300 | return 0; | 300 | return 0; |
301 | } | 301 | } |
diff --git a/drivers/block/Kconfig b/drivers/block/Kconfig index b6d230b3209f..0d1d2133d9bc 100644 --- a/drivers/block/Kconfig +++ b/drivers/block/Kconfig | |||
@@ -44,16 +44,6 @@ config MAC_FLOPPY | |||
44 | If you have a SWIM-3 (Super Woz Integrated Machine 3; from Apple) | 44 | If you have a SWIM-3 (Super Woz Integrated Machine 3; from Apple) |
45 | floppy controller, say Y here. Most commonly found in PowerMacs. | 45 | floppy controller, say Y here. Most commonly found in PowerMacs. |
46 | 46 | ||
47 | config BLK_DEV_PS2 | ||
48 | tristate "PS/2 ESDI hard disk support" | ||
49 | depends on MCA && MCA_LEGACY && BROKEN | ||
50 | help | ||
51 | Say Y here if you have a PS/2 machine with a MCA bus and an ESDI | ||
52 | hard disk. | ||
53 | |||
54 | To compile this driver as a module, choose M here: the | ||
55 | module will be called ps2esdi. | ||
56 | |||
57 | config AMIGA_Z2RAM | 47 | config AMIGA_Z2RAM |
58 | tristate "Amiga Zorro II ramdisk support" | 48 | tristate "Amiga Zorro II ramdisk support" |
59 | depends on ZORRO | 49 | depends on ZORRO |
diff --git a/drivers/block/Makefile b/drivers/block/Makefile index 01c972415cb2..5e584306be99 100644 --- a/drivers/block/Makefile +++ b/drivers/block/Makefile | |||
@@ -13,7 +13,6 @@ obj-$(CONFIG_ATARI_FLOPPY) += ataflop.o | |||
13 | obj-$(CONFIG_AMIGA_Z2RAM) += z2ram.o | 13 | obj-$(CONFIG_AMIGA_Z2RAM) += z2ram.o |
14 | obj-$(CONFIG_BLK_DEV_RAM) += brd.o | 14 | obj-$(CONFIG_BLK_DEV_RAM) += brd.o |
15 | obj-$(CONFIG_BLK_DEV_LOOP) += loop.o | 15 | obj-$(CONFIG_BLK_DEV_LOOP) += loop.o |
16 | obj-$(CONFIG_BLK_DEV_PS2) += ps2esdi.o | ||
17 | obj-$(CONFIG_BLK_DEV_XD) += xd.o | 16 | obj-$(CONFIG_BLK_DEV_XD) += xd.o |
18 | obj-$(CONFIG_BLK_CPQ_DA) += cpqarray.o | 17 | obj-$(CONFIG_BLK_CPQ_DA) += cpqarray.o |
19 | obj-$(CONFIG_BLK_CPQ_CISS_DA) += cciss.o | 18 | obj-$(CONFIG_BLK_CPQ_CISS_DA) += cciss.o |
diff --git a/drivers/block/ps2esdi.c b/drivers/block/ps2esdi.c deleted file mode 100644 index 3c796e236253..000000000000 --- a/drivers/block/ps2esdi.c +++ /dev/null | |||
@@ -1,1079 +0,0 @@ | |||
1 | /* ps2esdi driver based on assembler code by Arindam Banerji, | ||
2 | written by Peter De Schrijver */ | ||
3 | /* Reassuring note to IBM : This driver was NOT developed by vice-versa | ||
4 | engineering the PS/2's BIOS */ | ||
5 | /* Dedicated to Wannes, Tofke, Ykke, Godot, Killroy and all those | ||
6 | other lovely fish out there... */ | ||
7 | /* This code was written during the long and boring WINA | ||
8 | elections 1994 */ | ||
9 | /* Thanks to Arindam Banerij for giving me the source of his driver */ | ||
10 | /* This code may be freely distributed and modified in any way, | ||
11 | as long as these notes remain intact */ | ||
12 | |||
13 | /* Revised: 05/07/94 by Arindam Banerji (axb@cse.nd.edu) */ | ||
14 | /* Revised: 09/08/94 by Peter De Schrijver (stud11@cc4.kuleuven.ac.be) | ||
15 | Thanks to Arindam Banerij for sending me the docs of the adapter */ | ||
16 | |||
17 | /* BA Modified for ThinkPad 720 by Boris Ashkinazi */ | ||
18 | /* (bash@vnet.ibm.com) 08/08/95 */ | ||
19 | |||
20 | /* Modified further for ThinkPad-720C by Uri Blumenthal */ | ||
21 | /* (uri@watson.ibm.com) Sep 11, 1995 */ | ||
22 | |||
23 | /* TODO : | ||
24 | + Timeouts | ||
25 | + Get disk parameters | ||
26 | + DMA above 16MB | ||
27 | + reset after read/write error | ||
28 | */ | ||
29 | |||
30 | #define DEVICE_NAME "PS/2 ESDI" | ||
31 | |||
32 | #include <linux/major.h> | ||
33 | #include <linux/errno.h> | ||
34 | #include <linux/wait.h> | ||
35 | #include <linux/interrupt.h> | ||
36 | #include <linux/fs.h> | ||
37 | #include <linux/kernel.h> | ||
38 | #include <linux/genhd.h> | ||
39 | #include <linux/ps2esdi.h> | ||
40 | #include <linux/blkdev.h> | ||
41 | #include <linux/mca-legacy.h> | ||
42 | #include <linux/init.h> | ||
43 | #include <linux/ioport.h> | ||
44 | #include <linux/module.h> | ||
45 | #include <linux/hdreg.h> | ||
46 | |||
47 | #include <asm/system.h> | ||
48 | #include <asm/io.h> | ||
49 | #include <asm/dma.h> | ||
50 | #include <asm/mca_dma.h> | ||
51 | #include <asm/uaccess.h> | ||
52 | |||
53 | #define PS2ESDI_IRQ 14 | ||
54 | #define MAX_HD 2 | ||
55 | #define MAX_RETRIES 5 | ||
56 | #define MAX_16BIT 65536 | ||
57 | #define ESDI_TIMEOUT 0xf000 | ||
58 | #define ESDI_STAT_TIMEOUT 4 | ||
59 | |||
60 | #define TYPE_0_CMD_BLK_LENGTH 2 | ||
61 | #define TYPE_1_CMD_BLK_LENGTH 4 | ||
62 | |||
63 | static void reset_ctrl(void); | ||
64 | |||
65 | static int ps2esdi_geninit(void); | ||
66 | |||
67 | static void do_ps2esdi_request(struct request_queue * q); | ||
68 | |||
69 | static void ps2esdi_readwrite(int cmd, struct request *req); | ||
70 | |||
71 | static void ps2esdi_fill_cmd_block(u_short * cmd_blk, u_short cmd, | ||
72 | u_short cyl, u_short head, u_short sector, u_short length, u_char drive); | ||
73 | |||
74 | static int ps2esdi_out_cmd_blk(u_short * cmd_blk); | ||
75 | |||
76 | static void ps2esdi_prep_dma(char *buffer, u_short length, u_char dma_xmode); | ||
77 | |||
78 | static irqreturn_t ps2esdi_interrupt_handler(int irq, void *dev_id); | ||
79 | static void (*current_int_handler) (u_int) = NULL; | ||
80 | static void ps2esdi_normal_interrupt_handler(u_int); | ||
81 | static void ps2esdi_initial_reset_int_handler(u_int); | ||
82 | static void ps2esdi_geometry_int_handler(u_int); | ||
83 | static int ps2esdi_getgeo(struct block_device *bdev, struct hd_geometry *geo); | ||
84 | |||
85 | static int ps2esdi_read_status_words(int num_words, int max_words, u_short * buffer); | ||
86 | |||
87 | static void dump_cmd_complete_status(u_int int_ret_code); | ||
88 | |||
89 | static void ps2esdi_get_device_cfg(void); | ||
90 | |||
91 | static void ps2esdi_reset_timer(unsigned long unused); | ||
92 | |||
93 | static u_int dma_arb_level; /* DMA arbitration level */ | ||
94 | |||
95 | static DECLARE_WAIT_QUEUE_HEAD(ps2esdi_int); | ||
96 | |||
97 | static int no_int_yet; | ||
98 | static int ps2esdi_drives; | ||
99 | static u_short io_base; | ||
100 | static DEFINE_TIMER(esdi_timer, ps2esdi_reset_timer, 0, 0); | ||
101 | static int reset_status; | ||
102 | static int ps2esdi_slot = -1; | ||
103 | static int tp720esdi = 0; /* Is it Integrated ESDI of ThinkPad-720? */ | ||
104 | static int intg_esdi = 0; /* If integrated adapter */ | ||
105 | struct ps2esdi_i_struct { | ||
106 | unsigned int head, sect, cyl, wpcom, lzone, ctl; | ||
107 | }; | ||
108 | static DEFINE_SPINLOCK(ps2esdi_lock); | ||
109 | static struct request_queue *ps2esdi_queue; | ||
110 | static struct request *current_req; | ||
111 | |||
112 | #if 0 | ||
113 | #if 0 /* try both - I don't know which one is better... UB */ | ||
114 | static struct ps2esdi_i_struct ps2esdi_info[MAX_HD] = | ||
115 | { | ||
116 | {4, 48, 1553, 0, 0, 0}, | ||
117 | {0, 0, 0, 0, 0, 0}}; | ||
118 | #else | ||
119 | static struct ps2esdi_i_struct ps2esdi_info[MAX_HD] = | ||
120 | { | ||
121 | {64, 32, 161, 0, 0, 0}, | ||
122 | {0, 0, 0, 0, 0, 0}}; | ||
123 | #endif | ||
124 | #endif | ||
125 | static struct ps2esdi_i_struct ps2esdi_info[MAX_HD] = | ||
126 | { | ||
127 | {0, 0, 0, 0, 0, 0}, | ||
128 | {0, 0, 0, 0, 0, 0}}; | ||
129 | |||
130 | static struct block_device_operations ps2esdi_fops = | ||
131 | { | ||
132 | .owner = THIS_MODULE, | ||
133 | .getgeo = ps2esdi_getgeo, | ||
134 | }; | ||
135 | |||
136 | static struct gendisk *ps2esdi_gendisk[2]; | ||
137 | |||
138 | /* initialization routine called by ll_rw_blk.c */ | ||
139 | static int __init ps2esdi_init(void) | ||
140 | { | ||
141 | |||
142 | int error = 0; | ||
143 | |||
144 | /* register the device - pass the name and major number */ | ||
145 | if (register_blkdev(PS2ESDI_MAJOR, "ed")) | ||
146 | return -EBUSY; | ||
147 | |||
148 | /* set up some global information - indicating device specific info */ | ||
149 | ps2esdi_queue = blk_init_queue(do_ps2esdi_request, &ps2esdi_lock); | ||
150 | if (!ps2esdi_queue) { | ||
151 | unregister_blkdev(PS2ESDI_MAJOR, "ed"); | ||
152 | return -ENOMEM; | ||
153 | } | ||
154 | |||
155 | /* some minor housekeeping - setup the global gendisk structure */ | ||
156 | error = ps2esdi_geninit(); | ||
157 | if (error) { | ||
158 | printk(KERN_WARNING "PS2ESDI: error initialising" | ||
159 | " device, releasing resources\n"); | ||
160 | unregister_blkdev(PS2ESDI_MAJOR, "ed"); | ||
161 | blk_cleanup_queue(ps2esdi_queue); | ||
162 | return error; | ||
163 | } | ||
164 | return 0; | ||
165 | } /* ps2esdi_init */ | ||
166 | |||
167 | #ifndef MODULE | ||
168 | |||
169 | module_init(ps2esdi_init); | ||
170 | |||
171 | #else | ||
172 | |||
173 | static int cyl[MAX_HD] = {-1,-1}; | ||
174 | static int head[MAX_HD] = {-1, -1}; | ||
175 | static int sect[MAX_HD] = {-1, -1}; | ||
176 | |||
177 | module_param(tp720esdi, bool, 0); | ||
178 | module_param_array(cyl, int, NULL, 0); | ||
179 | module_param_array(head, int, NULL, 0); | ||
180 | module_param_array(sect, int, NULL, 0); | ||
181 | MODULE_LICENSE("GPL"); | ||
182 | |||
183 | int init_module(void) { | ||
184 | int drive; | ||
185 | |||
186 | for(drive = 0; drive < MAX_HD; drive++) { | ||
187 | struct ps2esdi_i_struct *info = &ps2esdi_info[drive]; | ||
188 | |||
189 | if (cyl[drive] != -1) { | ||
190 | info->cyl = info->lzone = cyl[drive]; | ||
191 | info->wpcom = 0; | ||
192 | } | ||
193 | if (head[drive] != -1) { | ||
194 | info->head = head[drive]; | ||
195 | info->ctl = (head[drive] > 8 ? 8 : 0); | ||
196 | } | ||
197 | if (sect[drive] != -1) info->sect = sect[drive]; | ||
198 | } | ||
199 | return ps2esdi_init(); | ||
200 | } | ||
201 | |||
202 | void | ||
203 | cleanup_module(void) { | ||
204 | int i; | ||
205 | if(ps2esdi_slot) { | ||
206 | mca_mark_as_unused(ps2esdi_slot); | ||
207 | mca_set_adapter_procfn(ps2esdi_slot, NULL, NULL); | ||
208 | } | ||
209 | release_region(io_base, 4); | ||
210 | free_dma(dma_arb_level); | ||
211 | free_irq(PS2ESDI_IRQ, &ps2esdi_gendisk); | ||
212 | unregister_blkdev(PS2ESDI_MAJOR, "ed"); | ||
213 | blk_cleanup_queue(ps2esdi_queue); | ||
214 | for (i = 0; i < ps2esdi_drives; i++) { | ||
215 | del_gendisk(ps2esdi_gendisk[i]); | ||
216 | put_disk(ps2esdi_gendisk[i]); | ||
217 | } | ||
218 | } | ||
219 | #endif /* MODULE */ | ||
220 | |||
221 | /* handles boot time command line parameters */ | ||
222 | void __init tp720_setup(char *str, int *ints) | ||
223 | { | ||
224 | /* no params, just sets the tp720esdi flag if it exists */ | ||
225 | |||
226 | printk("%s: TP 720 ESDI flag set\n", DEVICE_NAME); | ||
227 | tp720esdi = 1; | ||
228 | } | ||
229 | |||
230 | void __init ed_setup(char *str, int *ints) | ||
231 | { | ||
232 | int hdind = 0; | ||
233 | |||
234 | /* handles 3 parameters only - corresponding to | ||
235 | 1. Number of cylinders | ||
236 | 2. Number of heads | ||
237 | 3. Sectors/track | ||
238 | */ | ||
239 | |||
240 | if (ints[0] != 3) | ||
241 | return; | ||
242 | |||
243 | /* print out the information - seen at boot time */ | ||
244 | printk("%s: ints[0]=%d ints[1]=%d ints[2]=%d ints[3]=%d\n", | ||
245 | DEVICE_NAME, ints[0], ints[1], ints[2], ints[3]); | ||
246 | |||
247 | /* set the index into device specific information table */ | ||
248 | if (ps2esdi_info[0].head != 0) | ||
249 | hdind = 1; | ||
250 | |||
251 | /* set up all the device information */ | ||
252 | ps2esdi_info[hdind].head = ints[2]; | ||
253 | ps2esdi_info[hdind].sect = ints[3]; | ||
254 | ps2esdi_info[hdind].cyl = ints[1]; | ||
255 | ps2esdi_info[hdind].wpcom = 0; | ||
256 | ps2esdi_info[hdind].lzone = ints[1]; | ||
257 | ps2esdi_info[hdind].ctl = (ints[2] > 8 ? 8 : 0); | ||
258 | #if 0 /* this may be needed for PS2/Mod.80, but it hurts ThinkPad! */ | ||
259 | ps2esdi_drives = hdind + 1; /* increment index for the next time */ | ||
260 | #endif | ||
261 | } /* ed_setup */ | ||
262 | |||
263 | static int ps2esdi_getinfo(char *buf, int slot, void *d) | ||
264 | { | ||
265 | int len = 0; | ||
266 | |||
267 | len += sprintf(buf + len, "DMA Arbitration Level: %d\n", | ||
268 | dma_arb_level); | ||
269 | len += sprintf(buf + len, "IO Port: %x\n", io_base); | ||
270 | len += sprintf(buf + len, "IRQ: 14\n"); | ||
271 | len += sprintf(buf + len, "Drives: %d\n", ps2esdi_drives); | ||
272 | |||
273 | return len; | ||
274 | } | ||
275 | |||
276 | /* ps2 esdi specific initialization - called thru the gendisk chain */ | ||
277 | static int __init ps2esdi_geninit(void) | ||
278 | { | ||
279 | /* | ||
280 | The first part contains the initialization code | ||
281 | for the ESDI disk subsystem. All we really do | ||
282 | is search for the POS registers of the controller | ||
283 | to do some simple setup operations. First, we | ||
284 | must ensure that the controller is installed, | ||
285 | enabled, and configured as PRIMARY. Then we must | ||
286 | determine the DMA arbitration level being used by | ||
287 | the controller so we can handle data transfer | ||
288 | operations properly. If all of this works, then | ||
289 | we will set the INIT_FLAG to a non-zero value. | ||
290 | */ | ||
291 | |||
292 | int slot = 0, i, reset_start, reset_end; | ||
293 | u_char status; | ||
294 | unsigned short adapterID; | ||
295 | int error = 0; | ||
296 | |||
297 | if ((slot = mca_find_adapter(INTG_ESDI_ID, 0)) != MCA_NOTFOUND) { | ||
298 | adapterID = INTG_ESDI_ID; | ||
299 | printk("%s: integrated ESDI adapter found in slot %d\n", | ||
300 | DEVICE_NAME, slot+1); | ||
301 | #ifndef MODULE | ||
302 | mca_set_adapter_name(slot, "PS/2 Integrated ESDI"); | ||
303 | #endif | ||
304 | } else if ((slot = mca_find_adapter(NRML_ESDI_ID, 0)) != -1) { | ||
305 | adapterID = NRML_ESDI_ID; | ||
306 | printk("%s: normal ESDI adapter found in slot %d\n", | ||
307 | DEVICE_NAME, slot+1); | ||
308 | mca_set_adapter_name(slot, "PS/2 ESDI"); | ||
309 | } else { | ||
310 | return -ENODEV; | ||
311 | } | ||
312 | |||
313 | ps2esdi_slot = slot; | ||
314 | mca_mark_as_used(slot); | ||
315 | mca_set_adapter_procfn(slot, (MCA_ProcFn) ps2esdi_getinfo, NULL); | ||
316 | |||
317 | /* Found the slot - read the POS register 2 to get the necessary | ||
318 | configuration and status information. POS register 2 has the | ||
319 | following information : | ||
320 | Bit Function | ||
321 | 7 reserved = 0 | ||
322 | 6 arbitration method | ||
323 | 0 - fairness enabled | ||
324 | 1 - fairness disabled, linear priority assignment | ||
325 | 5-2 arbitration level | ||
326 | 1 alternate address | ||
327 | 1 alternate address | ||
328 | 0 - use addresses 0x3510 - 0x3517 | ||
329 | 0 adapter enable | ||
330 | */ | ||
331 | |||
332 | status = mca_read_stored_pos(slot, 2); | ||
333 | /* is it enabled ? */ | ||
334 | if (!(status & STATUS_ENABLED)) { | ||
335 | printk("%s: ESDI adapter disabled\n", DEVICE_NAME); | ||
336 | error = -ENODEV; | ||
337 | goto err_out1; | ||
338 | } | ||
339 | /* try to grab IRQ, and try to grab a slow IRQ if it fails, so we can | ||
340 | share with the SCSI driver */ | ||
341 | if (request_irq(PS2ESDI_IRQ, ps2esdi_interrupt_handler, | ||
342 | IRQF_DISABLED | IRQF_SHARED, "PS/2 ESDI", &ps2esdi_gendisk) | ||
343 | && request_irq(PS2ESDI_IRQ, ps2esdi_interrupt_handler, | ||
344 | IRQF_SHARED, "PS/2 ESDI", &ps2esdi_gendisk) | ||
345 | ) { | ||
346 | printk("%s: Unable to get IRQ %d\n", DEVICE_NAME, PS2ESDI_IRQ); | ||
347 | error = -EBUSY; | ||
348 | goto err_out1; | ||
349 | } | ||
350 | if (status & STATUS_ALTERNATE) | ||
351 | io_base = ALT_IO_BASE; | ||
352 | else | ||
353 | io_base = PRIMARY_IO_BASE; | ||
354 | |||
355 | if (!request_region(io_base, 4, "ed")) { | ||
356 | printk(KERN_WARNING"Unable to request region 0x%x\n", io_base); | ||
357 | error = -EBUSY; | ||
358 | goto err_out2; | ||
359 | } | ||
360 | /* get the dma arbitration level */ | ||
361 | dma_arb_level = (status >> 2) & 0xf; | ||
362 | |||
363 | /* BA */ | ||
364 | printk("%s: DMA arbitration level : %d\n", | ||
365 | DEVICE_NAME, dma_arb_level); | ||
366 | |||
367 | LITE_ON; | ||
368 | current_int_handler = ps2esdi_initial_reset_int_handler; | ||
369 | reset_ctrl(); | ||
370 | reset_status = 0; | ||
371 | reset_start = jiffies; | ||
372 | while (!reset_status) { | ||
373 | init_timer(&esdi_timer); | ||
374 | esdi_timer.expires = jiffies + HZ; | ||
375 | esdi_timer.data = 0; | ||
376 | add_timer(&esdi_timer); | ||
377 | sleep_on(&ps2esdi_int); | ||
378 | } | ||
379 | reset_end = jiffies; | ||
380 | LITE_OFF; | ||
381 | printk("%s: reset interrupt after %d jiffies, %u.%02u secs\n", | ||
382 | DEVICE_NAME, reset_end - reset_start, (reset_end - reset_start) / HZ, | ||
383 | (reset_end - reset_start) % HZ); | ||
384 | |||
385 | |||
386 | /* Integrated ESDI Disk and Controller has only one drive! */ | ||
387 | if (adapterID == INTG_ESDI_ID) {/* if not "normal" PS2 ESDI adapter */ | ||
388 | ps2esdi_drives = 1; /* then we have only one physical disk! */ intg_esdi = 1; | ||
389 | } | ||
390 | |||
391 | |||
392 | |||
393 | /* finally this part sets up some global data structures etc. */ | ||
394 | |||
395 | ps2esdi_get_device_cfg(); | ||
396 | |||
397 | /* some annoyance in the above routine returns TWO drives? | ||
398 | Is something else happining in the background? | ||
399 | Regaurdless we fix the # of drives again. AJK */ | ||
400 | /* Integrated ESDI Disk and Controller has only one drive! */ | ||
401 | if (adapterID == INTG_ESDI_ID) /* if not "normal" PS2 ESDI adapter */ | ||
402 | ps2esdi_drives = 1; /* Not three or two, ONE DAMNIT! */ | ||
403 | |||
404 | current_int_handler = ps2esdi_normal_interrupt_handler; | ||
405 | |||
406 | if (request_dma(dma_arb_level, "ed") !=0) { | ||
407 | printk(KERN_WARNING "PS2ESDI: Can't request dma-channel %d\n" | ||
408 | ,(int) dma_arb_level); | ||
409 | error = -EBUSY; | ||
410 | goto err_out3; | ||
411 | } | ||
412 | blk_queue_max_sectors(ps2esdi_queue, 128); | ||
413 | |||
414 | error = -ENOMEM; | ||
415 | for (i = 0; i < ps2esdi_drives; i++) { | ||
416 | struct gendisk *disk = alloc_disk(64); | ||
417 | if (!disk) | ||
418 | goto err_out4; | ||
419 | disk->major = PS2ESDI_MAJOR; | ||
420 | disk->first_minor = i<<6; | ||
421 | sprintf(disk->disk_name, "ed%c", 'a'+i); | ||
422 | disk->fops = &ps2esdi_fops; | ||
423 | ps2esdi_gendisk[i] = disk; | ||
424 | } | ||
425 | |||
426 | for (i = 0; i < ps2esdi_drives; i++) { | ||
427 | struct gendisk *disk = ps2esdi_gendisk[i]; | ||
428 | set_capacity(disk, ps2esdi_info[i].head * ps2esdi_info[i].sect * | ||
429 | ps2esdi_info[i].cyl); | ||
430 | disk->queue = ps2esdi_queue; | ||
431 | disk->private_data = &ps2esdi_info[i]; | ||
432 | add_disk(disk); | ||
433 | } | ||
434 | return 0; | ||
435 | err_out4: | ||
436 | while (i--) | ||
437 | put_disk(ps2esdi_gendisk[i]); | ||
438 | err_out3: | ||
439 | release_region(io_base, 4); | ||
440 | err_out2: | ||
441 | free_irq(PS2ESDI_IRQ, &ps2esdi_gendisk); | ||
442 | err_out1: | ||
443 | if(ps2esdi_slot) { | ||
444 | mca_mark_as_unused(ps2esdi_slot); | ||
445 | mca_set_adapter_procfn(ps2esdi_slot, NULL, NULL); | ||
446 | } | ||
447 | return error; | ||
448 | } | ||
449 | |||
450 | static void __init ps2esdi_get_device_cfg(void) | ||
451 | { | ||
452 | u_short cmd_blk[TYPE_0_CMD_BLK_LENGTH]; | ||
453 | |||
454 | /*BA */ printk("%s: Drive 0\n", DEVICE_NAME); | ||
455 | current_int_handler = ps2esdi_geometry_int_handler; | ||
456 | cmd_blk[0] = CMD_GET_DEV_CONFIG | 0x600; | ||
457 | cmd_blk[1] = 0; | ||
458 | no_int_yet = TRUE; | ||
459 | ps2esdi_out_cmd_blk(cmd_blk); | ||
460 | if (no_int_yet) | ||
461 | sleep_on(&ps2esdi_int); | ||
462 | |||
463 | if (ps2esdi_drives > 1) { | ||
464 | printk("%s: Drive 1\n", DEVICE_NAME); /*BA */ | ||
465 | cmd_blk[0] = CMD_GET_DEV_CONFIG | (1 << 5) | 0x600; | ||
466 | cmd_blk[1] = 0; | ||
467 | no_int_yet = TRUE; | ||
468 | ps2esdi_out_cmd_blk(cmd_blk); | ||
469 | if (no_int_yet) | ||
470 | sleep_on(&ps2esdi_int); | ||
471 | } /* if second physical drive is present */ | ||
472 | return; | ||
473 | } | ||
474 | |||
475 | /* strategy routine that handles most of the IO requests */ | ||
476 | static void do_ps2esdi_request(struct request_queue * q) | ||
477 | { | ||
478 | struct request *req; | ||
479 | /* since, this routine is called with interrupts cleared - they | ||
480 | must be before it finishes */ | ||
481 | |||
482 | req = elv_next_request(q); | ||
483 | if (!req) | ||
484 | return; | ||
485 | |||
486 | #if 0 | ||
487 | printk("%s:got request. device : %s command : %d sector : %ld count : %ld, buffer: %p\n", | ||
488 | DEVICE_NAME, | ||
489 | req->rq_disk->disk_name, | ||
490 | req->cmd, req->sector, | ||
491 | req->current_nr_sectors, req->buffer); | ||
492 | #endif | ||
493 | |||
494 | /* check for above 16Mb dmas */ | ||
495 | if (isa_virt_to_bus(req->buffer + req->current_nr_sectors * 512) > 16 * MB) { | ||
496 | printk("%s: DMA above 16MB not supported\n", DEVICE_NAME); | ||
497 | end_request(req, FAIL); | ||
498 | return; | ||
499 | } | ||
500 | |||
501 | if (req->sector+req->current_nr_sectors > get_capacity(req->rq_disk)) { | ||
502 | printk("Grrr. error. ps2esdi_drives: %d, %llu %llu\n", | ||
503 | ps2esdi_drives, req->sector, | ||
504 | (unsigned long long)get_capacity(req->rq_disk)); | ||
505 | end_request(req, FAIL); | ||
506 | return; | ||
507 | } | ||
508 | |||
509 | switch (rq_data_dir(req)) { | ||
510 | case READ: | ||
511 | ps2esdi_readwrite(READ, req); | ||
512 | break; | ||
513 | case WRITE: | ||
514 | ps2esdi_readwrite(WRITE, req); | ||
515 | break; | ||
516 | default: | ||
517 | printk("%s: Unknown command\n", req->rq_disk->disk_name); | ||
518 | end_request(req, FAIL); | ||
519 | break; | ||
520 | } /* handle different commands */ | ||
521 | } /* main strategy routine */ | ||
522 | |||
523 | /* resets the ESDI adapter */ | ||
524 | static void reset_ctrl(void) | ||
525 | { | ||
526 | |||
527 | u_long expire; | ||
528 | u_short status; | ||
529 | |||
530 | /* enable interrupts on the controller */ | ||
531 | status = inb(ESDI_INTRPT); | ||
532 | outb((status & 0xe0) | ATT_EOI, ESDI_ATTN); /* to be sure we don't have | ||
533 | any interrupt pending... */ | ||
534 | outb_p(CTRL_ENABLE_INTR, ESDI_CONTROL); | ||
535 | |||
536 | /* read the ESDI status port - if the controller is not busy, | ||
537 | simply do a soft reset (fast) - otherwise we'll have to do a | ||
538 | hard (slow) reset. */ | ||
539 | if (!(inb_p(ESDI_STATUS) & STATUS_BUSY)) { | ||
540 | /*BA */ printk("%s: soft reset...\n", DEVICE_NAME); | ||
541 | outb_p(CTRL_SOFT_RESET, ESDI_ATTN); | ||
542 | } | ||
543 | /* soft reset */ | ||
544 | else { | ||
545 | /*BA */ | ||
546 | printk("%s: hard reset...\n", DEVICE_NAME); | ||
547 | outb_p(CTRL_HARD_RESET, ESDI_CONTROL); | ||
548 | expire = jiffies + 2*HZ; | ||
549 | while (time_before(jiffies, expire)); | ||
550 | outb_p(1, ESDI_CONTROL); | ||
551 | } /* hard reset */ | ||
552 | |||
553 | |||
554 | } /* reset the controller */ | ||
555 | |||
556 | /* called by the strategy routine to handle read and write requests */ | ||
557 | static void ps2esdi_readwrite(int cmd, struct request *req) | ||
558 | { | ||
559 | struct ps2esdi_i_struct *p = req->rq_disk->private_data; | ||
560 | unsigned block = req->sector; | ||
561 | unsigned count = req->current_nr_sectors; | ||
562 | int drive = p - ps2esdi_info; | ||
563 | u_short track, head, cylinder, sector; | ||
564 | u_short cmd_blk[TYPE_1_CMD_BLK_LENGTH]; | ||
565 | |||
566 | /* do some relevant arithmatic */ | ||
567 | track = block / p->sect; | ||
568 | head = track % p->head; | ||
569 | cylinder = track / p->head; | ||
570 | sector = block % p->sect; | ||
571 | |||
572 | #if 0 | ||
573 | printk("%s: cyl=%d head=%d sect=%d\n", DEVICE_NAME, cylinder, head, sector); | ||
574 | #endif | ||
575 | /* call the routine that actually fills out a command block */ | ||
576 | ps2esdi_fill_cmd_block | ||
577 | (cmd_blk, | ||
578 | (cmd == READ) ? CMD_READ : CMD_WRITE, | ||
579 | cylinder, head, sector, count, drive); | ||
580 | |||
581 | /* send the command block to the controller */ | ||
582 | current_req = req; | ||
583 | spin_unlock_irq(&ps2esdi_lock); | ||
584 | if (ps2esdi_out_cmd_blk(cmd_blk)) { | ||
585 | spin_lock_irq(&ps2esdi_lock); | ||
586 | printk("%s: Controller failed\n", DEVICE_NAME); | ||
587 | if ((++req->errors) >= MAX_RETRIES) | ||
588 | end_request(req, FAIL); | ||
589 | } | ||
590 | /* check for failure to put out the command block */ | ||
591 | else { | ||
592 | spin_lock_irq(&ps2esdi_lock); | ||
593 | #if 0 | ||
594 | printk("%s: waiting for xfer\n", DEVICE_NAME); | ||
595 | #endif | ||
596 | /* turn disk lights on */ | ||
597 | LITE_ON; | ||
598 | } | ||
599 | |||
600 | } /* ps2esdi_readwrite */ | ||
601 | |||
602 | /* fill out the command block */ | ||
603 | static void ps2esdi_fill_cmd_block(u_short * cmd_blk, u_short cmd, | ||
604 | u_short cyl, u_short head, u_short sector, u_short length, u_char drive) | ||
605 | { | ||
606 | |||
607 | cmd_blk[0] = (drive << 5) | cmd; | ||
608 | cmd_blk[1] = length; | ||
609 | cmd_blk[2] = ((cyl & 0x1f) << 11) | (head << 5) | sector; | ||
610 | cmd_blk[3] = (cyl & 0x3E0) >> 5; | ||
611 | |||
612 | } /* fill out the command block */ | ||
613 | |||
614 | /* write a command block to the controller */ | ||
615 | static int ps2esdi_out_cmd_blk(u_short * cmd_blk) | ||
616 | { | ||
617 | |||
618 | int i; | ||
619 | unsigned long jif; | ||
620 | u_char status; | ||
621 | |||
622 | /* enable interrupts */ | ||
623 | outb(CTRL_ENABLE_INTR, ESDI_CONTROL); | ||
624 | |||
625 | /* do not write to the controller, if it is busy */ | ||
626 | for (jif = jiffies + ESDI_STAT_TIMEOUT; | ||
627 | time_after(jif, jiffies) && | ||
628 | (inb(ESDI_STATUS) & STATUS_BUSY); ) | ||
629 | ; | ||
630 | |||
631 | #if 0 | ||
632 | printk("%s: i(1)=%ld\n", DEVICE_NAME, jif); | ||
633 | #endif | ||
634 | |||
635 | /* if device is still busy - then just time out */ | ||
636 | if (inb(ESDI_STATUS) & STATUS_BUSY) { | ||
637 | printk("%s: ps2esdi_out_cmd timed out (1)\n", DEVICE_NAME); | ||
638 | return ERROR; | ||
639 | } /* timeout ??? */ | ||
640 | /* Set up the attention register in the controller */ | ||
641 | outb(((*cmd_blk) & 0xE0) | 1, ESDI_ATTN); | ||
642 | |||
643 | #if 0 | ||
644 | printk("%s: sending %d words to controller\n", DEVICE_NAME, (((*cmd_blk) >> 14) + 1) << 1); | ||
645 | #endif | ||
646 | |||
647 | /* one by one send each word out */ | ||
648 | for (i = (((*cmd_blk) >> 14) + 1) << 1; i; i--) { | ||
649 | status = inb(ESDI_STATUS); | ||
650 | for (jif = jiffies + ESDI_STAT_TIMEOUT; | ||
651 | time_after(jif, jiffies) && (status & STATUS_BUSY) && | ||
652 | (status & STATUS_CMD_INF); status = inb(ESDI_STATUS)); | ||
653 | if ((status & (STATUS_BUSY | STATUS_CMD_INF)) == STATUS_BUSY) { | ||
654 | #if 0 | ||
655 | printk("%s: sending %04X\n", DEVICE_NAME, *cmd_blk); | ||
656 | #endif | ||
657 | outw(*cmd_blk++, ESDI_CMD_INT); | ||
658 | } else { | ||
659 | printk("%s: ps2esdi_out_cmd timed out while sending command (status=%02X)\n", | ||
660 | DEVICE_NAME, status); | ||
661 | return ERROR; | ||
662 | } | ||
663 | } /* send all words out */ | ||
664 | return OK; | ||
665 | } /* send out the commands */ | ||
666 | |||
667 | |||
668 | /* prepare for dma - do all the necessary setup */ | ||
669 | static void ps2esdi_prep_dma(char *buffer, u_short length, u_char dma_xmode) | ||
670 | { | ||
671 | unsigned long flags = claim_dma_lock(); | ||
672 | |||
673 | mca_disable_dma(dma_arb_level); | ||
674 | |||
675 | mca_set_dma_addr(dma_arb_level, isa_virt_to_bus(buffer)); | ||
676 | |||
677 | mca_set_dma_count(dma_arb_level, length * 512 / 2); | ||
678 | |||
679 | mca_set_dma_mode(dma_arb_level, dma_xmode); | ||
680 | |||
681 | mca_enable_dma(dma_arb_level); | ||
682 | |||
683 | release_dma_lock(flags); | ||
684 | |||
685 | } /* prepare for dma */ | ||
686 | |||
687 | |||
688 | |||
689 | static irqreturn_t ps2esdi_interrupt_handler(int irq, void *dev_id) | ||
690 | { | ||
691 | u_int int_ret_code; | ||
692 | |||
693 | if (inb(ESDI_STATUS) & STATUS_INTR) { | ||
694 | int_ret_code = inb(ESDI_INTRPT); | ||
695 | if (current_int_handler) { | ||
696 | /* Disable adapter interrupts till processing is finished */ | ||
697 | outb(CTRL_DISABLE_INTR, ESDI_CONTROL); | ||
698 | current_int_handler(int_ret_code); | ||
699 | } else | ||
700 | printk("%s: help ! No interrupt handler.\n", DEVICE_NAME); | ||
701 | } else { | ||
702 | return IRQ_NONE; | ||
703 | } | ||
704 | return IRQ_HANDLED; | ||
705 | } | ||
706 | |||
707 | static void ps2esdi_initial_reset_int_handler(u_int int_ret_code) | ||
708 | { | ||
709 | |||
710 | switch (int_ret_code & 0xf) { | ||
711 | case INT_RESET: | ||
712 | /*BA */ | ||
713 | printk("%s: initial reset completed.\n", DEVICE_NAME); | ||
714 | outb((int_ret_code & 0xe0) | ATT_EOI, ESDI_ATTN); | ||
715 | wake_up(&ps2esdi_int); | ||
716 | break; | ||
717 | case INT_ATTN_ERROR: | ||
718 | printk("%s: Attention error. interrupt status : %02X\n", DEVICE_NAME, | ||
719 | int_ret_code); | ||
720 | printk("%s: status: %02x\n", DEVICE_NAME, inb(ESDI_STATUS)); | ||
721 | break; | ||
722 | default: | ||
723 | printk("%s: initial reset handler received interrupt: %02X\n", | ||
724 | DEVICE_NAME, int_ret_code); | ||
725 | outb((int_ret_code & 0xe0) | ATT_EOI, ESDI_ATTN); | ||
726 | break; | ||
727 | } | ||
728 | outb(CTRL_ENABLE_INTR, ESDI_CONTROL); | ||
729 | } | ||
730 | |||
731 | |||
732 | static void ps2esdi_geometry_int_handler(u_int int_ret_code) | ||
733 | { | ||
734 | u_int status, drive_num; | ||
735 | unsigned long rba; | ||
736 | int i; | ||
737 | |||
738 | drive_num = int_ret_code >> 5; | ||
739 | switch (int_ret_code & 0xf) { | ||
740 | case INT_CMD_COMPLETE: | ||
741 | for (i = ESDI_TIMEOUT; i && !(inb(ESDI_STATUS) & STATUS_STAT_AVAIL); i--); | ||
742 | if (!(inb(ESDI_STATUS) & STATUS_STAT_AVAIL)) { | ||
743 | printk("%s: timeout reading status word\n", DEVICE_NAME); | ||
744 | outb((int_ret_code & 0xe0) | ATT_EOI, ESDI_ATTN); | ||
745 | break; | ||
746 | } | ||
747 | status = inw(ESDI_STT_INT); | ||
748 | if ((status & 0x1F) == CMD_GET_DEV_CONFIG) { | ||
749 | #define REPLY_WORDS 5 /* we already read word 0 */ | ||
750 | u_short reply[REPLY_WORDS]; | ||
751 | |||
752 | if (ps2esdi_read_status_words((status >> 8) - 1, REPLY_WORDS, reply)) { | ||
753 | /*BA */ | ||
754 | printk("%s: Device Configuration Status for drive %u\n", | ||
755 | DEVICE_NAME, drive_num); | ||
756 | |||
757 | printk("%s: Spares/cyls: %u", DEVICE_NAME, reply[0] >> 8); | ||
758 | |||
759 | printk | ||
760 | ("Config bits: %s%s%s%s%s\n", | ||
761 | (reply[0] & CONFIG_IS) ? "Invalid Secondary, " : "", | ||
762 | ((reply[0] & CONFIG_ZD) && !(reply[0] & CONFIG_IS)) | ||
763 | ? "Zero Defect, " : "Defects Present, ", | ||
764 | (reply[0] & CONFIG_SF) ? "Skewed Format, " : "", | ||
765 | (reply[0] & CONFIG_FR) ? "Removable, " : "Non-Removable, ", | ||
766 | (reply[0] & CONFIG_RT) ? "No Retries" : "Retries"); | ||
767 | |||
768 | rba = reply[1] | ((unsigned long) reply[2] << 16); | ||
769 | printk("%s: Number of RBA's: %lu\n", DEVICE_NAME, rba); | ||
770 | |||
771 | printk("%s: Physical number of cylinders: %u, Sectors/Track: %u, Heads: %u\n", | ||
772 | DEVICE_NAME, reply[3], reply[4] >> 8, reply[4] & 0xff); | ||
773 | |||
774 | if (!ps2esdi_info[drive_num].head) { | ||
775 | ps2esdi_info[drive_num].head = 64; | ||
776 | ps2esdi_info[drive_num].sect = 32; | ||
777 | ps2esdi_info[drive_num].cyl = rba / (64 * 32); | ||
778 | ps2esdi_info[drive_num].wpcom = 0; | ||
779 | ps2esdi_info[drive_num].lzone = ps2esdi_info[drive_num].cyl; | ||
780 | ps2esdi_info[drive_num].ctl = 8; | ||
781 | if (tp720esdi) { /* store the retrieved parameters */ | ||
782 | ps2esdi_info[0].head = reply[4] & 0Xff; | ||
783 | ps2esdi_info[0].sect = reply[4] >> 8; | ||
784 | ps2esdi_info[0].cyl = reply[3]; | ||
785 | ps2esdi_info[0].wpcom = 0; | ||
786 | ps2esdi_info[0].lzone = reply[3]; | ||
787 | } else { | ||
788 | if (!intg_esdi) | ||
789 | ps2esdi_drives++; | ||
790 | } | ||
791 | } | ||
792 | #ifdef OBSOLETE | ||
793 | if (!ps2esdi_info[drive_num].head) { | ||
794 | ps2esdi_info[drive_num].head = reply[4] & 0Xff; | ||
795 | ps2esdi_info[drive_num].sect = reply[4] >> 8; | ||
796 | ps2esdi_info[drive_num].cyl = reply[3]; | ||
797 | ps2esdi_info[drive_num].wpcom = 0; | ||
798 | ps2esdi_info[drive_num].lzone = reply[3]; | ||
799 | if (tp720esdi) { /* store the retrieved parameters */ | ||
800 | ps2esdi_info[0].head = reply[4] & 0Xff; | ||
801 | ps2esdi_info[0].sect = reply[4] >> 8; | ||
802 | ps2esdi_info[0].cyl = reply[3]; | ||
803 | ps2esdi_info[0].wpcom = 0; | ||
804 | ps2esdi_info[0].lzone = reply[3]; | ||
805 | } else { | ||
806 | ps2esdi_drives++; | ||
807 | } | ||
808 | } | ||
809 | #endif | ||
810 | |||
811 | } else | ||
812 | printk("%s: failed while getting device config\n", DEVICE_NAME); | ||
813 | #undef REPLY_WORDS | ||
814 | } else | ||
815 | printk("%s: command %02X unknown by geometry handler\n", | ||
816 | DEVICE_NAME, status & 0x1f); | ||
817 | |||
818 | outb((int_ret_code & 0xe0) | ATT_EOI, ESDI_ATTN); | ||
819 | break; | ||
820 | |||
821 | case INT_ATTN_ERROR: | ||
822 | printk("%s: Attention error. interrupt status : %02X\n", DEVICE_NAME, | ||
823 | int_ret_code); | ||
824 | printk("%s: Device not available\n", DEVICE_NAME); | ||
825 | break; | ||
826 | case INT_CMD_ECC: | ||
827 | case INT_CMD_RETRY: | ||
828 | case INT_CMD_ECC_RETRY: | ||
829 | case INT_CMD_WARNING: | ||
830 | case INT_CMD_ABORT: | ||
831 | case INT_CMD_FAILED: | ||
832 | case INT_DMA_ERR: | ||
833 | case INT_CMD_BLK_ERR: | ||
834 | /*BA */ printk("%s: Whaa. Error occurred...\n", DEVICE_NAME); | ||
835 | dump_cmd_complete_status(int_ret_code); | ||
836 | outb((int_ret_code & 0xe0) | ATT_EOI, ESDI_ATTN); | ||
837 | break; | ||
838 | default: | ||
839 | printk("%s: Unknown interrupt reason: %02X\n", | ||
840 | DEVICE_NAME, int_ret_code & 0xf); | ||
841 | outb((int_ret_code & 0xe0) | ATT_EOI, ESDI_ATTN); | ||
842 | break; | ||
843 | } | ||
844 | |||
845 | wake_up(&ps2esdi_int); | ||
846 | no_int_yet = FALSE; | ||
847 | outb(CTRL_ENABLE_INTR, ESDI_CONTROL); | ||
848 | |||
849 | } | ||
850 | |||
851 | static void ps2esdi_normal_interrupt_handler(u_int int_ret_code) | ||
852 | { | ||
853 | unsigned long flags; | ||
854 | u_int status; | ||
855 | u_int ending; | ||
856 | int i; | ||
857 | |||
858 | switch (int_ret_code & 0x0f) { | ||
859 | case INT_TRANSFER_REQ: | ||
860 | ps2esdi_prep_dma(current_req->buffer, | ||
861 | current_req->current_nr_sectors, | ||
862 | (rq_data_dir(current_req) == READ) | ||
863 | ? MCA_DMA_MODE_16 | MCA_DMA_MODE_WRITE | MCA_DMA_MODE_XFER | ||
864 | : MCA_DMA_MODE_16 | MCA_DMA_MODE_READ); | ||
865 | outb(CTRL_ENABLE_DMA | CTRL_ENABLE_INTR, ESDI_CONTROL); | ||
866 | ending = -1; | ||
867 | break; | ||
868 | |||
869 | case INT_ATTN_ERROR: | ||
870 | printk("%s: Attention error. interrupt status : %02X\n", DEVICE_NAME, | ||
871 | int_ret_code); | ||
872 | outb(CTRL_ENABLE_INTR, ESDI_CONTROL); | ||
873 | ending = FAIL; | ||
874 | break; | ||
875 | |||
876 | case INT_CMD_COMPLETE: | ||
877 | for (i = ESDI_TIMEOUT; i && !(inb(ESDI_STATUS) & STATUS_STAT_AVAIL); i--); | ||
878 | if (!(inb(ESDI_STATUS) & STATUS_STAT_AVAIL)) { | ||
879 | printk("%s: timeout reading status word\n", DEVICE_NAME); | ||
880 | outb((int_ret_code & 0xe0) | ATT_EOI, ESDI_ATTN); | ||
881 | outb(CTRL_ENABLE_INTR, ESDI_CONTROL); | ||
882 | if ((++current_req->errors) >= MAX_RETRIES) | ||
883 | ending = FAIL; | ||
884 | else | ||
885 | ending = -1; | ||
886 | break; | ||
887 | } | ||
888 | status = inw(ESDI_STT_INT); | ||
889 | switch (status & 0x1F) { | ||
890 | case (CMD_READ & 0xff): | ||
891 | case (CMD_WRITE & 0xff): | ||
892 | LITE_OFF; | ||
893 | outb((int_ret_code & 0xe0) | ATT_EOI, ESDI_ATTN); | ||
894 | outb(CTRL_ENABLE_INTR, ESDI_CONTROL); | ||
895 | ending = SUCCES; | ||
896 | break; | ||
897 | default: | ||
898 | printk("%s: interrupt for unknown command %02X\n", | ||
899 | DEVICE_NAME, status & 0x1f); | ||
900 | outb((int_ret_code & 0xe0) | ATT_EOI, ESDI_ATTN); | ||
901 | outb(CTRL_ENABLE_INTR, ESDI_CONTROL); | ||
902 | ending = -1; | ||
903 | break; | ||
904 | } | ||
905 | break; | ||
906 | case INT_CMD_ECC: | ||
907 | case INT_CMD_RETRY: | ||
908 | case INT_CMD_ECC_RETRY: | ||
909 | LITE_OFF; | ||
910 | dump_cmd_complete_status(int_ret_code); | ||
911 | outb((int_ret_code & 0xe0) | ATT_EOI, ESDI_ATTN); | ||
912 | outb(CTRL_ENABLE_INTR, ESDI_CONTROL); | ||
913 | ending = SUCCES; | ||
914 | break; | ||
915 | case INT_CMD_WARNING: | ||
916 | case INT_CMD_ABORT: | ||
917 | case INT_CMD_FAILED: | ||
918 | case INT_DMA_ERR: | ||
919 | LITE_OFF; | ||
920 | dump_cmd_complete_status(int_ret_code); | ||
921 | outb((int_ret_code & 0xe0) | ATT_EOI, ESDI_ATTN); | ||
922 | outb(CTRL_ENABLE_INTR, ESDI_CONTROL); | ||
923 | if ((++current_req->errors) >= MAX_RETRIES) | ||
924 | ending = FAIL; | ||
925 | else | ||
926 | ending = -1; | ||
927 | break; | ||
928 | |||
929 | case INT_CMD_BLK_ERR: | ||
930 | dump_cmd_complete_status(int_ret_code); | ||
931 | outb((int_ret_code & 0xe0) | ATT_EOI, ESDI_ATTN); | ||
932 | outb(CTRL_ENABLE_INTR, ESDI_CONTROL); | ||
933 | ending = FAIL; | ||
934 | break; | ||
935 | |||
936 | case INT_CMD_FORMAT: | ||
937 | printk("%s: huh ? Who issued this format command ?\n" | ||
938 | ,DEVICE_NAME); | ||
939 | outb((int_ret_code & 0xe0) | ATT_EOI, ESDI_ATTN); | ||
940 | outb(CTRL_ENABLE_INTR, ESDI_CONTROL); | ||
941 | ending = -1; | ||
942 | break; | ||
943 | |||
944 | case INT_RESET: | ||
945 | /* BA printk("%s: reset completed.\n", DEVICE_NAME) */ ; | ||
946 | outb((int_ret_code & 0xe0) | ATT_EOI, ESDI_ATTN); | ||
947 | outb(CTRL_ENABLE_INTR, ESDI_CONTROL); | ||
948 | ending = -1; | ||
949 | break; | ||
950 | |||
951 | default: | ||
952 | printk("%s: Unknown interrupt reason: %02X\n", | ||
953 | DEVICE_NAME, int_ret_code & 0xf); | ||
954 | outb((int_ret_code & 0xe0) | ATT_EOI, ESDI_ATTN); | ||
955 | outb(CTRL_ENABLE_INTR, ESDI_CONTROL); | ||
956 | ending = -1; | ||
957 | break; | ||
958 | } | ||
959 | if(ending != -1) { | ||
960 | spin_lock_irqsave(&ps2esdi_lock, flags); | ||
961 | end_request(current_req, ending); | ||
962 | current_req = NULL; | ||
963 | do_ps2esdi_request(ps2esdi_queue); | ||
964 | spin_unlock_irqrestore(&ps2esdi_lock, flags); | ||
965 | } | ||
966 | } /* handle interrupts */ | ||
967 | |||
968 | |||
969 | |||
970 | static int ps2esdi_read_status_words(int num_words, | ||
971 | int max_words, | ||
972 | u_short * buffer) | ||
973 | { | ||
974 | int i; | ||
975 | |||
976 | for (; max_words && num_words; max_words--, num_words--, buffer++) { | ||
977 | for (i = ESDI_TIMEOUT; i && !(inb(ESDI_STATUS) & STATUS_STAT_AVAIL); i--); | ||
978 | if (!(inb(ESDI_STATUS) & STATUS_STAT_AVAIL)) { | ||
979 | printk("%s: timeout reading status word\n", DEVICE_NAME); | ||
980 | return FAIL; | ||
981 | } | ||
982 | *buffer = inw(ESDI_STT_INT); | ||
983 | } | ||
984 | return SUCCES; | ||
985 | } | ||
986 | |||
987 | |||
988 | |||
989 | |||
990 | static void dump_cmd_complete_status(u_int int_ret_code) | ||
991 | { | ||
992 | #define WAIT_FOR_STATUS \ | ||
993 | for(i=ESDI_TIMEOUT;i && !(inb(ESDI_STATUS) & STATUS_STAT_AVAIL);i--); \ | ||
994 | if(!(inb(ESDI_STATUS) & STATUS_STAT_AVAIL)) { \ | ||
995 | printk("%s: timeout reading status word\n",DEVICE_NAME); \ | ||
996 | return; \ | ||
997 | } | ||
998 | |||
999 | int i, word_count; | ||
1000 | u_short stat_word; | ||
1001 | u_long rba; | ||
1002 | |||
1003 | printk("%s: Device: %u, interrupt ID: %02X\n", | ||
1004 | DEVICE_NAME, int_ret_code >> 5, | ||
1005 | int_ret_code & 0xf); | ||
1006 | |||
1007 | WAIT_FOR_STATUS; | ||
1008 | stat_word = inw(ESDI_STT_INT); | ||
1009 | word_count = (stat_word >> 8) - 1; | ||
1010 | printk("%s: %u status words, command: %02X\n", DEVICE_NAME, word_count, | ||
1011 | stat_word & 0xff); | ||
1012 | |||
1013 | if (word_count--) { | ||
1014 | WAIT_FOR_STATUS; | ||
1015 | stat_word = inw(ESDI_STT_INT); | ||
1016 | printk("%s: command status code: %02X, command error code: %02X\n", | ||
1017 | DEVICE_NAME, stat_word >> 8, stat_word & 0xff); | ||
1018 | } | ||
1019 | if (word_count--) { | ||
1020 | WAIT_FOR_STATUS; | ||
1021 | stat_word = inw(ESDI_STT_INT); | ||
1022 | printk("%s: device error code: %s%s%s%s%s,%02X\n", DEVICE_NAME, | ||
1023 | (stat_word & 0x1000) ? "Ready, " : "Not Ready, ", | ||
1024 | (stat_word & 0x0800) ? "Selected, " : "Not Selected, ", | ||
1025 | (stat_word & 0x0400) ? "Write Fault, " : "", | ||
1026 | (stat_word & 0x0200) ? "Track 0, " : "", | ||
1027 | (stat_word & 0x0100) ? "Seek or command complete, " : "", | ||
1028 | stat_word >> 8); | ||
1029 | } | ||
1030 | if (word_count--) { | ||
1031 | WAIT_FOR_STATUS; | ||
1032 | stat_word = inw(ESDI_STT_INT); | ||
1033 | printk("%s: Blocks to do: %u", DEVICE_NAME, stat_word); | ||
1034 | } | ||
1035 | if (word_count -= 2) { | ||
1036 | WAIT_FOR_STATUS; | ||
1037 | rba = inw(ESDI_STT_INT); | ||
1038 | WAIT_FOR_STATUS; | ||
1039 | rba |= inw(ESDI_STT_INT) << 16; | ||
1040 | printk(", Last Cyl: %u Head: %u Sector: %u\n", | ||
1041 | (u_short) ((rba & 0x1ff80000) >> 11), | ||
1042 | (u_short) ((rba & 0x7E0) >> 5), (u_short) (rba & 0x1f)); | ||
1043 | } else | ||
1044 | printk("\n"); | ||
1045 | |||
1046 | if (word_count--) { | ||
1047 | WAIT_FOR_STATUS; | ||
1048 | stat_word = inw(ESDI_STT_INT); | ||
1049 | printk("%s: Blocks required ECC: %u", DEVICE_NAME, stat_word); | ||
1050 | } | ||
1051 | printk("\n"); | ||
1052 | |||
1053 | #undef WAIT_FOR_STATUS | ||
1054 | |||
1055 | } | ||
1056 | |||
1057 | static int ps2esdi_getgeo(struct block_device *bdev, struct hd_geometry *geo) | ||
1058 | { | ||
1059 | struct ps2esdi_i_struct *p = bdev->bd_disk->private_data; | ||
1060 | |||
1061 | geo->heads = p->head; | ||
1062 | geo->sectors = p->sect; | ||
1063 | geo->cylinders = p->cyl; | ||
1064 | return 0; | ||
1065 | } | ||
1066 | |||
1067 | static void ps2esdi_reset_timer(unsigned long unused) | ||
1068 | { | ||
1069 | |||
1070 | int status; | ||
1071 | |||
1072 | status = inb(ESDI_INTRPT); | ||
1073 | if ((status & 0xf) == INT_RESET) { | ||
1074 | outb((status & 0xe0) | ATT_EOI, ESDI_ATTN); | ||
1075 | outb(CTRL_ENABLE_INTR, ESDI_CONTROL); | ||
1076 | reset_status = 1; | ||
1077 | } | ||
1078 | wake_up(&ps2esdi_int); | ||
1079 | } | ||
diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c index 3b1a68d6eddb..0cfbe8c594a5 100644 --- a/drivers/block/virtio_blk.c +++ b/drivers/block/virtio_blk.c | |||
@@ -238,6 +238,7 @@ static int virtblk_probe(struct virtio_device *vdev) | |||
238 | vblk->disk->first_minor = index_to_minor(index); | 238 | vblk->disk->first_minor = index_to_minor(index); |
239 | vblk->disk->private_data = vblk; | 239 | vblk->disk->private_data = vblk; |
240 | vblk->disk->fops = &virtblk_fops; | 240 | vblk->disk->fops = &virtblk_fops; |
241 | vblk->disk->driverfs_dev = &vdev->dev; | ||
241 | index++; | 242 | index++; |
242 | 243 | ||
243 | /* If barriers are supported, tell block layer that queue is ordered */ | 244 | /* If barriers are supported, tell block layer that queue is ordered */ |
diff --git a/drivers/char/drm/ati_pcigart.c b/drivers/char/drm/ati_pcigart.c index d352dbb4ccf7..e5a0e97cfdda 100644 --- a/drivers/char/drm/ati_pcigart.c +++ b/drivers/char/drm/ati_pcigart.c | |||
@@ -35,42 +35,23 @@ | |||
35 | 35 | ||
36 | # define ATI_PCIGART_PAGE_SIZE 4096 /**< PCI GART page size */ | 36 | # define ATI_PCIGART_PAGE_SIZE 4096 /**< PCI GART page size */ |
37 | 37 | ||
38 | static void *drm_ati_alloc_pcigart_table(int order) | 38 | static int drm_ati_alloc_pcigart_table(struct drm_device *dev, |
39 | struct drm_ati_pcigart_info *gart_info) | ||
39 | { | 40 | { |
40 | unsigned long address; | 41 | gart_info->table_handle = drm_pci_alloc(dev, gart_info->table_size, |
41 | struct page *page; | 42 | PAGE_SIZE, |
42 | int i; | 43 | gart_info->table_mask); |
43 | 44 | if (gart_info->table_handle == NULL) | |
44 | DRM_DEBUG("%d order\n", order); | 45 | return -ENOMEM; |
45 | |||
46 | address = __get_free_pages(GFP_KERNEL | __GFP_COMP, | ||
47 | order); | ||
48 | if (address == 0UL) { | ||
49 | return NULL; | ||
50 | } | ||
51 | |||
52 | page = virt_to_page(address); | ||
53 | 46 | ||
54 | for (i = 0; i < order; i++, page++) | 47 | return 0; |
55 | SetPageReserved(page); | ||
56 | |||
57 | DRM_DEBUG("returning 0x%08lx\n", address); | ||
58 | return (void *)address; | ||
59 | } | 48 | } |
60 | 49 | ||
61 | static void drm_ati_free_pcigart_table(void *address, int order) | 50 | static void drm_ati_free_pcigart_table(struct drm_device *dev, |
51 | struct drm_ati_pcigart_info *gart_info) | ||
62 | { | 52 | { |
63 | struct page *page; | 53 | drm_pci_free(dev, gart_info->table_handle); |
64 | int i; | 54 | gart_info->table_handle = NULL; |
65 | int num_pages = 1 << order; | ||
66 | DRM_DEBUG("\n"); | ||
67 | |||
68 | page = virt_to_page((unsigned long)address); | ||
69 | |||
70 | for (i = 0; i < num_pages; i++, page++) | ||
71 | ClearPageReserved(page); | ||
72 | |||
73 | free_pages((unsigned long)address, order); | ||
74 | } | 55 | } |
75 | 56 | ||
76 | int drm_ati_pcigart_cleanup(struct drm_device *dev, struct drm_ati_pcigart_info *gart_info) | 57 | int drm_ati_pcigart_cleanup(struct drm_device *dev, struct drm_ati_pcigart_info *gart_info) |
@@ -78,8 +59,7 @@ int drm_ati_pcigart_cleanup(struct drm_device *dev, struct drm_ati_pcigart_info | |||
78 | struct drm_sg_mem *entry = dev->sg; | 59 | struct drm_sg_mem *entry = dev->sg; |
79 | unsigned long pages; | 60 | unsigned long pages; |
80 | int i; | 61 | int i; |
81 | int order; | 62 | int max_pages; |
82 | int num_pages, max_pages; | ||
83 | 63 | ||
84 | /* we need to support large memory configurations */ | 64 | /* we need to support large memory configurations */ |
85 | if (!entry) { | 65 | if (!entry) { |
@@ -87,15 +67,7 @@ int drm_ati_pcigart_cleanup(struct drm_device *dev, struct drm_ati_pcigart_info | |||
87 | return 0; | 67 | return 0; |
88 | } | 68 | } |
89 | 69 | ||
90 | order = drm_order((gart_info->table_size + (PAGE_SIZE-1)) / PAGE_SIZE); | ||
91 | num_pages = 1 << order; | ||
92 | |||
93 | if (gart_info->bus_addr) { | 70 | if (gart_info->bus_addr) { |
94 | if (gart_info->gart_table_location == DRM_ATI_GART_MAIN) { | ||
95 | pci_unmap_single(dev->pdev, gart_info->bus_addr, | ||
96 | num_pages * PAGE_SIZE, | ||
97 | PCI_DMA_TODEVICE); | ||
98 | } | ||
99 | 71 | ||
100 | max_pages = (gart_info->table_size / sizeof(u32)); | 72 | max_pages = (gart_info->table_size / sizeof(u32)); |
101 | pages = (entry->pages <= max_pages) | 73 | pages = (entry->pages <= max_pages) |
@@ -112,10 +84,9 @@ int drm_ati_pcigart_cleanup(struct drm_device *dev, struct drm_ati_pcigart_info | |||
112 | gart_info->bus_addr = 0; | 84 | gart_info->bus_addr = 0; |
113 | } | 85 | } |
114 | 86 | ||
115 | if (gart_info->gart_table_location == DRM_ATI_GART_MAIN | 87 | if (gart_info->gart_table_location == DRM_ATI_GART_MAIN && |
116 | && gart_info->addr) { | 88 | gart_info->table_handle) { |
117 | drm_ati_free_pcigart_table(gart_info->addr, order); | 89 | drm_ati_free_pcigart_table(dev, gart_info); |
118 | gart_info->addr = NULL; | ||
119 | } | 90 | } |
120 | 91 | ||
121 | return 1; | 92 | return 1; |
@@ -127,11 +98,10 @@ int drm_ati_pcigart_init(struct drm_device *dev, struct drm_ati_pcigart_info *ga | |||
127 | struct drm_sg_mem *entry = dev->sg; | 98 | struct drm_sg_mem *entry = dev->sg; |
128 | void *address = NULL; | 99 | void *address = NULL; |
129 | unsigned long pages; | 100 | unsigned long pages; |
130 | u32 *pci_gart, page_base, bus_address = 0; | 101 | u32 *pci_gart, page_base; |
102 | dma_addr_t bus_address = 0; | ||
131 | int i, j, ret = 0; | 103 | int i, j, ret = 0; |
132 | int order; | ||
133 | int max_pages; | 104 | int max_pages; |
134 | int num_pages; | ||
135 | 105 | ||
136 | if (!entry) { | 106 | if (!entry) { |
137 | DRM_ERROR("no scatter/gather memory!\n"); | 107 | DRM_ERROR("no scatter/gather memory!\n"); |
@@ -141,31 +111,14 @@ int drm_ati_pcigart_init(struct drm_device *dev, struct drm_ati_pcigart_info *ga | |||
141 | if (gart_info->gart_table_location == DRM_ATI_GART_MAIN) { | 111 | if (gart_info->gart_table_location == DRM_ATI_GART_MAIN) { |
142 | DRM_DEBUG("PCI: no table in VRAM: using normal RAM\n"); | 112 | DRM_DEBUG("PCI: no table in VRAM: using normal RAM\n"); |
143 | 113 | ||
144 | order = drm_order((gart_info->table_size + | 114 | ret = drm_ati_alloc_pcigart_table(dev, gart_info); |
145 | (PAGE_SIZE-1)) / PAGE_SIZE); | 115 | if (ret) { |
146 | num_pages = 1 << order; | ||
147 | address = drm_ati_alloc_pcigart_table(order); | ||
148 | if (!address) { | ||
149 | DRM_ERROR("cannot allocate PCI GART page!\n"); | 116 | DRM_ERROR("cannot allocate PCI GART page!\n"); |
150 | goto done; | 117 | goto done; |
151 | } | 118 | } |
152 | 119 | ||
153 | if (!dev->pdev) { | 120 | address = gart_info->table_handle->vaddr; |
154 | DRM_ERROR("PCI device unknown!\n"); | 121 | bus_address = gart_info->table_handle->busaddr; |
155 | goto done; | ||
156 | } | ||
157 | |||
158 | bus_address = pci_map_single(dev->pdev, address, | ||
159 | num_pages * PAGE_SIZE, | ||
160 | PCI_DMA_TODEVICE); | ||
161 | if (bus_address == 0) { | ||
162 | DRM_ERROR("unable to map PCIGART pages!\n"); | ||
163 | order = drm_order((gart_info->table_size + | ||
164 | (PAGE_SIZE-1)) / PAGE_SIZE); | ||
165 | drm_ati_free_pcigart_table(address, order); | ||
166 | address = NULL; | ||
167 | goto done; | ||
168 | } | ||
169 | } else { | 122 | } else { |
170 | address = gart_info->addr; | 123 | address = gart_info->addr; |
171 | bus_address = gart_info->bus_addr; | 124 | bus_address = gart_info->bus_addr; |
diff --git a/drivers/char/drm/drmP.h b/drivers/char/drm/drmP.h index a6789f25009b..8ea9dd1717a9 100644 --- a/drivers/char/drm/drmP.h +++ b/drivers/char/drm/drmP.h | |||
@@ -54,6 +54,7 @@ | |||
54 | #include <linux/pci.h> | 54 | #include <linux/pci.h> |
55 | #include <linux/jiffies.h> | 55 | #include <linux/jiffies.h> |
56 | #include <linux/smp_lock.h> /* For (un)lock_kernel */ | 56 | #include <linux/smp_lock.h> /* For (un)lock_kernel */ |
57 | #include <linux/dma-mapping.h> | ||
57 | #include <linux/mm.h> | 58 | #include <linux/mm.h> |
58 | #include <linux/cdev.h> | 59 | #include <linux/cdev.h> |
59 | #include <linux/mutex.h> | 60 | #include <linux/mutex.h> |
@@ -551,6 +552,8 @@ struct drm_ati_pcigart_info { | |||
551 | int gart_reg_if; | 552 | int gart_reg_if; |
552 | void *addr; | 553 | void *addr; |
553 | dma_addr_t bus_addr; | 554 | dma_addr_t bus_addr; |
555 | dma_addr_t table_mask; | ||
556 | struct drm_dma_handle *table_handle; | ||
554 | drm_local_map_t mapping; | 557 | drm_local_map_t mapping; |
555 | int table_size; | 558 | int table_size; |
556 | }; | 559 | }; |
diff --git a/drivers/char/drm/drm_fops.c b/drivers/char/drm/drm_fops.c index 3992f73299cc..f09d4b5002b0 100644 --- a/drivers/char/drm/drm_fops.c +++ b/drivers/char/drm/drm_fops.c | |||
@@ -326,6 +326,7 @@ int drm_release(struct inode *inode, struct file *filp) | |||
326 | struct drm_file *file_priv = filp->private_data; | 326 | struct drm_file *file_priv = filp->private_data; |
327 | struct drm_device *dev = file_priv->head->dev; | 327 | struct drm_device *dev = file_priv->head->dev; |
328 | int retcode = 0; | 328 | int retcode = 0; |
329 | unsigned long irqflags; | ||
329 | 330 | ||
330 | lock_kernel(); | 331 | lock_kernel(); |
331 | 332 | ||
@@ -357,9 +358,11 @@ int drm_release(struct inode *inode, struct file *filp) | |||
357 | */ | 358 | */ |
358 | 359 | ||
359 | do{ | 360 | do{ |
360 | spin_lock(&dev->lock.spinlock); | 361 | spin_lock_irqsave(&dev->lock.spinlock, |
362 | irqflags); | ||
361 | locked = dev->lock.idle_has_lock; | 363 | locked = dev->lock.idle_has_lock; |
362 | spin_unlock(&dev->lock.spinlock); | 364 | spin_unlock_irqrestore(&dev->lock.spinlock, |
365 | irqflags); | ||
363 | if (locked) | 366 | if (locked) |
364 | break; | 367 | break; |
365 | schedule(); | 368 | schedule(); |
diff --git a/drivers/char/drm/drm_lock.c b/drivers/char/drm/drm_lock.c index bea2a7d5b2b2..12dcdd1832f0 100644 --- a/drivers/char/drm/drm_lock.c +++ b/drivers/char/drm/drm_lock.c | |||
@@ -53,6 +53,7 @@ int drm_lock(struct drm_device *dev, void *data, struct drm_file *file_priv) | |||
53 | DECLARE_WAITQUEUE(entry, current); | 53 | DECLARE_WAITQUEUE(entry, current); |
54 | struct drm_lock *lock = data; | 54 | struct drm_lock *lock = data; |
55 | int ret = 0; | 55 | int ret = 0; |
56 | unsigned long irqflags; | ||
56 | 57 | ||
57 | ++file_priv->lock_count; | 58 | ++file_priv->lock_count; |
58 | 59 | ||
@@ -71,9 +72,9 @@ int drm_lock(struct drm_device *dev, void *data, struct drm_file *file_priv) | |||
71 | return -EINVAL; | 72 | return -EINVAL; |
72 | 73 | ||
73 | add_wait_queue(&dev->lock.lock_queue, &entry); | 74 | add_wait_queue(&dev->lock.lock_queue, &entry); |
74 | spin_lock(&dev->lock.spinlock); | 75 | spin_lock_irqsave(&dev->lock.spinlock, irqflags); |
75 | dev->lock.user_waiters++; | 76 | dev->lock.user_waiters++; |
76 | spin_unlock(&dev->lock.spinlock); | 77 | spin_unlock_irqrestore(&dev->lock.spinlock, irqflags); |
77 | for (;;) { | 78 | for (;;) { |
78 | __set_current_state(TASK_INTERRUPTIBLE); | 79 | __set_current_state(TASK_INTERRUPTIBLE); |
79 | if (!dev->lock.hw_lock) { | 80 | if (!dev->lock.hw_lock) { |
@@ -95,9 +96,9 @@ int drm_lock(struct drm_device *dev, void *data, struct drm_file *file_priv) | |||
95 | break; | 96 | break; |
96 | } | 97 | } |
97 | } | 98 | } |
98 | spin_lock(&dev->lock.spinlock); | 99 | spin_lock_irqsave(&dev->lock.spinlock, irqflags); |
99 | dev->lock.user_waiters--; | 100 | dev->lock.user_waiters--; |
100 | spin_unlock(&dev->lock.spinlock); | 101 | spin_unlock_irqrestore(&dev->lock.spinlock, irqflags); |
101 | __set_current_state(TASK_RUNNING); | 102 | __set_current_state(TASK_RUNNING); |
102 | remove_wait_queue(&dev->lock.lock_queue, &entry); | 103 | remove_wait_queue(&dev->lock.lock_queue, &entry); |
103 | 104 | ||
@@ -198,8 +199,9 @@ int drm_lock_take(struct drm_lock_data *lock_data, | |||
198 | { | 199 | { |
199 | unsigned int old, new, prev; | 200 | unsigned int old, new, prev; |
200 | volatile unsigned int *lock = &lock_data->hw_lock->lock; | 201 | volatile unsigned int *lock = &lock_data->hw_lock->lock; |
202 | unsigned long irqflags; | ||
201 | 203 | ||
202 | spin_lock(&lock_data->spinlock); | 204 | spin_lock_irqsave(&lock_data->spinlock, irqflags); |
203 | do { | 205 | do { |
204 | old = *lock; | 206 | old = *lock; |
205 | if (old & _DRM_LOCK_HELD) | 207 | if (old & _DRM_LOCK_HELD) |
@@ -211,7 +213,7 @@ int drm_lock_take(struct drm_lock_data *lock_data, | |||
211 | } | 213 | } |
212 | prev = cmpxchg(lock, old, new); | 214 | prev = cmpxchg(lock, old, new); |
213 | } while (prev != old); | 215 | } while (prev != old); |
214 | spin_unlock(&lock_data->spinlock); | 216 | spin_unlock_irqrestore(&lock_data->spinlock, irqflags); |
215 | 217 | ||
216 | if (_DRM_LOCKING_CONTEXT(old) == context) { | 218 | if (_DRM_LOCKING_CONTEXT(old) == context) { |
217 | if (old & _DRM_LOCK_HELD) { | 219 | if (old & _DRM_LOCK_HELD) { |
@@ -272,15 +274,16 @@ int drm_lock_free(struct drm_lock_data *lock_data, unsigned int context) | |||
272 | { | 274 | { |
273 | unsigned int old, new, prev; | 275 | unsigned int old, new, prev; |
274 | volatile unsigned int *lock = &lock_data->hw_lock->lock; | 276 | volatile unsigned int *lock = &lock_data->hw_lock->lock; |
277 | unsigned long irqflags; | ||
275 | 278 | ||
276 | spin_lock(&lock_data->spinlock); | 279 | spin_lock_irqsave(&lock_data->spinlock, irqflags); |
277 | if (lock_data->kernel_waiters != 0) { | 280 | if (lock_data->kernel_waiters != 0) { |
278 | drm_lock_transfer(lock_data, 0); | 281 | drm_lock_transfer(lock_data, 0); |
279 | lock_data->idle_has_lock = 1; | 282 | lock_data->idle_has_lock = 1; |
280 | spin_unlock(&lock_data->spinlock); | 283 | spin_unlock_irqrestore(&lock_data->spinlock, irqflags); |
281 | return 1; | 284 | return 1; |
282 | } | 285 | } |
283 | spin_unlock(&lock_data->spinlock); | 286 | spin_unlock_irqrestore(&lock_data->spinlock, irqflags); |
284 | 287 | ||
285 | do { | 288 | do { |
286 | old = *lock; | 289 | old = *lock; |
@@ -344,19 +347,20 @@ static int drm_notifier(void *priv) | |||
344 | void drm_idlelock_take(struct drm_lock_data *lock_data) | 347 | void drm_idlelock_take(struct drm_lock_data *lock_data) |
345 | { | 348 | { |
346 | int ret = 0; | 349 | int ret = 0; |
350 | unsigned long irqflags; | ||
347 | 351 | ||
348 | spin_lock(&lock_data->spinlock); | 352 | spin_lock_irqsave(&lock_data->spinlock, irqflags); |
349 | lock_data->kernel_waiters++; | 353 | lock_data->kernel_waiters++; |
350 | if (!lock_data->idle_has_lock) { | 354 | if (!lock_data->idle_has_lock) { |
351 | 355 | ||
352 | spin_unlock(&lock_data->spinlock); | 356 | spin_unlock_irqrestore(&lock_data->spinlock, irqflags); |
353 | ret = drm_lock_take(lock_data, DRM_KERNEL_CONTEXT); | 357 | ret = drm_lock_take(lock_data, DRM_KERNEL_CONTEXT); |
354 | spin_lock(&lock_data->spinlock); | 358 | spin_lock_irqsave(&lock_data->spinlock, irqflags); |
355 | 359 | ||
356 | if (ret == 1) | 360 | if (ret == 1) |
357 | lock_data->idle_has_lock = 1; | 361 | lock_data->idle_has_lock = 1; |
358 | } | 362 | } |
359 | spin_unlock(&lock_data->spinlock); | 363 | spin_unlock_irqrestore(&lock_data->spinlock, irqflags); |
360 | } | 364 | } |
361 | EXPORT_SYMBOL(drm_idlelock_take); | 365 | EXPORT_SYMBOL(drm_idlelock_take); |
362 | 366 | ||
@@ -364,8 +368,9 @@ void drm_idlelock_release(struct drm_lock_data *lock_data) | |||
364 | { | 368 | { |
365 | unsigned int old, prev; | 369 | unsigned int old, prev; |
366 | volatile unsigned int *lock = &lock_data->hw_lock->lock; | 370 | volatile unsigned int *lock = &lock_data->hw_lock->lock; |
371 | unsigned long irqflags; | ||
367 | 372 | ||
368 | spin_lock(&lock_data->spinlock); | 373 | spin_lock_irqsave(&lock_data->spinlock, irqflags); |
369 | if (--lock_data->kernel_waiters == 0) { | 374 | if (--lock_data->kernel_waiters == 0) { |
370 | if (lock_data->idle_has_lock) { | 375 | if (lock_data->idle_has_lock) { |
371 | do { | 376 | do { |
@@ -376,7 +381,7 @@ void drm_idlelock_release(struct drm_lock_data *lock_data) | |||
376 | lock_data->idle_has_lock = 0; | 381 | lock_data->idle_has_lock = 0; |
377 | } | 382 | } |
378 | } | 383 | } |
379 | spin_unlock(&lock_data->spinlock); | 384 | spin_unlock_irqrestore(&lock_data->spinlock, irqflags); |
380 | } | 385 | } |
381 | EXPORT_SYMBOL(drm_idlelock_release); | 386 | EXPORT_SYMBOL(drm_idlelock_release); |
382 | 387 | ||
diff --git a/drivers/char/drm/drm_pciids.h b/drivers/char/drm/drm_pciids.h index 715b361f0c2b..a6a499f97e22 100644 --- a/drivers/char/drm/drm_pciids.h +++ b/drivers/char/drm/drm_pciids.h | |||
@@ -205,9 +205,9 @@ | |||
205 | {0x1002, 0x71D6, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV530|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ | 205 | {0x1002, 0x71D6, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV530|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ |
206 | {0x1002, 0x71DA, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV530|RADEON_NEW_MEMMAP}, \ | 206 | {0x1002, 0x71DA, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV530|RADEON_NEW_MEMMAP}, \ |
207 | {0x1002, 0x71DE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV530|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ | 207 | {0x1002, 0x71DE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV530|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ |
208 | {0x1002, 0x7200, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV530|RADEON_NEW_MEMMAP}, \ | 208 | {0x1002, 0x7200, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV515|RADEON_NEW_MEMMAP}, \ |
209 | {0x1002, 0x7210, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV530|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ | 209 | {0x1002, 0x7210, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV515|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ |
210 | {0x1002, 0x7211, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV530|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ | 210 | {0x1002, 0x7211, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV515|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ |
211 | {0x1002, 0x7240, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R580|RADEON_NEW_MEMMAP}, \ | 211 | {0x1002, 0x7240, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R580|RADEON_NEW_MEMMAP}, \ |
212 | {0x1002, 0x7243, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R580|RADEON_NEW_MEMMAP}, \ | 212 | {0x1002, 0x7243, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R580|RADEON_NEW_MEMMAP}, \ |
213 | {0x1002, 0x7244, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R580|RADEON_NEW_MEMMAP}, \ | 213 | {0x1002, 0x7244, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R580|RADEON_NEW_MEMMAP}, \ |
@@ -238,6 +238,7 @@ | |||
238 | {0x1002, 0x7834, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS300|RADEON_IS_IGP|RADEON_NEW_MEMMAP}, \ | 238 | {0x1002, 0x7834, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS300|RADEON_IS_IGP|RADEON_NEW_MEMMAP}, \ |
239 | {0x1002, 0x7835, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS300|RADEON_IS_IGP|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ | 239 | {0x1002, 0x7835, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS300|RADEON_IS_IGP|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ |
240 | {0x1002, 0x791e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS690|RADEON_IS_IGP|RADEON_NEW_MEMMAP|RADEON_IS_IGPGART}, \ | 240 | {0x1002, 0x791e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS690|RADEON_IS_IGP|RADEON_NEW_MEMMAP|RADEON_IS_IGPGART}, \ |
241 | {0x1002, 0x791f, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS690|RADEON_IS_IGP|RADEON_NEW_MEMMAP|RADEON_IS_IGPGART}, \ | ||
241 | {0, 0, 0} | 242 | {0, 0, 0} |
242 | 243 | ||
243 | #define r128_PCI_IDS \ | 244 | #define r128_PCI_IDS \ |
diff --git a/drivers/char/drm/r128_cce.c b/drivers/char/drm/r128_cce.c index 892e0a589846..f36adbd3aaf5 100644 --- a/drivers/char/drm/r128_cce.c +++ b/drivers/char/drm/r128_cce.c | |||
@@ -558,6 +558,7 @@ static int r128_do_init_cce(struct drm_device * dev, drm_r128_init_t * init) | |||
558 | #if __OS_HAS_AGP | 558 | #if __OS_HAS_AGP |
559 | if (dev_priv->is_pci) { | 559 | if (dev_priv->is_pci) { |
560 | #endif | 560 | #endif |
561 | dev_priv->gart_info.table_mask = DMA_BIT_MASK(32); | ||
561 | dev_priv->gart_info.gart_table_location = DRM_ATI_GART_MAIN; | 562 | dev_priv->gart_info.gart_table_location = DRM_ATI_GART_MAIN; |
562 | dev_priv->gart_info.table_size = R128_PCIGART_TABLE_SIZE; | 563 | dev_priv->gart_info.table_size = R128_PCIGART_TABLE_SIZE; |
563 | dev_priv->gart_info.addr = NULL; | 564 | dev_priv->gart_info.addr = NULL; |
diff --git a/drivers/char/drm/radeon_cp.c b/drivers/char/drm/radeon_cp.c index 833abc7e55fb..9072e4a1894e 100644 --- a/drivers/char/drm/radeon_cp.c +++ b/drivers/char/drm/radeon_cp.c | |||
@@ -1807,6 +1807,7 @@ static int radeon_do_init_cp(struct drm_device * dev, drm_radeon_init_t * init) | |||
1807 | } else | 1807 | } else |
1808 | #endif | 1808 | #endif |
1809 | { | 1809 | { |
1810 | dev_priv->gart_info.table_mask = DMA_BIT_MASK(32); | ||
1810 | /* if we have an offset set from userspace */ | 1811 | /* if we have an offset set from userspace */ |
1811 | if (dev_priv->pcigart_offset_set) { | 1812 | if (dev_priv->pcigart_offset_set) { |
1812 | dev_priv->gart_info.bus_addr = | 1813 | dev_priv->gart_info.bus_addr = |
diff --git a/drivers/char/drm/via_dma.c b/drivers/char/drm/via_dma.c index 94baec692b57..7a339dba6a69 100644 --- a/drivers/char/drm/via_dma.c +++ b/drivers/char/drm/via_dma.c | |||
@@ -126,6 +126,8 @@ via_cmdbuf_wait(drm_via_private_t * dev_priv, unsigned int size) | |||
126 | hw_addr, cur_addr, next_addr); | 126 | hw_addr, cur_addr, next_addr); |
127 | return -1; | 127 | return -1; |
128 | } | 128 | } |
129 | if ((cur_addr < hw_addr) && (next_addr >= hw_addr)) | ||
130 | msleep(1); | ||
129 | } while ((cur_addr < hw_addr) && (next_addr >= hw_addr)); | 131 | } while ((cur_addr < hw_addr) && (next_addr >= hw_addr)); |
130 | return 0; | 132 | return 0; |
131 | } | 133 | } |
@@ -416,27 +418,50 @@ static int via_hook_segment(drm_via_private_t * dev_priv, | |||
416 | int paused, count; | 418 | int paused, count; |
417 | volatile uint32_t *paused_at = dev_priv->last_pause_ptr; | 419 | volatile uint32_t *paused_at = dev_priv->last_pause_ptr; |
418 | uint32_t reader,ptr; | 420 | uint32_t reader,ptr; |
421 | uint32_t diff; | ||
419 | 422 | ||
420 | paused = 0; | 423 | paused = 0; |
421 | via_flush_write_combine(); | 424 | via_flush_write_combine(); |
422 | (void) *(volatile uint32_t *)(via_get_dma(dev_priv) -1); | 425 | (void) *(volatile uint32_t *)(via_get_dma(dev_priv) -1); |
426 | |||
423 | *paused_at = pause_addr_lo; | 427 | *paused_at = pause_addr_lo; |
424 | via_flush_write_combine(); | 428 | via_flush_write_combine(); |
425 | (void) *paused_at; | 429 | (void) *paused_at; |
430 | |||
426 | reader = *(dev_priv->hw_addr_ptr); | 431 | reader = *(dev_priv->hw_addr_ptr); |
427 | ptr = ((volatile char *)paused_at - dev_priv->dma_ptr) + | 432 | ptr = ((volatile char *)paused_at - dev_priv->dma_ptr) + |
428 | dev_priv->dma_offset + (uint32_t) dev_priv->agpAddr + 4; | 433 | dev_priv->dma_offset + (uint32_t) dev_priv->agpAddr + 4; |
434 | |||
429 | dev_priv->last_pause_ptr = via_get_dma(dev_priv) - 1; | 435 | dev_priv->last_pause_ptr = via_get_dma(dev_priv) - 1; |
430 | 436 | ||
431 | if ((ptr - reader) <= dev_priv->dma_diff ) { | 437 | /* |
432 | count = 10000000; | 438 | * If there is a possibility that the command reader will |
433 | while (!(paused = (VIA_READ(0x41c) & 0x80000000)) && count--); | 439 | * miss the new pause address and pause on the old one, |
440 | * In that case we need to program the new start address | ||
441 | * using PCI. | ||
442 | */ | ||
443 | |||
444 | diff = (uint32_t) (ptr - reader) - dev_priv->dma_diff; | ||
445 | count = 10000000; | ||
446 | while(diff == 0 && count--) { | ||
447 | paused = (VIA_READ(0x41c) & 0x80000000); | ||
448 | if (paused) | ||
449 | break; | ||
450 | reader = *(dev_priv->hw_addr_ptr); | ||
451 | diff = (uint32_t) (ptr - reader) - dev_priv->dma_diff; | ||
434 | } | 452 | } |
435 | 453 | ||
454 | paused = VIA_READ(0x41c) & 0x80000000; | ||
455 | |||
436 | if (paused && !no_pci_fire) { | 456 | if (paused && !no_pci_fire) { |
437 | reader = *(dev_priv->hw_addr_ptr); | 457 | reader = *(dev_priv->hw_addr_ptr); |
438 | if ((ptr - reader) == dev_priv->dma_diff) { | 458 | diff = (uint32_t) (ptr - reader) - dev_priv->dma_diff; |
439 | 459 | diff &= (dev_priv->dma_high - 1); | |
460 | if (diff != 0 && diff < (dev_priv->dma_high >> 1)) { | ||
461 | DRM_ERROR("Paused at incorrect address. " | ||
462 | "0x%08x, 0x%08x 0x%08x\n", | ||
463 | ptr, reader, dev_priv->dma_diff); | ||
464 | } else if (diff == 0) { | ||
440 | /* | 465 | /* |
441 | * There is a concern that these writes may stall the PCI bus | 466 | * There is a concern that these writes may stall the PCI bus |
442 | * if the GPU is not idle. However, idling the GPU first | 467 | * if the GPU is not idle. However, idling the GPU first |
@@ -577,6 +602,7 @@ static void via_cmdbuf_jump(drm_via_private_t * dev_priv) | |||
577 | uint32_t pause_addr_lo, pause_addr_hi; | 602 | uint32_t pause_addr_lo, pause_addr_hi; |
578 | uint32_t jump_addr_lo, jump_addr_hi; | 603 | uint32_t jump_addr_lo, jump_addr_hi; |
579 | volatile uint32_t *last_pause_ptr; | 604 | volatile uint32_t *last_pause_ptr; |
605 | uint32_t dma_low_save1, dma_low_save2; | ||
580 | 606 | ||
581 | agp_base = dev_priv->dma_offset + (uint32_t) dev_priv->agpAddr; | 607 | agp_base = dev_priv->dma_offset + (uint32_t) dev_priv->agpAddr; |
582 | via_align_cmd(dev_priv, HC_HAGPBpID_JUMP, 0, &jump_addr_hi, | 608 | via_align_cmd(dev_priv, HC_HAGPBpID_JUMP, 0, &jump_addr_hi, |
@@ -603,8 +629,29 @@ static void via_cmdbuf_jump(drm_via_private_t * dev_priv) | |||
603 | &pause_addr_lo, 0); | 629 | &pause_addr_lo, 0); |
604 | 630 | ||
605 | *last_pause_ptr = pause_addr_lo; | 631 | *last_pause_ptr = pause_addr_lo; |
632 | dma_low_save1 = dev_priv->dma_low; | ||
606 | 633 | ||
607 | via_hook_segment( dev_priv, jump_addr_hi, jump_addr_lo, 0); | 634 | /* |
635 | * Now, set a trap that will pause the regulator if it tries to rerun the old | ||
636 | * command buffer. (Which may happen if via_hook_segment detecs a command regulator pause | ||
637 | * and reissues the jump command over PCI, while the regulator has already taken the jump | ||
638 | * and actually paused at the current buffer end). | ||
639 | * There appears to be no other way to detect this condition, since the hw_addr_pointer | ||
640 | * does not seem to get updated immediately when a jump occurs. | ||
641 | */ | ||
642 | |||
643 | last_pause_ptr = | ||
644 | via_align_cmd(dev_priv, HC_HAGPBpID_PAUSE, 0, &pause_addr_hi, | ||
645 | &pause_addr_lo, 0) - 1; | ||
646 | via_align_cmd(dev_priv, HC_HAGPBpID_PAUSE, 0, &pause_addr_hi, | ||
647 | &pause_addr_lo, 0); | ||
648 | *last_pause_ptr = pause_addr_lo; | ||
649 | |||
650 | dma_low_save2 = dev_priv->dma_low; | ||
651 | dev_priv->dma_low = dma_low_save1; | ||
652 | via_hook_segment(dev_priv, jump_addr_hi, jump_addr_lo, 0); | ||
653 | dev_priv->dma_low = dma_low_save2; | ||
654 | via_hook_segment(dev_priv, pause_addr_hi, pause_addr_lo, 0); | ||
608 | } | 655 | } |
609 | 656 | ||
610 | 657 | ||
diff --git a/drivers/char/drm/via_dmablit.c b/drivers/char/drm/via_dmablit.c index 33c5197b73c4..409e00afdd07 100644 --- a/drivers/char/drm/via_dmablit.c +++ b/drivers/char/drm/via_dmablit.c | |||
@@ -603,7 +603,7 @@ via_build_sg_info(struct drm_device *dev, drm_via_sg_info_t *vsg, drm_via_dmabli | |||
603 | * (Not a big limitation anyway.) | 603 | * (Not a big limitation anyway.) |
604 | */ | 604 | */ |
605 | 605 | ||
606 | if ((xfer->mem_stride - xfer->line_length) >= PAGE_SIZE) { | 606 | if ((xfer->mem_stride - xfer->line_length) > 2*PAGE_SIZE) { |
607 | DRM_ERROR("Too large system memory stride. Stride: %d, " | 607 | DRM_ERROR("Too large system memory stride. Stride: %d, " |
608 | "Length: %d\n", xfer->mem_stride, xfer->line_length); | 608 | "Length: %d\n", xfer->mem_stride, xfer->line_length); |
609 | return -EINVAL; | 609 | return -EINVAL; |
diff --git a/drivers/input/misc/cobalt_btns.c b/drivers/input/misc/cobalt_btns.c index 4833b1a82623..5511ef006a66 100644 --- a/drivers/input/misc/cobalt_btns.c +++ b/drivers/input/misc/cobalt_btns.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * Cobalt button interface driver. | 2 | * Cobalt button interface driver. |
3 | * | 3 | * |
4 | * Copyright (C) 2007 Yoichi Yuasa <yoichi_yuasa@tripeaks.co.jp> | 4 | * Copyright (C) 2007-2008 Yoichi Yuasa <yoichi_yuasa@tripeaks.co.jp> |
5 | * | 5 | * |
6 | * This program is free software; you can redistribute it and/or modify | 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 | 7 | * it under the terms of the GNU General Public License as published by |
@@ -15,7 +15,7 @@ | |||
15 | * | 15 | * |
16 | * You should have received a copy of the GNU General Public License | 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 | 17 | * along with this program; if not, write to the Free Software |
18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | 18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
19 | */ | 19 | */ |
20 | #include <linux/init.h> | 20 | #include <linux/init.h> |
21 | #include <linux/input-polldev.h> | 21 | #include <linux/input-polldev.h> |
@@ -55,7 +55,7 @@ static void handle_buttons(struct input_polled_dev *dev) | |||
55 | status = ~readl(bdev->reg) >> 24; | 55 | status = ~readl(bdev->reg) >> 24; |
56 | 56 | ||
57 | for (i = 0; i < ARRAY_SIZE(bdev->keymap); i++) { | 57 | for (i = 0; i < ARRAY_SIZE(bdev->keymap); i++) { |
58 | if (status & (1UL << i)) { | 58 | if (status & (1U << i)) { |
59 | if (++bdev->count[i] == BUTTONS_COUNT_THRESHOLD) { | 59 | if (++bdev->count[i] == BUTTONS_COUNT_THRESHOLD) { |
60 | input_event(input, EV_MSC, MSC_SCAN, i); | 60 | input_event(input, EV_MSC, MSC_SCAN, i); |
61 | input_report_key(input, bdev->keymap[i], 1); | 61 | input_report_key(input, bdev->keymap[i], 1); |
@@ -97,16 +97,16 @@ static int __devinit cobalt_buttons_probe(struct platform_device *pdev) | |||
97 | input->name = "Cobalt buttons"; | 97 | input->name = "Cobalt buttons"; |
98 | input->phys = "cobalt/input0"; | 98 | input->phys = "cobalt/input0"; |
99 | input->id.bustype = BUS_HOST; | 99 | input->id.bustype = BUS_HOST; |
100 | input->cdev.dev = &pdev->dev; | 100 | input->dev.parent = &pdev->dev; |
101 | 101 | ||
102 | input->keycode = pdev->keymap; | 102 | input->keycode = bdev->keymap; |
103 | input->keycodemax = ARRAY_SIZE(pdev->keymap); | 103 | input->keycodemax = ARRAY_SIZE(bdev->keymap); |
104 | input->keycodesize = sizeof(unsigned short); | 104 | input->keycodesize = sizeof(unsigned short); |
105 | 105 | ||
106 | input_set_capability(input, EV_MSC, MSC_SCAN); | 106 | input_set_capability(input, EV_MSC, MSC_SCAN); |
107 | __set_bit(EV_KEY, input->evbit); | 107 | __set_bit(EV_KEY, input->evbit); |
108 | for (i = 0; i < ARRAY_SIZE(buttons_map); i++) | 108 | for (i = 0; i < ARRAY_SIZE(cobalt_map); i++) |
109 | __set_bit(input->keycode[i], input->keybit); | 109 | __set_bit(bdev->keymap[i], input->keybit); |
110 | __clear_bit(KEY_RESERVED, input->keybit); | 110 | __clear_bit(KEY_RESERVED, input->keybit); |
111 | 111 | ||
112 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 112 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c index b346a3b418ea..385e32bcf6a6 100644 --- a/drivers/input/mouse/alps.c +++ b/drivers/input/mouse/alps.c | |||
@@ -116,8 +116,8 @@ static void alps_process_packet(struct psmouse *psmouse) | |||
116 | } | 116 | } |
117 | 117 | ||
118 | if (priv->i->flags & ALPS_FW_BK_1) { | 118 | if (priv->i->flags & ALPS_FW_BK_1) { |
119 | back = packet[2] & 4; | 119 | back = packet[0] & 0x10; |
120 | forward = packet[0] & 0x10; | 120 | forward = packet[2] & 4; |
121 | } | 121 | } |
122 | 122 | ||
123 | if (priv->i->flags & ALPS_FW_BK_2) { | 123 | if (priv->i->flags & ALPS_FW_BK_2) { |
@@ -483,6 +483,7 @@ int alps_init(struct psmouse *psmouse) | |||
483 | dev2->id.vendor = 0x0002; | 483 | dev2->id.vendor = 0x0002; |
484 | dev2->id.product = PSMOUSE_ALPS; | 484 | dev2->id.product = PSMOUSE_ALPS; |
485 | dev2->id.version = 0x0000; | 485 | dev2->id.version = 0x0000; |
486 | dev2->dev.parent = &psmouse->ps2dev.serio->dev; | ||
486 | 487 | ||
487 | dev2->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL); | 488 | dev2->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL); |
488 | dev2->relbit[BIT_WORD(REL_X)] |= BIT_MASK(REL_X) | BIT_MASK(REL_Y); | 489 | dev2->relbit[BIT_WORD(REL_X)] |= BIT_MASK(REL_X) | BIT_MASK(REL_Y); |
diff --git a/drivers/input/serio/i8042-snirm.h b/drivers/input/serio/i8042-snirm.h new file mode 100644 index 000000000000..409a9341143d --- /dev/null +++ b/drivers/input/serio/i8042-snirm.h | |||
@@ -0,0 +1,75 @@ | |||
1 | #ifndef _I8042_SNIRM_H | ||
2 | #define _I8042_SNIRM_H | ||
3 | |||
4 | #include <asm/sni.h> | ||
5 | |||
6 | /* | ||
7 | * This program is free software; you can redistribute it and/or modify it | ||
8 | * under the terms of the GNU General Public License version 2 as published by | ||
9 | * the Free Software Foundation. | ||
10 | */ | ||
11 | |||
12 | /* | ||
13 | * Names. | ||
14 | */ | ||
15 | |||
16 | #define I8042_KBD_PHYS_DESC "onboard/serio0" | ||
17 | #define I8042_AUX_PHYS_DESC "onboard/serio1" | ||
18 | #define I8042_MUX_PHYS_DESC "onboard/serio%d" | ||
19 | |||
20 | /* | ||
21 | * IRQs. | ||
22 | */ | ||
23 | static int i8042_kbd_irq; | ||
24 | static int i8042_aux_irq; | ||
25 | #define I8042_KBD_IRQ i8042_kbd_irq | ||
26 | #define I8042_AUX_IRQ i8042_aux_irq | ||
27 | |||
28 | static void __iomem *kbd_iobase; | ||
29 | |||
30 | #define I8042_COMMAND_REG (kbd_iobase + 0x64UL) | ||
31 | #define I8042_DATA_REG (kbd_iobase + 0x60UL) | ||
32 | |||
33 | static inline int i8042_read_data(void) | ||
34 | { | ||
35 | return readb(kbd_iobase + 0x60UL); | ||
36 | } | ||
37 | |||
38 | static inline int i8042_read_status(void) | ||
39 | { | ||
40 | return readb(kbd_iobase + 0x64UL); | ||
41 | } | ||
42 | |||
43 | static inline void i8042_write_data(int val) | ||
44 | { | ||
45 | writeb(val, kbd_iobase + 0x60UL); | ||
46 | } | ||
47 | |||
48 | static inline void i8042_write_command(int val) | ||
49 | { | ||
50 | writeb(val, kbd_iobase + 0x64UL); | ||
51 | } | ||
52 | static inline int i8042_platform_init(void) | ||
53 | { | ||
54 | /* RM200 is strange ... */ | ||
55 | if (sni_brd_type == SNI_BRD_RM200) { | ||
56 | kbd_iobase = ioremap(0x16000000, 4); | ||
57 | i8042_kbd_irq = 33; | ||
58 | i8042_aux_irq = 44; | ||
59 | } else { | ||
60 | kbd_iobase = ioremap(0x14000000, 4); | ||
61 | i8042_kbd_irq = 1; | ||
62 | i8042_aux_irq = 12; | ||
63 | } | ||
64 | if (!kbd_iobase) | ||
65 | return -ENOMEM; | ||
66 | |||
67 | return 0; | ||
68 | } | ||
69 | |||
70 | static inline void i8042_platform_exit(void) | ||
71 | { | ||
72 | |||
73 | } | ||
74 | |||
75 | #endif /* _I8042_SNIRM_H */ | ||
diff --git a/drivers/input/serio/i8042-x86ia64io.h b/drivers/input/serio/i8042-x86ia64io.h index 662e84482c26..60931aceb828 100644 --- a/drivers/input/serio/i8042-x86ia64io.h +++ b/drivers/input/serio/i8042-x86ia64io.h | |||
@@ -277,6 +277,13 @@ static struct dmi_system_id __initdata i8042_dmi_nomux_table[] = { | |||
277 | DMI_MATCH(DMI_PRODUCT_NAME, "M636/A737 platform"), | 277 | DMI_MATCH(DMI_PRODUCT_NAME, "M636/A737 platform"), |
278 | }, | 278 | }, |
279 | }, | 279 | }, |
280 | { | ||
281 | .ident = "Lenovo 3000 n100", | ||
282 | .matches = { | ||
283 | DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), | ||
284 | DMI_MATCH(DMI_PRODUCT_VERSION, "3000 N100"), | ||
285 | }, | ||
286 | }, | ||
280 | { } | 287 | { } |
281 | }; | 288 | }; |
282 | 289 | ||
diff --git a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c index 2763394869d2..65a74cfc187b 100644 --- a/drivers/input/serio/i8042.c +++ b/drivers/input/serio/i8042.c | |||
@@ -1151,7 +1151,6 @@ static int __devinit i8042_setup_kbd(void) | |||
1151 | static int __devinit i8042_probe(struct platform_device *dev) | 1151 | static int __devinit i8042_probe(struct platform_device *dev) |
1152 | { | 1152 | { |
1153 | int error; | 1153 | int error; |
1154 | char param; | ||
1155 | 1154 | ||
1156 | error = i8042_controller_selftest(); | 1155 | error = i8042_controller_selftest(); |
1157 | if (error) | 1156 | if (error) |
@@ -1174,7 +1173,7 @@ static int __devinit i8042_probe(struct platform_device *dev) | |||
1174 | } | 1173 | } |
1175 | #ifdef CONFIG_X86 | 1174 | #ifdef CONFIG_X86 |
1176 | if (i8042_dritek) { | 1175 | if (i8042_dritek) { |
1177 | param = 0x90; | 1176 | char param = 0x90; |
1178 | error = i8042_command(¶m, 0x1059); | 1177 | error = i8042_command(¶m, 0x1059); |
1179 | if (error) | 1178 | if (error) |
1180 | goto out_fail; | 1179 | goto out_fail; |
diff --git a/drivers/input/serio/i8042.h b/drivers/input/serio/i8042.h index c972e5d03a3f..cbc1beb66574 100644 --- a/drivers/input/serio/i8042.h +++ b/drivers/input/serio/i8042.h | |||
@@ -18,6 +18,8 @@ | |||
18 | #include "i8042-jazzio.h" | 18 | #include "i8042-jazzio.h" |
19 | #elif defined(CONFIG_SGI_HAS_I8042) | 19 | #elif defined(CONFIG_SGI_HAS_I8042) |
20 | #include "i8042-ip22io.h" | 20 | #include "i8042-ip22io.h" |
21 | #elif defined(CONFIG_SNI_RM) | ||
22 | #include "i8042-snirm.h" | ||
21 | #elif defined(CONFIG_PPC) | 23 | #elif defined(CONFIG_PPC) |
22 | #include "i8042-ppcio.h" | 24 | #include "i8042-ppcio.h" |
23 | #elif defined(CONFIG_SPARC) | 25 | #elif defined(CONFIG_SPARC) |
diff --git a/drivers/input/tablet/wacom.h b/drivers/input/tablet/wacom.h index 6542edb6f76e..acf9830698cb 100644 --- a/drivers/input/tablet/wacom.h +++ b/drivers/input/tablet/wacom.h | |||
@@ -11,7 +11,7 @@ | |||
11 | * Copyright (c) 2000 Daniel Egger <egger@suse.de> | 11 | * Copyright (c) 2000 Daniel Egger <egger@suse.de> |
12 | * Copyright (c) 2001 Frederic Lepied <flepied@mandrakesoft.com> | 12 | * Copyright (c) 2001 Frederic Lepied <flepied@mandrakesoft.com> |
13 | * Copyright (c) 2004 Panagiotis Issaris <panagiotis.issaris@mech.kuleuven.ac.be> | 13 | * Copyright (c) 2004 Panagiotis Issaris <panagiotis.issaris@mech.kuleuven.ac.be> |
14 | * Copyright (c) 2002-2007 Ping Cheng <pingc@wacom.com> | 14 | * Copyright (c) 2002-2008 Ping Cheng <pingc@wacom.com> |
15 | * | 15 | * |
16 | * ChangeLog: | 16 | * ChangeLog: |
17 | * v0.1 (vp) - Initial release | 17 | * v0.1 (vp) - Initial release |
@@ -65,6 +65,7 @@ | |||
65 | * - and wacom_wac.c deals with Wacom specific code | 65 | * - and wacom_wac.c deals with Wacom specific code |
66 | * - Support Intuos3 4x6 | 66 | * - Support Intuos3 4x6 |
67 | * v1.47 (pc) - Added support for Bamboo | 67 | * v1.47 (pc) - Added support for Bamboo |
68 | * v1.48 (pc) - Added support for Bamboo1, BambooFun, and Cintiq 12WX | ||
68 | */ | 69 | */ |
69 | 70 | ||
70 | /* | 71 | /* |
@@ -85,7 +86,7 @@ | |||
85 | /* | 86 | /* |
86 | * Version Information | 87 | * Version Information |
87 | */ | 88 | */ |
88 | #define DRIVER_VERSION "v1.47" | 89 | #define DRIVER_VERSION "v1.48" |
89 | #define DRIVER_AUTHOR "Vojtech Pavlik <vojtech@ucw.cz>" | 90 | #define DRIVER_AUTHOR "Vojtech Pavlik <vojtech@ucw.cz>" |
90 | #define DRIVER_DESC "USB Wacom Graphire and Wacom Intuos tablet driver" | 91 | #define DRIVER_DESC "USB Wacom Graphire and Wacom Intuos tablet driver" |
91 | #define DRIVER_LICENSE "GPL" | 92 | #define DRIVER_LICENSE "GPL" |
@@ -125,6 +126,7 @@ extern void input_dev_i(struct input_dev *input_dev, struct wacom_wac *wacom_wac | |||
125 | extern void input_dev_pl(struct input_dev *input_dev, struct wacom_wac *wacom_wac); | 126 | extern void input_dev_pl(struct input_dev *input_dev, struct wacom_wac *wacom_wac); |
126 | extern void input_dev_pt(struct input_dev *input_dev, struct wacom_wac *wacom_wac); | 127 | extern void input_dev_pt(struct input_dev *input_dev, struct wacom_wac *wacom_wac); |
127 | extern void input_dev_mo(struct input_dev *input_dev, struct wacom_wac *wacom_wac); | 128 | extern void input_dev_mo(struct input_dev *input_dev, struct wacom_wac *wacom_wac); |
129 | extern void input_dev_bee(struct input_dev *input_dev, struct wacom_wac *wacom_wac); | ||
128 | extern __u16 wacom_le16_to_cpu(unsigned char *data); | 130 | extern __u16 wacom_le16_to_cpu(unsigned char *data); |
129 | extern __u16 wacom_be16_to_cpu(unsigned char *data); | 131 | extern __u16 wacom_be16_to_cpu(unsigned char *data); |
130 | extern struct wacom_features * get_wacom_feature(const struct usb_device_id *id); | 132 | extern struct wacom_features * get_wacom_feature(const struct usb_device_id *id); |
diff --git a/drivers/input/tablet/wacom_sys.c b/drivers/input/tablet/wacom_sys.c index d64b1ea136b3..41caaef8e2d7 100644 --- a/drivers/input/tablet/wacom_sys.c +++ b/drivers/input/tablet/wacom_sys.c | |||
@@ -171,6 +171,7 @@ void input_dev_i3s(struct input_dev *input_dev, struct wacom_wac *wacom_wac) | |||
171 | input_dev->keybit[BIT_WORD(BTN_LEFT)] |= BIT_MASK(BTN_0) | | 171 | input_dev->keybit[BIT_WORD(BTN_LEFT)] |= BIT_MASK(BTN_0) | |
172 | BIT_MASK(BTN_1) | BIT_MASK(BTN_2) | BIT_MASK(BTN_3); | 172 | BIT_MASK(BTN_1) | BIT_MASK(BTN_2) | BIT_MASK(BTN_3); |
173 | input_set_abs_params(input_dev, ABS_RX, 0, 4096, 0, 0); | 173 | input_set_abs_params(input_dev, ABS_RX, 0, 4096, 0, 0); |
174 | input_set_abs_params(input_dev, ABS_Z, -900, 899, 0, 0); | ||
174 | } | 175 | } |
175 | 176 | ||
176 | void input_dev_i3(struct input_dev *input_dev, struct wacom_wac *wacom_wac) | 177 | void input_dev_i3(struct input_dev *input_dev, struct wacom_wac *wacom_wac) |
@@ -180,6 +181,11 @@ void input_dev_i3(struct input_dev *input_dev, struct wacom_wac *wacom_wac) | |||
180 | input_set_abs_params(input_dev, ABS_RY, 0, 4096, 0, 0); | 181 | input_set_abs_params(input_dev, ABS_RY, 0, 4096, 0, 0); |
181 | } | 182 | } |
182 | 183 | ||
184 | void input_dev_bee(struct input_dev *input_dev, struct wacom_wac *wacom_wac) | ||
185 | { | ||
186 | input_dev->keybit[BIT_WORD(BTN_LEFT)] |= BIT_MASK(BTN_8) | BIT_MASK(BTN_9); | ||
187 | } | ||
188 | |||
183 | void input_dev_i(struct input_dev *input_dev, struct wacom_wac *wacom_wac) | 189 | void input_dev_i(struct input_dev *input_dev, struct wacom_wac *wacom_wac) |
184 | { | 190 | { |
185 | input_dev->evbit[0] |= BIT_MASK(EV_MSC) | BIT_MASK(EV_REL); | 191 | input_dev->evbit[0] |= BIT_MASK(EV_MSC) | BIT_MASK(EV_REL); |
diff --git a/drivers/input/tablet/wacom_wac.c b/drivers/input/tablet/wacom_wac.c index fc03ba256f4c..ffe33842143f 100644 --- a/drivers/input/tablet/wacom_wac.c +++ b/drivers/input/tablet/wacom_wac.c | |||
@@ -163,7 +163,9 @@ static int wacom_graphire_irq(struct wacom_wac *wacom, void *wcombo) | |||
163 | } | 163 | } |
164 | 164 | ||
165 | id = STYLUS_DEVICE_ID; | 165 | id = STYLUS_DEVICE_ID; |
166 | if (data[1] & 0x80) { /* in prox */ | 166 | if ((data[1] & 0x80) && ((data[1] & 0x07) || data[2] || data[3] || data[4] |
167 | || data[5] || data[6] || (data[7] & 0x07))) { | ||
168 | /* in prox and not a pad data */ | ||
167 | 169 | ||
168 | switch ((data[1] >> 5) & 3) { | 170 | switch ((data[1] >> 5) & 3) { |
169 | 171 | ||
@@ -233,7 +235,6 @@ static int wacom_graphire_irq(struct wacom_wac *wacom, void *wcombo) | |||
233 | if (data[7] & 0xf8) { | 235 | if (data[7] & 0xf8) { |
234 | wacom_input_sync(wcombo); /* sync last event */ | 236 | wacom_input_sync(wcombo); /* sync last event */ |
235 | wacom->id[1] = 1; | 237 | wacom->id[1] = 1; |
236 | wacom->serial[1] = (data[7] & 0xf8); | ||
237 | wacom_report_key(wcombo, BTN_0, (data[7] & 0x40)); | 238 | wacom_report_key(wcombo, BTN_0, (data[7] & 0x40)); |
238 | wacom_report_key(wcombo, BTN_4, (data[7] & 0x80)); | 239 | wacom_report_key(wcombo, BTN_4, (data[7] & 0x80)); |
239 | rw = ((data[7] & 0x18) >> 3) - ((data[7] & 0x20) >> 3); | 240 | rw = ((data[7] & 0x18) >> 3) - ((data[7] & 0x20) >> 3); |
@@ -252,10 +253,9 @@ static int wacom_graphire_irq(struct wacom_wac *wacom, void *wcombo) | |||
252 | } | 253 | } |
253 | break; | 254 | break; |
254 | case WACOM_MO: | 255 | case WACOM_MO: |
255 | if ((data[7] & 0xf8) || (data[8] & 0x80)) { | 256 | if ((data[7] & 0xf8) || (data[8] & 0xff)) { |
256 | wacom_input_sync(wcombo); /* sync last event */ | 257 | wacom_input_sync(wcombo); /* sync last event */ |
257 | wacom->id[1] = 1; | 258 | wacom->id[1] = 1; |
258 | wacom->serial[1] = (data[7] & 0xf8); | ||
259 | wacom_report_key(wcombo, BTN_0, (data[7] & 0x08)); | 259 | wacom_report_key(wcombo, BTN_0, (data[7] & 0x08)); |
260 | wacom_report_key(wcombo, BTN_1, (data[7] & 0x20)); | 260 | wacom_report_key(wcombo, BTN_1, (data[7] & 0x20)); |
261 | wacom_report_key(wcombo, BTN_4, (data[7] & 0x10)); | 261 | wacom_report_key(wcombo, BTN_4, (data[7] & 0x10)); |
@@ -434,10 +434,12 @@ static int wacom_intuos_irq(struct wacom_wac *wacom, void *wcombo) | |||
434 | wacom_report_key(wcombo, BTN_5, (data[6] & 0x02)); | 434 | wacom_report_key(wcombo, BTN_5, (data[6] & 0x02)); |
435 | wacom_report_key(wcombo, BTN_6, (data[6] & 0x04)); | 435 | wacom_report_key(wcombo, BTN_6, (data[6] & 0x04)); |
436 | wacom_report_key(wcombo, BTN_7, (data[6] & 0x08)); | 436 | wacom_report_key(wcombo, BTN_7, (data[6] & 0x08)); |
437 | wacom_report_key(wcombo, BTN_8, (data[5] & 0x10)); | ||
438 | wacom_report_key(wcombo, BTN_9, (data[6] & 0x10)); | ||
437 | wacom_report_abs(wcombo, ABS_RX, ((data[1] & 0x1f) << 8) | data[2]); | 439 | wacom_report_abs(wcombo, ABS_RX, ((data[1] & 0x1f) << 8) | data[2]); |
438 | wacom_report_abs(wcombo, ABS_RY, ((data[3] & 0x1f) << 8) | data[4]); | 440 | wacom_report_abs(wcombo, ABS_RY, ((data[3] & 0x1f) << 8) | data[4]); |
439 | 441 | ||
440 | if((data[5] & 0x0f) | (data[6] & 0x0f) | (data[1] & 0x1f) | | 442 | if ((data[5] & 0x1f) | (data[6] & 0x1f) | (data[1] & 0x1f) | |
441 | data[2] | (data[3] & 0x1f) | data[4]) | 443 | data[2] | (data[3] & 0x1f) | data[4]) |
442 | wacom_report_key(wcombo, wacom->tool[1], 1); | 444 | wacom_report_key(wcombo, wacom->tool[1], 1); |
443 | else | 445 | else |
@@ -481,13 +483,11 @@ static int wacom_intuos_irq(struct wacom_wac *wacom, void *wcombo) | |||
481 | if (data[1] & 0x02) { | 483 | if (data[1] & 0x02) { |
482 | /* Rotation packet */ | 484 | /* Rotation packet */ |
483 | if (wacom->features->type >= INTUOS3S) { | 485 | if (wacom->features->type >= INTUOS3S) { |
484 | /* I3 marker pen rotation reported as wheel | 486 | /* I3 marker pen rotation */ |
485 | * due to valuator limitation | ||
486 | */ | ||
487 | t = (data[6] << 3) | ((data[7] >> 5) & 7); | 487 | t = (data[6] << 3) | ((data[7] >> 5) & 7); |
488 | t = (data[7] & 0x20) ? ((t > 900) ? ((t-1) / 2 - 1350) : | 488 | t = (data[7] & 0x20) ? ((t > 900) ? ((t-1) / 2 - 1350) : |
489 | ((t-1) / 2 + 450)) : (450 - t / 2) ; | 489 | ((t-1) / 2 + 450)) : (450 - t / 2) ; |
490 | wacom_report_abs(wcombo, ABS_WHEEL, t); | 490 | wacom_report_abs(wcombo, ABS_Z, t); |
491 | } else { | 491 | } else { |
492 | /* 4D mouse rotation packet */ | 492 | /* 4D mouse rotation packet */ |
493 | t = (data[6] << 3) | ((data[7] >> 5) & 7); | 493 | t = (data[6] << 3) | ((data[7] >> 5) & 7); |
@@ -558,6 +558,7 @@ int wacom_wac_irq(struct wacom_wac *wacom_wac, void *wcombo) | |||
558 | case INTUOS3: | 558 | case INTUOS3: |
559 | case INTUOS3L: | 559 | case INTUOS3L: |
560 | case CINTIQ: | 560 | case CINTIQ: |
561 | case WACOM_BEE: | ||
561 | return (wacom_intuos_irq(wacom_wac, wcombo)); | 562 | return (wacom_intuos_irq(wacom_wac, wcombo)); |
562 | break; | 563 | break; |
563 | default: | 564 | default: |
@@ -577,6 +578,8 @@ void wacom_init_input_dev(struct input_dev *input_dev, struct wacom_wac *wacom_w | |||
577 | case GRAPHIRE: | 578 | case GRAPHIRE: |
578 | input_dev_g(input_dev, wacom_wac); | 579 | input_dev_g(input_dev, wacom_wac); |
579 | break; | 580 | break; |
581 | case WACOM_BEE: | ||
582 | input_dev_bee(input_dev, wacom_wac); | ||
580 | case INTUOS3: | 583 | case INTUOS3: |
581 | case INTUOS3L: | 584 | case INTUOS3L: |
582 | case CINTIQ: | 585 | case CINTIQ: |
@@ -607,12 +610,15 @@ static struct wacom_features wacom_features[] = { | |||
607 | { "Wacom Graphire3 6x8", 8, 16704, 12064, 511, 63, GRAPHIRE }, | 610 | { "Wacom Graphire3 6x8", 8, 16704, 12064, 511, 63, GRAPHIRE }, |
608 | { "Wacom Graphire4 4x5", 8, 10208, 7424, 511, 63, WACOM_G4 }, | 611 | { "Wacom Graphire4 4x5", 8, 10208, 7424, 511, 63, WACOM_G4 }, |
609 | { "Wacom Graphire4 6x8", 8, 16704, 12064, 511, 63, WACOM_G4 }, | 612 | { "Wacom Graphire4 6x8", 8, 16704, 12064, 511, 63, WACOM_G4 }, |
613 | { "Wacom BambooFun 4x5", 9, 14760, 9225, 511, 63, WACOM_MO }, | ||
614 | { "Wacom BambooFun 6x8", 9, 21648, 13530, 511, 63, WACOM_MO }, | ||
610 | { "Wacom Volito", 8, 5104, 3712, 511, 63, GRAPHIRE }, | 615 | { "Wacom Volito", 8, 5104, 3712, 511, 63, GRAPHIRE }, |
611 | { "Wacom PenStation2", 8, 3250, 2320, 255, 63, GRAPHIRE }, | 616 | { "Wacom PenStation2", 8, 3250, 2320, 255, 63, GRAPHIRE }, |
612 | { "Wacom Volito2 4x5", 8, 5104, 3712, 511, 63, GRAPHIRE }, | 617 | { "Wacom Volito2 4x5", 8, 5104, 3712, 511, 63, GRAPHIRE }, |
613 | { "Wacom Volito2 2x3", 8, 3248, 2320, 511, 63, GRAPHIRE }, | 618 | { "Wacom Volito2 2x3", 8, 3248, 2320, 511, 63, GRAPHIRE }, |
614 | { "Wacom PenPartner2", 8, 3250, 2320, 255, 63, GRAPHIRE }, | 619 | { "Wacom PenPartner2", 8, 3250, 2320, 511, 63, GRAPHIRE }, |
615 | { "Wacom Bamboo", 9, 14760, 9225, 511, 63, WACOM_MO }, | 620 | { "Wacom Bamboo", 9, 14760, 9225, 511, 63, WACOM_MO }, |
621 | { "Wacom Bamboo1", 8, 5104, 3712, 511, 63, GRAPHIRE }, | ||
616 | { "Wacom Intuos 4x5", 10, 12700, 10600, 1023, 31, INTUOS }, | 622 | { "Wacom Intuos 4x5", 10, 12700, 10600, 1023, 31, INTUOS }, |
617 | { "Wacom Intuos 6x8", 10, 20320, 16240, 1023, 31, INTUOS }, | 623 | { "Wacom Intuos 6x8", 10, 20320, 16240, 1023, 31, INTUOS }, |
618 | { "Wacom Intuos 9x12", 10, 30480, 24060, 1023, 31, INTUOS }, | 624 | { "Wacom Intuos 9x12", 10, 30480, 24060, 1023, 31, INTUOS }, |
@@ -643,6 +649,7 @@ static struct wacom_features wacom_features[] = { | |||
643 | { "Wacom Intuos3 6x11", 10, 54204, 31750, 1023, 63, INTUOS3 }, | 649 | { "Wacom Intuos3 6x11", 10, 54204, 31750, 1023, 63, INTUOS3 }, |
644 | { "Wacom Intuos3 4x6", 10, 31496, 19685, 1023, 63, INTUOS3S }, | 650 | { "Wacom Intuos3 4x6", 10, 31496, 19685, 1023, 63, INTUOS3S }, |
645 | { "Wacom Cintiq 21UX", 10, 87200, 65600, 1023, 63, CINTIQ }, | 651 | { "Wacom Cintiq 21UX", 10, 87200, 65600, 1023, 63, CINTIQ }, |
652 | { "Wacom Cintiq 12WX", 10, 53020, 33440, 1023, 63, WACOM_BEE }, | ||
646 | { "Wacom Intuos2 6x8", 10, 20320, 16240, 1023, 31, INTUOS }, | 653 | { "Wacom Intuos2 6x8", 10, 20320, 16240, 1023, 31, INTUOS }, |
647 | { } | 654 | { } |
648 | }; | 655 | }; |
@@ -656,12 +663,15 @@ static struct usb_device_id wacom_ids[] = { | |||
656 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x14) }, | 663 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x14) }, |
657 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x15) }, | 664 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x15) }, |
658 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x16) }, | 665 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x16) }, |
666 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x17) }, | ||
667 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x18) }, | ||
659 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x60) }, | 668 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x60) }, |
660 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x61) }, | 669 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x61) }, |
661 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x62) }, | 670 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x62) }, |
662 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x63) }, | 671 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x63) }, |
663 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x64) }, | 672 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x64) }, |
664 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x65) }, | 673 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x65) }, |
674 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x69) }, | ||
665 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x20) }, | 675 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x20) }, |
666 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x21) }, | 676 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x21) }, |
667 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x22) }, | 677 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x22) }, |
@@ -692,6 +702,7 @@ static struct usb_device_id wacom_ids[] = { | |||
692 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB5) }, | 702 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB5) }, |
693 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB7) }, | 703 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB7) }, |
694 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x3F) }, | 704 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x3F) }, |
705 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xC6) }, | ||
695 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x47) }, | 706 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x47) }, |
696 | { } | 707 | { } |
697 | }; | 708 | }; |
diff --git a/drivers/input/tablet/wacom_wac.h b/drivers/input/tablet/wacom_wac.h index a302e229bb8a..3342bc05847d 100644 --- a/drivers/input/tablet/wacom_wac.h +++ b/drivers/input/tablet/wacom_wac.h | |||
@@ -25,6 +25,7 @@ enum { | |||
25 | INTUOS3, | 25 | INTUOS3, |
26 | INTUOS3L, | 26 | INTUOS3L, |
27 | CINTIQ, | 27 | CINTIQ, |
28 | WACOM_BEE, | ||
28 | WACOM_MO, | 29 | WACOM_MO, |
29 | MAX_TYPE | 30 | MAX_TYPE |
30 | }; | 31 | }; |
diff --git a/drivers/input/touchscreen/ads7846.c b/drivers/input/touchscreen/ads7846.c index 58934a40f5ce..57a1c28bf122 100644 --- a/drivers/input/touchscreen/ads7846.c +++ b/drivers/input/touchscreen/ads7846.c | |||
@@ -213,7 +213,7 @@ static int ads7846_read12_ser(struct device *dev, unsigned command) | |||
213 | struct ads7846 *ts = dev_get_drvdata(dev); | 213 | struct ads7846 *ts = dev_get_drvdata(dev); |
214 | struct ser_req *req = kzalloc(sizeof *req, GFP_KERNEL); | 214 | struct ser_req *req = kzalloc(sizeof *req, GFP_KERNEL); |
215 | int status; | 215 | int status; |
216 | int sample; | 216 | int uninitialized_var(sample); |
217 | int use_internal; | 217 | int use_internal; |
218 | 218 | ||
219 | if (!req) | 219 | if (!req) |
diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c index 19fd4cb0ddf8..b58472cf76f8 100644 --- a/drivers/net/virtio_net.c +++ b/drivers/net/virtio_net.c | |||
@@ -203,8 +203,11 @@ again: | |||
203 | if (received < budget) { | 203 | if (received < budget) { |
204 | netif_rx_complete(vi->dev, napi); | 204 | netif_rx_complete(vi->dev, napi); |
205 | if (unlikely(!vi->rvq->vq_ops->enable_cb(vi->rvq)) | 205 | if (unlikely(!vi->rvq->vq_ops->enable_cb(vi->rvq)) |
206 | && netif_rx_reschedule(vi->dev, napi)) | 206 | && napi_schedule_prep(napi)) { |
207 | vi->rvq->vq_ops->disable_cb(vi->rvq); | ||
208 | __netif_rx_schedule(vi->dev, napi); | ||
207 | goto again; | 209 | goto again; |
210 | } | ||
208 | } | 211 | } |
209 | 212 | ||
210 | return received; | 213 | return received; |
@@ -278,10 +281,11 @@ again: | |||
278 | pr_debug("%s: virtio not prepared to send\n", dev->name); | 281 | pr_debug("%s: virtio not prepared to send\n", dev->name); |
279 | netif_stop_queue(dev); | 282 | netif_stop_queue(dev); |
280 | 283 | ||
281 | /* Activate callback for using skbs: if this fails it | 284 | /* Activate callback for using skbs: if this returns false it |
282 | * means some were used in the meantime. */ | 285 | * means some were used in the meantime. */ |
283 | if (unlikely(!vi->svq->vq_ops->enable_cb(vi->svq))) { | 286 | if (unlikely(!vi->svq->vq_ops->enable_cb(vi->svq))) { |
284 | printk("Unlikely: restart svq failed\n"); | 287 | printk("Unlikely: restart svq race\n"); |
288 | vi->svq->vq_ops->disable_cb(vi->svq); | ||
285 | netif_start_queue(dev); | 289 | netif_start_queue(dev); |
286 | goto again; | 290 | goto again; |
287 | } | 291 | } |
@@ -294,6 +298,15 @@ again: | |||
294 | return 0; | 298 | return 0; |
295 | } | 299 | } |
296 | 300 | ||
301 | #ifdef CONFIG_NET_POLL_CONTROLLER | ||
302 | static void virtnet_netpoll(struct net_device *dev) | ||
303 | { | ||
304 | struct virtnet_info *vi = netdev_priv(dev); | ||
305 | |||
306 | napi_schedule(&vi->napi); | ||
307 | } | ||
308 | #endif | ||
309 | |||
297 | static int virtnet_open(struct net_device *dev) | 310 | static int virtnet_open(struct net_device *dev) |
298 | { | 311 | { |
299 | struct virtnet_info *vi = netdev_priv(dev); | 312 | struct virtnet_info *vi = netdev_priv(dev); |
@@ -336,6 +349,9 @@ static int virtnet_probe(struct virtio_device *vdev) | |||
336 | dev->stop = virtnet_close; | 349 | dev->stop = virtnet_close; |
337 | dev->hard_start_xmit = start_xmit; | 350 | dev->hard_start_xmit = start_xmit; |
338 | dev->features = NETIF_F_HIGHDMA; | 351 | dev->features = NETIF_F_HIGHDMA; |
352 | #ifdef CONFIG_NET_POLL_CONTROLLER | ||
353 | dev->poll_controller = virtnet_netpoll; | ||
354 | #endif | ||
339 | SET_NETDEV_DEV(dev, &vdev->dev); | 355 | SET_NETDEV_DEV(dev, &vdev->dev); |
340 | 356 | ||
341 | /* Do we support "hardware" checksums? */ | 357 | /* Do we support "hardware" checksums? */ |
diff --git a/drivers/pci/hotplug/pciehp_core.c b/drivers/pci/hotplug/pciehp_core.c index 7f4836b8e71e..5fa4ba0d9934 100644 --- a/drivers/pci/hotplug/pciehp_core.c +++ b/drivers/pci/hotplug/pciehp_core.c | |||
@@ -467,7 +467,7 @@ static int pciehp_probe(struct pcie_device *dev, const struct pcie_port_service_ | |||
467 | t_slot = pciehp_find_slot(ctrl, ctrl->slot_device_offset); | 467 | t_slot = pciehp_find_slot(ctrl, ctrl->slot_device_offset); |
468 | 468 | ||
469 | t_slot->hpc_ops->get_adapter_status(t_slot, &value); /* Check if slot is occupied */ | 469 | t_slot->hpc_ops->get_adapter_status(t_slot, &value); /* Check if slot is occupied */ |
470 | if (value) { | 470 | if (value && pciehp_force) { |
471 | rc = pciehp_enable_slot(t_slot); | 471 | rc = pciehp_enable_slot(t_slot); |
472 | if (rc) /* -ENODEV: shouldn't happen, but deal with it */ | 472 | if (rc) /* -ENODEV: shouldn't happen, but deal with it */ |
473 | value = 0; | 473 | value = 0; |
diff --git a/drivers/thermal/Kconfig b/drivers/thermal/Kconfig index 3ab313ed441c..17e71d56f31e 100644 --- a/drivers/thermal/Kconfig +++ b/drivers/thermal/Kconfig | |||
@@ -4,8 +4,6 @@ | |||
4 | 4 | ||
5 | menuconfig THERMAL | 5 | menuconfig THERMAL |
6 | bool "Generic Thermal sysfs driver" | 6 | bool "Generic Thermal sysfs driver" |
7 | select HWMON | ||
8 | default y | ||
9 | help | 7 | help |
10 | Generic Thermal Sysfs driver offers a generic mechanism for | 8 | Generic Thermal Sysfs driver offers a generic mechanism for |
11 | thermal management. Usually it's made up of one or more thermal | 9 | thermal management. Usually it's made up of one or more thermal |
diff --git a/drivers/thermal/thermal.c b/drivers/thermal/thermal.c index 41bd4c805ace..8b86e53ccf7a 100644 --- a/drivers/thermal/thermal.c +++ b/drivers/thermal/thermal.c | |||
@@ -30,10 +30,8 @@ | |||
30 | #include <linux/idr.h> | 30 | #include <linux/idr.h> |
31 | #include <linux/thermal.h> | 31 | #include <linux/thermal.h> |
32 | #include <linux/spinlock.h> | 32 | #include <linux/spinlock.h> |
33 | #include <linux/hwmon.h> | ||
34 | #include <linux/hwmon-sysfs.h> | ||
35 | 33 | ||
36 | MODULE_AUTHOR("Zhang Rui"); | 34 | MODULE_AUTHOR("Zhang Rui") |
37 | MODULE_DESCRIPTION("Generic thermal management sysfs support"); | 35 | MODULE_DESCRIPTION("Generic thermal management sysfs support"); |
38 | MODULE_LICENSE("GPL"); | 36 | MODULE_LICENSE("GPL"); |
39 | 37 | ||
@@ -58,9 +56,6 @@ static LIST_HEAD(thermal_tz_list); | |||
58 | static LIST_HEAD(thermal_cdev_list); | 56 | static LIST_HEAD(thermal_cdev_list); |
59 | static DEFINE_MUTEX(thermal_list_lock); | 57 | static DEFINE_MUTEX(thermal_list_lock); |
60 | 58 | ||
61 | static struct device *thermal_hwmon; | ||
62 | #define MAX_THERMAL_ZONES 10 | ||
63 | |||
64 | static int get_idr(struct idr *idr, struct mutex *lock, int *id) | 59 | static int get_idr(struct idr *idr, struct mutex *lock, int *id) |
65 | { | 60 | { |
66 | int err; | 61 | int err; |
@@ -92,67 +87,7 @@ static void release_idr(struct idr *idr, struct mutex *lock, int id) | |||
92 | mutex_unlock(lock); | 87 | mutex_unlock(lock); |
93 | } | 88 | } |
94 | 89 | ||
95 | /* hwmon sys I/F*/ | 90 | /* sys I/F for thermal zone */ |
96 | static ssize_t | ||
97 | name_show(struct device *dev, struct device_attribute *attr, char *buf) | ||
98 | { | ||
99 | return sprintf(buf, "thermal_sys_class\n"); | ||
100 | } | ||
101 | |||
102 | static ssize_t | ||
103 | temp_input_show(struct device *dev, struct device_attribute *attr, char *buf) | ||
104 | { | ||
105 | struct thermal_zone_device *tz; | ||
106 | struct sensor_device_attribute *sensor_attr | ||
107 | = to_sensor_dev_attr(attr); | ||
108 | |||
109 | list_for_each_entry(tz, &thermal_tz_list, node) | ||
110 | if (tz->id == sensor_attr->index) | ||
111 | return tz->ops->get_temp(tz, buf); | ||
112 | |||
113 | return -ENODEV; | ||
114 | } | ||
115 | |||
116 | static ssize_t | ||
117 | temp_crit_show(struct device *dev, struct device_attribute *attr, | ||
118 | char *buf) | ||
119 | { | ||
120 | struct thermal_zone_device *tz; | ||
121 | struct sensor_device_attribute *sensor_attr | ||
122 | = to_sensor_dev_attr(attr); | ||
123 | |||
124 | list_for_each_entry(tz, &thermal_tz_list, node) | ||
125 | if (tz->id == sensor_attr->index) | ||
126 | return tz->ops->get_trip_temp(tz, 0, buf); | ||
127 | |||
128 | return -ENODEV; | ||
129 | } | ||
130 | |||
131 | static DEVICE_ATTR(name, 0444, name_show, NULL); | ||
132 | static struct sensor_device_attribute sensor_attrs[] = { | ||
133 | SENSOR_ATTR(temp1_input, 0444, temp_input_show, NULL, 0), | ||
134 | SENSOR_ATTR(temp1_crit, 0444, temp_crit_show, NULL, 0), | ||
135 | SENSOR_ATTR(temp2_input, 0444, temp_input_show, NULL, 1), | ||
136 | SENSOR_ATTR(temp2_crit, 0444, temp_crit_show, NULL, 1), | ||
137 | SENSOR_ATTR(temp3_input, 0444, temp_input_show, NULL, 2), | ||
138 | SENSOR_ATTR(temp3_crit, 0444, temp_crit_show, NULL, 2), | ||
139 | SENSOR_ATTR(temp4_input, 0444, temp_input_show, NULL, 3), | ||
140 | SENSOR_ATTR(temp4_crit, 0444, temp_crit_show, NULL, 3), | ||
141 | SENSOR_ATTR(temp5_input, 0444, temp_input_show, NULL, 4), | ||
142 | SENSOR_ATTR(temp5_crit, 0444, temp_crit_show, NULL, 4), | ||
143 | SENSOR_ATTR(temp6_input, 0444, temp_input_show, NULL, 5), | ||
144 | SENSOR_ATTR(temp6_crit, 0444, temp_crit_show, NULL, 5), | ||
145 | SENSOR_ATTR(temp7_input, 0444, temp_input_show, NULL, 6), | ||
146 | SENSOR_ATTR(temp7_crit, 0444, temp_crit_show, NULL, 6), | ||
147 | SENSOR_ATTR(temp8_input, 0444, temp_input_show, NULL, 7), | ||
148 | SENSOR_ATTR(temp8_crit, 0444, temp_crit_show, NULL, 7), | ||
149 | SENSOR_ATTR(temp9_input, 0444, temp_input_show, NULL, 8), | ||
150 | SENSOR_ATTR(temp9_crit, 0444, temp_crit_show, NULL, 8), | ||
151 | SENSOR_ATTR(temp10_input, 0444, temp_input_show, NULL, 9), | ||
152 | SENSOR_ATTR(temp10_crit, 0444, temp_crit_show, NULL, 9), | ||
153 | }; | ||
154 | |||
155 | /* thermal zone sys I/F */ | ||
156 | 91 | ||
157 | #define to_thermal_zone(_dev) \ | 92 | #define to_thermal_zone(_dev) \ |
158 | container_of(_dev, struct thermal_zone_device, device) | 93 | container_of(_dev, struct thermal_zone_device, device) |
@@ -279,7 +214,7 @@ do { \ | |||
279 | device_remove_file(_dev, &trip_point_attrs[_index * 2 + 1]); \ | 214 | device_remove_file(_dev, &trip_point_attrs[_index * 2 + 1]); \ |
280 | } while (0) | 215 | } while (0) |
281 | 216 | ||
282 | /* cooling device sys I/F */ | 217 | /* sys I/F for cooling device */ |
283 | #define to_cooling_device(_dev) \ | 218 | #define to_cooling_device(_dev) \ |
284 | container_of(_dev, struct thermal_cooling_device, device) | 219 | container_of(_dev, struct thermal_cooling_device, device) |
285 | 220 | ||
@@ -512,9 +447,6 @@ struct thermal_cooling_device *thermal_cooling_device_register(char *type, | |||
512 | struct thermal_zone_device *pos; | 447 | struct thermal_zone_device *pos; |
513 | int result; | 448 | int result; |
514 | 449 | ||
515 | if (!type) | ||
516 | return ERR_PTR(-EINVAL); | ||
517 | |||
518 | if (strlen(type) >= THERMAL_NAME_LENGTH) | 450 | if (strlen(type) >= THERMAL_NAME_LENGTH) |
519 | return ERR_PTR(-EINVAL); | 451 | return ERR_PTR(-EINVAL); |
520 | 452 | ||
@@ -545,9 +477,11 @@ struct thermal_cooling_device *thermal_cooling_device_register(char *type, | |||
545 | } | 477 | } |
546 | 478 | ||
547 | /* sys I/F */ | 479 | /* sys I/F */ |
548 | result = device_create_file(&cdev->device, &dev_attr_cdev_type); | 480 | if (type) { |
549 | if (result) | 481 | result = device_create_file(&cdev->device, &dev_attr_cdev_type); |
550 | goto unregister; | 482 | if (result) |
483 | goto unregister; | ||
484 | } | ||
551 | 485 | ||
552 | result = device_create_file(&cdev->device, &dev_attr_max_state); | 486 | result = device_create_file(&cdev->device, &dev_attr_max_state); |
553 | if (result) | 487 | if (result) |
@@ -613,8 +547,8 @@ void thermal_cooling_device_unregister(struct | |||
613 | tz->ops->unbind(tz, cdev); | 547 | tz->ops->unbind(tz, cdev); |
614 | } | 548 | } |
615 | mutex_unlock(&thermal_list_lock); | 549 | mutex_unlock(&thermal_list_lock); |
616 | 550 | if (cdev->type[0]) | |
617 | device_remove_file(&cdev->device, &dev_attr_cdev_type); | 551 | device_remove_file(&cdev->device, &dev_attr_cdev_type); |
618 | device_remove_file(&cdev->device, &dev_attr_max_state); | 552 | device_remove_file(&cdev->device, &dev_attr_max_state); |
619 | device_remove_file(&cdev->device, &dev_attr_cur_state); | 553 | device_remove_file(&cdev->device, &dev_attr_cur_state); |
620 | 554 | ||
@@ -646,9 +580,6 @@ struct thermal_zone_device *thermal_zone_device_register(char *type, | |||
646 | int result; | 580 | int result; |
647 | int count; | 581 | int count; |
648 | 582 | ||
649 | if (!type) | ||
650 | return ERR_PTR(-EINVAL); | ||
651 | |||
652 | if (strlen(type) >= THERMAL_NAME_LENGTH) | 583 | if (strlen(type) >= THERMAL_NAME_LENGTH) |
653 | return ERR_PTR(-EINVAL); | 584 | return ERR_PTR(-EINVAL); |
654 | 585 | ||
@@ -670,13 +601,6 @@ struct thermal_zone_device *thermal_zone_device_register(char *type, | |||
670 | kfree(tz); | 601 | kfree(tz); |
671 | return ERR_PTR(result); | 602 | return ERR_PTR(result); |
672 | } | 603 | } |
673 | if (tz->id >= MAX_THERMAL_ZONES) { | ||
674 | printk(KERN_ERR PREFIX | ||
675 | "Too many thermal zones\n"); | ||
676 | release_idr(&thermal_tz_idr, &thermal_idr_lock, tz->id); | ||
677 | kfree(tz); | ||
678 | return ERR_PTR(-EINVAL); | ||
679 | } | ||
680 | 604 | ||
681 | strcpy(tz->type, type); | 605 | strcpy(tz->type, type); |
682 | tz->ops = ops; | 606 | tz->ops = ops; |
@@ -691,27 +615,12 @@ struct thermal_zone_device *thermal_zone_device_register(char *type, | |||
691 | return ERR_PTR(result); | 615 | return ERR_PTR(result); |
692 | } | 616 | } |
693 | 617 | ||
694 | /* hwmon sys I/F */ | ||
695 | result = device_create_file(thermal_hwmon, | ||
696 | &sensor_attrs[tz->id * 2].dev_attr); | ||
697 | if (result) | ||
698 | goto unregister; | ||
699 | |||
700 | if (trips > 0) { | ||
701 | char buf[40]; | ||
702 | result = tz->ops->get_trip_type(tz, 0, buf); | ||
703 | if (result > 0 && !strcmp(buf, "critical\n")) { | ||
704 | result = device_create_file(thermal_hwmon, | ||
705 | &sensor_attrs[tz->id * 2 + 1].dev_attr); | ||
706 | if (result) | ||
707 | goto unregister; | ||
708 | } | ||
709 | } | ||
710 | |||
711 | /* sys I/F */ | 618 | /* sys I/F */ |
712 | result = device_create_file(&tz->device, &dev_attr_type); | 619 | if (type) { |
713 | if (result) | 620 | result = device_create_file(&tz->device, &dev_attr_type); |
714 | goto unregister; | 621 | if (result) |
622 | goto unregister; | ||
623 | } | ||
715 | 624 | ||
716 | result = device_create_file(&tz->device, &dev_attr_temp); | 625 | result = device_create_file(&tz->device, &dev_attr_temp); |
717 | if (result) | 626 | if (result) |
@@ -778,17 +687,8 @@ void thermal_zone_device_unregister(struct thermal_zone_device *tz) | |||
778 | tz->ops->unbind(tz, cdev); | 687 | tz->ops->unbind(tz, cdev); |
779 | mutex_unlock(&thermal_list_lock); | 688 | mutex_unlock(&thermal_list_lock); |
780 | 689 | ||
781 | device_remove_file(thermal_hwmon, | 690 | if (tz->type[0]) |
782 | &sensor_attrs[tz->id * 2].dev_attr); | 691 | device_remove_file(&tz->device, &dev_attr_type); |
783 | if (tz->trips > 0) { | ||
784 | char buf[40]; | ||
785 | if (tz->ops->get_trip_type(tz, 0, buf) > 0) | ||
786 | if (!strcmp(buf, "critical\n")) | ||
787 | device_remove_file(thermal_hwmon, | ||
788 | &sensor_attrs[tz->id * 2 + 1].dev_attr); | ||
789 | } | ||
790 | |||
791 | device_remove_file(&tz->device, &dev_attr_type); | ||
792 | device_remove_file(&tz->device, &dev_attr_temp); | 692 | device_remove_file(&tz->device, &dev_attr_temp); |
793 | if (tz->ops->get_mode) | 693 | if (tz->ops->get_mode) |
794 | device_remove_file(&tz->device, &dev_attr_mode); | 694 | device_remove_file(&tz->device, &dev_attr_mode); |
@@ -805,19 +705,6 @@ void thermal_zone_device_unregister(struct thermal_zone_device *tz) | |||
805 | 705 | ||
806 | EXPORT_SYMBOL(thermal_zone_device_unregister); | 706 | EXPORT_SYMBOL(thermal_zone_device_unregister); |
807 | 707 | ||
808 | static void thermal_exit(void) | ||
809 | { | ||
810 | if (thermal_hwmon) { | ||
811 | device_remove_file(thermal_hwmon, &dev_attr_name); | ||
812 | hwmon_device_unregister(thermal_hwmon); | ||
813 | } | ||
814 | class_unregister(&thermal_class); | ||
815 | idr_destroy(&thermal_tz_idr); | ||
816 | idr_destroy(&thermal_cdev_idr); | ||
817 | mutex_destroy(&thermal_idr_lock); | ||
818 | mutex_destroy(&thermal_list_lock); | ||
819 | } | ||
820 | |||
821 | static int __init thermal_init(void) | 708 | static int __init thermal_init(void) |
822 | { | 709 | { |
823 | int result = 0; | 710 | int result = 0; |
@@ -829,21 +716,17 @@ static int __init thermal_init(void) | |||
829 | mutex_destroy(&thermal_idr_lock); | 716 | mutex_destroy(&thermal_idr_lock); |
830 | mutex_destroy(&thermal_list_lock); | 717 | mutex_destroy(&thermal_list_lock); |
831 | } | 718 | } |
832 | |||
833 | thermal_hwmon = hwmon_device_register(NULL); | ||
834 | if (IS_ERR(thermal_hwmon)) { | ||
835 | result = PTR_ERR(thermal_hwmon); | ||
836 | thermal_hwmon = NULL; | ||
837 | printk(KERN_ERR PREFIX | ||
838 | "unable to register hwmon device\n"); | ||
839 | thermal_exit(); | ||
840 | return result; | ||
841 | } | ||
842 | |||
843 | result = device_create_file(thermal_hwmon, &dev_attr_name); | ||
844 | |||
845 | return result; | 719 | return result; |
846 | } | 720 | } |
847 | 721 | ||
722 | static void __exit thermal_exit(void) | ||
723 | { | ||
724 | class_unregister(&thermal_class); | ||
725 | idr_destroy(&thermal_tz_idr); | ||
726 | idr_destroy(&thermal_cdev_idr); | ||
727 | mutex_destroy(&thermal_idr_lock); | ||
728 | mutex_destroy(&thermal_list_lock); | ||
729 | } | ||
730 | |||
848 | subsys_initcall(thermal_init); | 731 | subsys_initcall(thermal_init); |
849 | module_exit(thermal_exit); | 732 | module_exit(thermal_exit); |
diff --git a/drivers/virtio/virtio_balloon.c b/drivers/virtio/virtio_balloon.c index c8a4332d1132..0b3efc31ee6d 100644 --- a/drivers/virtio/virtio_balloon.c +++ b/drivers/virtio/virtio_balloon.c | |||
@@ -152,7 +152,7 @@ static void virtballoon_changed(struct virtio_device *vdev) | |||
152 | wake_up(&vb->config_change); | 152 | wake_up(&vb->config_change); |
153 | } | 153 | } |
154 | 154 | ||
155 | static inline int towards_target(struct virtio_balloon *vb) | 155 | static inline s64 towards_target(struct virtio_balloon *vb) |
156 | { | 156 | { |
157 | u32 v; | 157 | u32 v; |
158 | __virtio_config_val(vb->vdev, | 158 | __virtio_config_val(vb->vdev, |
@@ -176,7 +176,7 @@ static int balloon(void *_vballoon) | |||
176 | 176 | ||
177 | set_freezable(); | 177 | set_freezable(); |
178 | while (!kthread_should_stop()) { | 178 | while (!kthread_should_stop()) { |
179 | int diff; | 179 | s64 diff; |
180 | 180 | ||
181 | try_to_freeze(); | 181 | try_to_freeze(); |
182 | wait_event_interruptible(vb->config_change, | 182 | wait_event_interruptible(vb->config_change, |
diff --git a/drivers/virtio/virtio_pci.c b/drivers/virtio/virtio_pci.c index 26f787ddd5ff..59a8f73dec73 100644 --- a/drivers/virtio/virtio_pci.c +++ b/drivers/virtio/virtio_pci.c | |||
@@ -177,6 +177,7 @@ static irqreturn_t vp_interrupt(int irq, void *opaque) | |||
177 | struct virtio_pci_device *vp_dev = opaque; | 177 | struct virtio_pci_device *vp_dev = opaque; |
178 | struct virtio_pci_vq_info *info; | 178 | struct virtio_pci_vq_info *info; |
179 | irqreturn_t ret = IRQ_NONE; | 179 | irqreturn_t ret = IRQ_NONE; |
180 | unsigned long flags; | ||
180 | u8 isr; | 181 | u8 isr; |
181 | 182 | ||
182 | /* reading the ISR has the effect of also clearing it so it's very | 183 | /* reading the ISR has the effect of also clearing it so it's very |
@@ -197,12 +198,12 @@ static irqreturn_t vp_interrupt(int irq, void *opaque) | |||
197 | drv->config_changed(&vp_dev->vdev); | 198 | drv->config_changed(&vp_dev->vdev); |
198 | } | 199 | } |
199 | 200 | ||
200 | spin_lock(&vp_dev->lock); | 201 | spin_lock_irqsave(&vp_dev->lock, flags); |
201 | list_for_each_entry(info, &vp_dev->virtqueues, node) { | 202 | list_for_each_entry(info, &vp_dev->virtqueues, node) { |
202 | if (vring_interrupt(irq, info->vq) == IRQ_HANDLED) | 203 | if (vring_interrupt(irq, info->vq) == IRQ_HANDLED) |
203 | ret = IRQ_HANDLED; | 204 | ret = IRQ_HANDLED; |
204 | } | 205 | } |
205 | spin_unlock(&vp_dev->lock); | 206 | spin_unlock_irqrestore(&vp_dev->lock, flags); |
206 | 207 | ||
207 | return ret; | 208 | return ret; |
208 | } | 209 | } |
@@ -214,6 +215,7 @@ static struct virtqueue *vp_find_vq(struct virtio_device *vdev, unsigned index, | |||
214 | struct virtio_pci_device *vp_dev = to_vp_device(vdev); | 215 | struct virtio_pci_device *vp_dev = to_vp_device(vdev); |
215 | struct virtio_pci_vq_info *info; | 216 | struct virtio_pci_vq_info *info; |
216 | struct virtqueue *vq; | 217 | struct virtqueue *vq; |
218 | unsigned long flags; | ||
217 | u16 num; | 219 | u16 num; |
218 | int err; | 220 | int err; |
219 | 221 | ||
@@ -255,9 +257,9 @@ static struct virtqueue *vp_find_vq(struct virtio_device *vdev, unsigned index, | |||
255 | vq->priv = info; | 257 | vq->priv = info; |
256 | info->vq = vq; | 258 | info->vq = vq; |
257 | 259 | ||
258 | spin_lock(&vp_dev->lock); | 260 | spin_lock_irqsave(&vp_dev->lock, flags); |
259 | list_add(&info->node, &vp_dev->virtqueues); | 261 | list_add(&info->node, &vp_dev->virtqueues); |
260 | spin_unlock(&vp_dev->lock); | 262 | spin_unlock_irqrestore(&vp_dev->lock, flags); |
261 | 263 | ||
262 | return vq; | 264 | return vq; |
263 | 265 | ||
@@ -274,10 +276,11 @@ static void vp_del_vq(struct virtqueue *vq) | |||
274 | { | 276 | { |
275 | struct virtio_pci_device *vp_dev = to_vp_device(vq->vdev); | 277 | struct virtio_pci_device *vp_dev = to_vp_device(vq->vdev); |
276 | struct virtio_pci_vq_info *info = vq->priv; | 278 | struct virtio_pci_vq_info *info = vq->priv; |
279 | unsigned long flags; | ||
277 | 280 | ||
278 | spin_lock(&vp_dev->lock); | 281 | spin_lock_irqsave(&vp_dev->lock, flags); |
279 | list_del(&info->node); | 282 | list_del(&info->node); |
280 | spin_unlock(&vp_dev->lock); | 283 | spin_unlock_irqrestore(&vp_dev->lock, flags); |
281 | 284 | ||
282 | vring_del_virtqueue(vq); | 285 | vring_del_virtqueue(vq); |
283 | 286 | ||
diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c index 3a28c1382131..aa714028641e 100644 --- a/drivers/virtio/virtio_ring.c +++ b/drivers/virtio/virtio_ring.c | |||
@@ -232,7 +232,6 @@ static bool vring_enable_cb(struct virtqueue *_vq) | |||
232 | vq->vring.avail->flags &= ~VRING_AVAIL_F_NO_INTERRUPT; | 232 | vq->vring.avail->flags &= ~VRING_AVAIL_F_NO_INTERRUPT; |
233 | mb(); | 233 | mb(); |
234 | if (unlikely(more_used(vq))) { | 234 | if (unlikely(more_used(vq))) { |
235 | vq->vring.avail->flags |= VRING_AVAIL_F_NO_INTERRUPT; | ||
236 | END_USE(vq); | 235 | END_USE(vq); |
237 | return false; | 236 | return false; |
238 | } | 237 | } |