diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/input/joystick/iforce/iforce-main.c | 6 | ||||
-rw-r--r-- | drivers/input/joystick/iforce/iforce-usb.c | 1 | ||||
-rw-r--r-- | drivers/input/mouse/elantech.c | 24 | ||||
-rw-r--r-- | drivers/input/mouse/elantech.h | 5 | ||||
-rw-r--r-- | drivers/input/mouse/psmouse-base.c | 14 | ||||
-rw-r--r-- | drivers/input/touchscreen/ad7877.c | 15 | ||||
-rw-r--r-- | drivers/pci/setup-bus.c | 114 | ||||
-rw-r--r-- | drivers/s390/block/dasd.c | 17 |
8 files changed, 54 insertions, 142 deletions
diff --git a/drivers/input/joystick/iforce/iforce-main.c b/drivers/input/joystick/iforce/iforce-main.c index b1edd778639c..405febd94f24 100644 --- a/drivers/input/joystick/iforce/iforce-main.c +++ b/drivers/input/joystick/iforce/iforce-main.c | |||
@@ -54,6 +54,9 @@ static signed short btn_avb_wheel[] = | |||
54 | static signed short abs_joystick[] = | 54 | static signed short abs_joystick[] = |
55 | { ABS_X, ABS_Y, ABS_THROTTLE, ABS_HAT0X, ABS_HAT0Y, -1 }; | 55 | { ABS_X, ABS_Y, ABS_THROTTLE, ABS_HAT0X, ABS_HAT0Y, -1 }; |
56 | 56 | ||
57 | static signed short abs_joystick_rudder[] = | ||
58 | { ABS_X, ABS_Y, ABS_THROTTLE, ABS_RUDDER, ABS_HAT0X, ABS_HAT0Y, -1 }; | ||
59 | |||
57 | static signed short abs_avb_pegasus[] = | 60 | static signed short abs_avb_pegasus[] = |
58 | { ABS_X, ABS_Y, ABS_THROTTLE, ABS_RUDDER, ABS_HAT0X, ABS_HAT0Y, | 61 | { ABS_X, ABS_Y, ABS_THROTTLE, ABS_RUDDER, ABS_HAT0X, ABS_HAT0Y, |
59 | ABS_HAT1X, ABS_HAT1Y, -1 }; | 62 | ABS_HAT1X, ABS_HAT1Y, -1 }; |
@@ -76,8 +79,9 @@ static struct iforce_device iforce_device[] = { | |||
76 | { 0x061c, 0xc0a4, "ACT LABS Force RS", btn_wheel, abs_wheel, ff_iforce }, //? | 79 | { 0x061c, 0xc0a4, "ACT LABS Force RS", btn_wheel, abs_wheel, ff_iforce }, //? |
77 | { 0x061c, 0xc084, "ACT LABS Force RS", btn_wheel, abs_wheel, ff_iforce }, | 80 | { 0x061c, 0xc084, "ACT LABS Force RS", btn_wheel, abs_wheel, ff_iforce }, |
78 | { 0x06f8, 0x0001, "Guillemot Race Leader Force Feedback", btn_wheel, abs_wheel, ff_iforce }, //? | 81 | { 0x06f8, 0x0001, "Guillemot Race Leader Force Feedback", btn_wheel, abs_wheel, ff_iforce }, //? |
82 | { 0x06f8, 0x0001, "Guillemot Jet Leader Force Feedback", btn_joystick, abs_joystick_rudder, ff_iforce }, | ||
79 | { 0x06f8, 0x0004, "Guillemot Force Feedback Racing Wheel", btn_wheel, abs_wheel, ff_iforce }, //? | 83 | { 0x06f8, 0x0004, "Guillemot Force Feedback Racing Wheel", btn_wheel, abs_wheel, ff_iforce }, //? |
80 | { 0x06f8, 0x0004, "Gullemot Jet Leader 3D", btn_joystick, abs_joystick, ff_iforce }, //? | 84 | { 0x06f8, 0xa302, "Guillemot Jet Leader 3D", btn_joystick, abs_joystick, ff_iforce }, //? |
81 | { 0x06d6, 0x29bc, "Trust Force Feedback Race Master", btn_wheel, abs_wheel, ff_iforce }, | 85 | { 0x06d6, 0x29bc, "Trust Force Feedback Race Master", btn_wheel, abs_wheel, ff_iforce }, |
82 | { 0x0000, 0x0000, "Unknown I-Force Device [%04x:%04x]", btn_joystick, abs_joystick, ff_iforce } | 86 | { 0x0000, 0x0000, "Unknown I-Force Device [%04x:%04x]", btn_joystick, abs_joystick, ff_iforce } |
83 | }; | 87 | }; |
diff --git a/drivers/input/joystick/iforce/iforce-usb.c b/drivers/input/joystick/iforce/iforce-usb.c index b41303d3ec54..6c96631ae5d9 100644 --- a/drivers/input/joystick/iforce/iforce-usb.c +++ b/drivers/input/joystick/iforce/iforce-usb.c | |||
@@ -212,6 +212,7 @@ static struct usb_device_id iforce_usb_ids [] = { | |||
212 | { USB_DEVICE(0x061c, 0xc0a4) }, /* ACT LABS Force RS */ | 212 | { USB_DEVICE(0x061c, 0xc0a4) }, /* ACT LABS Force RS */ |
213 | { USB_DEVICE(0x061c, 0xc084) }, /* ACT LABS Force RS */ | 213 | { USB_DEVICE(0x061c, 0xc084) }, /* ACT LABS Force RS */ |
214 | { USB_DEVICE(0x06f8, 0x0001) }, /* Guillemot Race Leader Force Feedback */ | 214 | { USB_DEVICE(0x06f8, 0x0001) }, /* Guillemot Race Leader Force Feedback */ |
215 | { USB_DEVICE(0x06f8, 0x0003) }, /* Guillemot Jet Leader Force Feedback */ | ||
215 | { USB_DEVICE(0x06f8, 0x0004) }, /* Guillemot Force Feedback Racing Wheel */ | 216 | { USB_DEVICE(0x06f8, 0x0004) }, /* Guillemot Force Feedback Racing Wheel */ |
216 | { USB_DEVICE(0x06f8, 0xa302) }, /* Guillemot Jet Leader 3D */ | 217 | { USB_DEVICE(0x06f8, 0xa302) }, /* Guillemot Jet Leader 3D */ |
217 | { } /* Terminating entry */ | 218 | { } /* Terminating entry */ |
diff --git a/drivers/input/mouse/elantech.c b/drivers/input/mouse/elantech.c index 0520c2e19927..112b4ee52ff2 100644 --- a/drivers/input/mouse/elantech.c +++ b/drivers/input/mouse/elantech.c | |||
@@ -185,7 +185,7 @@ static void elantech_report_absolute_v1(struct psmouse *psmouse) | |||
185 | int fingers; | 185 | int fingers; |
186 | static int old_fingers; | 186 | static int old_fingers; |
187 | 187 | ||
188 | if (etd->fw_version_maj == 0x01) { | 188 | if (etd->fw_version < 0x020000) { |
189 | /* | 189 | /* |
190 | * byte 0: D U p1 p2 1 p3 R L | 190 | * byte 0: D U p1 p2 1 p3 R L |
191 | * byte 1: f 0 th tw x9 x8 y9 y8 | 191 | * byte 1: f 0 th tw x9 x8 y9 y8 |
@@ -227,7 +227,7 @@ static void elantech_report_absolute_v1(struct psmouse *psmouse) | |||
227 | input_report_key(dev, BTN_LEFT, packet[0] & 0x01); | 227 | input_report_key(dev, BTN_LEFT, packet[0] & 0x01); |
228 | input_report_key(dev, BTN_RIGHT, packet[0] & 0x02); | 228 | input_report_key(dev, BTN_RIGHT, packet[0] & 0x02); |
229 | 229 | ||
230 | if ((etd->fw_version_maj == 0x01) && | 230 | if (etd->fw_version < 0x020000 && |
231 | (etd->capabilities & ETP_CAP_HAS_ROCKER)) { | 231 | (etd->capabilities & ETP_CAP_HAS_ROCKER)) { |
232 | /* rocker up */ | 232 | /* rocker up */ |
233 | input_report_key(dev, BTN_FORWARD, packet[0] & 0x40); | 233 | input_report_key(dev, BTN_FORWARD, packet[0] & 0x40); |
@@ -321,7 +321,7 @@ static int elantech_check_parity_v1(struct psmouse *psmouse) | |||
321 | unsigned char p1, p2, p3; | 321 | unsigned char p1, p2, p3; |
322 | 322 | ||
323 | /* Parity bits are placed differently */ | 323 | /* Parity bits are placed differently */ |
324 | if (etd->fw_version_maj == 0x01) { | 324 | if (etd->fw_version < 0x020000) { |
325 | /* byte 0: D U p1 p2 1 p3 R L */ | 325 | /* byte 0: D U p1 p2 1 p3 R L */ |
326 | p1 = (packet[0] & 0x20) >> 5; | 326 | p1 = (packet[0] & 0x20) >> 5; |
327 | p2 = (packet[0] & 0x10) >> 4; | 327 | p2 = (packet[0] & 0x10) >> 4; |
@@ -457,7 +457,7 @@ static void elantech_set_input_params(struct psmouse *psmouse) | |||
457 | switch (etd->hw_version) { | 457 | switch (etd->hw_version) { |
458 | case 1: | 458 | case 1: |
459 | /* Rocker button */ | 459 | /* Rocker button */ |
460 | if ((etd->fw_version_maj == 0x01) && | 460 | if (etd->fw_version < 0x020000 && |
461 | (etd->capabilities & ETP_CAP_HAS_ROCKER)) { | 461 | (etd->capabilities & ETP_CAP_HAS_ROCKER)) { |
462 | __set_bit(BTN_FORWARD, dev->keybit); | 462 | __set_bit(BTN_FORWARD, dev->keybit); |
463 | __set_bit(BTN_BACK, dev->keybit); | 463 | __set_bit(BTN_BACK, dev->keybit); |
@@ -686,15 +686,14 @@ int elantech_init(struct psmouse *psmouse) | |||
686 | pr_err("elantech.c: failed to query firmware version.\n"); | 686 | pr_err("elantech.c: failed to query firmware version.\n"); |
687 | goto init_fail; | 687 | goto init_fail; |
688 | } | 688 | } |
689 | etd->fw_version_maj = param[0]; | 689 | |
690 | etd->fw_version_min = param[2]; | 690 | etd->fw_version = (param[0] << 16) | (param[1] << 8) | param[2]; |
691 | 691 | ||
692 | /* | 692 | /* |
693 | * Assume every version greater than this is new EeePC style | 693 | * Assume every version greater than this is new EeePC style |
694 | * hardware with 6 byte packets | 694 | * hardware with 6 byte packets |
695 | */ | 695 | */ |
696 | if ((etd->fw_version_maj == 0x02 && etd->fw_version_min >= 0x30) || | 696 | if (etd->fw_version >= 0x020030) { |
697 | etd->fw_version_maj > 0x02) { | ||
698 | etd->hw_version = 2; | 697 | etd->hw_version = 2; |
699 | /* For now show extra debug information */ | 698 | /* For now show extra debug information */ |
700 | etd->debug = 1; | 699 | etd->debug = 1; |
@@ -704,8 +703,9 @@ int elantech_init(struct psmouse *psmouse) | |||
704 | etd->hw_version = 1; | 703 | etd->hw_version = 1; |
705 | etd->paritycheck = 1; | 704 | etd->paritycheck = 1; |
706 | } | 705 | } |
707 | pr_info("elantech.c: assuming hardware version %d, firmware version %d.%d\n", | 706 | |
708 | etd->hw_version, etd->fw_version_maj, etd->fw_version_min); | 707 | pr_info("elantech.c: assuming hardware version %d, firmware version %d.%d.%d\n", |
708 | etd->hw_version, param[0], param[1], param[2]); | ||
709 | 709 | ||
710 | if (synaptics_send_cmd(psmouse, ETP_CAPABILITIES_QUERY, param)) { | 710 | if (synaptics_send_cmd(psmouse, ETP_CAPABILITIES_QUERY, param)) { |
711 | pr_err("elantech.c: failed to query capabilities.\n"); | 711 | pr_err("elantech.c: failed to query capabilities.\n"); |
@@ -720,8 +720,8 @@ int elantech_init(struct psmouse *psmouse) | |||
720 | * a touch action starts causing the mouse cursor or scrolled page | 720 | * a touch action starts causing the mouse cursor or scrolled page |
721 | * to jump. Enable a workaround. | 721 | * to jump. Enable a workaround. |
722 | */ | 722 | */ |
723 | if (etd->fw_version_maj == 0x02 && etd->fw_version_min == 0x22) { | 723 | if (etd->fw_version == 0x020022) { |
724 | pr_info("elantech.c: firmware version 2.34 detected, " | 724 | pr_info("elantech.c: firmware version 2.0.34 detected, " |
725 | "enabling jumpy cursor workaround\n"); | 725 | "enabling jumpy cursor workaround\n"); |
726 | etd->jumpy_cursor = 1; | 726 | etd->jumpy_cursor = 1; |
727 | } | 727 | } |
diff --git a/drivers/input/mouse/elantech.h b/drivers/input/mouse/elantech.h index feac5f7af966..ac57bde1bb9f 100644 --- a/drivers/input/mouse/elantech.h +++ b/drivers/input/mouse/elantech.h | |||
@@ -100,11 +100,10 @@ struct elantech_data { | |||
100 | unsigned char reg_26; | 100 | unsigned char reg_26; |
101 | unsigned char debug; | 101 | unsigned char debug; |
102 | unsigned char capabilities; | 102 | unsigned char capabilities; |
103 | unsigned char fw_version_maj; | ||
104 | unsigned char fw_version_min; | ||
105 | unsigned char hw_version; | ||
106 | unsigned char paritycheck; | 103 | unsigned char paritycheck; |
107 | unsigned char jumpy_cursor; | 104 | unsigned char jumpy_cursor; |
105 | unsigned char hw_version; | ||
106 | unsigned int fw_version; | ||
108 | unsigned char parity[256]; | 107 | unsigned char parity[256]; |
109 | }; | 108 | }; |
110 | 109 | ||
diff --git a/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c index cbc807264940..a3c97315a473 100644 --- a/drivers/input/mouse/psmouse-base.c +++ b/drivers/input/mouse/psmouse-base.c | |||
@@ -1394,6 +1394,7 @@ static int psmouse_reconnect(struct serio *serio) | |||
1394 | struct psmouse *psmouse = serio_get_drvdata(serio); | 1394 | struct psmouse *psmouse = serio_get_drvdata(serio); |
1395 | struct psmouse *parent = NULL; | 1395 | struct psmouse *parent = NULL; |
1396 | struct serio_driver *drv = serio->drv; | 1396 | struct serio_driver *drv = serio->drv; |
1397 | unsigned char type; | ||
1397 | int rc = -1; | 1398 | int rc = -1; |
1398 | 1399 | ||
1399 | if (!drv || !psmouse) { | 1400 | if (!drv || !psmouse) { |
@@ -1413,10 +1414,15 @@ static int psmouse_reconnect(struct serio *serio) | |||
1413 | if (psmouse->reconnect) { | 1414 | if (psmouse->reconnect) { |
1414 | if (psmouse->reconnect(psmouse)) | 1415 | if (psmouse->reconnect(psmouse)) |
1415 | goto out; | 1416 | goto out; |
1416 | } else if (psmouse_probe(psmouse) < 0 || | 1417 | } else { |
1417 | psmouse->type != psmouse_extensions(psmouse, | 1418 | psmouse_reset(psmouse); |
1418 | psmouse_max_proto, false)) { | 1419 | |
1419 | goto out; | 1420 | if (psmouse_probe(psmouse) < 0) |
1421 | goto out; | ||
1422 | |||
1423 | type = psmouse_extensions(psmouse, psmouse_max_proto, false); | ||
1424 | if (psmouse->type != type) | ||
1425 | goto out; | ||
1420 | } | 1426 | } |
1421 | 1427 | ||
1422 | /* ok, the device type (and capabilities) match the old one, | 1428 | /* ok, the device type (and capabilities) match the old one, |
diff --git a/drivers/input/touchscreen/ad7877.c b/drivers/input/touchscreen/ad7877.c index e019d53d1ab4..0d2d7e54b465 100644 --- a/drivers/input/touchscreen/ad7877.c +++ b/drivers/input/touchscreen/ad7877.c | |||
@@ -156,9 +156,14 @@ struct ser_req { | |||
156 | u16 reset; | 156 | u16 reset; |
157 | u16 ref_on; | 157 | u16 ref_on; |
158 | u16 command; | 158 | u16 command; |
159 | u16 sample; | ||
160 | struct spi_message msg; | 159 | struct spi_message msg; |
161 | struct spi_transfer xfer[6]; | 160 | struct spi_transfer xfer[6]; |
161 | |||
162 | /* | ||
163 | * DMA (thus cache coherency maintenance) requires the | ||
164 | * transfer buffers to live in their own cache lines. | ||
165 | */ | ||
166 | u16 sample ____cacheline_aligned; | ||
162 | }; | 167 | }; |
163 | 168 | ||
164 | struct ad7877 { | 169 | struct ad7877 { |
@@ -182,8 +187,6 @@ struct ad7877 { | |||
182 | u8 averaging; | 187 | u8 averaging; |
183 | u8 pen_down_acc_interval; | 188 | u8 pen_down_acc_interval; |
184 | 189 | ||
185 | u16 conversion_data[AD7877_NR_SENSE]; | ||
186 | |||
187 | struct spi_transfer xfer[AD7877_NR_SENSE + 2]; | 190 | struct spi_transfer xfer[AD7877_NR_SENSE + 2]; |
188 | struct spi_message msg; | 191 | struct spi_message msg; |
189 | 192 | ||
@@ -195,6 +198,12 @@ struct ad7877 { | |||
195 | spinlock_t lock; | 198 | spinlock_t lock; |
196 | struct timer_list timer; /* P: lock */ | 199 | struct timer_list timer; /* P: lock */ |
197 | unsigned pending:1; /* P: lock */ | 200 | unsigned pending:1; /* P: lock */ |
201 | |||
202 | /* | ||
203 | * DMA (thus cache coherency maintenance) requires the | ||
204 | * transfer buffers to live in their own cache lines. | ||
205 | */ | ||
206 | u16 conversion_data[AD7877_NR_SENSE] ____cacheline_aligned; | ||
198 | }; | 207 | }; |
199 | 208 | ||
200 | static int gpio3; | 209 | static int gpio3; |
diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c index 4fe36d2e1049..19b111383f62 100644 --- a/drivers/pci/setup-bus.c +++ b/drivers/pci/setup-bus.c | |||
@@ -838,65 +838,11 @@ static void pci_bus_dump_resources(struct pci_bus *bus) | |||
838 | } | 838 | } |
839 | } | 839 | } |
840 | 840 | ||
841 | static int __init pci_bus_get_depth(struct pci_bus *bus) | ||
842 | { | ||
843 | int depth = 0; | ||
844 | struct pci_dev *dev; | ||
845 | |||
846 | list_for_each_entry(dev, &bus->devices, bus_list) { | ||
847 | int ret; | ||
848 | struct pci_bus *b = dev->subordinate; | ||
849 | if (!b) | ||
850 | continue; | ||
851 | |||
852 | ret = pci_bus_get_depth(b); | ||
853 | if (ret + 1 > depth) | ||
854 | depth = ret + 1; | ||
855 | } | ||
856 | |||
857 | return depth; | ||
858 | } | ||
859 | static int __init pci_get_max_depth(void) | ||
860 | { | ||
861 | int depth = 0; | ||
862 | struct pci_bus *bus; | ||
863 | |||
864 | list_for_each_entry(bus, &pci_root_buses, node) { | ||
865 | int ret; | ||
866 | |||
867 | ret = pci_bus_get_depth(bus); | ||
868 | if (ret > depth) | ||
869 | depth = ret; | ||
870 | } | ||
871 | |||
872 | return depth; | ||
873 | } | ||
874 | |||
875 | /* | ||
876 | * first try will not touch pci bridge res | ||
877 | * second and later try will clear small leaf bridge res | ||
878 | * will stop till to the max deepth if can not find good one | ||
879 | */ | ||
880 | void __init | 841 | void __init |
881 | pci_assign_unassigned_resources(void) | 842 | pci_assign_unassigned_resources(void) |
882 | { | 843 | { |
883 | struct pci_bus *bus; | 844 | struct pci_bus *bus; |
884 | int tried_times = 0; | ||
885 | enum release_type rel_type = leaf_only; | ||
886 | struct resource_list_x head, *list; | ||
887 | unsigned long type_mask = IORESOURCE_IO | IORESOURCE_MEM | | ||
888 | IORESOURCE_PREFETCH; | ||
889 | unsigned long failed_type; | ||
890 | int max_depth = pci_get_max_depth(); | ||
891 | int pci_try_num; | ||
892 | 845 | ||
893 | head.next = NULL; | ||
894 | |||
895 | pci_try_num = max_depth + 1; | ||
896 | printk(KERN_DEBUG "PCI: max bus depth: %d pci_try_num: %d\n", | ||
897 | max_depth, pci_try_num); | ||
898 | |||
899 | again: | ||
900 | /* Depth first, calculate sizes and alignments of all | 846 | /* Depth first, calculate sizes and alignments of all |
901 | subordinate buses. */ | 847 | subordinate buses. */ |
902 | list_for_each_entry(bus, &pci_root_buses, node) { | 848 | list_for_each_entry(bus, &pci_root_buses, node) { |
@@ -904,65 +850,9 @@ again: | |||
904 | } | 850 | } |
905 | /* Depth last, allocate resources and update the hardware. */ | 851 | /* Depth last, allocate resources and update the hardware. */ |
906 | list_for_each_entry(bus, &pci_root_buses, node) { | 852 | list_for_each_entry(bus, &pci_root_buses, node) { |
907 | __pci_bus_assign_resources(bus, &head); | 853 | pci_bus_assign_resources(bus); |
908 | } | ||
909 | tried_times++; | ||
910 | |||
911 | /* any device complain? */ | ||
912 | if (!head.next) | ||
913 | goto enable_and_dump; | ||
914 | failed_type = 0; | ||
915 | for (list = head.next; list;) { | ||
916 | failed_type |= list->flags; | ||
917 | list = list->next; | ||
918 | } | ||
919 | /* | ||
920 | * io port are tight, don't try extra | ||
921 | * or if reach the limit, don't want to try more | ||
922 | */ | ||
923 | failed_type &= type_mask; | ||
924 | if ((failed_type == IORESOURCE_IO) || (tried_times >= pci_try_num)) { | ||
925 | free_failed_list(&head); | ||
926 | goto enable_and_dump; | ||
927 | } | ||
928 | |||
929 | printk(KERN_DEBUG "PCI: No. %d try to assign unassigned res\n", | ||
930 | tried_times + 1); | ||
931 | |||
932 | /* third times and later will not check if it is leaf */ | ||
933 | if ((tried_times + 1) > 2) | ||
934 | rel_type = whole_subtree; | ||
935 | |||
936 | /* | ||
937 | * Try to release leaf bridge's resources that doesn't fit resource of | ||
938 | * child device under that bridge | ||
939 | */ | ||
940 | for (list = head.next; list;) { | ||
941 | bus = list->dev->bus; | ||
942 | pci_bus_release_bridge_resources(bus, list->flags & type_mask, | ||
943 | rel_type); | ||
944 | list = list->next; | ||
945 | } | ||
946 | /* restore size and flags */ | ||
947 | for (list = head.next; list;) { | ||
948 | struct resource *res = list->res; | ||
949 | |||
950 | res->start = list->start; | ||
951 | res->end = list->end; | ||
952 | res->flags = list->flags; | ||
953 | if (list->dev->subordinate) | ||
954 | res->flags = 0; | ||
955 | |||
956 | list = list->next; | ||
957 | } | ||
958 | free_failed_list(&head); | ||
959 | |||
960 | goto again; | ||
961 | |||
962 | enable_and_dump: | ||
963 | /* Depth last, update the hardware. */ | ||
964 | list_for_each_entry(bus, &pci_root_buses, node) | ||
965 | pci_enable_bridges(bus); | 854 | pci_enable_bridges(bus); |
855 | } | ||
966 | 856 | ||
967 | /* dump the resource on buses */ | 857 | /* dump the resource on buses */ |
968 | list_for_each_entry(bus, &pci_root_buses, node) { | 858 | list_for_each_entry(bus, &pci_root_buses, node) { |
diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c index acf222f91f5a..fa2339cb1681 100644 --- a/drivers/s390/block/dasd.c +++ b/drivers/s390/block/dasd.c | |||
@@ -37,6 +37,9 @@ | |||
37 | */ | 37 | */ |
38 | #define DASD_CHANQ_MAX_SIZE 4 | 38 | #define DASD_CHANQ_MAX_SIZE 4 |
39 | 39 | ||
40 | #define DASD_SLEEPON_START_TAG (void *) 1 | ||
41 | #define DASD_SLEEPON_END_TAG (void *) 2 | ||
42 | |||
40 | /* | 43 | /* |
41 | * SECTION: exported variables of dasd.c | 44 | * SECTION: exported variables of dasd.c |
42 | */ | 45 | */ |
@@ -1472,7 +1475,10 @@ void dasd_add_request_tail(struct dasd_ccw_req *cqr) | |||
1472 | */ | 1475 | */ |
1473 | static void dasd_wakeup_cb(struct dasd_ccw_req *cqr, void *data) | 1476 | static void dasd_wakeup_cb(struct dasd_ccw_req *cqr, void *data) |
1474 | { | 1477 | { |
1475 | wake_up((wait_queue_head_t *) data); | 1478 | spin_lock_irq(get_ccwdev_lock(cqr->startdev->cdev)); |
1479 | cqr->callback_data = DASD_SLEEPON_END_TAG; | ||
1480 | spin_unlock_irq(get_ccwdev_lock(cqr->startdev->cdev)); | ||
1481 | wake_up(&generic_waitq); | ||
1476 | } | 1482 | } |
1477 | 1483 | ||
1478 | static inline int _wait_for_wakeup(struct dasd_ccw_req *cqr) | 1484 | static inline int _wait_for_wakeup(struct dasd_ccw_req *cqr) |
@@ -1482,10 +1488,7 @@ static inline int _wait_for_wakeup(struct dasd_ccw_req *cqr) | |||
1482 | 1488 | ||
1483 | device = cqr->startdev; | 1489 | device = cqr->startdev; |
1484 | spin_lock_irq(get_ccwdev_lock(device->cdev)); | 1490 | spin_lock_irq(get_ccwdev_lock(device->cdev)); |
1485 | rc = ((cqr->status == DASD_CQR_DONE || | 1491 | rc = (cqr->callback_data == DASD_SLEEPON_END_TAG); |
1486 | cqr->status == DASD_CQR_NEED_ERP || | ||
1487 | cqr->status == DASD_CQR_TERMINATED) && | ||
1488 | list_empty(&cqr->devlist)); | ||
1489 | spin_unlock_irq(get_ccwdev_lock(device->cdev)); | 1492 | spin_unlock_irq(get_ccwdev_lock(device->cdev)); |
1490 | return rc; | 1493 | return rc; |
1491 | } | 1494 | } |
@@ -1573,7 +1576,7 @@ static int _dasd_sleep_on(struct dasd_ccw_req *maincqr, int interruptible) | |||
1573 | wait_event(generic_waitq, !(device->stopped)); | 1576 | wait_event(generic_waitq, !(device->stopped)); |
1574 | 1577 | ||
1575 | cqr->callback = dasd_wakeup_cb; | 1578 | cqr->callback = dasd_wakeup_cb; |
1576 | cqr->callback_data = (void *) &generic_waitq; | 1579 | cqr->callback_data = DASD_SLEEPON_START_TAG; |
1577 | dasd_add_request_tail(cqr); | 1580 | dasd_add_request_tail(cqr); |
1578 | if (interruptible) { | 1581 | if (interruptible) { |
1579 | rc = wait_event_interruptible( | 1582 | rc = wait_event_interruptible( |
@@ -1652,7 +1655,7 @@ int dasd_sleep_on_immediatly(struct dasd_ccw_req *cqr) | |||
1652 | } | 1655 | } |
1653 | 1656 | ||
1654 | cqr->callback = dasd_wakeup_cb; | 1657 | cqr->callback = dasd_wakeup_cb; |
1655 | cqr->callback_data = (void *) &generic_waitq; | 1658 | cqr->callback_data = DASD_SLEEPON_START_TAG; |
1656 | cqr->status = DASD_CQR_QUEUED; | 1659 | cqr->status = DASD_CQR_QUEUED; |
1657 | list_add(&cqr->devlist, &device->ccw_queue); | 1660 | list_add(&cqr->devlist, &device->ccw_queue); |
1658 | 1661 | ||