diff options
author | Trond Myklebust <Trond.Myklebust@netapp.com> | 2006-07-05 13:13:03 -0400 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2006-07-05 13:13:03 -0400 |
commit | 5e66dd6d66ffe758b39b6dcadf2330753ee1159b (patch) | |
tree | a72cdcff4448e4af9425cc213ddf56ab23e697fe /drivers | |
parent | 026477c1141b67e98e3bd8bdedb7d4b88a3ecd09 (diff) | |
parent | ca78f6baca863afe2e6a244a0fe94b3a70211d46 (diff) |
Merge branch 'master' of /home/trondmy/kernel/linux-2.6/
Diffstat (limited to 'drivers')
265 files changed, 9695 insertions, 4269 deletions
diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig index bc2652d72fdc..fef7bab12244 100644 --- a/drivers/acpi/Kconfig +++ b/drivers/acpi/Kconfig | |||
@@ -352,6 +352,18 @@ config ACPI_HOTPLUG_MEMORY | |||
352 | If one selects "m," this driver can be loaded using the following | 352 | If one selects "m," this driver can be loaded using the following |
353 | command: | 353 | command: |
354 | $>modprobe acpi_memhotplug | 354 | $>modprobe acpi_memhotplug |
355 | |||
356 | config ACPI_SBS | ||
357 | tristate "Smart Battery System (EXPERIMENTAL)" | ||
358 | depends on X86 && I2C | ||
359 | depends on EXPERIMENTAL | ||
360 | default y | ||
361 | help | ||
362 | This driver adds support for the Smart Battery System. | ||
363 | Depends on I2C (Device Drivers ---> I2C support) | ||
364 | A "Smart Battery" is quite old and quite rare compared | ||
365 | to today's ACPI "Control Method" battery. | ||
366 | |||
355 | endif # ACPI | 367 | endif # ACPI |
356 | 368 | ||
357 | endmenu | 369 | endmenu |
diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile index f0a68ecf1e57..bce7ca27b429 100644 --- a/drivers/acpi/Makefile +++ b/drivers/acpi/Makefile | |||
@@ -58,3 +58,5 @@ obj-$(CONFIG_ACPI_IBM) += ibm_acpi.o | |||
58 | obj-$(CONFIG_ACPI_TOSHIBA) += toshiba_acpi.o | 58 | obj-$(CONFIG_ACPI_TOSHIBA) += toshiba_acpi.o |
59 | obj-y += scan.o motherboard.o | 59 | obj-y += scan.o motherboard.o |
60 | obj-$(CONFIG_ACPI_HOTPLUG_MEMORY) += acpi_memhotplug.o | 60 | obj-$(CONFIG_ACPI_HOTPLUG_MEMORY) += acpi_memhotplug.o |
61 | obj-y += cm_sbs.o | ||
62 | obj-$(CONFIG_ACPI_SBS) += i2c_ec.o sbs.o | ||
diff --git a/drivers/acpi/ac.c b/drivers/acpi/ac.c index 36ca365bcead..24ccf81d135f 100644 --- a/drivers/acpi/ac.c +++ b/drivers/acpi/ac.c | |||
@@ -50,6 +50,9 @@ ACPI_MODULE_NAME("acpi_ac") | |||
50 | MODULE_DESCRIPTION(ACPI_AC_DRIVER_NAME); | 50 | MODULE_DESCRIPTION(ACPI_AC_DRIVER_NAME); |
51 | MODULE_LICENSE("GPL"); | 51 | MODULE_LICENSE("GPL"); |
52 | 52 | ||
53 | extern struct proc_dir_entry *acpi_lock_ac_dir(void); | ||
54 | extern void *acpi_unlock_ac_dir(struct proc_dir_entry *acpi_ac_dir); | ||
55 | |||
53 | static int acpi_ac_add(struct acpi_device *device); | 56 | static int acpi_ac_add(struct acpi_device *device); |
54 | static int acpi_ac_remove(struct acpi_device *device, int type); | 57 | static int acpi_ac_remove(struct acpi_device *device, int type); |
55 | static int acpi_ac_open_fs(struct inode *inode, struct file *file); | 58 | static int acpi_ac_open_fs(struct inode *inode, struct file *file); |
@@ -65,7 +68,7 @@ static struct acpi_driver acpi_ac_driver = { | |||
65 | }; | 68 | }; |
66 | 69 | ||
67 | struct acpi_ac { | 70 | struct acpi_ac { |
68 | acpi_handle handle; | 71 | struct acpi_device * device; |
69 | unsigned long state; | 72 | unsigned long state; |
70 | }; | 73 | }; |
71 | 74 | ||
@@ -88,7 +91,7 @@ static int acpi_ac_get_state(struct acpi_ac *ac) | |||
88 | if (!ac) | 91 | if (!ac) |
89 | return -EINVAL; | 92 | return -EINVAL; |
90 | 93 | ||
91 | status = acpi_evaluate_integer(ac->handle, "_PSR", NULL, &ac->state); | 94 | status = acpi_evaluate_integer(ac->device->handle, "_PSR", NULL, &ac->state); |
92 | if (ACPI_FAILURE(status)) { | 95 | if (ACPI_FAILURE(status)) { |
93 | ACPI_EXCEPTION((AE_INFO, status, "Error reading AC Adapter state")); | 96 | ACPI_EXCEPTION((AE_INFO, status, "Error reading AC Adapter state")); |
94 | ac->state = ACPI_AC_STATUS_UNKNOWN; | 97 | ac->state = ACPI_AC_STATUS_UNKNOWN; |
@@ -191,11 +194,11 @@ static void acpi_ac_notify(acpi_handle handle, u32 event, void *data) | |||
191 | if (!ac) | 194 | if (!ac) |
192 | return; | 195 | return; |
193 | 196 | ||
194 | if (acpi_bus_get_device(ac->handle, &device)) | 197 | device = ac->device; |
195 | return; | ||
196 | |||
197 | switch (event) { | 198 | switch (event) { |
198 | case ACPI_AC_NOTIFY_STATUS: | 199 | case ACPI_AC_NOTIFY_STATUS: |
200 | case ACPI_NOTIFY_BUS_CHECK: | ||
201 | case ACPI_NOTIFY_DEVICE_CHECK: | ||
199 | acpi_ac_get_state(ac); | 202 | acpi_ac_get_state(ac); |
200 | acpi_bus_generate_event(device, event, (u32) ac->state); | 203 | acpi_bus_generate_event(device, event, (u32) ac->state); |
201 | break; | 204 | break; |
@@ -223,7 +226,7 @@ static int acpi_ac_add(struct acpi_device *device) | |||
223 | return -ENOMEM; | 226 | return -ENOMEM; |
224 | memset(ac, 0, sizeof(struct acpi_ac)); | 227 | memset(ac, 0, sizeof(struct acpi_ac)); |
225 | 228 | ||
226 | ac->handle = device->handle; | 229 | ac->device = device; |
227 | strcpy(acpi_device_name(device), ACPI_AC_DEVICE_NAME); | 230 | strcpy(acpi_device_name(device), ACPI_AC_DEVICE_NAME); |
228 | strcpy(acpi_device_class(device), ACPI_AC_CLASS); | 231 | strcpy(acpi_device_class(device), ACPI_AC_CLASS); |
229 | acpi_driver_data(device) = ac; | 232 | acpi_driver_data(device) = ac; |
@@ -236,8 +239,8 @@ static int acpi_ac_add(struct acpi_device *device) | |||
236 | if (result) | 239 | if (result) |
237 | goto end; | 240 | goto end; |
238 | 241 | ||
239 | status = acpi_install_notify_handler(ac->handle, | 242 | status = acpi_install_notify_handler(device->handle, |
240 | ACPI_DEVICE_NOTIFY, acpi_ac_notify, | 243 | ACPI_ALL_NOTIFY, acpi_ac_notify, |
241 | ac); | 244 | ac); |
242 | if (ACPI_FAILURE(status)) { | 245 | if (ACPI_FAILURE(status)) { |
243 | result = -ENODEV; | 246 | result = -ENODEV; |
@@ -268,8 +271,8 @@ static int acpi_ac_remove(struct acpi_device *device, int type) | |||
268 | 271 | ||
269 | ac = (struct acpi_ac *)acpi_driver_data(device); | 272 | ac = (struct acpi_ac *)acpi_driver_data(device); |
270 | 273 | ||
271 | status = acpi_remove_notify_handler(ac->handle, | 274 | status = acpi_remove_notify_handler(device->handle, |
272 | ACPI_DEVICE_NOTIFY, acpi_ac_notify); | 275 | ACPI_ALL_NOTIFY, acpi_ac_notify); |
273 | 276 | ||
274 | acpi_ac_remove_fs(device); | 277 | acpi_ac_remove_fs(device); |
275 | 278 | ||
@@ -280,17 +283,16 @@ static int acpi_ac_remove(struct acpi_device *device, int type) | |||
280 | 283 | ||
281 | static int __init acpi_ac_init(void) | 284 | static int __init acpi_ac_init(void) |
282 | { | 285 | { |
283 | int result = 0; | 286 | int result; |
284 | 287 | ||
285 | 288 | ||
286 | acpi_ac_dir = proc_mkdir(ACPI_AC_CLASS, acpi_root_dir); | 289 | acpi_ac_dir = acpi_lock_ac_dir(); |
287 | if (!acpi_ac_dir) | 290 | if (!acpi_ac_dir) |
288 | return -ENODEV; | 291 | return -ENODEV; |
289 | acpi_ac_dir->owner = THIS_MODULE; | ||
290 | 292 | ||
291 | result = acpi_bus_register_driver(&acpi_ac_driver); | 293 | result = acpi_bus_register_driver(&acpi_ac_driver); |
292 | if (result < 0) { | 294 | if (result < 0) { |
293 | remove_proc_entry(ACPI_AC_CLASS, acpi_root_dir); | 295 | acpi_unlock_ac_dir(acpi_ac_dir); |
294 | return -ENODEV; | 296 | return -ENODEV; |
295 | } | 297 | } |
296 | 298 | ||
@@ -302,7 +304,7 @@ static void __exit acpi_ac_exit(void) | |||
302 | 304 | ||
303 | acpi_bus_unregister_driver(&acpi_ac_driver); | 305 | acpi_bus_unregister_driver(&acpi_ac_driver); |
304 | 306 | ||
305 | remove_proc_entry(ACPI_AC_CLASS, acpi_root_dir); | 307 | acpi_unlock_ac_dir(acpi_ac_dir); |
306 | 308 | ||
307 | return; | 309 | return; |
308 | } | 310 | } |
diff --git a/drivers/acpi/acpi_memhotplug.c b/drivers/acpi/acpi_memhotplug.c index cd57372a6729..81e970adeab3 100644 --- a/drivers/acpi/acpi_memhotplug.c +++ b/drivers/acpi/acpi_memhotplug.c | |||
@@ -80,7 +80,7 @@ struct acpi_memory_info { | |||
80 | }; | 80 | }; |
81 | 81 | ||
82 | struct acpi_memory_device { | 82 | struct acpi_memory_device { |
83 | acpi_handle handle; | 83 | struct acpi_device * device; |
84 | unsigned int state; /* State of the memory device */ | 84 | unsigned int state; /* State of the memory device */ |
85 | struct list_head res_list; | 85 | struct list_head res_list; |
86 | }; | 86 | }; |
@@ -129,7 +129,7 @@ acpi_memory_get_device_resources(struct acpi_memory_device *mem_device) | |||
129 | struct acpi_memory_info *info, *n; | 129 | struct acpi_memory_info *info, *n; |
130 | 130 | ||
131 | 131 | ||
132 | status = acpi_walk_resources(mem_device->handle, METHOD_NAME__CRS, | 132 | status = acpi_walk_resources(mem_device->device->handle, METHOD_NAME__CRS, |
133 | acpi_memory_get_resource, mem_device); | 133 | acpi_memory_get_resource, mem_device); |
134 | if (ACPI_FAILURE(status)) { | 134 | if (ACPI_FAILURE(status)) { |
135 | list_for_each_entry_safe(info, n, &mem_device->res_list, list) | 135 | list_for_each_entry_safe(info, n, &mem_device->res_list, list) |
@@ -192,7 +192,7 @@ static int acpi_memory_check_device(struct acpi_memory_device *mem_device) | |||
192 | 192 | ||
193 | 193 | ||
194 | /* Get device present/absent information from the _STA */ | 194 | /* Get device present/absent information from the _STA */ |
195 | if (ACPI_FAILURE(acpi_evaluate_integer(mem_device->handle, "_STA", | 195 | if (ACPI_FAILURE(acpi_evaluate_integer(mem_device->device->handle, "_STA", |
196 | NULL, ¤t_status))) | 196 | NULL, ¤t_status))) |
197 | return -ENODEV; | 197 | return -ENODEV; |
198 | /* | 198 | /* |
@@ -222,7 +222,7 @@ static int acpi_memory_enable_device(struct acpi_memory_device *mem_device) | |||
222 | return result; | 222 | return result; |
223 | } | 223 | } |
224 | 224 | ||
225 | node = acpi_get_node(mem_device->handle); | 225 | node = acpi_get_node(mem_device->device->handle); |
226 | /* | 226 | /* |
227 | * Tell the VM there is more memory here... | 227 | * Tell the VM there is more memory here... |
228 | * Note: Assume that this function returns zero on success | 228 | * Note: Assume that this function returns zero on success |
@@ -269,7 +269,7 @@ static int acpi_memory_powerdown_device(struct acpi_memory_device *mem_device) | |||
269 | arg_list.pointer = &arg; | 269 | arg_list.pointer = &arg; |
270 | arg.type = ACPI_TYPE_INTEGER; | 270 | arg.type = ACPI_TYPE_INTEGER; |
271 | arg.integer.value = 1; | 271 | arg.integer.value = 1; |
272 | status = acpi_evaluate_object(mem_device->handle, | 272 | status = acpi_evaluate_object(mem_device->device->handle, |
273 | "_EJ0", &arg_list, NULL); | 273 | "_EJ0", &arg_list, NULL); |
274 | /* Return on _EJ0 failure */ | 274 | /* Return on _EJ0 failure */ |
275 | if (ACPI_FAILURE(status)) { | 275 | if (ACPI_FAILURE(status)) { |
@@ -278,7 +278,7 @@ static int acpi_memory_powerdown_device(struct acpi_memory_device *mem_device) | |||
278 | } | 278 | } |
279 | 279 | ||
280 | /* Evalute _STA to check if the device is disabled */ | 280 | /* Evalute _STA to check if the device is disabled */ |
281 | status = acpi_evaluate_integer(mem_device->handle, "_STA", | 281 | status = acpi_evaluate_integer(mem_device->device->handle, "_STA", |
282 | NULL, ¤t_status); | 282 | NULL, ¤t_status); |
283 | if (ACPI_FAILURE(status)) | 283 | if (ACPI_FAILURE(status)) |
284 | return -ENODEV; | 284 | return -ENODEV; |
@@ -398,7 +398,7 @@ static int acpi_memory_device_add(struct acpi_device *device) | |||
398 | memset(mem_device, 0, sizeof(struct acpi_memory_device)); | 398 | memset(mem_device, 0, sizeof(struct acpi_memory_device)); |
399 | 399 | ||
400 | INIT_LIST_HEAD(&mem_device->res_list); | 400 | INIT_LIST_HEAD(&mem_device->res_list); |
401 | mem_device->handle = device->handle; | 401 | mem_device->device = device; |
402 | sprintf(acpi_device_name(device), "%s", ACPI_MEMORY_DEVICE_NAME); | 402 | sprintf(acpi_device_name(device), "%s", ACPI_MEMORY_DEVICE_NAME); |
403 | sprintf(acpi_device_class(device), "%s", ACPI_MEMORY_DEVICE_CLASS); | 403 | sprintf(acpi_device_class(device), "%s", ACPI_MEMORY_DEVICE_CLASS); |
404 | acpi_driver_data(device) = mem_device; | 404 | acpi_driver_data(device) = mem_device; |
@@ -466,7 +466,7 @@ static acpi_status is_memory_device(acpi_handle handle) | |||
466 | 466 | ||
467 | info = buffer.pointer; | 467 | info = buffer.pointer; |
468 | if (!(info->valid & ACPI_VALID_HID)) { | 468 | if (!(info->valid & ACPI_VALID_HID)) { |
469 | acpi_os_free(buffer.pointer); | 469 | kfree(buffer.pointer); |
470 | return AE_ERROR; | 470 | return AE_ERROR; |
471 | } | 471 | } |
472 | 472 | ||
@@ -475,7 +475,7 @@ static acpi_status is_memory_device(acpi_handle handle) | |||
475 | (strcmp(hardware_id, ACPI_MEMORY_DEVICE_HID))) | 475 | (strcmp(hardware_id, ACPI_MEMORY_DEVICE_HID))) |
476 | status = AE_ERROR; | 476 | status = AE_ERROR; |
477 | 477 | ||
478 | acpi_os_free(buffer.pointer); | 478 | kfree(buffer.pointer); |
479 | return status; | 479 | return status; |
480 | } | 480 | } |
481 | 481 | ||
diff --git a/drivers/acpi/asus_acpi.c b/drivers/acpi/asus_acpi.c index 055cfd5c8766..e9ee4c52a5f6 100644 --- a/drivers/acpi/asus_acpi.c +++ b/drivers/acpi/asus_acpi.c | |||
@@ -2,7 +2,7 @@ | |||
2 | * asus_acpi.c - Asus Laptop ACPI Extras | 2 | * asus_acpi.c - Asus Laptop ACPI Extras |
3 | * | 3 | * |
4 | * | 4 | * |
5 | * Copyright (C) 2002, 2003, 2004 Julien Lerouge, Karol Kozimor | 5 | * Copyright (C) 2002-2005 Julien Lerouge, 2003-2006 Karol Kozimor |
6 | * | 6 | * |
7 | * This program is free software; you can redistribute it and/or modify | 7 | * This program is free software; you can redistribute it and/or modify |
8 | * it under the terms of the GNU General Public License as published by | 8 | * it under the terms of the GNU General Public License as published by |
@@ -26,11 +26,8 @@ | |||
26 | * Pontus Fuchs - Helper functions, cleanup | 26 | * Pontus Fuchs - Helper functions, cleanup |
27 | * Johann Wiesner - Small compile fixes | 27 | * Johann Wiesner - Small compile fixes |
28 | * John Belmonte - ACPI code for Toshiba laptop was a good starting point. | 28 | * John Belmonte - ACPI code for Toshiba laptop was a good starting point. |
29 | * Éric Burghard - LED display support for W1N | ||
29 | * | 30 | * |
30 | * TODO: | ||
31 | * add Fn key status | ||
32 | * Add mode selection on module loading (parameter) -> still necessary? | ||
33 | * Complete display switching -- may require dirty hacks or calling _DOS? | ||
34 | */ | 31 | */ |
35 | 32 | ||
36 | #include <linux/kernel.h> | 33 | #include <linux/kernel.h> |
@@ -42,12 +39,14 @@ | |||
42 | #include <acpi/acpi_bus.h> | 39 | #include <acpi/acpi_bus.h> |
43 | #include <asm/uaccess.h> | 40 | #include <asm/uaccess.h> |
44 | 41 | ||
45 | #define ASUS_ACPI_VERSION "0.29" | 42 | #define ASUS_ACPI_VERSION "0.30" |
46 | 43 | ||
47 | #define PROC_ASUS "asus" //the directory | 44 | #define PROC_ASUS "asus" //the directory |
48 | #define PROC_MLED "mled" | 45 | #define PROC_MLED "mled" |
49 | #define PROC_WLED "wled" | 46 | #define PROC_WLED "wled" |
50 | #define PROC_TLED "tled" | 47 | #define PROC_TLED "tled" |
48 | #define PROC_BT "bluetooth" | ||
49 | #define PROC_LEDD "ledd" | ||
51 | #define PROC_INFO "info" | 50 | #define PROC_INFO "info" |
52 | #define PROC_LCD "lcd" | 51 | #define PROC_LCD "lcd" |
53 | #define PROC_BRN "brn" | 52 | #define PROC_BRN "brn" |
@@ -67,9 +66,10 @@ | |||
67 | /* | 66 | /* |
68 | * Flags for hotk status | 67 | * Flags for hotk status |
69 | */ | 68 | */ |
70 | #define MLED_ON 0x01 //is MLED ON ? | 69 | #define MLED_ON 0x01 //mail LED |
71 | #define WLED_ON 0x02 | 70 | #define WLED_ON 0x02 //wireless LED |
72 | #define TLED_ON 0x04 | 71 | #define TLED_ON 0x04 //touchpad LED |
72 | #define BT_ON 0x08 //internal Bluetooth | ||
73 | 73 | ||
74 | MODULE_AUTHOR("Julien Lerouge, Karol Kozimor"); | 74 | MODULE_AUTHOR("Julien Lerouge, Karol Kozimor"); |
75 | MODULE_DESCRIPTION(ACPI_HOTK_NAME); | 75 | MODULE_DESCRIPTION(ACPI_HOTK_NAME); |
@@ -92,7 +92,10 @@ struct model_data { | |||
92 | char *wled_status; //node to handle wled reading_______A | 92 | char *wled_status; //node to handle wled reading_______A |
93 | char *mt_tled; //method to handle tled_____________R | 93 | char *mt_tled; //method to handle tled_____________R |
94 | char *tled_status; //node to handle tled reading_______A | 94 | char *tled_status; //node to handle tled reading_______A |
95 | char *mt_lcd_switch; //method to turn LCD ON/OFF_________A | 95 | char *mt_ledd; //method to handle LED display______R |
96 | char *mt_bt_switch; //method to switch Bluetooth on/off_R | ||
97 | char *bt_status; //no model currently supports this__? | ||
98 | char *mt_lcd_switch; //method to turn LCD on/off_________A | ||
96 | char *lcd_status; //node to read LCD panel state______A | 99 | char *lcd_status; //node to read LCD panel state______A |
97 | char *brightness_up; //method to set brightness up_______A | 100 | char *brightness_up; //method to set brightness up_______A |
98 | char *brightness_down; //guess what ?______________________A | 101 | char *brightness_down; //guess what ?______________________A |
@@ -111,27 +114,31 @@ struct asus_hotk { | |||
111 | struct acpi_device *device; //the device we are in | 114 | struct acpi_device *device; //the device we are in |
112 | acpi_handle handle; //the handle of the hotk device | 115 | acpi_handle handle; //the handle of the hotk device |
113 | char status; //status of the hotk, for LEDs, ... | 116 | char status; //status of the hotk, for LEDs, ... |
117 | u32 ledd_status; //status of the LED display | ||
114 | struct model_data *methods; //methods available on the laptop | 118 | struct model_data *methods; //methods available on the laptop |
115 | u8 brightness; //brightness level | 119 | u8 brightness; //brightness level |
116 | enum { | 120 | enum { |
117 | A1x = 0, //A1340D, A1300F | 121 | A1x = 0, //A1340D, A1300F |
118 | A2x, //A2500H | 122 | A2x, //A2500H |
123 | A4G, //A4700G | ||
119 | D1x, //D1 | 124 | D1x, //D1 |
120 | L2D, //L2000D | 125 | L2D, //L2000D |
121 | L3C, //L3800C | 126 | L3C, //L3800C |
122 | L3D, //L3400D | 127 | L3D, //L3400D |
123 | L3H, //L3H, but also L2000E | 128 | L3H, //L3H, L2000E, L5D |
124 | L4R, //L4500R | 129 | L4R, //L4500R |
125 | L5x, //L5800C | 130 | L5x, //L5800C |
126 | L8L, //L8400L | 131 | L8L, //L8400L |
127 | M1A, //M1300A | 132 | M1A, //M1300A |
128 | M2E, //M2400E, L4400L | 133 | M2E, //M2400E, L4400L |
129 | M6N, //M6800N | 134 | M6N, //M6800N, W3400N |
130 | M6R, //M6700R | 135 | M6R, //M6700R, A3000G |
131 | P30, //Samsung P30 | 136 | P30, //Samsung P30 |
132 | S1x, //S1300A, but also L1400B and M2400A (L84F) | 137 | S1x, //S1300A, but also L1400B and M2400A (L84F) |
133 | S2x, //S200 (J1 reported), Victor MP-XP7210 | 138 | S2x, //S200 (J1 reported), Victor MP-XP7210 |
134 | xxN, //M2400N, M3700N, M5200N, S1300N, S5200N, W1OOON | 139 | W1N, //W1000N |
140 | W5A, //W5A | ||
141 | xxN, //M2400N, M3700N, M5200N, M6800N, S1300N, S5200N | ||
135 | //(Centrino) | 142 | //(Centrino) |
136 | END_MODEL | 143 | END_MODEL |
137 | } model; //Models currently supported | 144 | } model; //Models currently supported |
@@ -149,17 +156,8 @@ struct asus_hotk { | |||
149 | 156 | ||
150 | static struct model_data model_conf[END_MODEL] = { | 157 | static struct model_data model_conf[END_MODEL] = { |
151 | /* | 158 | /* |
152 | * Those pathnames are relative to the HOTK / ATKD device : | ||
153 | * - mt_mled | ||
154 | * - mt_wled | ||
155 | * - brightness_set | ||
156 | * - brightness_get | ||
157 | * - display_set | ||
158 | * - display_get | ||
159 | * | ||
160 | * TODO I have seen a SWBX and AIBX method on some models, like L1400B, | 159 | * TODO I have seen a SWBX and AIBX method on some models, like L1400B, |
161 | * it seems to be a kind of switch, but what for ? | 160 | * it seems to be a kind of switch, but what for ? |
162 | * | ||
163 | */ | 161 | */ |
164 | 162 | ||
165 | { | 163 | { |
@@ -184,6 +182,16 @@ static struct model_data model_conf[END_MODEL] = { | |||
184 | .display_get = "\\INFB"}, | 182 | .display_get = "\\INFB"}, |
185 | 183 | ||
186 | { | 184 | { |
185 | .name = "A4G", | ||
186 | .mt_mled = "MLED", | ||
187 | /* WLED present, but not controlled by ACPI */ | ||
188 | .mt_lcd_switch = xxN_PREFIX "_Q10", | ||
189 | .brightness_set = "SPLV", | ||
190 | .brightness_get = "GPLV", | ||
191 | .display_set = "SDSP", | ||
192 | .display_get = "\\ADVG"}, | ||
193 | |||
194 | { | ||
187 | .name = "D1x", | 195 | .name = "D1x", |
188 | .mt_mled = "MLED", | 196 | .mt_mled = "MLED", |
189 | .mt_lcd_switch = "\\Q0D", | 197 | .mt_lcd_switch = "\\Q0D", |
@@ -302,7 +310,8 @@ static struct model_data model_conf[END_MODEL] = { | |||
302 | .brightness_set = "SPLV", | 310 | .brightness_set = "SPLV", |
303 | .brightness_get = "GPLV", | 311 | .brightness_get = "GPLV", |
304 | .display_set = "SDSP", | 312 | .display_set = "SDSP", |
305 | .display_get = "\\_SB.PCI0.P0P1.VGA.GETD"}, | 313 | .display_get = "\\SSTE"}, |
314 | |||
306 | { | 315 | { |
307 | .name = "M6R", | 316 | .name = "M6R", |
308 | .mt_mled = "MLED", | 317 | .mt_mled = "MLED", |
@@ -312,7 +321,7 @@ static struct model_data model_conf[END_MODEL] = { | |||
312 | .brightness_set = "SPLV", | 321 | .brightness_set = "SPLV", |
313 | .brightness_get = "GPLV", | 322 | .brightness_get = "GPLV", |
314 | .display_set = "SDSP", | 323 | .display_set = "SDSP", |
315 | .display_get = "\\SSTE"}, | 324 | .display_get = "\\_SB.PCI0.P0P1.VGA.GETD"}, |
316 | 325 | ||
317 | { | 326 | { |
318 | .name = "P30", | 327 | .name = "P30", |
@@ -345,6 +354,28 @@ static struct model_data model_conf[END_MODEL] = { | |||
345 | .brightness_down = S2x_PREFIX "_Q0A"}, | 354 | .brightness_down = S2x_PREFIX "_Q0A"}, |
346 | 355 | ||
347 | { | 356 | { |
357 | .name = "W1N", | ||
358 | .mt_mled = "MLED", | ||
359 | .mt_wled = "WLED", | ||
360 | .mt_ledd = "SLCM", | ||
361 | .mt_lcd_switch = xxN_PREFIX "_Q10", | ||
362 | .lcd_status = "\\BKLT", | ||
363 | .brightness_set = "SPLV", | ||
364 | .brightness_get = "GPLV", | ||
365 | .display_set = "SDSP", | ||
366 | .display_get = "\\ADVG"}, | ||
367 | |||
368 | { | ||
369 | .name = "W5A", | ||
370 | .mt_bt_switch = "BLED", | ||
371 | .mt_wled = "WLED", | ||
372 | .mt_lcd_switch = xxN_PREFIX "_Q10", | ||
373 | .brightness_set = "SPLV", | ||
374 | .brightness_get = "GPLV", | ||
375 | .display_set = "SDSP", | ||
376 | .display_get = "\\ADVG"}, | ||
377 | |||
378 | { | ||
348 | .name = "xxN", | 379 | .name = "xxN", |
349 | .mt_mled = "MLED", | 380 | .mt_mled = "MLED", |
350 | /* WLED present, but not controlled by ACPI */ | 381 | /* WLED present, but not controlled by ACPI */ |
@@ -563,6 +594,36 @@ proc_write_mled(struct file *file, const char __user * buffer, | |||
563 | } | 594 | } |
564 | 595 | ||
565 | /* | 596 | /* |
597 | * Proc handlers for LED display | ||
598 | */ | ||
599 | static int | ||
600 | proc_read_ledd(char *page, char **start, off_t off, int count, int *eof, | ||
601 | void *data) | ||
602 | { | ||
603 | return sprintf(page, "0x%08x\n", hotk->ledd_status); | ||
604 | } | ||
605 | |||
606 | static int | ||
607 | proc_write_ledd(struct file *file, const char __user * buffer, | ||
608 | unsigned long count, void *data) | ||
609 | { | ||
610 | int value; | ||
611 | |||
612 | count = parse_arg(buffer, count, &value); | ||
613 | if (count > 0) { | ||
614 | if (!write_acpi_int | ||
615 | (hotk->handle, hotk->methods->mt_ledd, value, NULL)) | ||
616 | printk(KERN_WARNING | ||
617 | "Asus ACPI: LED display write failed\n"); | ||
618 | else | ||
619 | hotk->ledd_status = (u32) value; | ||
620 | } else if (count < 0) | ||
621 | printk(KERN_WARNING "Asus ACPI: Error reading user input\n"); | ||
622 | |||
623 | return count; | ||
624 | } | ||
625 | |||
626 | /* | ||
566 | * Proc handlers for WLED | 627 | * Proc handlers for WLED |
567 | */ | 628 | */ |
568 | static int | 629 | static int |
@@ -581,6 +642,25 @@ proc_write_wled(struct file *file, const char __user * buffer, | |||
581 | } | 642 | } |
582 | 643 | ||
583 | /* | 644 | /* |
645 | * Proc handlers for Bluetooth | ||
646 | */ | ||
647 | static int | ||
648 | proc_read_bluetooth(char *page, char **start, off_t off, int count, int *eof, | ||
649 | void *data) | ||
650 | { | ||
651 | return sprintf(page, "%d\n", read_led(hotk->methods->bt_status, BT_ON)); | ||
652 | } | ||
653 | |||
654 | static int | ||
655 | proc_write_bluetooth(struct file *file, const char __user * buffer, | ||
656 | unsigned long count, void *data) | ||
657 | { | ||
658 | /* Note: mt_bt_switch controls both internal Bluetooth adapter's | ||
659 | presence and its LED */ | ||
660 | return write_led(buffer, count, hotk->methods->mt_bt_switch, BT_ON, 0); | ||
661 | } | ||
662 | |||
663 | /* | ||
584 | * Proc handlers for TLED | 664 | * Proc handlers for TLED |
585 | */ | 665 | */ |
586 | static int | 666 | static int |
@@ -876,6 +956,11 @@ static int asus_hotk_add_fs(struct acpi_device *device) | |||
876 | mode, device); | 956 | mode, device); |
877 | } | 957 | } |
878 | 958 | ||
959 | if (hotk->methods->mt_ledd) { | ||
960 | asus_proc_add(PROC_LEDD, &proc_write_ledd, &proc_read_ledd, | ||
961 | mode, device); | ||
962 | } | ||
963 | |||
879 | if (hotk->methods->mt_mled) { | 964 | if (hotk->methods->mt_mled) { |
880 | asus_proc_add(PROC_MLED, &proc_write_mled, &proc_read_mled, | 965 | asus_proc_add(PROC_MLED, &proc_write_mled, &proc_read_mled, |
881 | mode, device); | 966 | mode, device); |
@@ -886,6 +971,11 @@ static int asus_hotk_add_fs(struct acpi_device *device) | |||
886 | mode, device); | 971 | mode, device); |
887 | } | 972 | } |
888 | 973 | ||
974 | if (hotk->methods->mt_bt_switch) { | ||
975 | asus_proc_add(PROC_BT, &proc_write_bluetooth, | ||
976 | &proc_read_bluetooth, mode, device); | ||
977 | } | ||
978 | |||
889 | /* | 979 | /* |
890 | * We need both read node and write method as LCD switch is also accessible | 980 | * We need both read node and write method as LCD switch is also accessible |
891 | * from keyboard | 981 | * from keyboard |
@@ -919,6 +1009,10 @@ static int asus_hotk_remove_fs(struct acpi_device *device) | |||
919 | remove_proc_entry(PROC_MLED, acpi_device_dir(device)); | 1009 | remove_proc_entry(PROC_MLED, acpi_device_dir(device)); |
920 | if (hotk->methods->mt_tled) | 1010 | if (hotk->methods->mt_tled) |
921 | remove_proc_entry(PROC_TLED, acpi_device_dir(device)); | 1011 | remove_proc_entry(PROC_TLED, acpi_device_dir(device)); |
1012 | if (hotk->methods->mt_ledd) | ||
1013 | remove_proc_entry(PROC_LEDD, acpi_device_dir(device)); | ||
1014 | if (hotk->methods->mt_bt_switch) | ||
1015 | remove_proc_entry(PROC_BT, acpi_device_dir(device)); | ||
922 | if (hotk->methods->mt_lcd_switch && hotk->methods->lcd_status) | 1016 | if (hotk->methods->mt_lcd_switch && hotk->methods->lcd_status) |
923 | remove_proc_entry(PROC_LCD, acpi_device_dir(device)); | 1017 | remove_proc_entry(PROC_LCD, acpi_device_dir(device)); |
924 | if ((hotk->methods->brightness_up | 1018 | if ((hotk->methods->brightness_up |
@@ -951,6 +1045,65 @@ static void asus_hotk_notify(acpi_handle handle, u32 event, void *data) | |||
951 | } | 1045 | } |
952 | 1046 | ||
953 | /* | 1047 | /* |
1048 | * Match the model string to the list of supported models. Return END_MODEL if | ||
1049 | * no match or model is NULL. | ||
1050 | */ | ||
1051 | static int asus_model_match(char *model) | ||
1052 | { | ||
1053 | if (model == NULL) | ||
1054 | return END_MODEL; | ||
1055 | |||
1056 | if (strncmp(model, "L3D", 3) == 0) | ||
1057 | return L3D; | ||
1058 | else if (strncmp(model, "L2E", 3) == 0 || | ||
1059 | strncmp(model, "L3H", 3) == 0 || strncmp(model, "L5D", 3) == 0) | ||
1060 | return L3H; | ||
1061 | else if (strncmp(model, "L3", 2) == 0 || strncmp(model, "L2B", 3) == 0) | ||
1062 | return L3C; | ||
1063 | else if (strncmp(model, "L8L", 3) == 0) | ||
1064 | return L8L; | ||
1065 | else if (strncmp(model, "L4R", 3) == 0) | ||
1066 | return L4R; | ||
1067 | else if (strncmp(model, "M6N", 3) == 0 || strncmp(model, "W3N", 3) == 0) | ||
1068 | return M6N; | ||
1069 | else if (strncmp(model, "M6R", 3) == 0 || strncmp(model, "A3G", 3) == 0) | ||
1070 | return M6R; | ||
1071 | else if (strncmp(model, "M2N", 3) == 0 || | ||
1072 | strncmp(model, "M3N", 3) == 0 || | ||
1073 | strncmp(model, "M5N", 3) == 0 || | ||
1074 | strncmp(model, "M6N", 3) == 0 || | ||
1075 | strncmp(model, "S1N", 3) == 0 || | ||
1076 | strncmp(model, "S5N", 3) == 0 || strncmp(model, "W1N", 3) == 0) | ||
1077 | return xxN; | ||
1078 | else if (strncmp(model, "M1", 2) == 0) | ||
1079 | return M1A; | ||
1080 | else if (strncmp(model, "M2", 2) == 0 || strncmp(model, "L4E", 3) == 0) | ||
1081 | return M2E; | ||
1082 | else if (strncmp(model, "L2", 2) == 0) | ||
1083 | return L2D; | ||
1084 | else if (strncmp(model, "L8", 2) == 0) | ||
1085 | return S1x; | ||
1086 | else if (strncmp(model, "D1", 2) == 0) | ||
1087 | return D1x; | ||
1088 | else if (strncmp(model, "A1", 2) == 0) | ||
1089 | return A1x; | ||
1090 | else if (strncmp(model, "A2", 2) == 0) | ||
1091 | return A2x; | ||
1092 | else if (strncmp(model, "J1", 2) == 0) | ||
1093 | return S2x; | ||
1094 | else if (strncmp(model, "L5", 2) == 0) | ||
1095 | return L5x; | ||
1096 | else if (strncmp(model, "A4G", 3) == 0) | ||
1097 | return A4G; | ||
1098 | else if (strncmp(model, "W1N", 3) == 0) | ||
1099 | return W1N; | ||
1100 | else if (strncmp(model, "W5A", 3) == 0) | ||
1101 | return W5A; | ||
1102 | else | ||
1103 | return END_MODEL; | ||
1104 | } | ||
1105 | |||
1106 | /* | ||
954 | * This function is used to initialize the hotk with right values. In this | 1107 | * This function is used to initialize the hotk with right values. In this |
955 | * method, we can make all the detection we want, and modify the hotk struct | 1108 | * method, we can make all the detection we want, and modify the hotk struct |
956 | */ | 1109 | */ |
@@ -960,6 +1113,7 @@ static int asus_hotk_get_info(void) | |||
960 | struct acpi_buffer dsdt = { ACPI_ALLOCATE_BUFFER, NULL }; | 1113 | struct acpi_buffer dsdt = { ACPI_ALLOCATE_BUFFER, NULL }; |
961 | union acpi_object *model = NULL; | 1114 | union acpi_object *model = NULL; |
962 | int bsts_result; | 1115 | int bsts_result; |
1116 | char *string = NULL; | ||
963 | acpi_status status; | 1117 | acpi_status status; |
964 | 1118 | ||
965 | /* | 1119 | /* |
@@ -989,114 +1143,73 @@ static int asus_hotk_get_info(void) | |||
989 | printk(KERN_NOTICE " BSTS called, 0x%02x returned\n", | 1143 | printk(KERN_NOTICE " BSTS called, 0x%02x returned\n", |
990 | bsts_result); | 1144 | bsts_result); |
991 | 1145 | ||
992 | /* This is unlikely with implicit return */ | ||
993 | if (buffer.pointer == NULL) | ||
994 | return -EINVAL; | ||
995 | |||
996 | model = (union acpi_object *) buffer.pointer; | ||
997 | /* | 1146 | /* |
998 | * Samsung P30 has a device with a valid _HID whose INIT does not | 1147 | * Try to match the object returned by INIT to the specific model. |
999 | * return anything. It used to be possible to catch this exception, | 1148 | * Handle every possible object (or the lack of thereof) the DSDT |
1000 | * but the implicit return code will now happily confuse the | 1149 | * writers might throw at us. When in trouble, we pass NULL to |
1001 | * driver. We assume that every ACPI_TYPE_STRING is a valid model | 1150 | * asus_model_match() and try something completely different. |
1002 | * identifier but it's still possible to get completely bogus data. | ||
1003 | */ | 1151 | */ |
1004 | if (model->type == ACPI_TYPE_STRING) { | 1152 | if (buffer.pointer) { |
1005 | printk(KERN_NOTICE " %s model detected, ", model->string.pointer); | 1153 | model = (union acpi_object *)buffer.pointer; |
1006 | } else { | 1154 | switch (model->type) { |
1007 | if (asus_info && /* Samsung P30 */ | 1155 | case ACPI_TYPE_STRING: |
1156 | string = model->string.pointer; | ||
1157 | break; | ||
1158 | case ACPI_TYPE_BUFFER: | ||
1159 | string = model->buffer.pointer; | ||
1160 | break; | ||
1161 | default: | ||
1162 | kfree(model); | ||
1163 | break; | ||
1164 | } | ||
1165 | } | ||
1166 | hotk->model = asus_model_match(string); | ||
1167 | if (hotk->model == END_MODEL) { /* match failed */ | ||
1168 | if (asus_info && | ||
1008 | strncmp(asus_info->oem_table_id, "ODEM", 4) == 0) { | 1169 | strncmp(asus_info->oem_table_id, "ODEM", 4) == 0) { |
1009 | hotk->model = P30; | 1170 | hotk->model = P30; |
1010 | printk(KERN_NOTICE | 1171 | printk(KERN_NOTICE |
1011 | " Samsung P30 detected, supported\n"); | 1172 | " Samsung P30 detected, supported\n"); |
1012 | } else { | 1173 | } else { |
1013 | hotk->model = M2E; | 1174 | hotk->model = M2E; |
1014 | printk(KERN_WARNING " no string returned by INIT\n"); | 1175 | printk(KERN_NOTICE " unsupported model %s, trying " |
1015 | printk(KERN_WARNING " trying default values, supply " | 1176 | "default values\n", string); |
1016 | "the developers with your DSDT\n"); | 1177 | printk(KERN_NOTICE |
1178 | " send /proc/acpi/dsdt to the developers\n"); | ||
1017 | } | 1179 | } |
1018 | hotk->methods = &model_conf[hotk->model]; | 1180 | hotk->methods = &model_conf[hotk->model]; |
1019 | |||
1020 | acpi_os_free(model); | ||
1021 | |||
1022 | return AE_OK; | 1181 | return AE_OK; |
1023 | } | 1182 | } |
1024 | |||
1025 | hotk->model = END_MODEL; | ||
1026 | if (strncmp(model->string.pointer, "L3D", 3) == 0) | ||
1027 | hotk->model = L3D; | ||
1028 | else if (strncmp(model->string.pointer, "L3H", 3) == 0 || | ||
1029 | strncmp(model->string.pointer, "L2E", 3) == 0) | ||
1030 | hotk->model = L3H; | ||
1031 | else if (strncmp(model->string.pointer, "L3", 2) == 0 || | ||
1032 | strncmp(model->string.pointer, "L2B", 3) == 0) | ||
1033 | hotk->model = L3C; | ||
1034 | else if (strncmp(model->string.pointer, "L8L", 3) == 0) | ||
1035 | hotk->model = L8L; | ||
1036 | else if (strncmp(model->string.pointer, "L4R", 3) == 0) | ||
1037 | hotk->model = L4R; | ||
1038 | else if (strncmp(model->string.pointer, "M6N", 3) == 0) | ||
1039 | hotk->model = M6N; | ||
1040 | else if (strncmp(model->string.pointer, "M6R", 3) == 0) | ||
1041 | hotk->model = M6R; | ||
1042 | else if (strncmp(model->string.pointer, "M2N", 3) == 0 || | ||
1043 | strncmp(model->string.pointer, "M3N", 3) == 0 || | ||
1044 | strncmp(model->string.pointer, "M5N", 3) == 0 || | ||
1045 | strncmp(model->string.pointer, "M6N", 3) == 0 || | ||
1046 | strncmp(model->string.pointer, "S1N", 3) == 0 || | ||
1047 | strncmp(model->string.pointer, "S5N", 3) == 0 || | ||
1048 | strncmp(model->string.pointer, "W1N", 3) == 0) | ||
1049 | hotk->model = xxN; | ||
1050 | else if (strncmp(model->string.pointer, "M1", 2) == 0) | ||
1051 | hotk->model = M1A; | ||
1052 | else if (strncmp(model->string.pointer, "M2", 2) == 0 || | ||
1053 | strncmp(model->string.pointer, "L4E", 3) == 0) | ||
1054 | hotk->model = M2E; | ||
1055 | else if (strncmp(model->string.pointer, "L2", 2) == 0) | ||
1056 | hotk->model = L2D; | ||
1057 | else if (strncmp(model->string.pointer, "L8", 2) == 0) | ||
1058 | hotk->model = S1x; | ||
1059 | else if (strncmp(model->string.pointer, "D1", 2) == 0) | ||
1060 | hotk->model = D1x; | ||
1061 | else if (strncmp(model->string.pointer, "A1", 2) == 0) | ||
1062 | hotk->model = A1x; | ||
1063 | else if (strncmp(model->string.pointer, "A2", 2) == 0) | ||
1064 | hotk->model = A2x; | ||
1065 | else if (strncmp(model->string.pointer, "J1", 2) == 0) | ||
1066 | hotk->model = S2x; | ||
1067 | else if (strncmp(model->string.pointer, "L5", 2) == 0) | ||
1068 | hotk->model = L5x; | ||
1069 | |||
1070 | if (hotk->model == END_MODEL) { | ||
1071 | printk("unsupported, trying default values, supply the " | ||
1072 | "developers with your DSDT\n"); | ||
1073 | hotk->model = M2E; | ||
1074 | } else { | ||
1075 | printk("supported\n"); | ||
1076 | } | ||
1077 | |||
1078 | hotk->methods = &model_conf[hotk->model]; | 1183 | hotk->methods = &model_conf[hotk->model]; |
1184 | printk(KERN_NOTICE " %s model detected, supported\n", string); | ||
1079 | 1185 | ||
1080 | /* Sort of per-model blacklist */ | 1186 | /* Sort of per-model blacklist */ |
1081 | if (strncmp(model->string.pointer, "L2B", 3) == 0) | 1187 | if (strncmp(string, "L2B", 3) == 0) |
1082 | hotk->methods->lcd_status = NULL; | 1188 | hotk->methods->lcd_status = NULL; |
1083 | /* L2B is similar enough to L3C to use its settings, with this only | 1189 | /* L2B is similar enough to L3C to use its settings, with this only |
1084 | exception */ | 1190 | exception */ |
1085 | else if (strncmp(model->string.pointer, "S5N", 3) == 0 || | 1191 | else if (strncmp(string, "A3G", 3) == 0) |
1086 | strncmp(model->string.pointer, "M5N", 3) == 0) | 1192 | hotk->methods->lcd_status = "\\BLFG"; |
1193 | /* A3G is like M6R */ | ||
1194 | else if (strncmp(string, "S5N", 3) == 0 || | ||
1195 | strncmp(string, "M5N", 3) == 0 || | ||
1196 | strncmp(string, "W3N", 3) == 0) | ||
1087 | hotk->methods->mt_mled = NULL; | 1197 | hotk->methods->mt_mled = NULL; |
1088 | /* S5N and M5N have no MLED */ | 1198 | /* S5N, M5N and W3N have no MLED */ |
1089 | else if (strncmp(model->string.pointer, "M2N", 3) == 0 || | 1199 | else if (strncmp(string, "L5D", 3) == 0) |
1090 | strncmp(model->string.pointer, "W1N", 3) == 0) | 1200 | hotk->methods->mt_wled = NULL; |
1201 | /* L5D's WLED is not controlled by ACPI */ | ||
1202 | else if (strncmp(string, "M2N", 3) == 0 || | ||
1203 | strncmp(string, "S1N", 3) == 0) | ||
1091 | hotk->methods->mt_wled = "WLED"; | 1204 | hotk->methods->mt_wled = "WLED"; |
1092 | /* M2N and W1N have a usable WLED */ | 1205 | /* M2N and S1N have a usable WLED */ |
1093 | else if (asus_info) { | 1206 | else if (asus_info) { |
1094 | if (strncmp(asus_info->oem_table_id, "L1", 2) == 0) | 1207 | if (strncmp(asus_info->oem_table_id, "L1", 2) == 0) |
1095 | hotk->methods->mled_status = NULL; | 1208 | hotk->methods->mled_status = NULL; |
1096 | /* S1300A reports L84F, but L1400B too, account for that */ | 1209 | /* S1300A reports L84F, but L1400B too, account for that */ |
1097 | } | 1210 | } |
1098 | 1211 | ||
1099 | acpi_os_free(model); | 1212 | kfree(model); |
1100 | 1213 | ||
1101 | return AE_OK; | 1214 | return AE_OK; |
1102 | } | 1215 | } |
@@ -1164,8 +1277,7 @@ static int asus_hotk_add(struct acpi_device *device) | |||
1164 | /* For laptops without GPLV: init the hotk->brightness value */ | 1277 | /* For laptops without GPLV: init the hotk->brightness value */ |
1165 | if ((!hotk->methods->brightness_get) | 1278 | if ((!hotk->methods->brightness_get) |
1166 | && (!hotk->methods->brightness_status) | 1279 | && (!hotk->methods->brightness_status) |
1167 | && (hotk->methods->brightness_up | 1280 | && (hotk->methods->brightness_up && hotk->methods->brightness_down)) { |
1168 | && hotk->methods->brightness_down)) { | ||
1169 | status = | 1281 | status = |
1170 | acpi_evaluate_object(NULL, hotk->methods->brightness_down, | 1282 | acpi_evaluate_object(NULL, hotk->methods->brightness_down, |
1171 | NULL, NULL); | 1283 | NULL, NULL); |
@@ -1184,6 +1296,9 @@ static int asus_hotk_add(struct acpi_device *device) | |||
1184 | 1296 | ||
1185 | asus_hotk_found = 1; | 1297 | asus_hotk_found = 1; |
1186 | 1298 | ||
1299 | /* LED display is off by default */ | ||
1300 | hotk->ledd_status = 0xFFF; | ||
1301 | |||
1187 | end: | 1302 | end: |
1188 | if (result) { | 1303 | if (result) { |
1189 | kfree(hotk); | 1304 | kfree(hotk); |
@@ -1256,7 +1371,7 @@ static void __exit asus_acpi_exit(void) | |||
1256 | acpi_bus_unregister_driver(&asus_hotk_driver); | 1371 | acpi_bus_unregister_driver(&asus_hotk_driver); |
1257 | remove_proc_entry(PROC_ASUS, acpi_root_dir); | 1372 | remove_proc_entry(PROC_ASUS, acpi_root_dir); |
1258 | 1373 | ||
1259 | acpi_os_free(asus_info); | 1374 | kfree(asus_info); |
1260 | 1375 | ||
1261 | return; | 1376 | return; |
1262 | } | 1377 | } |
diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c index 00b0728efe82..24bf4dca88cc 100644 --- a/drivers/acpi/battery.c +++ b/drivers/acpi/battery.c | |||
@@ -59,6 +59,9 @@ ACPI_MODULE_NAME("acpi_battery") | |||
59 | MODULE_DESCRIPTION(ACPI_BATTERY_DRIVER_NAME); | 59 | MODULE_DESCRIPTION(ACPI_BATTERY_DRIVER_NAME); |
60 | MODULE_LICENSE("GPL"); | 60 | MODULE_LICENSE("GPL"); |
61 | 61 | ||
62 | extern struct proc_dir_entry *acpi_lock_battery_dir(void); | ||
63 | extern void *acpi_unlock_battery_dir(struct proc_dir_entry *acpi_battery_dir); | ||
64 | |||
62 | static int acpi_battery_add(struct acpi_device *device); | 65 | static int acpi_battery_add(struct acpi_device *device); |
63 | static int acpi_battery_remove(struct acpi_device *device, int type); | 66 | static int acpi_battery_remove(struct acpi_device *device, int type); |
64 | 67 | ||
@@ -108,7 +111,7 @@ struct acpi_battery_trips { | |||
108 | }; | 111 | }; |
109 | 112 | ||
110 | struct acpi_battery { | 113 | struct acpi_battery { |
111 | acpi_handle handle; | 114 | struct acpi_device * device; |
112 | struct acpi_battery_flags flags; | 115 | struct acpi_battery_flags flags; |
113 | struct acpi_battery_trips trips; | 116 | struct acpi_battery_trips trips; |
114 | unsigned long alarm; | 117 | unsigned long alarm; |
@@ -138,7 +141,7 @@ acpi_battery_get_info(struct acpi_battery *battery, | |||
138 | 141 | ||
139 | /* Evalute _BIF */ | 142 | /* Evalute _BIF */ |
140 | 143 | ||
141 | status = acpi_evaluate_object(battery->handle, "_BIF", NULL, &buffer); | 144 | status = acpi_evaluate_object(battery->device->handle, "_BIF", NULL, &buffer); |
142 | if (ACPI_FAILURE(status)) { | 145 | if (ACPI_FAILURE(status)) { |
143 | ACPI_EXCEPTION((AE_INFO, status, "Evaluating _BIF")); | 146 | ACPI_EXCEPTION((AE_INFO, status, "Evaluating _BIF")); |
144 | return -ENODEV; | 147 | return -ENODEV; |
@@ -171,7 +174,7 @@ acpi_battery_get_info(struct acpi_battery *battery, | |||
171 | } | 174 | } |
172 | 175 | ||
173 | end: | 176 | end: |
174 | acpi_os_free(buffer.pointer); | 177 | kfree(buffer.pointer); |
175 | 178 | ||
176 | if (!result) | 179 | if (!result) |
177 | (*bif) = (struct acpi_battery_info *)data.pointer; | 180 | (*bif) = (struct acpi_battery_info *)data.pointer; |
@@ -198,7 +201,7 @@ acpi_battery_get_status(struct acpi_battery *battery, | |||
198 | 201 | ||
199 | /* Evalute _BST */ | 202 | /* Evalute _BST */ |
200 | 203 | ||
201 | status = acpi_evaluate_object(battery->handle, "_BST", NULL, &buffer); | 204 | status = acpi_evaluate_object(battery->device->handle, "_BST", NULL, &buffer); |
202 | if (ACPI_FAILURE(status)) { | 205 | if (ACPI_FAILURE(status)) { |
203 | ACPI_EXCEPTION((AE_INFO, status, "Evaluating _BST")); | 206 | ACPI_EXCEPTION((AE_INFO, status, "Evaluating _BST")); |
204 | return -ENODEV; | 207 | return -ENODEV; |
@@ -231,7 +234,7 @@ acpi_battery_get_status(struct acpi_battery *battery, | |||
231 | } | 234 | } |
232 | 235 | ||
233 | end: | 236 | end: |
234 | acpi_os_free(buffer.pointer); | 237 | kfree(buffer.pointer); |
235 | 238 | ||
236 | if (!result) | 239 | if (!result) |
237 | (*bst) = (struct acpi_battery_status *)data.pointer; | 240 | (*bst) = (struct acpi_battery_status *)data.pointer; |
@@ -255,7 +258,7 @@ acpi_battery_set_alarm(struct acpi_battery *battery, unsigned long alarm) | |||
255 | 258 | ||
256 | arg0.integer.value = alarm; | 259 | arg0.integer.value = alarm; |
257 | 260 | ||
258 | status = acpi_evaluate_object(battery->handle, "_BTP", &arg_list, NULL); | 261 | status = acpi_evaluate_object(battery->device->handle, "_BTP", &arg_list, NULL); |
259 | if (ACPI_FAILURE(status)) | 262 | if (ACPI_FAILURE(status)) |
260 | return -ENODEV; | 263 | return -ENODEV; |
261 | 264 | ||
@@ -278,9 +281,7 @@ static int acpi_battery_check(struct acpi_battery *battery) | |||
278 | if (!battery) | 281 | if (!battery) |
279 | return -EINVAL; | 282 | return -EINVAL; |
280 | 283 | ||
281 | result = acpi_bus_get_device(battery->handle, &device); | 284 | device = battery->device; |
282 | if (result) | ||
283 | return result; | ||
284 | 285 | ||
285 | result = acpi_bus_get_status(device); | 286 | result = acpi_bus_get_status(device); |
286 | if (result) | 287 | if (result) |
@@ -305,7 +306,7 @@ static int acpi_battery_check(struct acpi_battery *battery) | |||
305 | 306 | ||
306 | /* See if alarms are supported, and if so, set default */ | 307 | /* See if alarms are supported, and if so, set default */ |
307 | 308 | ||
308 | status = acpi_get_handle(battery->handle, "_BTP", &handle); | 309 | status = acpi_get_handle(battery->device->handle, "_BTP", &handle); |
309 | if (ACPI_SUCCESS(status)) { | 310 | if (ACPI_SUCCESS(status)) { |
310 | battery->flags.alarm = 1; | 311 | battery->flags.alarm = 1; |
311 | acpi_battery_set_alarm(battery, battery->trips.warning); | 312 | acpi_battery_set_alarm(battery, battery->trips.warning); |
@@ -662,12 +663,13 @@ static void acpi_battery_notify(acpi_handle handle, u32 event, void *data) | |||
662 | if (!battery) | 663 | if (!battery) |
663 | return; | 664 | return; |
664 | 665 | ||
665 | if (acpi_bus_get_device(handle, &device)) | 666 | device = battery->device; |
666 | return; | ||
667 | 667 | ||
668 | switch (event) { | 668 | switch (event) { |
669 | case ACPI_BATTERY_NOTIFY_STATUS: | 669 | case ACPI_BATTERY_NOTIFY_STATUS: |
670 | case ACPI_BATTERY_NOTIFY_INFO: | 670 | case ACPI_BATTERY_NOTIFY_INFO: |
671 | case ACPI_NOTIFY_BUS_CHECK: | ||
672 | case ACPI_NOTIFY_DEVICE_CHECK: | ||
671 | acpi_battery_check(battery); | 673 | acpi_battery_check(battery); |
672 | acpi_bus_generate_event(device, event, battery->flags.present); | 674 | acpi_bus_generate_event(device, event, battery->flags.present); |
673 | break; | 675 | break; |
@@ -695,7 +697,7 @@ static int acpi_battery_add(struct acpi_device *device) | |||
695 | return -ENOMEM; | 697 | return -ENOMEM; |
696 | memset(battery, 0, sizeof(struct acpi_battery)); | 698 | memset(battery, 0, sizeof(struct acpi_battery)); |
697 | 699 | ||
698 | battery->handle = device->handle; | 700 | battery->device = device; |
699 | strcpy(acpi_device_name(device), ACPI_BATTERY_DEVICE_NAME); | 701 | strcpy(acpi_device_name(device), ACPI_BATTERY_DEVICE_NAME); |
700 | strcpy(acpi_device_class(device), ACPI_BATTERY_CLASS); | 702 | strcpy(acpi_device_class(device), ACPI_BATTERY_CLASS); |
701 | acpi_driver_data(device) = battery; | 703 | acpi_driver_data(device) = battery; |
@@ -708,8 +710,8 @@ static int acpi_battery_add(struct acpi_device *device) | |||
708 | if (result) | 710 | if (result) |
709 | goto end; | 711 | goto end; |
710 | 712 | ||
711 | status = acpi_install_notify_handler(battery->handle, | 713 | status = acpi_install_notify_handler(device->handle, |
712 | ACPI_DEVICE_NOTIFY, | 714 | ACPI_ALL_NOTIFY, |
713 | acpi_battery_notify, battery); | 715 | acpi_battery_notify, battery); |
714 | if (ACPI_FAILURE(status)) { | 716 | if (ACPI_FAILURE(status)) { |
715 | result = -ENODEV; | 717 | result = -ENODEV; |
@@ -740,8 +742,8 @@ static int acpi_battery_remove(struct acpi_device *device, int type) | |||
740 | 742 | ||
741 | battery = (struct acpi_battery *)acpi_driver_data(device); | 743 | battery = (struct acpi_battery *)acpi_driver_data(device); |
742 | 744 | ||
743 | status = acpi_remove_notify_handler(battery->handle, | 745 | status = acpi_remove_notify_handler(device->handle, |
744 | ACPI_DEVICE_NOTIFY, | 746 | ACPI_ALL_NOTIFY, |
745 | acpi_battery_notify); | 747 | acpi_battery_notify); |
746 | 748 | ||
747 | acpi_battery_remove_fs(device); | 749 | acpi_battery_remove_fs(device); |
@@ -753,17 +755,15 @@ static int acpi_battery_remove(struct acpi_device *device, int type) | |||
753 | 755 | ||
754 | static int __init acpi_battery_init(void) | 756 | static int __init acpi_battery_init(void) |
755 | { | 757 | { |
756 | int result = 0; | 758 | int result; |
757 | |||
758 | 759 | ||
759 | acpi_battery_dir = proc_mkdir(ACPI_BATTERY_CLASS, acpi_root_dir); | 760 | acpi_battery_dir = acpi_lock_battery_dir(); |
760 | if (!acpi_battery_dir) | 761 | if (!acpi_battery_dir) |
761 | return -ENODEV; | 762 | return -ENODEV; |
762 | acpi_battery_dir->owner = THIS_MODULE; | ||
763 | 763 | ||
764 | result = acpi_bus_register_driver(&acpi_battery_driver); | 764 | result = acpi_bus_register_driver(&acpi_battery_driver); |
765 | if (result < 0) { | 765 | if (result < 0) { |
766 | remove_proc_entry(ACPI_BATTERY_CLASS, acpi_root_dir); | 766 | acpi_unlock_battery_dir(acpi_battery_dir); |
767 | return -ENODEV; | 767 | return -ENODEV; |
768 | } | 768 | } |
769 | 769 | ||
@@ -775,7 +775,7 @@ static void __exit acpi_battery_exit(void) | |||
775 | 775 | ||
776 | acpi_bus_unregister_driver(&acpi_battery_driver); | 776 | acpi_bus_unregister_driver(&acpi_battery_driver); |
777 | 777 | ||
778 | remove_proc_entry(ACPI_BATTERY_CLASS, acpi_root_dir); | 778 | acpi_unlock_battery_dir(acpi_battery_dir); |
779 | 779 | ||
780 | return; | 780 | return; |
781 | } | 781 | } |
diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c index 02594639c4d9..fd1ba05eab68 100644 --- a/drivers/acpi/button.c +++ b/drivers/acpi/button.c | |||
@@ -82,7 +82,6 @@ static struct acpi_driver acpi_button_driver = { | |||
82 | }; | 82 | }; |
83 | 83 | ||
84 | struct acpi_button { | 84 | struct acpi_button { |
85 | acpi_handle handle; | ||
86 | struct acpi_device *device; /* Fixed button kludge */ | 85 | struct acpi_device *device; /* Fixed button kludge */ |
87 | u8 type; | 86 | u8 type; |
88 | unsigned long pushed; | 87 | unsigned long pushed; |
@@ -137,7 +136,7 @@ static int acpi_button_state_seq_show(struct seq_file *seq, void *offset) | |||
137 | if (!button || !button->device) | 136 | if (!button || !button->device) |
138 | return 0; | 137 | return 0; |
139 | 138 | ||
140 | status = acpi_evaluate_integer(button->handle, "_LID", NULL, &state); | 139 | status = acpi_evaluate_integer(button->device->handle, "_LID", NULL, &state); |
141 | if (ACPI_FAILURE(status)) { | 140 | if (ACPI_FAILURE(status)) { |
142 | seq_printf(seq, "state: unsupported\n"); | 141 | seq_printf(seq, "state: unsupported\n"); |
143 | } else { | 142 | } else { |
@@ -282,7 +281,7 @@ static acpi_status acpi_button_notify_fixed(void *data) | |||
282 | if (!button) | 281 | if (!button) |
283 | return AE_BAD_PARAMETER; | 282 | return AE_BAD_PARAMETER; |
284 | 283 | ||
285 | acpi_button_notify(button->handle, ACPI_BUTTON_NOTIFY_STATUS, button); | 284 | acpi_button_notify(button->device->handle, ACPI_BUTTON_NOTIFY_STATUS, button); |
286 | 285 | ||
287 | return AE_OK; | 286 | return AE_OK; |
288 | } | 287 | } |
@@ -303,7 +302,6 @@ static int acpi_button_add(struct acpi_device *device) | |||
303 | memset(button, 0, sizeof(struct acpi_button)); | 302 | memset(button, 0, sizeof(struct acpi_button)); |
304 | 303 | ||
305 | button->device = device; | 304 | button->device = device; |
306 | button->handle = device->handle; | ||
307 | acpi_driver_data(device) = button; | 305 | acpi_driver_data(device) = button; |
308 | 306 | ||
309 | /* | 307 | /* |
@@ -362,7 +360,7 @@ static int acpi_button_add(struct acpi_device *device) | |||
362 | button); | 360 | button); |
363 | break; | 361 | break; |
364 | default: | 362 | default: |
365 | status = acpi_install_notify_handler(button->handle, | 363 | status = acpi_install_notify_handler(device->handle, |
366 | ACPI_DEVICE_NOTIFY, | 364 | ACPI_DEVICE_NOTIFY, |
367 | acpi_button_notify, | 365 | acpi_button_notify, |
368 | button); | 366 | button); |
@@ -420,7 +418,7 @@ static int acpi_button_remove(struct acpi_device *device, int type) | |||
420 | acpi_button_notify_fixed); | 418 | acpi_button_notify_fixed); |
421 | break; | 419 | break; |
422 | default: | 420 | default: |
423 | status = acpi_remove_notify_handler(button->handle, | 421 | status = acpi_remove_notify_handler(device->handle, |
424 | ACPI_DEVICE_NOTIFY, | 422 | ACPI_DEVICE_NOTIFY, |
425 | acpi_button_notify); | 423 | acpi_button_notify); |
426 | break; | 424 | break; |
diff --git a/drivers/acpi/cm_sbs.c b/drivers/acpi/cm_sbs.c new file mode 100644 index 000000000000..574a75a166c5 --- /dev/null +++ b/drivers/acpi/cm_sbs.c | |||
@@ -0,0 +1,131 @@ | |||
1 | /* | ||
2 | * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License as published by | ||
6 | * the Free Software Foundation; either version 2 of the License, or (at | ||
7 | * your option) any later version. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, but | ||
10 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
12 | * General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License along | ||
15 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
16 | * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. | ||
17 | * | ||
18 | * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
19 | */ | ||
20 | |||
21 | #include <linux/kernel.h> | ||
22 | #include <linux/module.h> | ||
23 | #include <linux/init.h> | ||
24 | #include <linux/acpi.h> | ||
25 | #include <linux/types.h> | ||
26 | #include <linux/proc_fs.h> | ||
27 | #include <linux/seq_file.h> | ||
28 | #include <acpi/acpi_bus.h> | ||
29 | #include <acpi/acpi_drivers.h> | ||
30 | #include <acpi/acmacros.h> | ||
31 | #include <acpi/actypes.h> | ||
32 | #include <acpi/acutils.h> | ||
33 | |||
34 | ACPI_MODULE_NAME("cm_sbs") | ||
35 | #define ACPI_AC_CLASS "ac_adapter" | ||
36 | #define ACPI_BATTERY_CLASS "battery" | ||
37 | #define ACPI_SBS_COMPONENT 0x00080000 | ||
38 | #define _COMPONENT ACPI_SBS_COMPONENT | ||
39 | static struct proc_dir_entry *acpi_ac_dir; | ||
40 | static struct proc_dir_entry *acpi_battery_dir; | ||
41 | |||
42 | static struct semaphore cm_sbs_sem; | ||
43 | |||
44 | static int lock_ac_dir_cnt = 0; | ||
45 | static int lock_battery_dir_cnt = 0; | ||
46 | |||
47 | struct proc_dir_entry *acpi_lock_ac_dir(void) | ||
48 | { | ||
49 | |||
50 | down(&cm_sbs_sem); | ||
51 | if (!acpi_ac_dir) { | ||
52 | acpi_ac_dir = proc_mkdir(ACPI_AC_CLASS, acpi_root_dir); | ||
53 | } | ||
54 | if (acpi_ac_dir) { | ||
55 | lock_ac_dir_cnt++; | ||
56 | } else { | ||
57 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, | ||
58 | "Cannot create %s\n", ACPI_AC_CLASS)); | ||
59 | } | ||
60 | up(&cm_sbs_sem); | ||
61 | return acpi_ac_dir; | ||
62 | } | ||
63 | |||
64 | EXPORT_SYMBOL(acpi_lock_ac_dir); | ||
65 | |||
66 | void acpi_unlock_ac_dir(struct proc_dir_entry *acpi_ac_dir_param) | ||
67 | { | ||
68 | |||
69 | down(&cm_sbs_sem); | ||
70 | if (acpi_ac_dir_param) { | ||
71 | lock_ac_dir_cnt--; | ||
72 | } | ||
73 | if (lock_ac_dir_cnt == 0 && acpi_ac_dir_param && acpi_ac_dir) { | ||
74 | remove_proc_entry(ACPI_AC_CLASS, acpi_root_dir); | ||
75 | acpi_ac_dir = 0; | ||
76 | } | ||
77 | up(&cm_sbs_sem); | ||
78 | } | ||
79 | |||
80 | EXPORT_SYMBOL(acpi_unlock_ac_dir); | ||
81 | |||
82 | struct proc_dir_entry *acpi_lock_battery_dir(void) | ||
83 | { | ||
84 | |||
85 | down(&cm_sbs_sem); | ||
86 | if (!acpi_battery_dir) { | ||
87 | acpi_battery_dir = | ||
88 | proc_mkdir(ACPI_BATTERY_CLASS, acpi_root_dir); | ||
89 | } | ||
90 | if (acpi_battery_dir) { | ||
91 | lock_battery_dir_cnt++; | ||
92 | } else { | ||
93 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, | ||
94 | "Cannot create %s\n", ACPI_BATTERY_CLASS)); | ||
95 | } | ||
96 | up(&cm_sbs_sem); | ||
97 | return acpi_battery_dir; | ||
98 | } | ||
99 | |||
100 | EXPORT_SYMBOL(acpi_lock_battery_dir); | ||
101 | |||
102 | void acpi_unlock_battery_dir(struct proc_dir_entry *acpi_battery_dir_param) | ||
103 | { | ||
104 | |||
105 | down(&cm_sbs_sem); | ||
106 | if (acpi_battery_dir_param) { | ||
107 | lock_battery_dir_cnt--; | ||
108 | } | ||
109 | if (lock_battery_dir_cnt == 0 && acpi_battery_dir_param | ||
110 | && acpi_battery_dir) { | ||
111 | remove_proc_entry(ACPI_BATTERY_CLASS, acpi_root_dir); | ||
112 | acpi_battery_dir = 0; | ||
113 | } | ||
114 | up(&cm_sbs_sem); | ||
115 | return; | ||
116 | } | ||
117 | |||
118 | EXPORT_SYMBOL(acpi_unlock_battery_dir); | ||
119 | |||
120 | static int __init acpi_cm_sbs_init(void) | ||
121 | { | ||
122 | |||
123 | if (acpi_disabled) | ||
124 | return 0; | ||
125 | |||
126 | init_MUTEX(&cm_sbs_sem); | ||
127 | |||
128 | return 0; | ||
129 | } | ||
130 | |||
131 | subsys_initcall(acpi_cm_sbs_init); | ||
diff --git a/drivers/acpi/container.c b/drivers/acpi/container.c index 7f7e41d40a3b..871aa520ece7 100644 --- a/drivers/acpi/container.c +++ b/drivers/acpi/container.c | |||
@@ -236,7 +236,7 @@ container_walk_namespace_cb(acpi_handle handle, | |||
236 | } | 236 | } |
237 | 237 | ||
238 | end: | 238 | end: |
239 | acpi_os_free(buffer.pointer); | 239 | kfree(buffer.pointer); |
240 | 240 | ||
241 | return AE_OK; | 241 | return AE_OK; |
242 | } | 242 | } |
diff --git a/drivers/acpi/fan.c b/drivers/acpi/fan.c index 38acc69b21bc..daed2460924d 100644 --- a/drivers/acpi/fan.c +++ b/drivers/acpi/fan.c | |||
@@ -64,7 +64,7 @@ static struct acpi_driver acpi_fan_driver = { | |||
64 | }; | 64 | }; |
65 | 65 | ||
66 | struct acpi_fan { | 66 | struct acpi_fan { |
67 | acpi_handle handle; | 67 | struct acpi_device * device; |
68 | }; | 68 | }; |
69 | 69 | ||
70 | /* -------------------------------------------------------------------------- | 70 | /* -------------------------------------------------------------------------- |
@@ -80,7 +80,7 @@ static int acpi_fan_read_state(struct seq_file *seq, void *offset) | |||
80 | 80 | ||
81 | 81 | ||
82 | if (fan) { | 82 | if (fan) { |
83 | if (acpi_bus_get_power(fan->handle, &state)) | 83 | if (acpi_bus_get_power(fan->device->handle, &state)) |
84 | seq_printf(seq, "status: ERROR\n"); | 84 | seq_printf(seq, "status: ERROR\n"); |
85 | else | 85 | else |
86 | seq_printf(seq, "status: %s\n", | 86 | seq_printf(seq, "status: %s\n", |
@@ -112,7 +112,7 @@ acpi_fan_write_state(struct file *file, const char __user * buffer, | |||
112 | 112 | ||
113 | state_string[count] = '\0'; | 113 | state_string[count] = '\0'; |
114 | 114 | ||
115 | result = acpi_bus_set_power(fan->handle, | 115 | result = acpi_bus_set_power(fan->device->handle, |
116 | simple_strtoul(state_string, NULL, 0)); | 116 | simple_strtoul(state_string, NULL, 0)); |
117 | if (result) | 117 | if (result) |
118 | return result; | 118 | return result; |
@@ -191,12 +191,12 @@ static int acpi_fan_add(struct acpi_device *device) | |||
191 | return -ENOMEM; | 191 | return -ENOMEM; |
192 | memset(fan, 0, sizeof(struct acpi_fan)); | 192 | memset(fan, 0, sizeof(struct acpi_fan)); |
193 | 193 | ||
194 | fan->handle = device->handle; | 194 | fan->device = device; |
195 | strcpy(acpi_device_name(device), "Fan"); | 195 | strcpy(acpi_device_name(device), "Fan"); |
196 | strcpy(acpi_device_class(device), ACPI_FAN_CLASS); | 196 | strcpy(acpi_device_class(device), ACPI_FAN_CLASS); |
197 | acpi_driver_data(device) = fan; | 197 | acpi_driver_data(device) = fan; |
198 | 198 | ||
199 | result = acpi_bus_get_power(fan->handle, &state); | 199 | result = acpi_bus_get_power(device->handle, &state); |
200 | if (result) { | 200 | if (result) { |
201 | printk(KERN_ERR PREFIX "Reading power state\n"); | 201 | printk(KERN_ERR PREFIX "Reading power state\n"); |
202 | goto end; | 202 | goto end; |
diff --git a/drivers/acpi/glue.c b/drivers/acpi/glue.c index 8daef57b994c..10f160dc75b1 100644 --- a/drivers/acpi/glue.c +++ b/drivers/acpi/glue.c | |||
@@ -152,7 +152,7 @@ static int get_root_bridge_busnr(acpi_handle handle) | |||
152 | bbn = bus; | 152 | bbn = bus; |
153 | } | 153 | } |
154 | exit: | 154 | exit: |
155 | acpi_os_free(buffer.pointer); | 155 | kfree(buffer.pointer); |
156 | return (int)bbn; | 156 | return (int)bbn; |
157 | } | 157 | } |
158 | 158 | ||
@@ -192,7 +192,7 @@ find_pci_rootbridge(acpi_handle handle, u32 lvl, void *context, void **rv) | |||
192 | find->handle = handle; | 192 | find->handle = handle; |
193 | status = AE_OK; | 193 | status = AE_OK; |
194 | exit: | 194 | exit: |
195 | acpi_os_free(buffer.pointer); | 195 | kfree(buffer.pointer); |
196 | return status; | 196 | return status; |
197 | } | 197 | } |
198 | 198 | ||
@@ -224,7 +224,7 @@ do_acpi_find_child(acpi_handle handle, u32 lvl, void *context, void **rv) | |||
224 | info = buffer.pointer; | 224 | info = buffer.pointer; |
225 | if (info->address == find->address) | 225 | if (info->address == find->address) |
226 | find->handle = handle; | 226 | find->handle = handle; |
227 | acpi_os_free(buffer.pointer); | 227 | kfree(buffer.pointer); |
228 | } | 228 | } |
229 | return AE_OK; | 229 | return AE_OK; |
230 | } | 230 | } |
@@ -330,7 +330,7 @@ static int acpi_platform_notify(struct device *dev) | |||
330 | 330 | ||
331 | acpi_get_name(dev->firmware_data, ACPI_FULL_PATHNAME, &buffer); | 331 | acpi_get_name(dev->firmware_data, ACPI_FULL_PATHNAME, &buffer); |
332 | DBG("Device %s -> %s\n", dev->bus_id, (char *)buffer.pointer); | 332 | DBG("Device %s -> %s\n", dev->bus_id, (char *)buffer.pointer); |
333 | acpi_os_free(buffer.pointer); | 333 | kfree(buffer.pointer); |
334 | } else | 334 | } else |
335 | DBG("Device %s -> No ACPI support\n", dev->bus_id); | 335 | DBG("Device %s -> No ACPI support\n", dev->bus_id); |
336 | #endif | 336 | #endif |
diff --git a/drivers/acpi/i2c_ec.c b/drivers/acpi/i2c_ec.c new file mode 100644 index 000000000000..84239d51dc0c --- /dev/null +++ b/drivers/acpi/i2c_ec.c | |||
@@ -0,0 +1,406 @@ | |||
1 | /* | ||
2 | * SMBus driver for ACPI Embedded Controller ($Revision: 1.3 $) | ||
3 | * | ||
4 | * Copyright (c) 2002, 2005 Ducrot Bruno | ||
5 | * Copyright (c) 2005 Rich Townsend (tiny hacks & tweaks) | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License as published by | ||
9 | * the Free Software Foundation version 2. | ||
10 | */ | ||
11 | |||
12 | #include <linux/version.h> | ||
13 | #include <linux/module.h> | ||
14 | #include <linux/slab.h> | ||
15 | #include <linux/kernel.h> | ||
16 | #include <linux/stddef.h> | ||
17 | #include <linux/sched.h> | ||
18 | #include <linux/init.h> | ||
19 | #include <linux/i2c.h> | ||
20 | #include <linux/acpi.h> | ||
21 | #include <linux/delay.h> | ||
22 | |||
23 | #include "i2c_ec.h" | ||
24 | |||
25 | #define xudelay(t) udelay(t) | ||
26 | #define xmsleep(t) msleep(t) | ||
27 | |||
28 | #define ACPI_EC_HC_COMPONENT 0x00080000 | ||
29 | #define ACPI_EC_HC_CLASS "ec_hc_smbus" | ||
30 | #define ACPI_EC_HC_HID "ACPI0001" | ||
31 | #define ACPI_EC_HC_DRIVER_NAME "ACPI EC HC smbus driver" | ||
32 | #define ACPI_EC_HC_DEVICE_NAME "EC HC smbus" | ||
33 | |||
34 | #define _COMPONENT ACPI_EC_HC_COMPONENT | ||
35 | |||
36 | ACPI_MODULE_NAME("acpi_smbus") | ||
37 | |||
38 | static int acpi_ec_hc_add(struct acpi_device *device); | ||
39 | static int acpi_ec_hc_remove(struct acpi_device *device, int type); | ||
40 | |||
41 | static struct acpi_driver acpi_ec_hc_driver = { | ||
42 | .name = ACPI_EC_HC_DRIVER_NAME, | ||
43 | .class = ACPI_EC_HC_CLASS, | ||
44 | .ids = ACPI_EC_HC_HID, | ||
45 | .ops = { | ||
46 | .add = acpi_ec_hc_add, | ||
47 | .remove = acpi_ec_hc_remove, | ||
48 | }, | ||
49 | }; | ||
50 | |||
51 | /* Various bit mask for EC_SC (R) */ | ||
52 | #define OBF 0x01 | ||
53 | #define IBF 0x02 | ||
54 | #define CMD 0x08 | ||
55 | #define BURST 0x10 | ||
56 | #define SCI_EVT 0x20 | ||
57 | #define SMI_EVT 0x40 | ||
58 | |||
59 | /* Commands for EC_SC (W) */ | ||
60 | #define RD_EC 0x80 | ||
61 | #define WR_EC 0x81 | ||
62 | #define BE_EC 0x82 | ||
63 | #define BD_EC 0x83 | ||
64 | #define QR_EC 0x84 | ||
65 | |||
66 | /* | ||
67 | * ACPI 2.0 chapter 13 SMBus 2.0 EC register model | ||
68 | */ | ||
69 | |||
70 | #define ACPI_EC_SMB_PRTCL 0x00 /* protocol, PEC */ | ||
71 | #define ACPI_EC_SMB_STS 0x01 /* status */ | ||
72 | #define ACPI_EC_SMB_ADDR 0x02 /* address */ | ||
73 | #define ACPI_EC_SMB_CMD 0x03 /* command */ | ||
74 | #define ACPI_EC_SMB_DATA 0x04 /* 32 data registers */ | ||
75 | #define ACPI_EC_SMB_BCNT 0x24 /* number of data bytes */ | ||
76 | #define ACPI_EC_SMB_ALRM_A 0x25 /* alarm address */ | ||
77 | #define ACPI_EC_SMB_ALRM_D 0x26 /* 2 bytes alarm data */ | ||
78 | |||
79 | #define ACPI_EC_SMB_STS_DONE 0x80 | ||
80 | #define ACPI_EC_SMB_STS_ALRM 0x40 | ||
81 | #define ACPI_EC_SMB_STS_RES 0x20 | ||
82 | #define ACPI_EC_SMB_STS_STATUS 0x1f | ||
83 | |||
84 | #define ACPI_EC_SMB_STATUS_OK 0x00 | ||
85 | #define ACPI_EC_SMB_STATUS_FAIL 0x07 | ||
86 | #define ACPI_EC_SMB_STATUS_DNAK 0x10 | ||
87 | #define ACPI_EC_SMB_STATUS_DERR 0x11 | ||
88 | #define ACPI_EC_SMB_STATUS_CMD_DENY 0x12 | ||
89 | #define ACPI_EC_SMB_STATUS_UNKNOWN 0x13 | ||
90 | #define ACPI_EC_SMB_STATUS_ACC_DENY 0x17 | ||
91 | #define ACPI_EC_SMB_STATUS_TIMEOUT 0x18 | ||
92 | #define ACPI_EC_SMB_STATUS_NOTSUP 0x19 | ||
93 | #define ACPI_EC_SMB_STATUS_BUSY 0x1A | ||
94 | #define ACPI_EC_SMB_STATUS_PEC 0x1F | ||
95 | |||
96 | #define ACPI_EC_SMB_PRTCL_WRITE 0x00 | ||
97 | #define ACPI_EC_SMB_PRTCL_READ 0x01 | ||
98 | #define ACPI_EC_SMB_PRTCL_QUICK 0x02 | ||
99 | #define ACPI_EC_SMB_PRTCL_BYTE 0x04 | ||
100 | #define ACPI_EC_SMB_PRTCL_BYTE_DATA 0x06 | ||
101 | #define ACPI_EC_SMB_PRTCL_WORD_DATA 0x08 | ||
102 | #define ACPI_EC_SMB_PRTCL_BLOCK_DATA 0x0a | ||
103 | #define ACPI_EC_SMB_PRTCL_PROC_CALL 0x0c | ||
104 | #define ACPI_EC_SMB_PRTCL_BLOCK_PROC_CALL 0x0d | ||
105 | #define ACPI_EC_SMB_PRTCL_I2C_BLOCK_DATA 0x4a | ||
106 | #define ACPI_EC_SMB_PRTCL_PEC 0x80 | ||
107 | |||
108 | /* Length of pre/post transaction sleep (msec) */ | ||
109 | #define ACPI_EC_SMB_TRANSACTION_SLEEP 1 | ||
110 | #define ACPI_EC_SMB_ACCESS_SLEEP1 1 | ||
111 | #define ACPI_EC_SMB_ACCESS_SLEEP2 10 | ||
112 | |||
113 | static int acpi_ec_smb_read(struct acpi_ec_smbus *smbus, u8 address, u8 * data) | ||
114 | { | ||
115 | u8 val; | ||
116 | int err; | ||
117 | |||
118 | err = ec_read(smbus->base + address, &val); | ||
119 | if (!err) { | ||
120 | *data = val; | ||
121 | } | ||
122 | xmsleep(ACPI_EC_SMB_TRANSACTION_SLEEP); | ||
123 | return (err); | ||
124 | } | ||
125 | |||
126 | static int acpi_ec_smb_write(struct acpi_ec_smbus *smbus, u8 address, u8 data) | ||
127 | { | ||
128 | int err; | ||
129 | |||
130 | err = ec_write(smbus->base + address, data); | ||
131 | return (err); | ||
132 | } | ||
133 | |||
134 | static int | ||
135 | acpi_ec_smb_access(struct i2c_adapter *adap, u16 addr, unsigned short flags, | ||
136 | char read_write, u8 command, int size, | ||
137 | union i2c_smbus_data *data) | ||
138 | { | ||
139 | struct acpi_ec_smbus *smbus = adap->algo_data; | ||
140 | unsigned char protocol, len = 0, pec, temp[2] = { 0, 0 }; | ||
141 | int i; | ||
142 | |||
143 | if (read_write == I2C_SMBUS_READ) { | ||
144 | protocol = ACPI_EC_SMB_PRTCL_READ; | ||
145 | } else { | ||
146 | protocol = ACPI_EC_SMB_PRTCL_WRITE; | ||
147 | } | ||
148 | pec = (flags & I2C_CLIENT_PEC) ? ACPI_EC_SMB_PRTCL_PEC : 0; | ||
149 | |||
150 | switch (size) { | ||
151 | |||
152 | case I2C_SMBUS_QUICK: | ||
153 | protocol |= ACPI_EC_SMB_PRTCL_QUICK; | ||
154 | read_write = I2C_SMBUS_WRITE; | ||
155 | break; | ||
156 | |||
157 | case I2C_SMBUS_BYTE: | ||
158 | if (read_write == I2C_SMBUS_WRITE) { | ||
159 | acpi_ec_smb_write(smbus, ACPI_EC_SMB_DATA, data->byte); | ||
160 | } | ||
161 | protocol |= ACPI_EC_SMB_PRTCL_BYTE; | ||
162 | break; | ||
163 | |||
164 | case I2C_SMBUS_BYTE_DATA: | ||
165 | acpi_ec_smb_write(smbus, ACPI_EC_SMB_CMD, command); | ||
166 | if (read_write == I2C_SMBUS_WRITE) { | ||
167 | acpi_ec_smb_write(smbus, ACPI_EC_SMB_DATA, data->byte); | ||
168 | } | ||
169 | protocol |= ACPI_EC_SMB_PRTCL_BYTE_DATA; | ||
170 | break; | ||
171 | |||
172 | case I2C_SMBUS_WORD_DATA: | ||
173 | acpi_ec_smb_write(smbus, ACPI_EC_SMB_CMD, command); | ||
174 | if (read_write == I2C_SMBUS_WRITE) { | ||
175 | acpi_ec_smb_write(smbus, ACPI_EC_SMB_DATA, data->word); | ||
176 | acpi_ec_smb_write(smbus, ACPI_EC_SMB_DATA + 1, | ||
177 | data->word >> 8); | ||
178 | } | ||
179 | protocol |= ACPI_EC_SMB_PRTCL_WORD_DATA | pec; | ||
180 | break; | ||
181 | |||
182 | case I2C_SMBUS_BLOCK_DATA: | ||
183 | acpi_ec_smb_write(smbus, ACPI_EC_SMB_CMD, command); | ||
184 | if (read_write == I2C_SMBUS_WRITE) { | ||
185 | len = min_t(u8, data->block[0], 32); | ||
186 | acpi_ec_smb_write(smbus, ACPI_EC_SMB_BCNT, len); | ||
187 | for (i = 0; i < len; i++) | ||
188 | acpi_ec_smb_write(smbus, ACPI_EC_SMB_DATA + i, | ||
189 | data->block[i + 1]); | ||
190 | } | ||
191 | protocol |= ACPI_EC_SMB_PRTCL_BLOCK_DATA | pec; | ||
192 | break; | ||
193 | |||
194 | case I2C_SMBUS_I2C_BLOCK_DATA: | ||
195 | len = min_t(u8, data->block[0], 32); | ||
196 | acpi_ec_smb_write(smbus, ACPI_EC_SMB_CMD, command); | ||
197 | acpi_ec_smb_write(smbus, ACPI_EC_SMB_BCNT, len); | ||
198 | if (read_write == I2C_SMBUS_WRITE) { | ||
199 | for (i = 0; i < len; i++) { | ||
200 | acpi_ec_smb_write(smbus, ACPI_EC_SMB_DATA + i, | ||
201 | data->block[i + 1]); | ||
202 | } | ||
203 | } | ||
204 | protocol |= ACPI_EC_SMB_PRTCL_I2C_BLOCK_DATA; | ||
205 | break; | ||
206 | |||
207 | case I2C_SMBUS_PROC_CALL: | ||
208 | acpi_ec_smb_write(smbus, ACPI_EC_SMB_CMD, command); | ||
209 | acpi_ec_smb_write(smbus, ACPI_EC_SMB_DATA, data->word); | ||
210 | acpi_ec_smb_write(smbus, ACPI_EC_SMB_DATA + 1, data->word >> 8); | ||
211 | protocol = ACPI_EC_SMB_PRTCL_PROC_CALL | pec; | ||
212 | read_write = I2C_SMBUS_READ; | ||
213 | break; | ||
214 | |||
215 | case I2C_SMBUS_BLOCK_PROC_CALL: | ||
216 | protocol |= pec; | ||
217 | len = min_t(u8, data->block[0], 31); | ||
218 | acpi_ec_smb_write(smbus, ACPI_EC_SMB_CMD, command); | ||
219 | acpi_ec_smb_write(smbus, ACPI_EC_SMB_BCNT, len); | ||
220 | for (i = 0; i < len; i++) | ||
221 | acpi_ec_smb_write(smbus, ACPI_EC_SMB_DATA + i, | ||
222 | data->block[i + 1]); | ||
223 | protocol = ACPI_EC_SMB_PRTCL_BLOCK_PROC_CALL | pec; | ||
224 | read_write = I2C_SMBUS_READ; | ||
225 | break; | ||
226 | |||
227 | default: | ||
228 | ACPI_DEBUG_PRINT((ACPI_DB_WARN, "EC SMBus adapter: " | ||
229 | "Unsupported transaction %d\n", size)); | ||
230 | return (-1); | ||
231 | } | ||
232 | |||
233 | acpi_ec_smb_write(smbus, ACPI_EC_SMB_ADDR, addr << 1); | ||
234 | acpi_ec_smb_write(smbus, ACPI_EC_SMB_PRTCL, protocol); | ||
235 | |||
236 | acpi_ec_smb_read(smbus, ACPI_EC_SMB_STS, temp + 0); | ||
237 | |||
238 | if (~temp[0] & ACPI_EC_SMB_STS_DONE) { | ||
239 | xudelay(500); | ||
240 | acpi_ec_smb_read(smbus, ACPI_EC_SMB_STS, temp + 0); | ||
241 | } | ||
242 | if (~temp[0] & ACPI_EC_SMB_STS_DONE) { | ||
243 | xmsleep(ACPI_EC_SMB_ACCESS_SLEEP2); | ||
244 | acpi_ec_smb_read(smbus, ACPI_EC_SMB_STS, temp + 0); | ||
245 | } | ||
246 | if ((~temp[0] & ACPI_EC_SMB_STS_DONE) | ||
247 | || (temp[0] & ACPI_EC_SMB_STS_STATUS)) { | ||
248 | return (-1); | ||
249 | } | ||
250 | |||
251 | if (read_write == I2C_SMBUS_WRITE) { | ||
252 | return (0); | ||
253 | } | ||
254 | |||
255 | switch (size) { | ||
256 | |||
257 | case I2C_SMBUS_BYTE: | ||
258 | case I2C_SMBUS_BYTE_DATA: | ||
259 | acpi_ec_smb_read(smbus, ACPI_EC_SMB_DATA, &data->byte); | ||
260 | break; | ||
261 | |||
262 | case I2C_SMBUS_WORD_DATA: | ||
263 | case I2C_SMBUS_PROC_CALL: | ||
264 | acpi_ec_smb_read(smbus, ACPI_EC_SMB_DATA, temp + 0); | ||
265 | acpi_ec_smb_read(smbus, ACPI_EC_SMB_DATA + 1, temp + 1); | ||
266 | data->word = (temp[1] << 8) | temp[0]; | ||
267 | break; | ||
268 | |||
269 | case I2C_SMBUS_BLOCK_DATA: | ||
270 | case I2C_SMBUS_BLOCK_PROC_CALL: | ||
271 | len = 0; | ||
272 | acpi_ec_smb_read(smbus, ACPI_EC_SMB_BCNT, &len); | ||
273 | len = min_t(u8, len, 32); | ||
274 | case I2C_SMBUS_I2C_BLOCK_DATA: | ||
275 | for (i = 0; i < len; i++) | ||
276 | acpi_ec_smb_read(smbus, ACPI_EC_SMB_DATA + i, | ||
277 | data->block + i + 1); | ||
278 | data->block[0] = len; | ||
279 | break; | ||
280 | } | ||
281 | |||
282 | return (0); | ||
283 | } | ||
284 | |||
285 | static u32 acpi_ec_smb_func(struct i2c_adapter *adapter) | ||
286 | { | ||
287 | |||
288 | return (I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE | | ||
289 | I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA | | ||
290 | I2C_FUNC_SMBUS_BLOCK_DATA | | ||
291 | I2C_FUNC_SMBUS_PROC_CALL | | ||
292 | I2C_FUNC_SMBUS_BLOCK_PROC_CALL | | ||
293 | I2C_FUNC_SMBUS_I2C_BLOCK | I2C_FUNC_SMBUS_HWPEC_CALC); | ||
294 | } | ||
295 | |||
296 | static struct i2c_algorithm acpi_ec_smbus_algorithm = { | ||
297 | .smbus_xfer = acpi_ec_smb_access, | ||
298 | .functionality = acpi_ec_smb_func, | ||
299 | }; | ||
300 | |||
301 | static int acpi_ec_hc_add(struct acpi_device *device) | ||
302 | { | ||
303 | int status; | ||
304 | unsigned long val; | ||
305 | struct acpi_ec_hc *ec_hc; | ||
306 | struct acpi_ec_smbus *smbus; | ||
307 | |||
308 | if (!device) { | ||
309 | return -EINVAL; | ||
310 | } | ||
311 | |||
312 | ec_hc = kmalloc(sizeof(struct acpi_ec_hc), GFP_KERNEL); | ||
313 | if (!ec_hc) { | ||
314 | return -ENOMEM; | ||
315 | } | ||
316 | memset(ec_hc, 0, sizeof(struct acpi_ec_hc)); | ||
317 | |||
318 | smbus = kmalloc(sizeof(struct acpi_ec_smbus), GFP_KERNEL); | ||
319 | if (!smbus) { | ||
320 | kfree(ec_hc); | ||
321 | return -ENOMEM; | ||
322 | } | ||
323 | memset(smbus, 0, sizeof(struct acpi_ec_smbus)); | ||
324 | |||
325 | ec_hc->handle = device->handle; | ||
326 | strcpy(acpi_device_name(device), ACPI_EC_HC_DEVICE_NAME); | ||
327 | strcpy(acpi_device_class(device), ACPI_EC_HC_CLASS); | ||
328 | acpi_driver_data(device) = ec_hc; | ||
329 | |||
330 | status = acpi_evaluate_integer(ec_hc->handle, "_EC", NULL, &val); | ||
331 | if (ACPI_FAILURE(status)) { | ||
332 | ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Error obtaining _EC\n")); | ||
333 | kfree(ec_hc->smbus); | ||
334 | kfree(smbus); | ||
335 | return -EIO; | ||
336 | } | ||
337 | |||
338 | smbus->ec = acpi_driver_data(device->parent); | ||
339 | smbus->base = (val & 0xff00ull) >> 8; | ||
340 | smbus->alert = val & 0xffull; | ||
341 | |||
342 | smbus->adapter.owner = THIS_MODULE; | ||
343 | smbus->adapter.algo = &acpi_ec_smbus_algorithm; | ||
344 | smbus->adapter.algo_data = smbus; | ||
345 | |||
346 | if (i2c_add_adapter(&smbus->adapter)) { | ||
347 | ACPI_DEBUG_PRINT((ACPI_DB_WARN, | ||
348 | "EC SMBus adapter: Failed to register adapter\n")); | ||
349 | kfree(smbus); | ||
350 | kfree(ec_hc); | ||
351 | return -EIO; | ||
352 | } | ||
353 | |||
354 | ec_hc->smbus = smbus; | ||
355 | |||
356 | printk(KERN_INFO PREFIX "%s [%s]\n", | ||
357 | acpi_device_name(device), acpi_device_bid(device)); | ||
358 | |||
359 | return AE_OK; | ||
360 | } | ||
361 | |||
362 | static int acpi_ec_hc_remove(struct acpi_device *device, int type) | ||
363 | { | ||
364 | struct acpi_ec_hc *ec_hc; | ||
365 | |||
366 | if (!device) { | ||
367 | return -EINVAL; | ||
368 | } | ||
369 | ec_hc = acpi_driver_data(device); | ||
370 | |||
371 | i2c_del_adapter(&ec_hc->smbus->adapter); | ||
372 | kfree(ec_hc->smbus); | ||
373 | kfree(ec_hc); | ||
374 | |||
375 | return AE_OK; | ||
376 | } | ||
377 | |||
378 | static int __init acpi_ec_hc_init(void) | ||
379 | { | ||
380 | int result; | ||
381 | |||
382 | result = acpi_bus_register_driver(&acpi_ec_hc_driver); | ||
383 | if (result < 0) { | ||
384 | return -ENODEV; | ||
385 | } | ||
386 | return 0; | ||
387 | } | ||
388 | |||
389 | static void __exit acpi_ec_hc_exit(void) | ||
390 | { | ||
391 | acpi_bus_unregister_driver(&acpi_ec_hc_driver); | ||
392 | } | ||
393 | |||
394 | struct acpi_ec_hc *acpi_get_ec_hc(struct acpi_device *device) | ||
395 | { | ||
396 | return ((struct acpi_ec_hc *)acpi_driver_data(device->parent)); | ||
397 | } | ||
398 | |||
399 | EXPORT_SYMBOL(acpi_get_ec_hc); | ||
400 | |||
401 | module_init(acpi_ec_hc_init); | ||
402 | module_exit(acpi_ec_hc_exit); | ||
403 | |||
404 | MODULE_LICENSE("GPL"); | ||
405 | MODULE_AUTHOR("Ducrot Bruno"); | ||
406 | MODULE_DESCRIPTION("ACPI EC SMBus driver"); | ||
diff --git a/drivers/acpi/i2c_ec.h b/drivers/acpi/i2c_ec.h new file mode 100644 index 000000000000..7c53fb732d61 --- /dev/null +++ b/drivers/acpi/i2c_ec.h | |||
@@ -0,0 +1,23 @@ | |||
1 | /* | ||
2 | * SMBus driver for ACPI Embedded Controller ($Revision: 1.2 $) | ||
3 | * | ||
4 | * Copyright (c) 2002, 2005 Ducrot Bruno | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation version 2. | ||
9 | */ | ||
10 | |||
11 | struct acpi_ec_smbus { | ||
12 | struct i2c_adapter adapter; | ||
13 | union acpi_ec *ec; | ||
14 | int base; | ||
15 | int alert; | ||
16 | }; | ||
17 | |||
18 | struct acpi_ec_hc { | ||
19 | acpi_handle handle; | ||
20 | struct acpi_ec_smbus *smbus; | ||
21 | }; | ||
22 | |||
23 | struct acpi_ec_hc *acpi_get_ec_hc(struct acpi_device *device); | ||
diff --git a/drivers/acpi/namespace/nsxfeval.c b/drivers/acpi/namespace/nsxfeval.c index 6d9bd45af30a..dca6799ac678 100644 --- a/drivers/acpi/namespace/nsxfeval.c +++ b/drivers/acpi/namespace/nsxfeval.c | |||
@@ -133,7 +133,7 @@ acpi_evaluate_object_typed(acpi_handle handle, | |||
133 | 133 | ||
134 | /* Caller used ACPI_ALLOCATE_BUFFER, free the return buffer */ | 134 | /* Caller used ACPI_ALLOCATE_BUFFER, free the return buffer */ |
135 | 135 | ||
136 | acpi_os_free(return_buffer->pointer); | 136 | ACPI_FREE(return_buffer->pointer); |
137 | return_buffer->pointer = NULL; | 137 | return_buffer->pointer = NULL; |
138 | } | 138 | } |
139 | 139 | ||
diff --git a/drivers/acpi/numa.c b/drivers/acpi/numa.c index 4d622981f61a..e5e448edca41 100644 --- a/drivers/acpi/numa.c +++ b/drivers/acpi/numa.c | |||
@@ -259,12 +259,10 @@ int acpi_get_node(acpi_handle *handle) | |||
259 | { | 259 | { |
260 | int pxm, node = -1; | 260 | int pxm, node = -1; |
261 | 261 | ||
262 | ACPI_FUNCTION_TRACE("acpi_get_node"); | ||
263 | |||
264 | pxm = acpi_get_pxm(handle); | 262 | pxm = acpi_get_pxm(handle); |
265 | if (pxm >= 0) | 263 | if (pxm >= 0) |
266 | node = acpi_map_pxm_to_node(pxm); | 264 | node = acpi_map_pxm_to_node(pxm); |
267 | 265 | ||
268 | return_VALUE(node); | 266 | return node; |
269 | } | 267 | } |
270 | EXPORT_SYMBOL(acpi_get_node); | 268 | EXPORT_SYMBOL(acpi_get_node); |
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c index 5a468e2779ae..eedb05c6dc7b 100644 --- a/drivers/acpi/osl.c +++ b/drivers/acpi/osl.c | |||
@@ -146,13 +146,6 @@ void *acpi_os_allocate(acpi_size size) | |||
146 | return kmalloc(size, GFP_KERNEL); | 146 | return kmalloc(size, GFP_KERNEL); |
147 | } | 147 | } |
148 | 148 | ||
149 | void acpi_os_free(void *ptr) | ||
150 | { | ||
151 | kfree(ptr); | ||
152 | } | ||
153 | |||
154 | EXPORT_SYMBOL(acpi_os_free); | ||
155 | |||
156 | acpi_status acpi_os_get_root_pointer(u32 flags, struct acpi_pointer *addr) | 149 | acpi_status acpi_os_get_root_pointer(u32 flags, struct acpi_pointer *addr) |
157 | { | 150 | { |
158 | if (efi_enabled) { | 151 | if (efi_enabled) { |
@@ -742,7 +735,7 @@ acpi_status acpi_os_delete_semaphore(acpi_handle handle) | |||
742 | 735 | ||
743 | ACPI_DEBUG_PRINT((ACPI_DB_MUTEX, "Deleting semaphore[%p].\n", handle)); | 736 | ACPI_DEBUG_PRINT((ACPI_DB_MUTEX, "Deleting semaphore[%p].\n", handle)); |
744 | 737 | ||
745 | acpi_os_free(sem); | 738 | kfree(sem); |
746 | sem = NULL; | 739 | sem = NULL; |
747 | 740 | ||
748 | return AE_OK; | 741 | return AE_OK; |
diff --git a/drivers/acpi/pci_link.c b/drivers/acpi/pci_link.c index 1badce27a83f..8197c0e40769 100644 --- a/drivers/acpi/pci_link.c +++ b/drivers/acpi/pci_link.c | |||
@@ -83,7 +83,6 @@ struct acpi_pci_link_irq { | |||
83 | struct acpi_pci_link { | 83 | struct acpi_pci_link { |
84 | struct list_head node; | 84 | struct list_head node; |
85 | struct acpi_device *device; | 85 | struct acpi_device *device; |
86 | acpi_handle handle; | ||
87 | struct acpi_pci_link_irq irq; | 86 | struct acpi_pci_link_irq irq; |
88 | int refcnt; | 87 | int refcnt; |
89 | }; | 88 | }; |
@@ -175,7 +174,7 @@ static int acpi_pci_link_get_possible(struct acpi_pci_link *link) | |||
175 | if (!link) | 174 | if (!link) |
176 | return -EINVAL; | 175 | return -EINVAL; |
177 | 176 | ||
178 | status = acpi_walk_resources(link->handle, METHOD_NAME__PRS, | 177 | status = acpi_walk_resources(link->device->handle, METHOD_NAME__PRS, |
179 | acpi_pci_link_check_possible, link); | 178 | acpi_pci_link_check_possible, link); |
180 | if (ACPI_FAILURE(status)) { | 179 | if (ACPI_FAILURE(status)) { |
181 | ACPI_EXCEPTION((AE_INFO, status, "Evaluating _PRS")); | 180 | ACPI_EXCEPTION((AE_INFO, status, "Evaluating _PRS")); |
@@ -249,8 +248,7 @@ static int acpi_pci_link_get_current(struct acpi_pci_link *link) | |||
249 | acpi_status status = AE_OK; | 248 | acpi_status status = AE_OK; |
250 | int irq = 0; | 249 | int irq = 0; |
251 | 250 | ||
252 | 251 | if (!link) | |
253 | if (!link || !link->handle) | ||
254 | return -EINVAL; | 252 | return -EINVAL; |
255 | 253 | ||
256 | link->irq.active = 0; | 254 | link->irq.active = 0; |
@@ -274,7 +272,7 @@ static int acpi_pci_link_get_current(struct acpi_pci_link *link) | |||
274 | * Query and parse _CRS to get the current IRQ assignment. | 272 | * Query and parse _CRS to get the current IRQ assignment. |
275 | */ | 273 | */ |
276 | 274 | ||
277 | status = acpi_walk_resources(link->handle, METHOD_NAME__CRS, | 275 | status = acpi_walk_resources(link->device->handle, METHOD_NAME__CRS, |
278 | acpi_pci_link_check_current, &irq); | 276 | acpi_pci_link_check_current, &irq); |
279 | if (ACPI_FAILURE(status)) { | 277 | if (ACPI_FAILURE(status)) { |
280 | ACPI_EXCEPTION((AE_INFO, status, "Evaluating _CRS")); | 278 | ACPI_EXCEPTION((AE_INFO, status, "Evaluating _CRS")); |
@@ -360,7 +358,7 @@ static int acpi_pci_link_set(struct acpi_pci_link *link, int irq) | |||
360 | resource->end.type = ACPI_RESOURCE_TYPE_END_TAG; | 358 | resource->end.type = ACPI_RESOURCE_TYPE_END_TAG; |
361 | 359 | ||
362 | /* Attempt to set the resource */ | 360 | /* Attempt to set the resource */ |
363 | status = acpi_set_current_resources(link->handle, &buffer); | 361 | status = acpi_set_current_resources(link->device->handle, &buffer); |
364 | 362 | ||
365 | /* check for total failure */ | 363 | /* check for total failure */ |
366 | if (ACPI_FAILURE(status)) { | 364 | if (ACPI_FAILURE(status)) { |
@@ -699,7 +697,7 @@ int acpi_pci_link_free_irq(acpi_handle handle) | |||
699 | acpi_device_bid(link->device))); | 697 | acpi_device_bid(link->device))); |
700 | 698 | ||
701 | if (link->refcnt == 0) { | 699 | if (link->refcnt == 0) { |
702 | acpi_ut_evaluate_object(link->handle, "_DIS", 0, NULL); | 700 | acpi_ut_evaluate_object(link->device->handle, "_DIS", 0, NULL); |
703 | } | 701 | } |
704 | mutex_unlock(&acpi_link_lock); | 702 | mutex_unlock(&acpi_link_lock); |
705 | return (link->irq.active); | 703 | return (link->irq.active); |
@@ -726,7 +724,6 @@ static int acpi_pci_link_add(struct acpi_device *device) | |||
726 | memset(link, 0, sizeof(struct acpi_pci_link)); | 724 | memset(link, 0, sizeof(struct acpi_pci_link)); |
727 | 725 | ||
728 | link->device = device; | 726 | link->device = device; |
729 | link->handle = device->handle; | ||
730 | strcpy(acpi_device_name(device), ACPI_PCI_LINK_DEVICE_NAME); | 727 | strcpy(acpi_device_name(device), ACPI_PCI_LINK_DEVICE_NAME); |
731 | strcpy(acpi_device_class(device), ACPI_PCI_LINK_CLASS); | 728 | strcpy(acpi_device_class(device), ACPI_PCI_LINK_CLASS); |
732 | acpi_driver_data(device) = link; | 729 | acpi_driver_data(device) = link; |
@@ -765,7 +762,7 @@ static int acpi_pci_link_add(struct acpi_device *device) | |||
765 | 762 | ||
766 | end: | 763 | end: |
767 | /* disable all links -- to be activated on use */ | 764 | /* disable all links -- to be activated on use */ |
768 | acpi_ut_evaluate_object(link->handle, "_DIS", 0, NULL); | 765 | acpi_ut_evaluate_object(device->handle, "_DIS", 0, NULL); |
769 | mutex_unlock(&acpi_link_lock); | 766 | mutex_unlock(&acpi_link_lock); |
770 | 767 | ||
771 | if (result) | 768 | if (result) |
diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c index 8f10442119f0..0984a1ee24ed 100644 --- a/drivers/acpi/pci_root.c +++ b/drivers/acpi/pci_root.c | |||
@@ -58,7 +58,7 @@ static struct acpi_driver acpi_pci_root_driver = { | |||
58 | 58 | ||
59 | struct acpi_pci_root { | 59 | struct acpi_pci_root { |
60 | struct list_head node; | 60 | struct list_head node; |
61 | acpi_handle handle; | 61 | struct acpi_device * device; |
62 | struct acpi_pci_id id; | 62 | struct acpi_pci_id id; |
63 | struct pci_bus *bus; | 63 | struct pci_bus *bus; |
64 | }; | 64 | }; |
@@ -83,7 +83,7 @@ int acpi_pci_register_driver(struct acpi_pci_driver *driver) | |||
83 | list_for_each(entry, &acpi_pci_roots) { | 83 | list_for_each(entry, &acpi_pci_roots) { |
84 | struct acpi_pci_root *root; | 84 | struct acpi_pci_root *root; |
85 | root = list_entry(entry, struct acpi_pci_root, node); | 85 | root = list_entry(entry, struct acpi_pci_root, node); |
86 | driver->add(root->handle); | 86 | driver->add(root->device->handle); |
87 | n++; | 87 | n++; |
88 | } | 88 | } |
89 | 89 | ||
@@ -110,7 +110,7 @@ void acpi_pci_unregister_driver(struct acpi_pci_driver *driver) | |||
110 | list_for_each(entry, &acpi_pci_roots) { | 110 | list_for_each(entry, &acpi_pci_roots) { |
111 | struct acpi_pci_root *root; | 111 | struct acpi_pci_root *root; |
112 | root = list_entry(entry, struct acpi_pci_root, node); | 112 | root = list_entry(entry, struct acpi_pci_root, node); |
113 | driver->remove(root->handle); | 113 | driver->remove(root->device->handle); |
114 | } | 114 | } |
115 | } | 115 | } |
116 | 116 | ||
@@ -170,7 +170,7 @@ static int acpi_pci_root_add(struct acpi_device *device) | |||
170 | memset(root, 0, sizeof(struct acpi_pci_root)); | 170 | memset(root, 0, sizeof(struct acpi_pci_root)); |
171 | INIT_LIST_HEAD(&root->node); | 171 | INIT_LIST_HEAD(&root->node); |
172 | 172 | ||
173 | root->handle = device->handle; | 173 | root->device = device; |
174 | strcpy(acpi_device_name(device), ACPI_PCI_ROOT_DEVICE_NAME); | 174 | strcpy(acpi_device_name(device), ACPI_PCI_ROOT_DEVICE_NAME); |
175 | strcpy(acpi_device_class(device), ACPI_PCI_ROOT_CLASS); | 175 | strcpy(acpi_device_class(device), ACPI_PCI_ROOT_CLASS); |
176 | acpi_driver_data(device) = root; | 176 | acpi_driver_data(device) = root; |
@@ -185,7 +185,7 @@ static int acpi_pci_root_add(struct acpi_device *device) | |||
185 | * ------- | 185 | * ------- |
186 | * Obtained via _SEG, if exists, otherwise assumed to be zero (0). | 186 | * Obtained via _SEG, if exists, otherwise assumed to be zero (0). |
187 | */ | 187 | */ |
188 | status = acpi_evaluate_integer(root->handle, METHOD_NAME__SEG, NULL, | 188 | status = acpi_evaluate_integer(device->handle, METHOD_NAME__SEG, NULL, |
189 | &value); | 189 | &value); |
190 | switch (status) { | 190 | switch (status) { |
191 | case AE_OK: | 191 | case AE_OK: |
@@ -207,7 +207,7 @@ static int acpi_pci_root_add(struct acpi_device *device) | |||
207 | * --- | 207 | * --- |
208 | * Obtained via _BBN, if exists, otherwise assumed to be zero (0). | 208 | * Obtained via _BBN, if exists, otherwise assumed to be zero (0). |
209 | */ | 209 | */ |
210 | status = acpi_evaluate_integer(root->handle, METHOD_NAME__BBN, NULL, | 210 | status = acpi_evaluate_integer(device->handle, METHOD_NAME__BBN, NULL, |
211 | &value); | 211 | &value); |
212 | switch (status) { | 212 | switch (status) { |
213 | case AE_OK: | 213 | case AE_OK: |
@@ -234,7 +234,7 @@ static int acpi_pci_root_add(struct acpi_device *device) | |||
234 | "Wrong _BBN value, reboot" | 234 | "Wrong _BBN value, reboot" |
235 | " and use option 'pci=noacpi'\n"); | 235 | " and use option 'pci=noacpi'\n"); |
236 | 236 | ||
237 | status = try_get_root_bridge_busnr(root->handle, &bus); | 237 | status = try_get_root_bridge_busnr(device->handle, &bus); |
238 | if (ACPI_FAILURE(status)) | 238 | if (ACPI_FAILURE(status)) |
239 | break; | 239 | break; |
240 | if (bus != root->id.bus) { | 240 | if (bus != root->id.bus) { |
@@ -294,9 +294,9 @@ static int acpi_pci_root_add(struct acpi_device *device) | |||
294 | * ----------------- | 294 | * ----------------- |
295 | * Evaluate and parse _PRT, if exists. | 295 | * Evaluate and parse _PRT, if exists. |
296 | */ | 296 | */ |
297 | status = acpi_get_handle(root->handle, METHOD_NAME__PRT, &handle); | 297 | status = acpi_get_handle(device->handle, METHOD_NAME__PRT, &handle); |
298 | if (ACPI_SUCCESS(status)) | 298 | if (ACPI_SUCCESS(status)) |
299 | result = acpi_pci_irq_add_prt(root->handle, root->id.segment, | 299 | result = acpi_pci_irq_add_prt(device->handle, root->id.segment, |
300 | root->id.bus); | 300 | root->id.bus); |
301 | 301 | ||
302 | end: | 302 | end: |
@@ -315,7 +315,7 @@ static int acpi_pci_root_start(struct acpi_device *device) | |||
315 | 315 | ||
316 | 316 | ||
317 | list_for_each_entry(root, &acpi_pci_roots, node) { | 317 | list_for_each_entry(root, &acpi_pci_roots, node) { |
318 | if (root->handle == device->handle) { | 318 | if (root->device == device) { |
319 | pci_bus_add_devices(root->bus); | 319 | pci_bus_add_devices(root->bus); |
320 | return 0; | 320 | return 0; |
321 | } | 321 | } |
diff --git a/drivers/acpi/power.c b/drivers/acpi/power.c index 224f729f700e..5d3447f4582c 100644 --- a/drivers/acpi/power.c +++ b/drivers/acpi/power.c | |||
@@ -70,7 +70,7 @@ static struct acpi_driver acpi_power_driver = { | |||
70 | }; | 70 | }; |
71 | 71 | ||
72 | struct acpi_power_resource { | 72 | struct acpi_power_resource { |
73 | acpi_handle handle; | 73 | struct acpi_device * device; |
74 | acpi_bus_id name; | 74 | acpi_bus_id name; |
75 | u32 system_level; | 75 | u32 system_level; |
76 | u32 order; | 76 | u32 order; |
@@ -124,7 +124,7 @@ static int acpi_power_get_state(struct acpi_power_resource *resource) | |||
124 | if (!resource) | 124 | if (!resource) |
125 | return -EINVAL; | 125 | return -EINVAL; |
126 | 126 | ||
127 | status = acpi_evaluate_integer(resource->handle, "_STA", NULL, &sta); | 127 | status = acpi_evaluate_integer(resource->device->handle, "_STA", NULL, &sta); |
128 | if (ACPI_FAILURE(status)) | 128 | if (ACPI_FAILURE(status)) |
129 | return -ENODEV; | 129 | return -ENODEV; |
130 | 130 | ||
@@ -192,7 +192,7 @@ static int acpi_power_on(acpi_handle handle) | |||
192 | return 0; | 192 | return 0; |
193 | } | 193 | } |
194 | 194 | ||
195 | status = acpi_evaluate_object(resource->handle, "_ON", NULL, NULL); | 195 | status = acpi_evaluate_object(resource->device->handle, "_ON", NULL, NULL); |
196 | if (ACPI_FAILURE(status)) | 196 | if (ACPI_FAILURE(status)) |
197 | return -ENODEV; | 197 | return -ENODEV; |
198 | 198 | ||
@@ -203,10 +203,8 @@ static int acpi_power_on(acpi_handle handle) | |||
203 | return -ENOEXEC; | 203 | return -ENOEXEC; |
204 | 204 | ||
205 | /* Update the power resource's _device_ power state */ | 205 | /* Update the power resource's _device_ power state */ |
206 | result = acpi_bus_get_device(resource->handle, &device); | 206 | device = resource->device; |
207 | if (result) | 207 | resource->device->power.state = ACPI_STATE_D0; |
208 | return result; | ||
209 | device->power.state = ACPI_STATE_D0; | ||
210 | 208 | ||
211 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Resource [%s] turned on\n", | 209 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Resource [%s] turned on\n", |
212 | resource->name)); | 210 | resource->name)); |
@@ -242,7 +240,7 @@ static int acpi_power_off_device(acpi_handle handle) | |||
242 | return 0; | 240 | return 0; |
243 | } | 241 | } |
244 | 242 | ||
245 | status = acpi_evaluate_object(resource->handle, "_OFF", NULL, NULL); | 243 | status = acpi_evaluate_object(resource->device->handle, "_OFF", NULL, NULL); |
246 | if (ACPI_FAILURE(status)) | 244 | if (ACPI_FAILURE(status)) |
247 | return -ENODEV; | 245 | return -ENODEV; |
248 | 246 | ||
@@ -253,9 +251,7 @@ static int acpi_power_off_device(acpi_handle handle) | |||
253 | return -ENOEXEC; | 251 | return -ENOEXEC; |
254 | 252 | ||
255 | /* Update the power resource's _device_ power state */ | 253 | /* Update the power resource's _device_ power state */ |
256 | result = acpi_bus_get_device(resource->handle, &device); | 254 | device = resource->device; |
257 | if (result) | ||
258 | return result; | ||
259 | device->power.state = ACPI_STATE_D3; | 255 | device->power.state = ACPI_STATE_D3; |
260 | 256 | ||
261 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Resource [%s] turned off\n", | 257 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Resource [%s] turned off\n", |
@@ -544,14 +540,14 @@ static int acpi_power_add(struct acpi_device *device) | |||
544 | return -ENOMEM; | 540 | return -ENOMEM; |
545 | memset(resource, 0, sizeof(struct acpi_power_resource)); | 541 | memset(resource, 0, sizeof(struct acpi_power_resource)); |
546 | 542 | ||
547 | resource->handle = device->handle; | 543 | resource->device = device; |
548 | strcpy(resource->name, device->pnp.bus_id); | 544 | strcpy(resource->name, device->pnp.bus_id); |
549 | strcpy(acpi_device_name(device), ACPI_POWER_DEVICE_NAME); | 545 | strcpy(acpi_device_name(device), ACPI_POWER_DEVICE_NAME); |
550 | strcpy(acpi_device_class(device), ACPI_POWER_CLASS); | 546 | strcpy(acpi_device_class(device), ACPI_POWER_CLASS); |
551 | acpi_driver_data(device) = resource; | 547 | acpi_driver_data(device) = resource; |
552 | 548 | ||
553 | /* Evalute the object to get the system level and resource order. */ | 549 | /* Evalute the object to get the system level and resource order. */ |
554 | status = acpi_evaluate_object(resource->handle, NULL, NULL, &buffer); | 550 | status = acpi_evaluate_object(device->handle, NULL, NULL, &buffer); |
555 | if (ACPI_FAILURE(status)) { | 551 | if (ACPI_FAILURE(status)) { |
556 | result = -ENODEV; | 552 | result = -ENODEV; |
557 | goto end; | 553 | goto end; |
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c index e439eb77d283..8e9c26aae8fe 100644 --- a/drivers/acpi/processor_idle.c +++ b/drivers/acpi/processor_idle.c | |||
@@ -768,7 +768,7 @@ static int acpi_processor_get_power_info_cst(struct acpi_processor *pr) | |||
768 | status = -EFAULT; | 768 | status = -EFAULT; |
769 | 769 | ||
770 | end: | 770 | end: |
771 | acpi_os_free(buffer.pointer); | 771 | kfree(buffer.pointer); |
772 | 772 | ||
773 | return status; | 773 | return status; |
774 | } | 774 | } |
diff --git a/drivers/acpi/processor_perflib.c b/drivers/acpi/processor_perflib.c index 14a00e5a8f6a..7ba5e49ab302 100644 --- a/drivers/acpi/processor_perflib.c +++ b/drivers/acpi/processor_perflib.c | |||
@@ -216,7 +216,7 @@ static int acpi_processor_get_performance_control(struct acpi_processor *pr) | |||
216 | sizeof(struct acpi_pct_register)); | 216 | sizeof(struct acpi_pct_register)); |
217 | 217 | ||
218 | end: | 218 | end: |
219 | acpi_os_free(buffer.pointer); | 219 | kfree(buffer.pointer); |
220 | 220 | ||
221 | return result; | 221 | return result; |
222 | } | 222 | } |
@@ -294,7 +294,7 @@ static int acpi_processor_get_performance_states(struct acpi_processor *pr) | |||
294 | } | 294 | } |
295 | 295 | ||
296 | end: | 296 | end: |
297 | acpi_os_free(buffer.pointer); | 297 | kfree(buffer.pointer); |
298 | 298 | ||
299 | return result; | 299 | return result; |
300 | } | 300 | } |
@@ -592,7 +592,7 @@ static int acpi_processor_get_psd(struct acpi_processor *pr) | |||
592 | } | 592 | } |
593 | 593 | ||
594 | end: | 594 | end: |
595 | acpi_os_free(buffer.pointer); | 595 | kfree(buffer.pointer); |
596 | return result; | 596 | return result; |
597 | } | 597 | } |
598 | 598 | ||
diff --git a/drivers/acpi/sbs.c b/drivers/acpi/sbs.c new file mode 100644 index 000000000000..db7b350a5035 --- /dev/null +++ b/drivers/acpi/sbs.c | |||
@@ -0,0 +1,1766 @@ | |||
1 | /* | ||
2 | * acpi_sbs.c - ACPI Smart Battery System Driver ($Revision: 1.16 $) | ||
3 | * | ||
4 | * Copyright (c) 2005 Rich Townsend <rhdt@bartol.udel.edu> | ||
5 | * | ||
6 | * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License as published by | ||
10 | * the Free Software Foundation; either version 2 of the License, or (at | ||
11 | * your option) any later version. | ||
12 | * | ||
13 | * This program is distributed in the hope that it will be useful, but | ||
14 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
16 | * General Public License for more details. | ||
17 | * | ||
18 | * You should have received a copy of the GNU General Public License along | ||
19 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
20 | * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. | ||
21 | * | ||
22 | * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
23 | */ | ||
24 | |||
25 | #include <linux/init.h> | ||
26 | #include <linux/module.h> | ||
27 | #include <linux/moduleparam.h> | ||
28 | #include <linux/kernel.h> | ||
29 | #include <linux/proc_fs.h> | ||
30 | #include <linux/seq_file.h> | ||
31 | #include <asm/uaccess.h> | ||
32 | #include <linux/acpi.h> | ||
33 | #include <linux/i2c.h> | ||
34 | #include <linux/delay.h> | ||
35 | |||
36 | #include "i2c_ec.h" | ||
37 | |||
38 | #define DEF_CAPACITY_UNIT 3 | ||
39 | #define MAH_CAPACITY_UNIT 1 | ||
40 | #define MWH_CAPACITY_UNIT 2 | ||
41 | #define CAPACITY_UNIT DEF_CAPACITY_UNIT | ||
42 | |||
43 | #define REQUEST_UPDATE_MODE 1 | ||
44 | #define QUEUE_UPDATE_MODE 2 | ||
45 | |||
46 | #define DATA_TYPE_COMMON 0 | ||
47 | #define DATA_TYPE_INFO 1 | ||
48 | #define DATA_TYPE_STATE 2 | ||
49 | #define DATA_TYPE_ALARM 3 | ||
50 | #define DATA_TYPE_AC_STATE 4 | ||
51 | |||
52 | extern struct proc_dir_entry *acpi_lock_ac_dir(void); | ||
53 | extern struct proc_dir_entry *acpi_lock_battery_dir(void); | ||
54 | extern void acpi_unlock_ac_dir(struct proc_dir_entry *acpi_ac_dir); | ||
55 | extern void acpi_unlock_battery_dir(struct proc_dir_entry *acpi_battery_dir); | ||
56 | |||
57 | #define ACPI_SBS_COMPONENT 0x00080000 | ||
58 | #define ACPI_SBS_CLASS "sbs" | ||
59 | #define ACPI_AC_CLASS "ac_adapter" | ||
60 | #define ACPI_BATTERY_CLASS "battery" | ||
61 | #define ACPI_SBS_HID "ACPI0002" | ||
62 | #define ACPI_SBS_DRIVER_NAME "ACPI Smart Battery System Driver" | ||
63 | #define ACPI_SBS_DEVICE_NAME "Smart Battery System" | ||
64 | #define ACPI_SBS_FILE_INFO "info" | ||
65 | #define ACPI_SBS_FILE_STATE "state" | ||
66 | #define ACPI_SBS_FILE_ALARM "alarm" | ||
67 | #define ACPI_BATTERY_DIR_NAME "BAT%i" | ||
68 | #define ACPI_AC_DIR_NAME "AC0" | ||
69 | #define ACPI_SBC_SMBUS_ADDR 0x9 | ||
70 | #define ACPI_SBSM_SMBUS_ADDR 0xa | ||
71 | #define ACPI_SB_SMBUS_ADDR 0xb | ||
72 | #define ACPI_SBS_AC_NOTIFY_STATUS 0x80 | ||
73 | #define ACPI_SBS_BATTERY_NOTIFY_STATUS 0x80 | ||
74 | #define ACPI_SBS_BATTERY_NOTIFY_INFO 0x81 | ||
75 | |||
76 | #define _COMPONENT ACPI_SBS_COMPONENT | ||
77 | |||
78 | #define MAX_SBS_BAT 4 | ||
79 | #define MAX_SMBUS_ERR 1 | ||
80 | |||
81 | ACPI_MODULE_NAME("acpi_sbs"); | ||
82 | |||
83 | MODULE_AUTHOR("Rich Townsend"); | ||
84 | MODULE_DESCRIPTION("Smart Battery System ACPI interface driver"); | ||
85 | MODULE_LICENSE("GPL"); | ||
86 | |||
87 | static struct semaphore sbs_sem; | ||
88 | |||
89 | #define UPDATE_MODE QUEUE_UPDATE_MODE | ||
90 | /* REQUEST_UPDATE_MODE QUEUE_UPDATE_MODE */ | ||
91 | #define UPDATE_INFO_MODE 0 | ||
92 | #define UPDATE_TIME 60 | ||
93 | #define UPDATE_TIME2 0 | ||
94 | |||
95 | static int capacity_mode = CAPACITY_UNIT; | ||
96 | static int update_mode = UPDATE_MODE; | ||
97 | static int update_info_mode = UPDATE_INFO_MODE; | ||
98 | static int update_time = UPDATE_TIME; | ||
99 | static int update_time2 = UPDATE_TIME2; | ||
100 | |||
101 | module_param(capacity_mode, int, CAPACITY_UNIT); | ||
102 | module_param(update_mode, int, UPDATE_MODE); | ||
103 | module_param(update_info_mode, int, UPDATE_INFO_MODE); | ||
104 | module_param(update_time, int, UPDATE_TIME); | ||
105 | module_param(update_time2, int, UPDATE_TIME2); | ||
106 | |||
107 | static int acpi_sbs_add(struct acpi_device *device); | ||
108 | static int acpi_sbs_remove(struct acpi_device *device, int type); | ||
109 | static void acpi_battery_smbus_err_handler(struct acpi_ec_smbus *smbus); | ||
110 | static void acpi_sbs_update_queue(void *data); | ||
111 | |||
112 | static struct acpi_driver acpi_sbs_driver = { | ||
113 | .name = ACPI_SBS_DRIVER_NAME, | ||
114 | .class = ACPI_SBS_CLASS, | ||
115 | .ids = ACPI_SBS_HID, | ||
116 | .ops = { | ||
117 | .add = acpi_sbs_add, | ||
118 | .remove = acpi_sbs_remove, | ||
119 | }, | ||
120 | }; | ||
121 | |||
122 | struct acpi_battery_info { | ||
123 | int capacity_mode; | ||
124 | s16 full_charge_capacity; | ||
125 | s16 design_capacity; | ||
126 | s16 design_voltage; | ||
127 | int vscale; | ||
128 | int ipscale; | ||
129 | s16 serial_number; | ||
130 | char manufacturer_name[I2C_SMBUS_BLOCK_MAX + 3]; | ||
131 | char device_name[I2C_SMBUS_BLOCK_MAX + 3]; | ||
132 | char device_chemistry[I2C_SMBUS_BLOCK_MAX + 3]; | ||
133 | }; | ||
134 | |||
135 | struct acpi_battery_state { | ||
136 | s16 voltage; | ||
137 | s16 amperage; | ||
138 | s16 remaining_capacity; | ||
139 | s16 average_time_to_empty; | ||
140 | s16 average_time_to_full; | ||
141 | s16 battery_status; | ||
142 | }; | ||
143 | |||
144 | struct acpi_battery_alarm { | ||
145 | s16 remaining_capacity; | ||
146 | }; | ||
147 | |||
148 | struct acpi_battery { | ||
149 | int alive; | ||
150 | int battery_present; | ||
151 | int id; | ||
152 | int init_state; | ||
153 | struct acpi_sbs *sbs; | ||
154 | struct acpi_battery_info info; | ||
155 | struct acpi_battery_state state; | ||
156 | struct acpi_battery_alarm alarm; | ||
157 | struct proc_dir_entry *battery_entry; | ||
158 | }; | ||
159 | |||
160 | struct acpi_sbs { | ||
161 | acpi_handle handle; | ||
162 | struct acpi_device *device; | ||
163 | struct acpi_ec_smbus *smbus; | ||
164 | int sbsm_present; | ||
165 | int sbsm_batteries_supported; | ||
166 | int ac_present; | ||
167 | struct proc_dir_entry *ac_entry; | ||
168 | struct acpi_battery battery[MAX_SBS_BAT]; | ||
169 | int update_info_mode; | ||
170 | int zombie; | ||
171 | int update_time; | ||
172 | int update_time2; | ||
173 | struct timer_list update_timer; | ||
174 | }; | ||
175 | |||
176 | static void acpi_update_delay(struct acpi_sbs *sbs); | ||
177 | static int acpi_sbs_update_run(struct acpi_sbs *sbs, int data_type); | ||
178 | |||
179 | /* -------------------------------------------------------------------------- | ||
180 | SMBus Communication | ||
181 | -------------------------------------------------------------------------- */ | ||
182 | |||
183 | static void acpi_battery_smbus_err_handler(struct acpi_ec_smbus *smbus) | ||
184 | { | ||
185 | union i2c_smbus_data data; | ||
186 | int result = 0; | ||
187 | char *err_str; | ||
188 | int err_number; | ||
189 | |||
190 | data.word = 0; | ||
191 | |||
192 | result = smbus->adapter.algo-> | ||
193 | smbus_xfer(&smbus->adapter, | ||
194 | ACPI_SB_SMBUS_ADDR, | ||
195 | 0, I2C_SMBUS_READ, 0x16, I2C_SMBUS_BLOCK_DATA, &data); | ||
196 | |||
197 | err_number = (data.word & 0x000f); | ||
198 | |||
199 | switch (data.word & 0x000f) { | ||
200 | case 0x0000: | ||
201 | err_str = "unexpected bus error"; | ||
202 | break; | ||
203 | case 0x0001: | ||
204 | err_str = "busy"; | ||
205 | break; | ||
206 | case 0x0002: | ||
207 | err_str = "reserved command"; | ||
208 | break; | ||
209 | case 0x0003: | ||
210 | err_str = "unsupported command"; | ||
211 | break; | ||
212 | case 0x0004: | ||
213 | err_str = "access denied"; | ||
214 | break; | ||
215 | case 0x0005: | ||
216 | err_str = "overflow/underflow"; | ||
217 | break; | ||
218 | case 0x0006: | ||
219 | err_str = "bad size"; | ||
220 | break; | ||
221 | case 0x0007: | ||
222 | err_str = "unknown error"; | ||
223 | break; | ||
224 | default: | ||
225 | err_str = "unrecognized error"; | ||
226 | } | ||
227 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, | ||
228 | "%s: ret %i, err %i\n", err_str, result, err_number)); | ||
229 | } | ||
230 | |||
231 | static int | ||
232 | acpi_sbs_smbus_read_word(struct acpi_ec_smbus *smbus, int addr, int func, | ||
233 | u16 * word, | ||
234 | void (*err_handler) (struct acpi_ec_smbus * smbus)) | ||
235 | { | ||
236 | union i2c_smbus_data data; | ||
237 | int result = 0; | ||
238 | int i; | ||
239 | |||
240 | if (err_handler == NULL) { | ||
241 | err_handler = acpi_battery_smbus_err_handler; | ||
242 | } | ||
243 | |||
244 | for (i = 0; i < MAX_SMBUS_ERR; i++) { | ||
245 | result = | ||
246 | smbus->adapter.algo->smbus_xfer(&smbus->adapter, addr, 0, | ||
247 | I2C_SMBUS_READ, func, | ||
248 | I2C_SMBUS_WORD_DATA, &data); | ||
249 | if (result) { | ||
250 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, | ||
251 | "try %i: smbus->adapter.algo->smbus_xfer() failed\n", | ||
252 | i)); | ||
253 | if (err_handler) { | ||
254 | err_handler(smbus); | ||
255 | } | ||
256 | } else { | ||
257 | *word = data.word; | ||
258 | break; | ||
259 | } | ||
260 | } | ||
261 | |||
262 | return result; | ||
263 | } | ||
264 | |||
265 | static int | ||
266 | acpi_sbs_smbus_read_str(struct acpi_ec_smbus *smbus, int addr, int func, | ||
267 | char *str, | ||
268 | void (*err_handler) (struct acpi_ec_smbus * smbus)) | ||
269 | { | ||
270 | union i2c_smbus_data data; | ||
271 | int result = 0; | ||
272 | int i; | ||
273 | |||
274 | if (err_handler == NULL) { | ||
275 | err_handler = acpi_battery_smbus_err_handler; | ||
276 | } | ||
277 | |||
278 | for (i = 0; i < MAX_SMBUS_ERR; i++) { | ||
279 | result = | ||
280 | smbus->adapter.algo->smbus_xfer(&smbus->adapter, addr, 0, | ||
281 | I2C_SMBUS_READ, func, | ||
282 | I2C_SMBUS_BLOCK_DATA, | ||
283 | &data); | ||
284 | if (result) { | ||
285 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, | ||
286 | "try %i: smbus->adapter.algo->smbus_xfer() failed\n", | ||
287 | i)); | ||
288 | if (err_handler) { | ||
289 | err_handler(smbus); | ||
290 | } | ||
291 | } else { | ||
292 | strncpy(str, (const char *)data.block + 1, | ||
293 | data.block[0]); | ||
294 | str[data.block[0]] = 0; | ||
295 | break; | ||
296 | } | ||
297 | } | ||
298 | |||
299 | return result; | ||
300 | } | ||
301 | |||
302 | static int | ||
303 | acpi_sbs_smbus_write_word(struct acpi_ec_smbus *smbus, int addr, int func, | ||
304 | int word, | ||
305 | void (*err_handler) (struct acpi_ec_smbus * smbus)) | ||
306 | { | ||
307 | union i2c_smbus_data data; | ||
308 | int result = 0; | ||
309 | int i; | ||
310 | |||
311 | if (err_handler == NULL) { | ||
312 | err_handler = acpi_battery_smbus_err_handler; | ||
313 | } | ||
314 | |||
315 | data.word = word; | ||
316 | |||
317 | for (i = 0; i < MAX_SMBUS_ERR; i++) { | ||
318 | result = | ||
319 | smbus->adapter.algo->smbus_xfer(&smbus->adapter, addr, 0, | ||
320 | I2C_SMBUS_WRITE, func, | ||
321 | I2C_SMBUS_WORD_DATA, &data); | ||
322 | if (result) { | ||
323 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, | ||
324 | "try %i: smbus->adapter.algo" | ||
325 | "->smbus_xfer() failed\n", i)); | ||
326 | if (err_handler) { | ||
327 | err_handler(smbus); | ||
328 | } | ||
329 | } else { | ||
330 | break; | ||
331 | } | ||
332 | } | ||
333 | |||
334 | return result; | ||
335 | } | ||
336 | |||
337 | /* -------------------------------------------------------------------------- | ||
338 | Smart Battery System Management | ||
339 | -------------------------------------------------------------------------- */ | ||
340 | |||
341 | /* Smart Battery */ | ||
342 | |||
343 | static int acpi_sbs_generate_event(struct acpi_device *device, | ||
344 | int event, int state, char *bid, char *class) | ||
345 | { | ||
346 | char bid_saved[5]; | ||
347 | char class_saved[20]; | ||
348 | int result = 0; | ||
349 | |||
350 | strcpy(bid_saved, acpi_device_bid(device)); | ||
351 | strcpy(class_saved, acpi_device_class(device)); | ||
352 | |||
353 | strcpy(acpi_device_bid(device), bid); | ||
354 | strcpy(acpi_device_class(device), class); | ||
355 | |||
356 | result = acpi_bus_generate_event(device, event, state); | ||
357 | |||
358 | strcpy(acpi_device_bid(device), bid_saved); | ||
359 | strcpy(acpi_device_class(device), class_saved); | ||
360 | |||
361 | return result; | ||
362 | } | ||
363 | |||
364 | static int acpi_battery_get_present(struct acpi_battery *battery) | ||
365 | { | ||
366 | s16 state; | ||
367 | int result = 0; | ||
368 | int is_present = 0; | ||
369 | |||
370 | result = acpi_sbs_smbus_read_word(battery->sbs->smbus, | ||
371 | ACPI_SBSM_SMBUS_ADDR, 0x01, | ||
372 | &state, NULL); | ||
373 | if (result) { | ||
374 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, | ||
375 | "acpi_sbs_smbus_read_word() failed")); | ||
376 | } | ||
377 | if (!result) { | ||
378 | is_present = (state & 0x000f) & (1 << battery->id); | ||
379 | } | ||
380 | battery->battery_present = is_present; | ||
381 | |||
382 | return result; | ||
383 | } | ||
384 | |||
385 | static int acpi_battery_is_present(struct acpi_battery *battery) | ||
386 | { | ||
387 | return (battery->battery_present); | ||
388 | } | ||
389 | |||
390 | static int acpi_ac_is_present(struct acpi_sbs *sbs) | ||
391 | { | ||
392 | return (sbs->ac_present); | ||
393 | } | ||
394 | |||
395 | static int acpi_battery_select(struct acpi_battery *battery) | ||
396 | { | ||
397 | struct acpi_ec_smbus *smbus = battery->sbs->smbus; | ||
398 | int result = 0; | ||
399 | s16 state; | ||
400 | int foo; | ||
401 | |||
402 | if (battery->sbs->sbsm_present) { | ||
403 | |||
404 | /* Take special care not to knobble other nibbles of | ||
405 | * state (aka selector_state), since | ||
406 | * it causes charging to halt on SBSELs */ | ||
407 | |||
408 | result = | ||
409 | acpi_sbs_smbus_read_word(smbus, ACPI_SBSM_SMBUS_ADDR, 0x01, | ||
410 | &state, NULL); | ||
411 | if (result) { | ||
412 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, | ||
413 | "acpi_sbs_smbus_read_word() failed\n")); | ||
414 | goto end; | ||
415 | } | ||
416 | |||
417 | foo = (state & 0x0fff) | (1 << (battery->id + 12)); | ||
418 | result = | ||
419 | acpi_sbs_smbus_write_word(smbus, ACPI_SBSM_SMBUS_ADDR, 0x01, | ||
420 | foo, NULL); | ||
421 | if (result) { | ||
422 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, | ||
423 | "acpi_sbs_smbus_write_word() failed\n")); | ||
424 | goto end; | ||
425 | } | ||
426 | } | ||
427 | |||
428 | end: | ||
429 | return result; | ||
430 | } | ||
431 | |||
432 | static int acpi_sbsm_get_info(struct acpi_sbs *sbs) | ||
433 | { | ||
434 | struct acpi_ec_smbus *smbus = sbs->smbus; | ||
435 | int result = 0; | ||
436 | s16 battery_system_info; | ||
437 | |||
438 | result = acpi_sbs_smbus_read_word(smbus, ACPI_SBSM_SMBUS_ADDR, 0x04, | ||
439 | &battery_system_info, NULL); | ||
440 | if (result) { | ||
441 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, | ||
442 | "acpi_sbs_smbus_read_word() failed\n")); | ||
443 | goto end; | ||
444 | } | ||
445 | |||
446 | sbs->sbsm_batteries_supported = battery_system_info & 0x000f; | ||
447 | |||
448 | end: | ||
449 | |||
450 | return result; | ||
451 | } | ||
452 | |||
453 | static int acpi_battery_get_info(struct acpi_battery *battery) | ||
454 | { | ||
455 | struct acpi_ec_smbus *smbus = battery->sbs->smbus; | ||
456 | int result = 0; | ||
457 | s16 battery_mode; | ||
458 | s16 specification_info; | ||
459 | |||
460 | result = acpi_sbs_smbus_read_word(smbus, ACPI_SB_SMBUS_ADDR, 0x03, | ||
461 | &battery_mode, | ||
462 | &acpi_battery_smbus_err_handler); | ||
463 | if (result) { | ||
464 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, | ||
465 | "acpi_sbs_smbus_read_word() failed\n")); | ||
466 | goto end; | ||
467 | } | ||
468 | battery->info.capacity_mode = (battery_mode & 0x8000) >> 15; | ||
469 | |||
470 | result = acpi_sbs_smbus_read_word(smbus, ACPI_SB_SMBUS_ADDR, 0x10, | ||
471 | &battery->info.full_charge_capacity, | ||
472 | &acpi_battery_smbus_err_handler); | ||
473 | if (result) { | ||
474 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, | ||
475 | "acpi_sbs_smbus_read_word() failed\n")); | ||
476 | goto end; | ||
477 | } | ||
478 | |||
479 | result = acpi_sbs_smbus_read_word(smbus, ACPI_SB_SMBUS_ADDR, 0x18, | ||
480 | &battery->info.design_capacity, | ||
481 | &acpi_battery_smbus_err_handler); | ||
482 | |||
483 | if (result) { | ||
484 | goto end; | ||
485 | } | ||
486 | |||
487 | result = acpi_sbs_smbus_read_word(smbus, ACPI_SB_SMBUS_ADDR, 0x19, | ||
488 | &battery->info.design_voltage, | ||
489 | &acpi_battery_smbus_err_handler); | ||
490 | if (result) { | ||
491 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, | ||
492 | "acpi_sbs_smbus_read_word() failed\n")); | ||
493 | goto end; | ||
494 | } | ||
495 | |||
496 | result = acpi_sbs_smbus_read_word(smbus, ACPI_SB_SMBUS_ADDR, 0x1a, | ||
497 | &specification_info, | ||
498 | &acpi_battery_smbus_err_handler); | ||
499 | if (result) { | ||
500 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, | ||
501 | "acpi_sbs_smbus_read_word() failed\n")); | ||
502 | goto end; | ||
503 | } | ||
504 | |||
505 | switch ((specification_info & 0x0f00) >> 8) { | ||
506 | case 1: | ||
507 | battery->info.vscale = 10; | ||
508 | break; | ||
509 | case 2: | ||
510 | battery->info.vscale = 100; | ||
511 | break; | ||
512 | case 3: | ||
513 | battery->info.vscale = 1000; | ||
514 | break; | ||
515 | default: | ||
516 | battery->info.vscale = 1; | ||
517 | } | ||
518 | |||
519 | switch ((specification_info & 0xf000) >> 12) { | ||
520 | case 1: | ||
521 | battery->info.ipscale = 10; | ||
522 | break; | ||
523 | case 2: | ||
524 | battery->info.ipscale = 100; | ||
525 | break; | ||
526 | case 3: | ||
527 | battery->info.ipscale = 1000; | ||
528 | break; | ||
529 | default: | ||
530 | battery->info.ipscale = 1; | ||
531 | } | ||
532 | |||
533 | result = acpi_sbs_smbus_read_word(smbus, ACPI_SB_SMBUS_ADDR, 0x1c, | ||
534 | &battery->info.serial_number, | ||
535 | &acpi_battery_smbus_err_handler); | ||
536 | if (result) { | ||
537 | goto end; | ||
538 | } | ||
539 | |||
540 | result = acpi_sbs_smbus_read_str(smbus, ACPI_SB_SMBUS_ADDR, 0x20, | ||
541 | battery->info.manufacturer_name, | ||
542 | &acpi_battery_smbus_err_handler); | ||
543 | if (result) { | ||
544 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, | ||
545 | "acpi_sbs_smbus_read_str() failed\n")); | ||
546 | goto end; | ||
547 | } | ||
548 | |||
549 | result = acpi_sbs_smbus_read_str(smbus, ACPI_SB_SMBUS_ADDR, 0x21, | ||
550 | battery->info.device_name, | ||
551 | &acpi_battery_smbus_err_handler); | ||
552 | if (result) { | ||
553 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, | ||
554 | "acpi_sbs_smbus_read_str() failed\n")); | ||
555 | goto end; | ||
556 | } | ||
557 | |||
558 | result = acpi_sbs_smbus_read_str(smbus, ACPI_SB_SMBUS_ADDR, 0x22, | ||
559 | battery->info.device_chemistry, | ||
560 | &acpi_battery_smbus_err_handler); | ||
561 | if (result) { | ||
562 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, | ||
563 | "acpi_sbs_smbus_read_str() failed\n")); | ||
564 | goto end; | ||
565 | } | ||
566 | |||
567 | end: | ||
568 | return result; | ||
569 | } | ||
570 | |||
571 | static void acpi_update_delay(struct acpi_sbs *sbs) | ||
572 | { | ||
573 | if (sbs->zombie) { | ||
574 | return; | ||
575 | } | ||
576 | if (sbs->update_time2 > 0) { | ||
577 | msleep(sbs->update_time2 * 1000); | ||
578 | } | ||
579 | } | ||
580 | |||
581 | static int acpi_battery_get_state(struct acpi_battery *battery) | ||
582 | { | ||
583 | struct acpi_ec_smbus *smbus = battery->sbs->smbus; | ||
584 | int result = 0; | ||
585 | |||
586 | acpi_update_delay(battery->sbs); | ||
587 | result = acpi_sbs_smbus_read_word(smbus, ACPI_SB_SMBUS_ADDR, 0x09, | ||
588 | &battery->state.voltage, | ||
589 | &acpi_battery_smbus_err_handler); | ||
590 | if (result) { | ||
591 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, | ||
592 | "acpi_sbs_smbus_read_word() failed\n")); | ||
593 | goto end; | ||
594 | } | ||
595 | |||
596 | acpi_update_delay(battery->sbs); | ||
597 | result = acpi_sbs_smbus_read_word(smbus, ACPI_SB_SMBUS_ADDR, 0x0a, | ||
598 | &battery->state.amperage, | ||
599 | &acpi_battery_smbus_err_handler); | ||
600 | if (result) { | ||
601 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, | ||
602 | "acpi_sbs_smbus_read_word() failed\n")); | ||
603 | goto end; | ||
604 | } | ||
605 | |||
606 | acpi_update_delay(battery->sbs); | ||
607 | result = acpi_sbs_smbus_read_word(smbus, ACPI_SB_SMBUS_ADDR, 0x0f, | ||
608 | &battery->state.remaining_capacity, | ||
609 | &acpi_battery_smbus_err_handler); | ||
610 | if (result) { | ||
611 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, | ||
612 | "acpi_sbs_smbus_read_word() failed\n")); | ||
613 | goto end; | ||
614 | } | ||
615 | |||
616 | acpi_update_delay(battery->sbs); | ||
617 | result = acpi_sbs_smbus_read_word(smbus, ACPI_SB_SMBUS_ADDR, 0x12, | ||
618 | &battery->state.average_time_to_empty, | ||
619 | &acpi_battery_smbus_err_handler); | ||
620 | if (result) { | ||
621 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, | ||
622 | "acpi_sbs_smbus_read_word() failed\n")); | ||
623 | goto end; | ||
624 | } | ||
625 | |||
626 | acpi_update_delay(battery->sbs); | ||
627 | result = acpi_sbs_smbus_read_word(smbus, ACPI_SB_SMBUS_ADDR, 0x13, | ||
628 | &battery->state.average_time_to_full, | ||
629 | &acpi_battery_smbus_err_handler); | ||
630 | if (result) { | ||
631 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, | ||
632 | "acpi_sbs_smbus_read_word() failed\n")); | ||
633 | goto end; | ||
634 | } | ||
635 | |||
636 | acpi_update_delay(battery->sbs); | ||
637 | result = acpi_sbs_smbus_read_word(smbus, ACPI_SB_SMBUS_ADDR, 0x16, | ||
638 | &battery->state.battery_status, | ||
639 | &acpi_battery_smbus_err_handler); | ||
640 | if (result) { | ||
641 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, | ||
642 | "acpi_sbs_smbus_read_word() failed\n")); | ||
643 | goto end; | ||
644 | } | ||
645 | |||
646 | acpi_update_delay(battery->sbs); | ||
647 | |||
648 | end: | ||
649 | return result; | ||
650 | } | ||
651 | |||
652 | static int acpi_battery_get_alarm(struct acpi_battery *battery) | ||
653 | { | ||
654 | struct acpi_ec_smbus *smbus = battery->sbs->smbus; | ||
655 | int result = 0; | ||
656 | |||
657 | result = acpi_sbs_smbus_read_word(smbus, ACPI_SB_SMBUS_ADDR, 0x01, | ||
658 | &battery->alarm.remaining_capacity, | ||
659 | &acpi_battery_smbus_err_handler); | ||
660 | if (result) { | ||
661 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, | ||
662 | "acpi_sbs_smbus_read_word() failed\n")); | ||
663 | goto end; | ||
664 | } | ||
665 | |||
666 | acpi_update_delay(battery->sbs); | ||
667 | |||
668 | end: | ||
669 | |||
670 | return result; | ||
671 | } | ||
672 | |||
673 | static int acpi_battery_set_alarm(struct acpi_battery *battery, | ||
674 | unsigned long alarm) | ||
675 | { | ||
676 | struct acpi_ec_smbus *smbus = battery->sbs->smbus; | ||
677 | int result = 0; | ||
678 | s16 battery_mode; | ||
679 | int foo; | ||
680 | |||
681 | result = acpi_battery_select(battery); | ||
682 | if (result) { | ||
683 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, | ||
684 | "acpi_battery_select() failed\n")); | ||
685 | goto end; | ||
686 | } | ||
687 | |||
688 | /* If necessary, enable the alarm */ | ||
689 | |||
690 | if (alarm > 0) { | ||
691 | result = | ||
692 | acpi_sbs_smbus_read_word(smbus, ACPI_SB_SMBUS_ADDR, 0x03, | ||
693 | &battery_mode, | ||
694 | &acpi_battery_smbus_err_handler); | ||
695 | if (result) { | ||
696 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, | ||
697 | "acpi_sbs_smbus_read_word() failed\n")); | ||
698 | goto end; | ||
699 | } | ||
700 | |||
701 | result = | ||
702 | acpi_sbs_smbus_write_word(smbus, ACPI_SB_SMBUS_ADDR, 0x01, | ||
703 | battery_mode & 0xbfff, | ||
704 | &acpi_battery_smbus_err_handler); | ||
705 | if (result) { | ||
706 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, | ||
707 | "acpi_sbs_smbus_write_word() failed\n")); | ||
708 | goto end; | ||
709 | } | ||
710 | } | ||
711 | |||
712 | foo = alarm / (battery->info.capacity_mode ? 10 : 1); | ||
713 | result = acpi_sbs_smbus_write_word(smbus, ACPI_SB_SMBUS_ADDR, 0x01, | ||
714 | foo, | ||
715 | &acpi_battery_smbus_err_handler); | ||
716 | if (result) { | ||
717 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, | ||
718 | "acpi_sbs_smbus_write_word() failed\n")); | ||
719 | goto end; | ||
720 | } | ||
721 | |||
722 | end: | ||
723 | |||
724 | return result; | ||
725 | } | ||
726 | |||
727 | static int acpi_battery_set_mode(struct acpi_battery *battery) | ||
728 | { | ||
729 | int result = 0; | ||
730 | s16 battery_mode; | ||
731 | |||
732 | if (capacity_mode == DEF_CAPACITY_UNIT) { | ||
733 | goto end; | ||
734 | } | ||
735 | |||
736 | result = acpi_sbs_smbus_read_word(battery->sbs->smbus, | ||
737 | ACPI_SB_SMBUS_ADDR, 0x03, | ||
738 | &battery_mode, NULL); | ||
739 | if (result) { | ||
740 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, | ||
741 | "acpi_sbs_smbus_read_word() failed\n")); | ||
742 | goto end; | ||
743 | } | ||
744 | |||
745 | if (capacity_mode == MAH_CAPACITY_UNIT) { | ||
746 | battery_mode &= 0x7fff; | ||
747 | } else { | ||
748 | battery_mode |= 0x8000; | ||
749 | } | ||
750 | result = acpi_sbs_smbus_write_word(battery->sbs->smbus, | ||
751 | ACPI_SB_SMBUS_ADDR, 0x03, | ||
752 | battery_mode, NULL); | ||
753 | if (result) { | ||
754 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, | ||
755 | "acpi_sbs_smbus_write_word() failed\n")); | ||
756 | goto end; | ||
757 | } | ||
758 | |||
759 | result = acpi_sbs_smbus_read_word(battery->sbs->smbus, | ||
760 | ACPI_SB_SMBUS_ADDR, 0x03, | ||
761 | &battery_mode, NULL); | ||
762 | if (result) { | ||
763 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, | ||
764 | "acpi_sbs_smbus_read_word() failed\n")); | ||
765 | goto end; | ||
766 | } | ||
767 | |||
768 | end: | ||
769 | return result; | ||
770 | } | ||
771 | |||
772 | static int acpi_battery_init(struct acpi_battery *battery) | ||
773 | { | ||
774 | int result = 0; | ||
775 | |||
776 | result = acpi_battery_select(battery); | ||
777 | if (result) { | ||
778 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, | ||
779 | "acpi_battery_init() failed\n")); | ||
780 | goto end; | ||
781 | } | ||
782 | |||
783 | result = acpi_battery_set_mode(battery); | ||
784 | if (result) { | ||
785 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, | ||
786 | "acpi_battery_set_mode() failed\n")); | ||
787 | goto end; | ||
788 | } | ||
789 | |||
790 | result = acpi_battery_get_info(battery); | ||
791 | if (result) { | ||
792 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, | ||
793 | "acpi_battery_get_info() failed\n")); | ||
794 | goto end; | ||
795 | } | ||
796 | |||
797 | result = acpi_battery_get_state(battery); | ||
798 | if (result) { | ||
799 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, | ||
800 | "acpi_battery_get_state() failed\n")); | ||
801 | goto end; | ||
802 | } | ||
803 | |||
804 | result = acpi_battery_get_alarm(battery); | ||
805 | if (result) { | ||
806 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, | ||
807 | "acpi_battery_get_alarm() failed\n")); | ||
808 | goto end; | ||
809 | } | ||
810 | |||
811 | end: | ||
812 | return result; | ||
813 | } | ||
814 | |||
815 | static int acpi_ac_get_present(struct acpi_sbs *sbs) | ||
816 | { | ||
817 | struct acpi_ec_smbus *smbus = sbs->smbus; | ||
818 | int result = 0; | ||
819 | s16 charger_status; | ||
820 | |||
821 | result = acpi_sbs_smbus_read_word(smbus, ACPI_SBC_SMBUS_ADDR, 0x13, | ||
822 | &charger_status, NULL); | ||
823 | |||
824 | if (result) { | ||
825 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, | ||
826 | "acpi_sbs_smbus_read_word() failed\n")); | ||
827 | goto end; | ||
828 | } | ||
829 | |||
830 | sbs->ac_present = (charger_status & 0x8000) >> 15; | ||
831 | |||
832 | end: | ||
833 | |||
834 | return result; | ||
835 | } | ||
836 | |||
837 | /* -------------------------------------------------------------------------- | ||
838 | FS Interface (/proc/acpi) | ||
839 | -------------------------------------------------------------------------- */ | ||
840 | |||
841 | /* Generic Routines */ | ||
842 | |||
843 | static int | ||
844 | acpi_sbs_generic_add_fs(struct proc_dir_entry **dir, | ||
845 | struct proc_dir_entry *parent_dir, | ||
846 | char *dir_name, | ||
847 | struct file_operations *info_fops, | ||
848 | struct file_operations *state_fops, | ||
849 | struct file_operations *alarm_fops, void *data) | ||
850 | { | ||
851 | struct proc_dir_entry *entry = NULL; | ||
852 | |||
853 | if (!*dir) { | ||
854 | *dir = proc_mkdir(dir_name, parent_dir); | ||
855 | if (!*dir) { | ||
856 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, | ||
857 | "proc_mkdir() failed\n")); | ||
858 | return -ENODEV; | ||
859 | } | ||
860 | (*dir)->owner = THIS_MODULE; | ||
861 | } | ||
862 | |||
863 | /* 'info' [R] */ | ||
864 | if (info_fops) { | ||
865 | entry = create_proc_entry(ACPI_SBS_FILE_INFO, S_IRUGO, *dir); | ||
866 | if (!entry) { | ||
867 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, | ||
868 | "create_proc_entry() failed\n")); | ||
869 | } else { | ||
870 | entry->proc_fops = info_fops; | ||
871 | entry->data = data; | ||
872 | entry->owner = THIS_MODULE; | ||
873 | } | ||
874 | } | ||
875 | |||
876 | /* 'state' [R] */ | ||
877 | if (state_fops) { | ||
878 | entry = create_proc_entry(ACPI_SBS_FILE_STATE, S_IRUGO, *dir); | ||
879 | if (!entry) { | ||
880 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, | ||
881 | "create_proc_entry() failed\n")); | ||
882 | } else { | ||
883 | entry->proc_fops = state_fops; | ||
884 | entry->data = data; | ||
885 | entry->owner = THIS_MODULE; | ||
886 | } | ||
887 | } | ||
888 | |||
889 | /* 'alarm' [R/W] */ | ||
890 | if (alarm_fops) { | ||
891 | entry = create_proc_entry(ACPI_SBS_FILE_ALARM, S_IRUGO, *dir); | ||
892 | if (!entry) { | ||
893 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, | ||
894 | "create_proc_entry() failed\n")); | ||
895 | } else { | ||
896 | entry->proc_fops = alarm_fops; | ||
897 | entry->data = data; | ||
898 | entry->owner = THIS_MODULE; | ||
899 | } | ||
900 | } | ||
901 | |||
902 | return 0; | ||
903 | } | ||
904 | |||
905 | static void | ||
906 | acpi_sbs_generic_remove_fs(struct proc_dir_entry **dir, | ||
907 | struct proc_dir_entry *parent_dir) | ||
908 | { | ||
909 | |||
910 | if (*dir) { | ||
911 | remove_proc_entry(ACPI_SBS_FILE_INFO, *dir); | ||
912 | remove_proc_entry(ACPI_SBS_FILE_STATE, *dir); | ||
913 | remove_proc_entry(ACPI_SBS_FILE_ALARM, *dir); | ||
914 | remove_proc_entry((*dir)->name, parent_dir); | ||
915 | *dir = NULL; | ||
916 | } | ||
917 | |||
918 | } | ||
919 | |||
920 | /* Smart Battery Interface */ | ||
921 | |||
922 | static struct proc_dir_entry *acpi_battery_dir = NULL; | ||
923 | |||
924 | static int acpi_battery_read_info(struct seq_file *seq, void *offset) | ||
925 | { | ||
926 | struct acpi_battery *battery = (struct acpi_battery *)seq->private; | ||
927 | int cscale; | ||
928 | int result = 0; | ||
929 | |||
930 | if (battery->sbs->zombie) { | ||
931 | return -ENODEV; | ||
932 | } | ||
933 | |||
934 | down(&sbs_sem); | ||
935 | |||
936 | if (update_mode == REQUEST_UPDATE_MODE) { | ||
937 | result = acpi_sbs_update_run(battery->sbs, DATA_TYPE_INFO); | ||
938 | if (result) { | ||
939 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, | ||
940 | "acpi_sbs_update_run() failed\n")); | ||
941 | } | ||
942 | } | ||
943 | |||
944 | if (acpi_battery_is_present(battery)) { | ||
945 | seq_printf(seq, "present: yes\n"); | ||
946 | } else { | ||
947 | seq_printf(seq, "present: no\n"); | ||
948 | goto end; | ||
949 | } | ||
950 | |||
951 | if (battery->info.capacity_mode) { | ||
952 | cscale = battery->info.vscale * battery->info.ipscale; | ||
953 | } else { | ||
954 | cscale = battery->info.ipscale; | ||
955 | } | ||
956 | seq_printf(seq, "design capacity: %i%s", | ||
957 | battery->info.design_capacity * cscale, | ||
958 | battery->info.capacity_mode ? "0 mWh\n" : " mAh\n"); | ||
959 | |||
960 | seq_printf(seq, "last full capacity: %i%s", | ||
961 | battery->info.full_charge_capacity * cscale, | ||
962 | battery->info.capacity_mode ? "0 mWh\n" : " mAh\n"); | ||
963 | |||
964 | seq_printf(seq, "battery technology: rechargeable\n"); | ||
965 | |||
966 | seq_printf(seq, "design voltage: %i mV\n", | ||
967 | battery->info.design_voltage * battery->info.vscale); | ||
968 | |||
969 | seq_printf(seq, "design capacity warning: unknown\n"); | ||
970 | seq_printf(seq, "design capacity low: unknown\n"); | ||
971 | seq_printf(seq, "capacity granularity 1: unknown\n"); | ||
972 | seq_printf(seq, "capacity granularity 2: unknown\n"); | ||
973 | |||
974 | seq_printf(seq, "model number: %s\n", | ||
975 | battery->info.device_name); | ||
976 | |||
977 | seq_printf(seq, "serial number: %i\n", | ||
978 | battery->info.serial_number); | ||
979 | |||
980 | seq_printf(seq, "battery type: %s\n", | ||
981 | battery->info.device_chemistry); | ||
982 | |||
983 | seq_printf(seq, "OEM info: %s\n", | ||
984 | battery->info.manufacturer_name); | ||
985 | |||
986 | end: | ||
987 | |||
988 | up(&sbs_sem); | ||
989 | |||
990 | return result; | ||
991 | } | ||
992 | |||
993 | static int acpi_battery_info_open_fs(struct inode *inode, struct file *file) | ||
994 | { | ||
995 | return single_open(file, acpi_battery_read_info, PDE(inode)->data); | ||
996 | } | ||
997 | |||
998 | static int acpi_battery_read_state(struct seq_file *seq, void *offset) | ||
999 | { | ||
1000 | struct acpi_battery *battery = (struct acpi_battery *)seq->private; | ||
1001 | int result = 0; | ||
1002 | int cscale; | ||
1003 | int foo; | ||
1004 | |||
1005 | if (battery->sbs->zombie) { | ||
1006 | return -ENODEV; | ||
1007 | } | ||
1008 | |||
1009 | down(&sbs_sem); | ||
1010 | |||
1011 | if (update_mode == REQUEST_UPDATE_MODE) { | ||
1012 | result = acpi_sbs_update_run(battery->sbs, DATA_TYPE_STATE); | ||
1013 | if (result) { | ||
1014 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, | ||
1015 | "acpi_sbs_update_run() failed\n")); | ||
1016 | } | ||
1017 | } | ||
1018 | |||
1019 | if (acpi_battery_is_present(battery)) { | ||
1020 | seq_printf(seq, "present: yes\n"); | ||
1021 | } else { | ||
1022 | seq_printf(seq, "present: no\n"); | ||
1023 | goto end; | ||
1024 | } | ||
1025 | |||
1026 | if (battery->info.capacity_mode) { | ||
1027 | cscale = battery->info.vscale * battery->info.ipscale; | ||
1028 | } else { | ||
1029 | cscale = battery->info.ipscale; | ||
1030 | } | ||
1031 | |||
1032 | if (battery->state.battery_status & 0x0010) { | ||
1033 | seq_printf(seq, "capacity state: critical\n"); | ||
1034 | } else { | ||
1035 | seq_printf(seq, "capacity state: ok\n"); | ||
1036 | } | ||
1037 | if (battery->state.amperage < 0) { | ||
1038 | seq_printf(seq, "charging state: discharging\n"); | ||
1039 | foo = battery->state.remaining_capacity * cscale * 60 / | ||
1040 | (battery->state.average_time_to_empty == 0 ? 1 : | ||
1041 | battery->state.average_time_to_empty); | ||
1042 | seq_printf(seq, "present rate: %i%s\n", | ||
1043 | foo, battery->info.capacity_mode ? "0 mW" : " mA"); | ||
1044 | } else if (battery->state.amperage > 0) { | ||
1045 | seq_printf(seq, "charging state: charging\n"); | ||
1046 | foo = (battery->info.full_charge_capacity - | ||
1047 | battery->state.remaining_capacity) * cscale * 60 / | ||
1048 | (battery->state.average_time_to_full == 0 ? 1 : | ||
1049 | battery->state.average_time_to_full); | ||
1050 | seq_printf(seq, "present rate: %i%s\n", | ||
1051 | foo, battery->info.capacity_mode ? "0 mW" : " mA"); | ||
1052 | } else { | ||
1053 | seq_printf(seq, "charging state: charged\n"); | ||
1054 | seq_printf(seq, "present rate: 0 %s\n", | ||
1055 | battery->info.capacity_mode ? "mW" : "mA"); | ||
1056 | } | ||
1057 | |||
1058 | seq_printf(seq, "remaining capacity: %i%s", | ||
1059 | battery->state.remaining_capacity * cscale, | ||
1060 | battery->info.capacity_mode ? "0 mWh\n" : " mAh\n"); | ||
1061 | |||
1062 | seq_printf(seq, "present voltage: %i mV\n", | ||
1063 | battery->state.voltage * battery->info.vscale); | ||
1064 | |||
1065 | end: | ||
1066 | |||
1067 | up(&sbs_sem); | ||
1068 | |||
1069 | return result; | ||
1070 | } | ||
1071 | |||
1072 | static int acpi_battery_state_open_fs(struct inode *inode, struct file *file) | ||
1073 | { | ||
1074 | return single_open(file, acpi_battery_read_state, PDE(inode)->data); | ||
1075 | } | ||
1076 | |||
1077 | static int acpi_battery_read_alarm(struct seq_file *seq, void *offset) | ||
1078 | { | ||
1079 | struct acpi_battery *battery = (struct acpi_battery *)seq->private; | ||
1080 | int result = 0; | ||
1081 | int cscale; | ||
1082 | |||
1083 | if (battery->sbs->zombie) { | ||
1084 | return -ENODEV; | ||
1085 | } | ||
1086 | |||
1087 | down(&sbs_sem); | ||
1088 | |||
1089 | if (update_mode == REQUEST_UPDATE_MODE) { | ||
1090 | result = acpi_sbs_update_run(battery->sbs, DATA_TYPE_ALARM); | ||
1091 | if (result) { | ||
1092 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, | ||
1093 | "acpi_sbs_update_run() failed\n")); | ||
1094 | } | ||
1095 | } | ||
1096 | |||
1097 | if (!acpi_battery_is_present(battery)) { | ||
1098 | seq_printf(seq, "present: no\n"); | ||
1099 | goto end; | ||
1100 | } | ||
1101 | |||
1102 | if (battery->info.capacity_mode) { | ||
1103 | cscale = battery->info.vscale * battery->info.ipscale; | ||
1104 | } else { | ||
1105 | cscale = battery->info.ipscale; | ||
1106 | } | ||
1107 | |||
1108 | seq_printf(seq, "alarm: "); | ||
1109 | if (battery->alarm.remaining_capacity) { | ||
1110 | seq_printf(seq, "%i%s", | ||
1111 | battery->alarm.remaining_capacity * cscale, | ||
1112 | battery->info.capacity_mode ? "0 mWh\n" : " mAh\n"); | ||
1113 | } else { | ||
1114 | seq_printf(seq, "disabled\n"); | ||
1115 | } | ||
1116 | |||
1117 | end: | ||
1118 | |||
1119 | up(&sbs_sem); | ||
1120 | |||
1121 | return result; | ||
1122 | } | ||
1123 | |||
1124 | static ssize_t | ||
1125 | acpi_battery_write_alarm(struct file *file, const char __user * buffer, | ||
1126 | size_t count, loff_t * ppos) | ||
1127 | { | ||
1128 | struct seq_file *seq = (struct seq_file *)file->private_data; | ||
1129 | struct acpi_battery *battery = (struct acpi_battery *)seq->private; | ||
1130 | char alarm_string[12] = { '\0' }; | ||
1131 | int result, old_alarm, new_alarm; | ||
1132 | |||
1133 | if (battery->sbs->zombie) { | ||
1134 | return -ENODEV; | ||
1135 | } | ||
1136 | |||
1137 | down(&sbs_sem); | ||
1138 | |||
1139 | if (!acpi_battery_is_present(battery)) { | ||
1140 | result = -ENODEV; | ||
1141 | goto end; | ||
1142 | } | ||
1143 | |||
1144 | if (count > sizeof(alarm_string) - 1) { | ||
1145 | result = -EINVAL; | ||
1146 | goto end; | ||
1147 | } | ||
1148 | |||
1149 | if (copy_from_user(alarm_string, buffer, count)) { | ||
1150 | result = -EFAULT; | ||
1151 | goto end; | ||
1152 | } | ||
1153 | |||
1154 | alarm_string[count] = 0; | ||
1155 | |||
1156 | old_alarm = battery->alarm.remaining_capacity; | ||
1157 | new_alarm = simple_strtoul(alarm_string, NULL, 0); | ||
1158 | |||
1159 | result = acpi_battery_set_alarm(battery, new_alarm); | ||
1160 | if (result) { | ||
1161 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, | ||
1162 | "acpi_battery_set_alarm() failed\n")); | ||
1163 | (void)acpi_battery_set_alarm(battery, old_alarm); | ||
1164 | goto end; | ||
1165 | } | ||
1166 | result = acpi_battery_get_alarm(battery); | ||
1167 | if (result) { | ||
1168 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, | ||
1169 | "acpi_battery_get_alarm() failed\n")); | ||
1170 | (void)acpi_battery_set_alarm(battery, old_alarm); | ||
1171 | goto end; | ||
1172 | } | ||
1173 | |||
1174 | end: | ||
1175 | up(&sbs_sem); | ||
1176 | |||
1177 | if (result) { | ||
1178 | return result; | ||
1179 | } else { | ||
1180 | return count; | ||
1181 | } | ||
1182 | } | ||
1183 | |||
1184 | static int acpi_battery_alarm_open_fs(struct inode *inode, struct file *file) | ||
1185 | { | ||
1186 | return single_open(file, acpi_battery_read_alarm, PDE(inode)->data); | ||
1187 | } | ||
1188 | |||
1189 | static struct file_operations acpi_battery_info_fops = { | ||
1190 | .open = acpi_battery_info_open_fs, | ||
1191 | .read = seq_read, | ||
1192 | .llseek = seq_lseek, | ||
1193 | .release = single_release, | ||
1194 | .owner = THIS_MODULE, | ||
1195 | }; | ||
1196 | |||
1197 | static struct file_operations acpi_battery_state_fops = { | ||
1198 | .open = acpi_battery_state_open_fs, | ||
1199 | .read = seq_read, | ||
1200 | .llseek = seq_lseek, | ||
1201 | .release = single_release, | ||
1202 | .owner = THIS_MODULE, | ||
1203 | }; | ||
1204 | |||
1205 | static struct file_operations acpi_battery_alarm_fops = { | ||
1206 | .open = acpi_battery_alarm_open_fs, | ||
1207 | .read = seq_read, | ||
1208 | .write = acpi_battery_write_alarm, | ||
1209 | .llseek = seq_lseek, | ||
1210 | .release = single_release, | ||
1211 | .owner = THIS_MODULE, | ||
1212 | }; | ||
1213 | |||
1214 | /* Legacy AC Adapter Interface */ | ||
1215 | |||
1216 | static struct proc_dir_entry *acpi_ac_dir = NULL; | ||
1217 | |||
1218 | static int acpi_ac_read_state(struct seq_file *seq, void *offset) | ||
1219 | { | ||
1220 | struct acpi_sbs *sbs = (struct acpi_sbs *)seq->private; | ||
1221 | int result; | ||
1222 | |||
1223 | if (sbs->zombie) { | ||
1224 | return -ENODEV; | ||
1225 | } | ||
1226 | |||
1227 | down(&sbs_sem); | ||
1228 | |||
1229 | if (update_mode == REQUEST_UPDATE_MODE) { | ||
1230 | result = acpi_sbs_update_run(sbs, DATA_TYPE_AC_STATE); | ||
1231 | if (result) { | ||
1232 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, | ||
1233 | "acpi_sbs_update_run() failed\n")); | ||
1234 | } | ||
1235 | } | ||
1236 | |||
1237 | seq_printf(seq, "state: %s\n", | ||
1238 | sbs->ac_present ? "on-line" : "off-line"); | ||
1239 | |||
1240 | up(&sbs_sem); | ||
1241 | |||
1242 | return 0; | ||
1243 | } | ||
1244 | |||
1245 | static int acpi_ac_state_open_fs(struct inode *inode, struct file *file) | ||
1246 | { | ||
1247 | return single_open(file, acpi_ac_read_state, PDE(inode)->data); | ||
1248 | } | ||
1249 | |||
1250 | static struct file_operations acpi_ac_state_fops = { | ||
1251 | .open = acpi_ac_state_open_fs, | ||
1252 | .read = seq_read, | ||
1253 | .llseek = seq_lseek, | ||
1254 | .release = single_release, | ||
1255 | .owner = THIS_MODULE, | ||
1256 | }; | ||
1257 | |||
1258 | /* -------------------------------------------------------------------------- | ||
1259 | Driver Interface | ||
1260 | -------------------------------------------------------------------------- */ | ||
1261 | |||
1262 | /* Smart Battery */ | ||
1263 | |||
1264 | static int acpi_battery_add(struct acpi_sbs *sbs, int id) | ||
1265 | { | ||
1266 | int is_present; | ||
1267 | int result; | ||
1268 | char dir_name[32]; | ||
1269 | struct acpi_battery *battery; | ||
1270 | |||
1271 | battery = &sbs->battery[id]; | ||
1272 | |||
1273 | battery->alive = 0; | ||
1274 | |||
1275 | battery->init_state = 0; | ||
1276 | battery->id = id; | ||
1277 | battery->sbs = sbs; | ||
1278 | |||
1279 | result = acpi_battery_select(battery); | ||
1280 | if (result) { | ||
1281 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, | ||
1282 | "acpi_battery_select() failed\n")); | ||
1283 | goto end; | ||
1284 | } | ||
1285 | |||
1286 | result = acpi_battery_get_present(battery); | ||
1287 | if (result) { | ||
1288 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, | ||
1289 | "acpi_battery_get_present() failed\n")); | ||
1290 | goto end; | ||
1291 | } | ||
1292 | |||
1293 | is_present = acpi_battery_is_present(battery); | ||
1294 | |||
1295 | if (is_present) { | ||
1296 | result = acpi_battery_init(battery); | ||
1297 | if (result) { | ||
1298 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, | ||
1299 | "acpi_battery_init() failed\n")); | ||
1300 | goto end; | ||
1301 | } | ||
1302 | battery->init_state = 1; | ||
1303 | } | ||
1304 | |||
1305 | (void)sprintf(dir_name, ACPI_BATTERY_DIR_NAME, id); | ||
1306 | |||
1307 | result = acpi_sbs_generic_add_fs(&battery->battery_entry, | ||
1308 | acpi_battery_dir, | ||
1309 | dir_name, | ||
1310 | &acpi_battery_info_fops, | ||
1311 | &acpi_battery_state_fops, | ||
1312 | &acpi_battery_alarm_fops, battery); | ||
1313 | if (result) { | ||
1314 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, | ||
1315 | "acpi_sbs_generic_add_fs() failed\n")); | ||
1316 | goto end; | ||
1317 | } | ||
1318 | battery->alive = 1; | ||
1319 | |||
1320 | end: | ||
1321 | return result; | ||
1322 | } | ||
1323 | |||
1324 | static void acpi_battery_remove(struct acpi_sbs *sbs, int id) | ||
1325 | { | ||
1326 | |||
1327 | if (sbs->battery[id].battery_entry) { | ||
1328 | acpi_sbs_generic_remove_fs(&(sbs->battery[id].battery_entry), | ||
1329 | acpi_battery_dir); | ||
1330 | } | ||
1331 | } | ||
1332 | |||
1333 | static int acpi_ac_add(struct acpi_sbs *sbs) | ||
1334 | { | ||
1335 | int result; | ||
1336 | |||
1337 | result = acpi_ac_get_present(sbs); | ||
1338 | if (result) { | ||
1339 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, | ||
1340 | "acpi_ac_get_present() failed\n")); | ||
1341 | goto end; | ||
1342 | } | ||
1343 | |||
1344 | result = acpi_sbs_generic_add_fs(&sbs->ac_entry, | ||
1345 | acpi_ac_dir, | ||
1346 | ACPI_AC_DIR_NAME, | ||
1347 | NULL, &acpi_ac_state_fops, NULL, sbs); | ||
1348 | if (result) { | ||
1349 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, | ||
1350 | "acpi_sbs_generic_add_fs() failed\n")); | ||
1351 | goto end; | ||
1352 | } | ||
1353 | |||
1354 | end: | ||
1355 | |||
1356 | return result; | ||
1357 | } | ||
1358 | |||
1359 | static void acpi_ac_remove(struct acpi_sbs *sbs) | ||
1360 | { | ||
1361 | |||
1362 | if (sbs->ac_entry) { | ||
1363 | acpi_sbs_generic_remove_fs(&sbs->ac_entry, acpi_ac_dir); | ||
1364 | } | ||
1365 | } | ||
1366 | |||
1367 | static void acpi_sbs_update_queue_run(unsigned long data) | ||
1368 | { | ||
1369 | acpi_os_execute(OSL_GPE_HANDLER, acpi_sbs_update_queue, (void *)data); | ||
1370 | } | ||
1371 | |||
1372 | static int acpi_sbs_update_run(struct acpi_sbs *sbs, int data_type) | ||
1373 | { | ||
1374 | struct acpi_battery *battery; | ||
1375 | int result = 0; | ||
1376 | int old_ac_present; | ||
1377 | int old_battery_present; | ||
1378 | int new_ac_present; | ||
1379 | int new_battery_present; | ||
1380 | int id; | ||
1381 | char dir_name[32]; | ||
1382 | int do_battery_init, do_ac_init; | ||
1383 | s16 old_remaining_capacity; | ||
1384 | |||
1385 | if (sbs->zombie) { | ||
1386 | goto end; | ||
1387 | } | ||
1388 | |||
1389 | old_ac_present = acpi_ac_is_present(sbs); | ||
1390 | |||
1391 | result = acpi_ac_get_present(sbs); | ||
1392 | if (result) { | ||
1393 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, | ||
1394 | "acpi_ac_get_present() failed\n")); | ||
1395 | } | ||
1396 | |||
1397 | new_ac_present = acpi_ac_is_present(sbs); | ||
1398 | |||
1399 | do_ac_init = (old_ac_present != new_ac_present); | ||
1400 | |||
1401 | if (data_type == DATA_TYPE_AC_STATE) { | ||
1402 | goto end; | ||
1403 | } | ||
1404 | |||
1405 | for (id = 0; id < MAX_SBS_BAT; id++) { | ||
1406 | battery = &sbs->battery[id]; | ||
1407 | if (battery->alive == 0) { | ||
1408 | continue; | ||
1409 | } | ||
1410 | |||
1411 | old_remaining_capacity = battery->state.remaining_capacity; | ||
1412 | |||
1413 | old_battery_present = acpi_battery_is_present(battery); | ||
1414 | |||
1415 | result = acpi_battery_select(battery); | ||
1416 | if (result) { | ||
1417 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, | ||
1418 | "acpi_battery_select() failed\n")); | ||
1419 | } | ||
1420 | if (sbs->zombie) { | ||
1421 | goto end; | ||
1422 | } | ||
1423 | |||
1424 | result = acpi_battery_get_present(battery); | ||
1425 | if (result) { | ||
1426 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, | ||
1427 | "acpi_battery_get_present() failed\n")); | ||
1428 | } | ||
1429 | if (sbs->zombie) { | ||
1430 | goto end; | ||
1431 | } | ||
1432 | |||
1433 | new_battery_present = acpi_battery_is_present(battery); | ||
1434 | |||
1435 | do_battery_init = ((old_battery_present != new_battery_present) | ||
1436 | && new_battery_present); | ||
1437 | |||
1438 | if (sbs->zombie) { | ||
1439 | goto end; | ||
1440 | } | ||
1441 | if (do_ac_init || do_battery_init || | ||
1442 | update_info_mode || sbs->update_info_mode) { | ||
1443 | if (sbs->update_info_mode) { | ||
1444 | sbs->update_info_mode = 0; | ||
1445 | } else { | ||
1446 | sbs->update_info_mode = 1; | ||
1447 | } | ||
1448 | result = acpi_battery_init(battery); | ||
1449 | if (result) { | ||
1450 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, | ||
1451 | "acpi_battery_init() " | ||
1452 | "failed\n")); | ||
1453 | } | ||
1454 | } | ||
1455 | if (data_type == DATA_TYPE_INFO) { | ||
1456 | continue; | ||
1457 | } | ||
1458 | |||
1459 | if (sbs->zombie) { | ||
1460 | goto end; | ||
1461 | } | ||
1462 | if (new_battery_present) { | ||
1463 | result = acpi_battery_get_alarm(battery); | ||
1464 | if (result) { | ||
1465 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, | ||
1466 | "acpi_battery_get_alarm() " | ||
1467 | "failed\n")); | ||
1468 | } | ||
1469 | if (data_type == DATA_TYPE_ALARM) { | ||
1470 | continue; | ||
1471 | } | ||
1472 | |||
1473 | result = acpi_battery_get_state(battery); | ||
1474 | if (result) { | ||
1475 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, | ||
1476 | "acpi_battery_get_state() " | ||
1477 | "failed\n")); | ||
1478 | } | ||
1479 | } | ||
1480 | if (sbs->zombie) { | ||
1481 | goto end; | ||
1482 | } | ||
1483 | if (data_type != DATA_TYPE_COMMON) { | ||
1484 | continue; | ||
1485 | } | ||
1486 | |||
1487 | if (old_battery_present != new_battery_present) { | ||
1488 | (void)sprintf(dir_name, ACPI_BATTERY_DIR_NAME, id); | ||
1489 | result = acpi_sbs_generate_event(sbs->device, | ||
1490 | ACPI_SBS_BATTERY_NOTIFY_STATUS, | ||
1491 | new_battery_present, | ||
1492 | dir_name, | ||
1493 | ACPI_BATTERY_CLASS); | ||
1494 | if (result) { | ||
1495 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, | ||
1496 | "acpi_sbs_generate_event() " | ||
1497 | "failed\n")); | ||
1498 | } | ||
1499 | } | ||
1500 | if (old_remaining_capacity != battery->state.remaining_capacity) { | ||
1501 | (void)sprintf(dir_name, ACPI_BATTERY_DIR_NAME, id); | ||
1502 | result = acpi_sbs_generate_event(sbs->device, | ||
1503 | ACPI_SBS_BATTERY_NOTIFY_STATUS, | ||
1504 | new_battery_present, | ||
1505 | dir_name, | ||
1506 | ACPI_BATTERY_CLASS); | ||
1507 | if (result) { | ||
1508 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, | ||
1509 | "acpi_sbs_generate_event() failed\n")); | ||
1510 | } | ||
1511 | } | ||
1512 | |||
1513 | } | ||
1514 | if (sbs->zombie) { | ||
1515 | goto end; | ||
1516 | } | ||
1517 | if (data_type != DATA_TYPE_COMMON) { | ||
1518 | goto end; | ||
1519 | } | ||
1520 | |||
1521 | if (old_ac_present != new_ac_present) { | ||
1522 | result = acpi_sbs_generate_event(sbs->device, | ||
1523 | ACPI_SBS_AC_NOTIFY_STATUS, | ||
1524 | new_ac_present, | ||
1525 | ACPI_AC_DIR_NAME, | ||
1526 | ACPI_AC_CLASS); | ||
1527 | if (result) { | ||
1528 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, | ||
1529 | "acpi_sbs_generate_event() failed\n")); | ||
1530 | } | ||
1531 | } | ||
1532 | |||
1533 | end: | ||
1534 | return result; | ||
1535 | } | ||
1536 | |||
1537 | static void acpi_sbs_update_queue(void *data) | ||
1538 | { | ||
1539 | struct acpi_sbs *sbs = data; | ||
1540 | unsigned long delay = -1; | ||
1541 | int result; | ||
1542 | |||
1543 | if (sbs->zombie) { | ||
1544 | goto end; | ||
1545 | } | ||
1546 | |||
1547 | result = acpi_sbs_update_run(sbs, DATA_TYPE_COMMON); | ||
1548 | if (result) { | ||
1549 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, | ||
1550 | "acpi_sbs_update_run() failed\n")); | ||
1551 | } | ||
1552 | |||
1553 | if (sbs->zombie) { | ||
1554 | goto end; | ||
1555 | } | ||
1556 | |||
1557 | if (update_mode == REQUEST_UPDATE_MODE) { | ||
1558 | goto end; | ||
1559 | } | ||
1560 | |||
1561 | delay = jiffies + HZ * update_time; | ||
1562 | sbs->update_timer.data = (unsigned long)data; | ||
1563 | sbs->update_timer.function = acpi_sbs_update_queue_run; | ||
1564 | sbs->update_timer.expires = delay; | ||
1565 | add_timer(&sbs->update_timer); | ||
1566 | end: | ||
1567 | ; | ||
1568 | } | ||
1569 | |||
1570 | static int acpi_sbs_add(struct acpi_device *device) | ||
1571 | { | ||
1572 | struct acpi_sbs *sbs = NULL; | ||
1573 | struct acpi_ec_hc *ec_hc = NULL; | ||
1574 | int result, remove_result = 0; | ||
1575 | unsigned long sbs_obj; | ||
1576 | int id, cnt; | ||
1577 | acpi_status status = AE_OK; | ||
1578 | |||
1579 | sbs = kmalloc(sizeof(struct acpi_sbs), GFP_KERNEL); | ||
1580 | if (!sbs) { | ||
1581 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "kmalloc() failed\n")); | ||
1582 | return -ENOMEM; | ||
1583 | } | ||
1584 | memset(sbs, 0, sizeof(struct acpi_sbs)); | ||
1585 | |||
1586 | cnt = 0; | ||
1587 | while (cnt < 10) { | ||
1588 | cnt++; | ||
1589 | ec_hc = acpi_get_ec_hc(device); | ||
1590 | if (ec_hc) { | ||
1591 | break; | ||
1592 | } | ||
1593 | msleep(1000); | ||
1594 | } | ||
1595 | |||
1596 | if (!ec_hc) { | ||
1597 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, | ||
1598 | "acpi_get_ec_hc() failed: " | ||
1599 | "NO driver found for EC HC SMBus\n")); | ||
1600 | result = -ENODEV; | ||
1601 | goto end; | ||
1602 | } | ||
1603 | |||
1604 | sbs->device = device; | ||
1605 | sbs->smbus = ec_hc->smbus; | ||
1606 | |||
1607 | strcpy(acpi_device_name(device), ACPI_SBS_DEVICE_NAME); | ||
1608 | strcpy(acpi_device_class(device), ACPI_SBS_CLASS); | ||
1609 | acpi_driver_data(device) = sbs; | ||
1610 | |||
1611 | sbs->update_time = 0; | ||
1612 | sbs->update_time2 = 0; | ||
1613 | |||
1614 | result = acpi_ac_add(sbs); | ||
1615 | if (result) { | ||
1616 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "acpi_ac_add() failed\n")); | ||
1617 | goto end; | ||
1618 | } | ||
1619 | result = acpi_evaluate_integer(device->handle, "_SBS", NULL, &sbs_obj); | ||
1620 | if (ACPI_FAILURE(result)) { | ||
1621 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, | ||
1622 | "acpi_evaluate_integer() failed\n")); | ||
1623 | result = -EIO; | ||
1624 | goto end; | ||
1625 | } | ||
1626 | |||
1627 | if (sbs_obj > 0) { | ||
1628 | result = acpi_sbsm_get_info(sbs); | ||
1629 | if (result) { | ||
1630 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, | ||
1631 | "acpi_sbsm_get_info() failed\n")); | ||
1632 | goto end; | ||
1633 | } | ||
1634 | sbs->sbsm_present = 1; | ||
1635 | } | ||
1636 | if (sbs->sbsm_present == 0) { | ||
1637 | result = acpi_battery_add(sbs, 0); | ||
1638 | if (result) { | ||
1639 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, | ||
1640 | "acpi_battery_add() failed\n")); | ||
1641 | goto end; | ||
1642 | } | ||
1643 | } else { | ||
1644 | for (id = 0; id < MAX_SBS_BAT; id++) { | ||
1645 | if ((sbs->sbsm_batteries_supported & (1 << id))) { | ||
1646 | result = acpi_battery_add(sbs, id); | ||
1647 | if (result) { | ||
1648 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, | ||
1649 | "acpi_battery_add() " | ||
1650 | "failed\n")); | ||
1651 | goto end; | ||
1652 | } | ||
1653 | } | ||
1654 | } | ||
1655 | } | ||
1656 | |||
1657 | sbs->handle = device->handle; | ||
1658 | |||
1659 | init_timer(&sbs->update_timer); | ||
1660 | if (update_mode == QUEUE_UPDATE_MODE) { | ||
1661 | status = acpi_os_execute(OSL_GPE_HANDLER, | ||
1662 | acpi_sbs_update_queue, (void *)sbs); | ||
1663 | if (status != AE_OK) { | ||
1664 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, | ||
1665 | "acpi_os_execute() failed\n")); | ||
1666 | } | ||
1667 | } | ||
1668 | sbs->update_time = update_time; | ||
1669 | sbs->update_time2 = update_time2; | ||
1670 | |||
1671 | printk(KERN_INFO PREFIX "%s [%s]\n", | ||
1672 | acpi_device_name(device), acpi_device_bid(device)); | ||
1673 | |||
1674 | end: | ||
1675 | if (result) { | ||
1676 | remove_result = acpi_sbs_remove(device, 0); | ||
1677 | if (remove_result) { | ||
1678 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, | ||
1679 | "acpi_sbs_remove() failed\n")); | ||
1680 | } | ||
1681 | } | ||
1682 | |||
1683 | return result; | ||
1684 | } | ||
1685 | |||
1686 | int acpi_sbs_remove(struct acpi_device *device, int type) | ||
1687 | { | ||
1688 | struct acpi_sbs *sbs = (struct acpi_sbs *)acpi_driver_data(device); | ||
1689 | int id; | ||
1690 | |||
1691 | if (!device || !sbs) { | ||
1692 | return -EINVAL; | ||
1693 | } | ||
1694 | |||
1695 | sbs->zombie = 1; | ||
1696 | sbs->update_time = 0; | ||
1697 | sbs->update_time2 = 0; | ||
1698 | del_timer_sync(&sbs->update_timer); | ||
1699 | acpi_os_wait_events_complete(NULL); | ||
1700 | del_timer_sync(&sbs->update_timer); | ||
1701 | |||
1702 | for (id = 0; id < MAX_SBS_BAT; id++) { | ||
1703 | acpi_battery_remove(sbs, id); | ||
1704 | } | ||
1705 | |||
1706 | acpi_ac_remove(sbs); | ||
1707 | |||
1708 | kfree(sbs); | ||
1709 | |||
1710 | return 0; | ||
1711 | } | ||
1712 | |||
1713 | static int __init acpi_sbs_init(void) | ||
1714 | { | ||
1715 | int result = 0; | ||
1716 | |||
1717 | init_MUTEX(&sbs_sem); | ||
1718 | |||
1719 | if (capacity_mode != DEF_CAPACITY_UNIT | ||
1720 | && capacity_mode != MAH_CAPACITY_UNIT | ||
1721 | && capacity_mode != MWH_CAPACITY_UNIT) { | ||
1722 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "acpi_sbs_init: " | ||
1723 | "invalid capacity_mode = %d\n", | ||
1724 | capacity_mode)); | ||
1725 | return -EINVAL; | ||
1726 | } | ||
1727 | |||
1728 | acpi_ac_dir = acpi_lock_ac_dir(); | ||
1729 | if (!acpi_ac_dir) { | ||
1730 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, | ||
1731 | "acpi_lock_ac_dir() failed\n")); | ||
1732 | return -ENODEV; | ||
1733 | } | ||
1734 | |||
1735 | acpi_battery_dir = acpi_lock_battery_dir(); | ||
1736 | if (!acpi_battery_dir) { | ||
1737 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, | ||
1738 | "acpi_lock_battery_dir() failed\n")); | ||
1739 | return -ENODEV; | ||
1740 | } | ||
1741 | |||
1742 | result = acpi_bus_register_driver(&acpi_sbs_driver); | ||
1743 | if (result < 0) { | ||
1744 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, | ||
1745 | "acpi_bus_register_driver() failed\n")); | ||
1746 | return -ENODEV; | ||
1747 | } | ||
1748 | |||
1749 | return 0; | ||
1750 | } | ||
1751 | |||
1752 | static void __exit acpi_sbs_exit(void) | ||
1753 | { | ||
1754 | |||
1755 | acpi_bus_unregister_driver(&acpi_sbs_driver); | ||
1756 | |||
1757 | acpi_unlock_ac_dir(acpi_ac_dir); | ||
1758 | acpi_ac_dir = NULL; | ||
1759 | acpi_unlock_battery_dir(acpi_battery_dir); | ||
1760 | acpi_battery_dir = NULL; | ||
1761 | |||
1762 | return; | ||
1763 | } | ||
1764 | |||
1765 | module_init(acpi_sbs_init); | ||
1766 | module_exit(acpi_sbs_exit); | ||
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index 861ac378ce42..5fcb50c7b778 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c | |||
@@ -319,7 +319,7 @@ static int acpi_bus_get_wakeup_device_flags(struct acpi_device *device) | |||
319 | goto end; | 319 | goto end; |
320 | } | 320 | } |
321 | 321 | ||
322 | acpi_os_free(buffer.pointer); | 322 | kfree(buffer.pointer); |
323 | 323 | ||
324 | device->wakeup.flags.valid = 1; | 324 | device->wakeup.flags.valid = 1; |
325 | /* Power button, Lid switch always enable wakeup */ | 325 | /* Power button, Lid switch always enable wakeup */ |
@@ -854,7 +854,7 @@ static void acpi_device_set_id(struct acpi_device *device, | |||
854 | printk(KERN_ERR "Memory allocation error\n"); | 854 | printk(KERN_ERR "Memory allocation error\n"); |
855 | } | 855 | } |
856 | 856 | ||
857 | acpi_os_free(buffer.pointer); | 857 | kfree(buffer.pointer); |
858 | } | 858 | } |
859 | 859 | ||
860 | static int acpi_device_set_context(struct acpi_device *device, int type) | 860 | static int acpi_device_set_context(struct acpi_device *device, int type) |
diff --git a/drivers/acpi/system.c b/drivers/acpi/system.c index c90bd2f70b3f..c3bb7faad75e 100644 --- a/drivers/acpi/system.c +++ b/drivers/acpi/system.c | |||
@@ -86,7 +86,7 @@ acpi_system_read_dsdt(struct file *file, | |||
86 | 86 | ||
87 | res = simple_read_from_buffer(buffer, count, ppos, | 87 | res = simple_read_from_buffer(buffer, count, ppos, |
88 | dsdt.pointer, dsdt.length); | 88 | dsdt.pointer, dsdt.length); |
89 | acpi_os_free(dsdt.pointer); | 89 | kfree(dsdt.pointer); |
90 | 90 | ||
91 | return res; | 91 | return res; |
92 | } | 92 | } |
@@ -113,7 +113,7 @@ acpi_system_read_fadt(struct file *file, | |||
113 | 113 | ||
114 | res = simple_read_from_buffer(buffer, count, ppos, | 114 | res = simple_read_from_buffer(buffer, count, ppos, |
115 | fadt.pointer, fadt.length); | 115 | fadt.pointer, fadt.length); |
116 | acpi_os_free(fadt.pointer); | 116 | kfree(fadt.pointer); |
117 | 117 | ||
118 | return res; | 118 | return res; |
119 | } | 119 | } |
diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c index c855f4446b5f..503c0b99db12 100644 --- a/drivers/acpi/thermal.c +++ b/drivers/acpi/thermal.c | |||
@@ -162,7 +162,7 @@ struct acpi_thermal_flags { | |||
162 | }; | 162 | }; |
163 | 163 | ||
164 | struct acpi_thermal { | 164 | struct acpi_thermal { |
165 | acpi_handle handle; | 165 | struct acpi_device * device; |
166 | acpi_bus_id name; | 166 | acpi_bus_id name; |
167 | unsigned long temperature; | 167 | unsigned long temperature; |
168 | unsigned long last_temperature; | 168 | unsigned long last_temperature; |
@@ -229,7 +229,7 @@ static int acpi_thermal_get_temperature(struct acpi_thermal *tz) | |||
229 | tz->last_temperature = tz->temperature; | 229 | tz->last_temperature = tz->temperature; |
230 | 230 | ||
231 | status = | 231 | status = |
232 | acpi_evaluate_integer(tz->handle, "_TMP", NULL, &tz->temperature); | 232 | acpi_evaluate_integer(tz->device->handle, "_TMP", NULL, &tz->temperature); |
233 | if (ACPI_FAILURE(status)) | 233 | if (ACPI_FAILURE(status)) |
234 | return -ENODEV; | 234 | return -ENODEV; |
235 | 235 | ||
@@ -248,7 +248,7 @@ static int acpi_thermal_get_polling_frequency(struct acpi_thermal *tz) | |||
248 | return -EINVAL; | 248 | return -EINVAL; |
249 | 249 | ||
250 | status = | 250 | status = |
251 | acpi_evaluate_integer(tz->handle, "_TZP", NULL, | 251 | acpi_evaluate_integer(tz->device->handle, "_TZP", NULL, |
252 | &tz->polling_frequency); | 252 | &tz->polling_frequency); |
253 | if (ACPI_FAILURE(status)) | 253 | if (ACPI_FAILURE(status)) |
254 | return -ENODEV; | 254 | return -ENODEV; |
@@ -285,7 +285,7 @@ static int acpi_thermal_set_cooling_mode(struct acpi_thermal *tz, int mode) | |||
285 | if (!tz) | 285 | if (!tz) |
286 | return -EINVAL; | 286 | return -EINVAL; |
287 | 287 | ||
288 | status = acpi_get_handle(tz->handle, "_SCP", &handle); | 288 | status = acpi_get_handle(tz->device->handle, "_SCP", &handle); |
289 | if (ACPI_FAILURE(status)) { | 289 | if (ACPI_FAILURE(status)) { |
290 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "_SCP not present\n")); | 290 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "_SCP not present\n")); |
291 | return -ENODEV; | 291 | return -ENODEV; |
@@ -316,7 +316,7 @@ static int acpi_thermal_get_trip_points(struct acpi_thermal *tz) | |||
316 | 316 | ||
317 | /* Critical Shutdown (required) */ | 317 | /* Critical Shutdown (required) */ |
318 | 318 | ||
319 | status = acpi_evaluate_integer(tz->handle, "_CRT", NULL, | 319 | status = acpi_evaluate_integer(tz->device->handle, "_CRT", NULL, |
320 | &tz->trips.critical.temperature); | 320 | &tz->trips.critical.temperature); |
321 | if (ACPI_FAILURE(status)) { | 321 | if (ACPI_FAILURE(status)) { |
322 | tz->trips.critical.flags.valid = 0; | 322 | tz->trips.critical.flags.valid = 0; |
@@ -332,7 +332,7 @@ static int acpi_thermal_get_trip_points(struct acpi_thermal *tz) | |||
332 | /* Critical Sleep (optional) */ | 332 | /* Critical Sleep (optional) */ |
333 | 333 | ||
334 | status = | 334 | status = |
335 | acpi_evaluate_integer(tz->handle, "_HOT", NULL, | 335 | acpi_evaluate_integer(tz->device->handle, "_HOT", NULL, |
336 | &tz->trips.hot.temperature); | 336 | &tz->trips.hot.temperature); |
337 | if (ACPI_FAILURE(status)) { | 337 | if (ACPI_FAILURE(status)) { |
338 | tz->trips.hot.flags.valid = 0; | 338 | tz->trips.hot.flags.valid = 0; |
@@ -346,7 +346,7 @@ static int acpi_thermal_get_trip_points(struct acpi_thermal *tz) | |||
346 | /* Passive: Processors (optional) */ | 346 | /* Passive: Processors (optional) */ |
347 | 347 | ||
348 | status = | 348 | status = |
349 | acpi_evaluate_integer(tz->handle, "_PSV", NULL, | 349 | acpi_evaluate_integer(tz->device->handle, "_PSV", NULL, |
350 | &tz->trips.passive.temperature); | 350 | &tz->trips.passive.temperature); |
351 | if (ACPI_FAILURE(status)) { | 351 | if (ACPI_FAILURE(status)) { |
352 | tz->trips.passive.flags.valid = 0; | 352 | tz->trips.passive.flags.valid = 0; |
@@ -355,25 +355,25 @@ static int acpi_thermal_get_trip_points(struct acpi_thermal *tz) | |||
355 | tz->trips.passive.flags.valid = 1; | 355 | tz->trips.passive.flags.valid = 1; |
356 | 356 | ||
357 | status = | 357 | status = |
358 | acpi_evaluate_integer(tz->handle, "_TC1", NULL, | 358 | acpi_evaluate_integer(tz->device->handle, "_TC1", NULL, |
359 | &tz->trips.passive.tc1); | 359 | &tz->trips.passive.tc1); |
360 | if (ACPI_FAILURE(status)) | 360 | if (ACPI_FAILURE(status)) |
361 | tz->trips.passive.flags.valid = 0; | 361 | tz->trips.passive.flags.valid = 0; |
362 | 362 | ||
363 | status = | 363 | status = |
364 | acpi_evaluate_integer(tz->handle, "_TC2", NULL, | 364 | acpi_evaluate_integer(tz->device->handle, "_TC2", NULL, |
365 | &tz->trips.passive.tc2); | 365 | &tz->trips.passive.tc2); |
366 | if (ACPI_FAILURE(status)) | 366 | if (ACPI_FAILURE(status)) |
367 | tz->trips.passive.flags.valid = 0; | 367 | tz->trips.passive.flags.valid = 0; |
368 | 368 | ||
369 | status = | 369 | status = |
370 | acpi_evaluate_integer(tz->handle, "_TSP", NULL, | 370 | acpi_evaluate_integer(tz->device->handle, "_TSP", NULL, |
371 | &tz->trips.passive.tsp); | 371 | &tz->trips.passive.tsp); |
372 | if (ACPI_FAILURE(status)) | 372 | if (ACPI_FAILURE(status)) |
373 | tz->trips.passive.flags.valid = 0; | 373 | tz->trips.passive.flags.valid = 0; |
374 | 374 | ||
375 | status = | 375 | status = |
376 | acpi_evaluate_reference(tz->handle, "_PSL", NULL, | 376 | acpi_evaluate_reference(tz->device->handle, "_PSL", NULL, |
377 | &tz->trips.passive.devices); | 377 | &tz->trips.passive.devices); |
378 | if (ACPI_FAILURE(status)) | 378 | if (ACPI_FAILURE(status)) |
379 | tz->trips.passive.flags.valid = 0; | 379 | tz->trips.passive.flags.valid = 0; |
@@ -393,14 +393,14 @@ static int acpi_thermal_get_trip_points(struct acpi_thermal *tz) | |||
393 | char name[5] = { '_', 'A', 'C', ('0' + i), '\0' }; | 393 | char name[5] = { '_', 'A', 'C', ('0' + i), '\0' }; |
394 | 394 | ||
395 | status = | 395 | status = |
396 | acpi_evaluate_integer(tz->handle, name, NULL, | 396 | acpi_evaluate_integer(tz->device->handle, name, NULL, |
397 | &tz->trips.active[i].temperature); | 397 | &tz->trips.active[i].temperature); |
398 | if (ACPI_FAILURE(status)) | 398 | if (ACPI_FAILURE(status)) |
399 | break; | 399 | break; |
400 | 400 | ||
401 | name[2] = 'L'; | 401 | name[2] = 'L'; |
402 | status = | 402 | status = |
403 | acpi_evaluate_reference(tz->handle, name, NULL, | 403 | acpi_evaluate_reference(tz->device->handle, name, NULL, |
404 | &tz->trips.active[i].devices); | 404 | &tz->trips.active[i].devices); |
405 | if (ACPI_SUCCESS(status)) { | 405 | if (ACPI_SUCCESS(status)) { |
406 | tz->trips.active[i].flags.valid = 1; | 406 | tz->trips.active[i].flags.valid = 1; |
@@ -424,7 +424,7 @@ static int acpi_thermal_get_devices(struct acpi_thermal *tz) | |||
424 | return -EINVAL; | 424 | return -EINVAL; |
425 | 425 | ||
426 | status = | 426 | status = |
427 | acpi_evaluate_reference(tz->handle, "_TZD", NULL, &tz->devices); | 427 | acpi_evaluate_reference(tz->device->handle, "_TZD", NULL, &tz->devices); |
428 | if (ACPI_FAILURE(status)) | 428 | if (ACPI_FAILURE(status)) |
429 | return -ENODEV; | 429 | return -ENODEV; |
430 | 430 | ||
@@ -453,10 +453,6 @@ static int acpi_thermal_call_usermode(char *path) | |||
453 | 453 | ||
454 | static int acpi_thermal_critical(struct acpi_thermal *tz) | 454 | static int acpi_thermal_critical(struct acpi_thermal *tz) |
455 | { | 455 | { |
456 | int result = 0; | ||
457 | struct acpi_device *device = NULL; | ||
458 | |||
459 | |||
460 | if (!tz || !tz->trips.critical.flags.valid) | 456 | if (!tz || !tz->trips.critical.flags.valid) |
461 | return -EINVAL; | 457 | return -EINVAL; |
462 | 458 | ||
@@ -466,14 +462,10 @@ static int acpi_thermal_critical(struct acpi_thermal *tz) | |||
466 | } else if (tz->trips.critical.flags.enabled) | 462 | } else if (tz->trips.critical.flags.enabled) |
467 | tz->trips.critical.flags.enabled = 0; | 463 | tz->trips.critical.flags.enabled = 0; |
468 | 464 | ||
469 | result = acpi_bus_get_device(tz->handle, &device); | ||
470 | if (result) | ||
471 | return result; | ||
472 | |||
473 | printk(KERN_EMERG | 465 | printk(KERN_EMERG |
474 | "Critical temperature reached (%ld C), shutting down.\n", | 466 | "Critical temperature reached (%ld C), shutting down.\n", |
475 | KELVIN_TO_CELSIUS(tz->temperature)); | 467 | KELVIN_TO_CELSIUS(tz->temperature)); |
476 | acpi_bus_generate_event(device, ACPI_THERMAL_NOTIFY_CRITICAL, | 468 | acpi_bus_generate_event(tz->device, ACPI_THERMAL_NOTIFY_CRITICAL, |
477 | tz->trips.critical.flags.enabled); | 469 | tz->trips.critical.flags.enabled); |
478 | 470 | ||
479 | acpi_thermal_call_usermode(ACPI_THERMAL_PATH_POWEROFF); | 471 | acpi_thermal_call_usermode(ACPI_THERMAL_PATH_POWEROFF); |
@@ -483,10 +475,6 @@ static int acpi_thermal_critical(struct acpi_thermal *tz) | |||
483 | 475 | ||
484 | static int acpi_thermal_hot(struct acpi_thermal *tz) | 476 | static int acpi_thermal_hot(struct acpi_thermal *tz) |
485 | { | 477 | { |
486 | int result = 0; | ||
487 | struct acpi_device *device = NULL; | ||
488 | |||
489 | |||
490 | if (!tz || !tz->trips.hot.flags.valid) | 478 | if (!tz || !tz->trips.hot.flags.valid) |
491 | return -EINVAL; | 479 | return -EINVAL; |
492 | 480 | ||
@@ -496,11 +484,7 @@ static int acpi_thermal_hot(struct acpi_thermal *tz) | |||
496 | } else if (tz->trips.hot.flags.enabled) | 484 | } else if (tz->trips.hot.flags.enabled) |
497 | tz->trips.hot.flags.enabled = 0; | 485 | tz->trips.hot.flags.enabled = 0; |
498 | 486 | ||
499 | result = acpi_bus_get_device(tz->handle, &device); | 487 | acpi_bus_generate_event(tz->device, ACPI_THERMAL_NOTIFY_HOT, |
500 | if (result) | ||
501 | return result; | ||
502 | |||
503 | acpi_bus_generate_event(device, ACPI_THERMAL_NOTIFY_HOT, | ||
504 | tz->trips.hot.flags.enabled); | 488 | tz->trips.hot.flags.enabled); |
505 | 489 | ||
506 | /* TBD: Call user-mode "sleep(S4)" function */ | 490 | /* TBD: Call user-mode "sleep(S4)" function */ |
@@ -1193,8 +1177,7 @@ static void acpi_thermal_notify(acpi_handle handle, u32 event, void *data) | |||
1193 | if (!tz) | 1177 | if (!tz) |
1194 | return; | 1178 | return; |
1195 | 1179 | ||
1196 | if (acpi_bus_get_device(tz->handle, &device)) | 1180 | device = tz->device; |
1197 | return; | ||
1198 | 1181 | ||
1199 | switch (event) { | 1182 | switch (event) { |
1200 | case ACPI_THERMAL_NOTIFY_TEMPERATURE: | 1183 | case ACPI_THERMAL_NOTIFY_TEMPERATURE: |
@@ -1293,7 +1276,7 @@ static int acpi_thermal_add(struct acpi_device *device) | |||
1293 | return -ENOMEM; | 1276 | return -ENOMEM; |
1294 | memset(tz, 0, sizeof(struct acpi_thermal)); | 1277 | memset(tz, 0, sizeof(struct acpi_thermal)); |
1295 | 1278 | ||
1296 | tz->handle = device->handle; | 1279 | tz->device = device; |
1297 | strcpy(tz->name, device->pnp.bus_id); | 1280 | strcpy(tz->name, device->pnp.bus_id); |
1298 | strcpy(acpi_device_name(device), ACPI_THERMAL_DEVICE_NAME); | 1281 | strcpy(acpi_device_name(device), ACPI_THERMAL_DEVICE_NAME); |
1299 | strcpy(acpi_device_class(device), ACPI_THERMAL_CLASS); | 1282 | strcpy(acpi_device_class(device), ACPI_THERMAL_CLASS); |
@@ -1311,7 +1294,7 @@ static int acpi_thermal_add(struct acpi_device *device) | |||
1311 | 1294 | ||
1312 | acpi_thermal_check(tz); | 1295 | acpi_thermal_check(tz); |
1313 | 1296 | ||
1314 | status = acpi_install_notify_handler(tz->handle, | 1297 | status = acpi_install_notify_handler(device->handle, |
1315 | ACPI_DEVICE_NOTIFY, | 1298 | ACPI_DEVICE_NOTIFY, |
1316 | acpi_thermal_notify, tz); | 1299 | acpi_thermal_notify, tz); |
1317 | if (ACPI_FAILURE(status)) { | 1300 | if (ACPI_FAILURE(status)) { |
@@ -1352,7 +1335,7 @@ static int acpi_thermal_remove(struct acpi_device *device, int type) | |||
1352 | /* deferred task may reinsert timer */ | 1335 | /* deferred task may reinsert timer */ |
1353 | del_timer_sync(&(tz->timer)); | 1336 | del_timer_sync(&(tz->timer)); |
1354 | 1337 | ||
1355 | status = acpi_remove_notify_handler(tz->handle, | 1338 | status = acpi_remove_notify_handler(device->handle, |
1356 | ACPI_DEVICE_NOTIFY, | 1339 | ACPI_DEVICE_NOTIFY, |
1357 | acpi_thermal_notify); | 1340 | acpi_thermal_notify); |
1358 | 1341 | ||
diff --git a/drivers/acpi/utilities/utalloc.c b/drivers/acpi/utilities/utalloc.c index 7940fc1bd69e..5cff17dc78b3 100644 --- a/drivers/acpi/utilities/utalloc.c +++ b/drivers/acpi/utilities/utalloc.c | |||
@@ -166,10 +166,10 @@ acpi_status acpi_ut_delete_caches(void) | |||
166 | 166 | ||
167 | /* Free memory lists */ | 167 | /* Free memory lists */ |
168 | 168 | ||
169 | acpi_os_free(acpi_gbl_global_list); | 169 | ACPI_FREE(acpi_gbl_global_list); |
170 | acpi_gbl_global_list = NULL; | 170 | acpi_gbl_global_list = NULL; |
171 | 171 | ||
172 | acpi_os_free(acpi_gbl_ns_node_list); | 172 | ACPI_FREE(acpi_gbl_ns_node_list); |
173 | acpi_gbl_ns_node_list = NULL; | 173 | acpi_gbl_ns_node_list = NULL; |
174 | #endif | 174 | #endif |
175 | 175 | ||
diff --git a/drivers/acpi/utilities/utcache.c b/drivers/acpi/utilities/utcache.c index 56270a30718a..1a1f8109159c 100644 --- a/drivers/acpi/utilities/utcache.c +++ b/drivers/acpi/utilities/utcache.c | |||
@@ -162,7 +162,7 @@ acpi_status acpi_os_delete_cache(struct acpi_memory_list * cache) | |||
162 | 162 | ||
163 | /* Now we can delete the cache object */ | 163 | /* Now we can delete the cache object */ |
164 | 164 | ||
165 | acpi_os_free(cache); | 165 | ACPI_FREE(cache); |
166 | return (AE_OK); | 166 | return (AE_OK); |
167 | } | 167 | } |
168 | 168 | ||
diff --git a/drivers/acpi/utils.c b/drivers/acpi/utils.c index 1930e1a75b22..f48227f4c8c9 100644 --- a/drivers/acpi/utils.c +++ b/drivers/acpi/utils.c | |||
@@ -332,7 +332,7 @@ acpi_evaluate_string(acpi_handle handle, | |||
332 | 332 | ||
333 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Return value [%s]\n", *data)); | 333 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Return value [%s]\n", *data)); |
334 | 334 | ||
335 | acpi_os_free(buffer.pointer); | 335 | kfree(buffer.pointer); |
336 | 336 | ||
337 | return AE_OK; | 337 | return AE_OK; |
338 | } | 338 | } |
@@ -418,7 +418,7 @@ acpi_evaluate_reference(acpi_handle handle, | |||
418 | //kfree(list->handles); | 418 | //kfree(list->handles); |
419 | } | 419 | } |
420 | 420 | ||
421 | acpi_os_free(buffer.pointer); | 421 | kfree(buffer.pointer); |
422 | 422 | ||
423 | return status; | 423 | return status; |
424 | } | 424 | } |
diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c index 9feb633087a9..56666a982476 100644 --- a/drivers/acpi/video.c +++ b/drivers/acpi/video.c | |||
@@ -117,7 +117,7 @@ struct acpi_video_enumerated_device { | |||
117 | }; | 117 | }; |
118 | 118 | ||
119 | struct acpi_video_bus { | 119 | struct acpi_video_bus { |
120 | acpi_handle handle; | 120 | struct acpi_device *device; |
121 | u8 dos_setting; | 121 | u8 dos_setting; |
122 | struct acpi_video_enumerated_device *attached_array; | 122 | struct acpi_video_enumerated_device *attached_array; |
123 | u8 attached_count; | 123 | u8 attached_count; |
@@ -155,7 +155,6 @@ struct acpi_video_device_brightness { | |||
155 | }; | 155 | }; |
156 | 156 | ||
157 | struct acpi_video_device { | 157 | struct acpi_video_device { |
158 | acpi_handle handle; | ||
159 | unsigned long device_id; | 158 | unsigned long device_id; |
160 | struct acpi_video_device_flags flags; | 159 | struct acpi_video_device_flags flags; |
161 | struct acpi_video_device_cap cap; | 160 | struct acpi_video_device_cap cap; |
@@ -272,7 +271,8 @@ static int | |||
272 | acpi_video_device_query(struct acpi_video_device *device, unsigned long *state) | 271 | acpi_video_device_query(struct acpi_video_device *device, unsigned long *state) |
273 | { | 272 | { |
274 | int status; | 273 | int status; |
275 | status = acpi_evaluate_integer(device->handle, "_DGS", NULL, state); | 274 | |
275 | status = acpi_evaluate_integer(device->dev->handle, "_DGS", NULL, state); | ||
276 | 276 | ||
277 | return status; | 277 | return status; |
278 | } | 278 | } |
@@ -283,8 +283,7 @@ acpi_video_device_get_state(struct acpi_video_device *device, | |||
283 | { | 283 | { |
284 | int status; | 284 | int status; |
285 | 285 | ||
286 | 286 | status = acpi_evaluate_integer(device->dev->handle, "_DCS", NULL, state); | |
287 | status = acpi_evaluate_integer(device->handle, "_DCS", NULL, state); | ||
288 | 287 | ||
289 | return status; | 288 | return status; |
290 | } | 289 | } |
@@ -299,7 +298,7 @@ acpi_video_device_set_state(struct acpi_video_device *device, int state) | |||
299 | 298 | ||
300 | 299 | ||
301 | arg0.integer.value = state; | 300 | arg0.integer.value = state; |
302 | status = acpi_evaluate_integer(device->handle, "_DSS", &args, &ret); | 301 | status = acpi_evaluate_integer(device->dev->handle, "_DSS", &args, &ret); |
303 | 302 | ||
304 | return status; | 303 | return status; |
305 | } | 304 | } |
@@ -315,7 +314,7 @@ acpi_video_device_lcd_query_levels(struct acpi_video_device *device, | |||
315 | 314 | ||
316 | *levels = NULL; | 315 | *levels = NULL; |
317 | 316 | ||
318 | status = acpi_evaluate_object(device->handle, "_BCL", NULL, &buffer); | 317 | status = acpi_evaluate_object(device->dev->handle, "_BCL", NULL, &buffer); |
319 | if (!ACPI_SUCCESS(status)) | 318 | if (!ACPI_SUCCESS(status)) |
320 | return status; | 319 | return status; |
321 | obj = (union acpi_object *)buffer.pointer; | 320 | obj = (union acpi_object *)buffer.pointer; |
@@ -344,7 +343,7 @@ acpi_video_device_lcd_set_level(struct acpi_video_device *device, int level) | |||
344 | 343 | ||
345 | 344 | ||
346 | arg0.integer.value = level; | 345 | arg0.integer.value = level; |
347 | status = acpi_evaluate_object(device->handle, "_BCM", &args, NULL); | 346 | status = acpi_evaluate_object(device->dev->handle, "_BCM", &args, NULL); |
348 | 347 | ||
349 | printk(KERN_DEBUG "set_level status: %x\n", status); | 348 | printk(KERN_DEBUG "set_level status: %x\n", status); |
350 | return status; | 349 | return status; |
@@ -356,7 +355,7 @@ acpi_video_device_lcd_get_level_current(struct acpi_video_device *device, | |||
356 | { | 355 | { |
357 | int status; | 356 | int status; |
358 | 357 | ||
359 | status = acpi_evaluate_integer(device->handle, "_BQC", NULL, level); | 358 | status = acpi_evaluate_integer(device->dev->handle, "_BQC", NULL, level); |
360 | 359 | ||
361 | return status; | 360 | return status; |
362 | } | 361 | } |
@@ -383,7 +382,7 @@ acpi_video_device_EDID(struct acpi_video_device *device, | |||
383 | else | 382 | else |
384 | return -EINVAL; | 383 | return -EINVAL; |
385 | 384 | ||
386 | status = acpi_evaluate_object(device->handle, "_DDC", &args, &buffer); | 385 | status = acpi_evaluate_object(device->dev->handle, "_DDC", &args, &buffer); |
387 | if (ACPI_FAILURE(status)) | 386 | if (ACPI_FAILURE(status)) |
388 | return -ENODEV; | 387 | return -ENODEV; |
389 | 388 | ||
@@ -413,7 +412,7 @@ acpi_video_bus_set_POST(struct acpi_video_bus *video, unsigned long option) | |||
413 | 412 | ||
414 | arg0.integer.value = option; | 413 | arg0.integer.value = option; |
415 | 414 | ||
416 | status = acpi_evaluate_integer(video->handle, "_SPD", &args, &tmp); | 415 | status = acpi_evaluate_integer(video->device->handle, "_SPD", &args, &tmp); |
417 | if (ACPI_SUCCESS(status)) | 416 | if (ACPI_SUCCESS(status)) |
418 | status = tmp ? (-EINVAL) : (AE_OK); | 417 | status = tmp ? (-EINVAL) : (AE_OK); |
419 | 418 | ||
@@ -425,8 +424,7 @@ acpi_video_bus_get_POST(struct acpi_video_bus *video, unsigned long *id) | |||
425 | { | 424 | { |
426 | int status; | 425 | int status; |
427 | 426 | ||
428 | 427 | status = acpi_evaluate_integer(video->device->handle, "_GPD", NULL, id); | |
429 | status = acpi_evaluate_integer(video->handle, "_GPD", NULL, id); | ||
430 | 428 | ||
431 | return status; | 429 | return status; |
432 | } | 430 | } |
@@ -437,7 +435,7 @@ acpi_video_bus_POST_options(struct acpi_video_bus *video, | |||
437 | { | 435 | { |
438 | int status; | 436 | int status; |
439 | 437 | ||
440 | status = acpi_evaluate_integer(video->handle, "_VPO", NULL, options); | 438 | status = acpi_evaluate_integer(video->device->handle, "_VPO", NULL, options); |
441 | *options &= 3; | 439 | *options &= 3; |
442 | 440 | ||
443 | return status; | 441 | return status; |
@@ -478,7 +476,7 @@ acpi_video_bus_DOS(struct acpi_video_bus *video, int bios_flag, int lcd_flag) | |||
478 | } | 476 | } |
479 | arg0.integer.value = (lcd_flag << 2) | bios_flag; | 477 | arg0.integer.value = (lcd_flag << 2) | bios_flag; |
480 | video->dos_setting = arg0.integer.value; | 478 | video->dos_setting = arg0.integer.value; |
481 | acpi_evaluate_object(video->handle, "_DOS", &args, NULL); | 479 | acpi_evaluate_object(video->device->handle, "_DOS", &args, NULL); |
482 | 480 | ||
483 | Failed: | 481 | Failed: |
484 | return status; | 482 | return status; |
@@ -506,25 +504,25 @@ static void acpi_video_device_find_cap(struct acpi_video_device *device) | |||
506 | 504 | ||
507 | memset(&device->cap, 0, 4); | 505 | memset(&device->cap, 0, 4); |
508 | 506 | ||
509 | if (ACPI_SUCCESS(acpi_get_handle(device->handle, "_ADR", &h_dummy1))) { | 507 | if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle, "_ADR", &h_dummy1))) { |
510 | device->cap._ADR = 1; | 508 | device->cap._ADR = 1; |
511 | } | 509 | } |
512 | if (ACPI_SUCCESS(acpi_get_handle(device->handle, "_BCL", &h_dummy1))) { | 510 | if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle, "_BCL", &h_dummy1))) { |
513 | device->cap._BCL = 1; | 511 | device->cap._BCL = 1; |
514 | } | 512 | } |
515 | if (ACPI_SUCCESS(acpi_get_handle(device->handle, "_BCM", &h_dummy1))) { | 513 | if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle, "_BCM", &h_dummy1))) { |
516 | device->cap._BCM = 1; | 514 | device->cap._BCM = 1; |
517 | } | 515 | } |
518 | if (ACPI_SUCCESS(acpi_get_handle(device->handle, "_DDC", &h_dummy1))) { | 516 | if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle, "_DDC", &h_dummy1))) { |
519 | device->cap._DDC = 1; | 517 | device->cap._DDC = 1; |
520 | } | 518 | } |
521 | if (ACPI_SUCCESS(acpi_get_handle(device->handle, "_DCS", &h_dummy1))) { | 519 | if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle, "_DCS", &h_dummy1))) { |
522 | device->cap._DCS = 1; | 520 | device->cap._DCS = 1; |
523 | } | 521 | } |
524 | if (ACPI_SUCCESS(acpi_get_handle(device->handle, "_DGS", &h_dummy1))) { | 522 | if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle, "_DGS", &h_dummy1))) { |
525 | device->cap._DGS = 1; | 523 | device->cap._DGS = 1; |
526 | } | 524 | } |
527 | if (ACPI_SUCCESS(acpi_get_handle(device->handle, "_DSS", &h_dummy1))) { | 525 | if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle, "_DSS", &h_dummy1))) { |
528 | device->cap._DSS = 1; | 526 | device->cap._DSS = 1; |
529 | } | 527 | } |
530 | 528 | ||
@@ -588,22 +586,22 @@ static void acpi_video_bus_find_cap(struct acpi_video_bus *video) | |||
588 | acpi_handle h_dummy1; | 586 | acpi_handle h_dummy1; |
589 | 587 | ||
590 | memset(&video->cap, 0, 4); | 588 | memset(&video->cap, 0, 4); |
591 | if (ACPI_SUCCESS(acpi_get_handle(video->handle, "_DOS", &h_dummy1))) { | 589 | if (ACPI_SUCCESS(acpi_get_handle(video->device->handle, "_DOS", &h_dummy1))) { |
592 | video->cap._DOS = 1; | 590 | video->cap._DOS = 1; |
593 | } | 591 | } |
594 | if (ACPI_SUCCESS(acpi_get_handle(video->handle, "_DOD", &h_dummy1))) { | 592 | if (ACPI_SUCCESS(acpi_get_handle(video->device->handle, "_DOD", &h_dummy1))) { |
595 | video->cap._DOD = 1; | 593 | video->cap._DOD = 1; |
596 | } | 594 | } |
597 | if (ACPI_SUCCESS(acpi_get_handle(video->handle, "_ROM", &h_dummy1))) { | 595 | if (ACPI_SUCCESS(acpi_get_handle(video->device->handle, "_ROM", &h_dummy1))) { |
598 | video->cap._ROM = 1; | 596 | video->cap._ROM = 1; |
599 | } | 597 | } |
600 | if (ACPI_SUCCESS(acpi_get_handle(video->handle, "_GPD", &h_dummy1))) { | 598 | if (ACPI_SUCCESS(acpi_get_handle(video->device->handle, "_GPD", &h_dummy1))) { |
601 | video->cap._GPD = 1; | 599 | video->cap._GPD = 1; |
602 | } | 600 | } |
603 | if (ACPI_SUCCESS(acpi_get_handle(video->handle, "_SPD", &h_dummy1))) { | 601 | if (ACPI_SUCCESS(acpi_get_handle(video->device->handle, "_SPD", &h_dummy1))) { |
604 | video->cap._SPD = 1; | 602 | video->cap._SPD = 1; |
605 | } | 603 | } |
606 | if (ACPI_SUCCESS(acpi_get_handle(video->handle, "_VPO", &h_dummy1))) { | 604 | if (ACPI_SUCCESS(acpi_get_handle(video->device->handle, "_VPO", &h_dummy1))) { |
607 | video->cap._VPO = 1; | 605 | video->cap._VPO = 1; |
608 | } | 606 | } |
609 | } | 607 | } |
@@ -1271,7 +1269,6 @@ acpi_video_bus_get_one_device(struct acpi_device *device, | |||
1271 | 1269 | ||
1272 | memset(data, 0, sizeof(struct acpi_video_device)); | 1270 | memset(data, 0, sizeof(struct acpi_video_device)); |
1273 | 1271 | ||
1274 | data->handle = device->handle; | ||
1275 | strcpy(acpi_device_name(device), ACPI_VIDEO_DEVICE_NAME); | 1272 | strcpy(acpi_device_name(device), ACPI_VIDEO_DEVICE_NAME); |
1276 | strcpy(acpi_device_class(device), ACPI_VIDEO_CLASS); | 1273 | strcpy(acpi_device_class(device), ACPI_VIDEO_CLASS); |
1277 | acpi_driver_data(device) = data; | 1274 | acpi_driver_data(device) = data; |
@@ -1298,7 +1295,7 @@ acpi_video_bus_get_one_device(struct acpi_device *device, | |||
1298 | acpi_video_device_bind(video, data); | 1295 | acpi_video_device_bind(video, data); |
1299 | acpi_video_device_find_cap(data); | 1296 | acpi_video_device_find_cap(data); |
1300 | 1297 | ||
1301 | status = acpi_install_notify_handler(data->handle, | 1298 | status = acpi_install_notify_handler(device->handle, |
1302 | ACPI_DEVICE_NOTIFY, | 1299 | ACPI_DEVICE_NOTIFY, |
1303 | acpi_video_device_notify, | 1300 | acpi_video_device_notify, |
1304 | data); | 1301 | data); |
@@ -1400,8 +1397,7 @@ static int acpi_video_device_enumerate(struct acpi_video_bus *video) | |||
1400 | union acpi_object *dod = NULL; | 1397 | union acpi_object *dod = NULL; |
1401 | union acpi_object *obj; | 1398 | union acpi_object *obj; |
1402 | 1399 | ||
1403 | 1400 | status = acpi_evaluate_object(video->device->handle, "_DOD", NULL, &buffer); | |
1404 | status = acpi_evaluate_object(video->handle, "_DOD", NULL, &buffer); | ||
1405 | if (!ACPI_SUCCESS(status)) { | 1401 | if (!ACPI_SUCCESS(status)) { |
1406 | ACPI_EXCEPTION((AE_INFO, status, "Evaluating _DOD")); | 1402 | ACPI_EXCEPTION((AE_INFO, status, "Evaluating _DOD")); |
1407 | return status; | 1403 | return status; |
@@ -1450,7 +1446,7 @@ static int acpi_video_device_enumerate(struct acpi_video_bus *video) | |||
1450 | video->attached_array = active_device_list; | 1446 | video->attached_array = active_device_list; |
1451 | video->attached_count = count; | 1447 | video->attached_count = count; |
1452 | out: | 1448 | out: |
1453 | acpi_os_free(buffer.pointer); | 1449 | kfree(buffer.pointer); |
1454 | return status; | 1450 | return status; |
1455 | } | 1451 | } |
1456 | 1452 | ||
@@ -1569,7 +1565,7 @@ static int acpi_video_bus_put_one_device(struct acpi_video_device *device) | |||
1569 | up(&video->sem); | 1565 | up(&video->sem); |
1570 | acpi_video_device_remove_fs(device->dev); | 1566 | acpi_video_device_remove_fs(device->dev); |
1571 | 1567 | ||
1572 | status = acpi_remove_notify_handler(device->handle, | 1568 | status = acpi_remove_notify_handler(device->dev->handle, |
1573 | ACPI_DEVICE_NOTIFY, | 1569 | ACPI_DEVICE_NOTIFY, |
1574 | acpi_video_device_notify); | 1570 | acpi_video_device_notify); |
1575 | 1571 | ||
@@ -1624,8 +1620,7 @@ static void acpi_video_bus_notify(acpi_handle handle, u32 event, void *data) | |||
1624 | if (!video) | 1620 | if (!video) |
1625 | return; | 1621 | return; |
1626 | 1622 | ||
1627 | if (acpi_bus_get_device(handle, &device)) | 1623 | device = video->device; |
1628 | return; | ||
1629 | 1624 | ||
1630 | switch (event) { | 1625 | switch (event) { |
1631 | case ACPI_VIDEO_NOTIFY_SWITCH: /* User request that a switch occur, | 1626 | case ACPI_VIDEO_NOTIFY_SWITCH: /* User request that a switch occur, |
@@ -1668,8 +1663,7 @@ static void acpi_video_device_notify(acpi_handle handle, u32 event, void *data) | |||
1668 | if (!video_device) | 1663 | if (!video_device) |
1669 | return; | 1664 | return; |
1670 | 1665 | ||
1671 | if (acpi_bus_get_device(handle, &device)) | 1666 | device = video_device->dev; |
1672 | return; | ||
1673 | 1667 | ||
1674 | switch (event) { | 1668 | switch (event) { |
1675 | case ACPI_VIDEO_NOTIFY_SWITCH: /* change in status (cycle output device) */ | 1669 | case ACPI_VIDEO_NOTIFY_SWITCH: /* change in status (cycle output device) */ |
@@ -1707,7 +1701,7 @@ static int acpi_video_bus_add(struct acpi_device *device) | |||
1707 | return -ENOMEM; | 1701 | return -ENOMEM; |
1708 | memset(video, 0, sizeof(struct acpi_video_bus)); | 1702 | memset(video, 0, sizeof(struct acpi_video_bus)); |
1709 | 1703 | ||
1710 | video->handle = device->handle; | 1704 | video->device = device; |
1711 | strcpy(acpi_device_name(device), ACPI_VIDEO_BUS_NAME); | 1705 | strcpy(acpi_device_name(device), ACPI_VIDEO_BUS_NAME); |
1712 | strcpy(acpi_device_class(device), ACPI_VIDEO_CLASS); | 1706 | strcpy(acpi_device_class(device), ACPI_VIDEO_CLASS); |
1713 | acpi_driver_data(device) = video; | 1707 | acpi_driver_data(device) = video; |
@@ -1727,7 +1721,7 @@ static int acpi_video_bus_add(struct acpi_device *device) | |||
1727 | acpi_video_bus_get_devices(video, device); | 1721 | acpi_video_bus_get_devices(video, device); |
1728 | acpi_video_bus_start_devices(video); | 1722 | acpi_video_bus_start_devices(video); |
1729 | 1723 | ||
1730 | status = acpi_install_notify_handler(video->handle, | 1724 | status = acpi_install_notify_handler(device->handle, |
1731 | ACPI_DEVICE_NOTIFY, | 1725 | ACPI_DEVICE_NOTIFY, |
1732 | acpi_video_bus_notify, video); | 1726 | acpi_video_bus_notify, video); |
1733 | if (ACPI_FAILURE(status)) { | 1727 | if (ACPI_FAILURE(status)) { |
@@ -1767,7 +1761,7 @@ static int acpi_video_bus_remove(struct acpi_device *device, int type) | |||
1767 | 1761 | ||
1768 | acpi_video_bus_stop_devices(video); | 1762 | acpi_video_bus_stop_devices(video); |
1769 | 1763 | ||
1770 | status = acpi_remove_notify_handler(video->handle, | 1764 | status = acpi_remove_notify_handler(video->device->handle, |
1771 | ACPI_DEVICE_NOTIFY, | 1765 | ACPI_DEVICE_NOTIFY, |
1772 | acpi_video_bus_notify); | 1766 | acpi_video_bus_notify); |
1773 | 1767 | ||
diff --git a/drivers/atm/ambassador.c b/drivers/atm/ambassador.c index d3b426313a41..4521a249dd56 100644 --- a/drivers/atm/ambassador.c +++ b/drivers/atm/ambassador.c | |||
@@ -31,6 +31,7 @@ | |||
31 | #include <linux/atmdev.h> | 31 | #include <linux/atmdev.h> |
32 | #include <linux/delay.h> | 32 | #include <linux/delay.h> |
33 | #include <linux/interrupt.h> | 33 | #include <linux/interrupt.h> |
34 | #include <linux/poison.h> | ||
34 | 35 | ||
35 | #include <asm/atomic.h> | 36 | #include <asm/atomic.h> |
36 | #include <asm/io.h> | 37 | #include <asm/io.h> |
@@ -1995,7 +1996,7 @@ static int __devinit ucode_init (loader_block * lb, amb_dev * dev) { | |||
1995 | } | 1996 | } |
1996 | i += 1; | 1997 | i += 1; |
1997 | } | 1998 | } |
1998 | if (*pointer == 0xdeadbeef) { | 1999 | if (*pointer == ATM_POISON) { |
1999 | return loader_start (lb, dev, ucode_start); | 2000 | return loader_start (lb, dev, ucode_start); |
2000 | } else { | 2001 | } else { |
2001 | // cast needed as there is no %? for pointer differnces | 2002 | // cast needed as there is no %? for pointer differnces |
diff --git a/drivers/atm/idt77252.c b/drivers/atm/idt77252.c index 5d1c6c95262c..b0369bb20f08 100644 --- a/drivers/atm/idt77252.c +++ b/drivers/atm/idt77252.c | |||
@@ -35,6 +35,7 @@ static char const rcsid[] = | |||
35 | 35 | ||
36 | #include <linux/module.h> | 36 | #include <linux/module.h> |
37 | #include <linux/pci.h> | 37 | #include <linux/pci.h> |
38 | #include <linux/poison.h> | ||
38 | #include <linux/skbuff.h> | 39 | #include <linux/skbuff.h> |
39 | #include <linux/kernel.h> | 40 | #include <linux/kernel.h> |
40 | #include <linux/vmalloc.h> | 41 | #include <linux/vmalloc.h> |
@@ -3657,7 +3658,7 @@ probe_sram(struct idt77252_dev *card) | |||
3657 | writel(SAR_CMD_WRITE_SRAM | (0 << 2), SAR_REG_CMD); | 3658 | writel(SAR_CMD_WRITE_SRAM | (0 << 2), SAR_REG_CMD); |
3658 | 3659 | ||
3659 | for (addr = 0x4000; addr < 0x80000; addr += 0x4000) { | 3660 | for (addr = 0x4000; addr < 0x80000; addr += 0x4000) { |
3660 | writel(0xdeadbeef, SAR_REG_DR0); | 3661 | writel(ATM_POISON, SAR_REG_DR0); |
3661 | writel(SAR_CMD_WRITE_SRAM | (addr << 2), SAR_REG_CMD); | 3662 | writel(SAR_CMD_WRITE_SRAM | (addr << 2), SAR_REG_CMD); |
3662 | 3663 | ||
3663 | writel(SAR_CMD_READ_SRAM | (0 << 2), SAR_REG_CMD); | 3664 | writel(SAR_CMD_READ_SRAM | (0 << 2), SAR_REG_CMD); |
diff --git a/drivers/block/floppy.c b/drivers/block/floppy.c index 0242cbb86a87..5109fa37c662 100644 --- a/drivers/block/floppy.c +++ b/drivers/block/floppy.c | |||
@@ -249,18 +249,6 @@ static int irqdma_allocated; | |||
249 | #include <linux/cdrom.h> /* for the compatibility eject ioctl */ | 249 | #include <linux/cdrom.h> /* for the compatibility eject ioctl */ |
250 | #include <linux/completion.h> | 250 | #include <linux/completion.h> |
251 | 251 | ||
252 | /* | ||
253 | * Interrupt freeing also means /proc VFS work - dont do it | ||
254 | * from interrupt context. We push this work into keventd: | ||
255 | */ | ||
256 | static void fd_free_irq_fn(void *data) | ||
257 | { | ||
258 | fd_free_irq(); | ||
259 | } | ||
260 | |||
261 | static DECLARE_WORK(fd_free_irq_work, fd_free_irq_fn, NULL); | ||
262 | |||
263 | |||
264 | static struct request *current_req; | 252 | static struct request *current_req; |
265 | static struct request_queue *floppy_queue; | 253 | static struct request_queue *floppy_queue; |
266 | static void do_fd_request(request_queue_t * q); | 254 | static void do_fd_request(request_queue_t * q); |
@@ -826,15 +814,6 @@ static int set_dor(int fdc, char mask, char data) | |||
826 | UDRS->select_date = jiffies; | 814 | UDRS->select_date = jiffies; |
827 | } | 815 | } |
828 | } | 816 | } |
829 | /* | ||
830 | * We should propagate failures to grab the resources back | ||
831 | * nicely from here. Actually we ought to rewrite the fd | ||
832 | * driver some day too. | ||
833 | */ | ||
834 | if (newdor & FLOPPY_MOTOR_MASK) | ||
835 | floppy_grab_irq_and_dma(); | ||
836 | if (olddor & FLOPPY_MOTOR_MASK) | ||
837 | floppy_release_irq_and_dma(); | ||
838 | return olddor; | 817 | return olddor; |
839 | } | 818 | } |
840 | 819 | ||
@@ -892,8 +871,6 @@ static int _lock_fdc(int drive, int interruptible, int line) | |||
892 | line); | 871 | line); |
893 | return -1; | 872 | return -1; |
894 | } | 873 | } |
895 | if (floppy_grab_irq_and_dma() == -1) | ||
896 | return -EBUSY; | ||
897 | 874 | ||
898 | if (test_and_set_bit(0, &fdc_busy)) { | 875 | if (test_and_set_bit(0, &fdc_busy)) { |
899 | DECLARE_WAITQUEUE(wait, current); | 876 | DECLARE_WAITQUEUE(wait, current); |
@@ -915,6 +892,8 @@ static int _lock_fdc(int drive, int interruptible, int line) | |||
915 | 892 | ||
916 | set_current_state(TASK_RUNNING); | 893 | set_current_state(TASK_RUNNING); |
917 | remove_wait_queue(&fdc_wait, &wait); | 894 | remove_wait_queue(&fdc_wait, &wait); |
895 | |||
896 | flush_scheduled_work(); | ||
918 | } | 897 | } |
919 | command_status = FD_COMMAND_NONE; | 898 | command_status = FD_COMMAND_NONE; |
920 | 899 | ||
@@ -948,7 +927,6 @@ static inline void unlock_fdc(void) | |||
948 | if (elv_next_request(floppy_queue)) | 927 | if (elv_next_request(floppy_queue)) |
949 | do_fd_request(floppy_queue); | 928 | do_fd_request(floppy_queue); |
950 | spin_unlock_irqrestore(&floppy_lock, flags); | 929 | spin_unlock_irqrestore(&floppy_lock, flags); |
951 | floppy_release_irq_and_dma(); | ||
952 | wake_up(&fdc_wait); | 930 | wake_up(&fdc_wait); |
953 | } | 931 | } |
954 | 932 | ||
@@ -3694,8 +3672,8 @@ static int floppy_release(struct inode *inode, struct file *filp) | |||
3694 | } | 3672 | } |
3695 | if (!UDRS->fd_ref) | 3673 | if (!UDRS->fd_ref) |
3696 | opened_bdev[drive] = NULL; | 3674 | opened_bdev[drive] = NULL; |
3697 | floppy_release_irq_and_dma(); | ||
3698 | mutex_unlock(&open_lock); | 3675 | mutex_unlock(&open_lock); |
3676 | |||
3699 | return 0; | 3677 | return 0; |
3700 | } | 3678 | } |
3701 | 3679 | ||
@@ -3726,9 +3704,6 @@ static int floppy_open(struct inode *inode, struct file *filp) | |||
3726 | if (UDRS->fd_ref == -1 || (UDRS->fd_ref && (filp->f_flags & O_EXCL))) | 3704 | if (UDRS->fd_ref == -1 || (UDRS->fd_ref && (filp->f_flags & O_EXCL))) |
3727 | goto out2; | 3705 | goto out2; |
3728 | 3706 | ||
3729 | if (floppy_grab_irq_and_dma()) | ||
3730 | goto out2; | ||
3731 | |||
3732 | if (filp->f_flags & O_EXCL) | 3707 | if (filp->f_flags & O_EXCL) |
3733 | UDRS->fd_ref = -1; | 3708 | UDRS->fd_ref = -1; |
3734 | else | 3709 | else |
@@ -3805,7 +3780,6 @@ out: | |||
3805 | UDRS->fd_ref--; | 3780 | UDRS->fd_ref--; |
3806 | if (!UDRS->fd_ref) | 3781 | if (!UDRS->fd_ref) |
3807 | opened_bdev[drive] = NULL; | 3782 | opened_bdev[drive] = NULL; |
3808 | floppy_release_irq_and_dma(); | ||
3809 | out2: | 3783 | out2: |
3810 | mutex_unlock(&open_lock); | 3784 | mutex_unlock(&open_lock); |
3811 | return res; | 3785 | return res; |
@@ -3822,14 +3796,9 @@ static int check_floppy_change(struct gendisk *disk) | |||
3822 | return 1; | 3796 | return 1; |
3823 | 3797 | ||
3824 | if (time_after(jiffies, UDRS->last_checked + UDP->checkfreq)) { | 3798 | if (time_after(jiffies, UDRS->last_checked + UDP->checkfreq)) { |
3825 | if (floppy_grab_irq_and_dma()) { | ||
3826 | return 1; | ||
3827 | } | ||
3828 | |||
3829 | lock_fdc(drive, 0); | 3799 | lock_fdc(drive, 0); |
3830 | poll_drive(0, 0); | 3800 | poll_drive(0, 0); |
3831 | process_fd_request(); | 3801 | process_fd_request(); |
3832 | floppy_release_irq_and_dma(); | ||
3833 | } | 3802 | } |
3834 | 3803 | ||
3835 | if (UTESTF(FD_DISK_CHANGED) || | 3804 | if (UTESTF(FD_DISK_CHANGED) || |
@@ -4346,7 +4315,6 @@ static int __init floppy_init(void) | |||
4346 | fdc = 0; | 4315 | fdc = 0; |
4347 | del_timer(&fd_timeout); | 4316 | del_timer(&fd_timeout); |
4348 | current_drive = 0; | 4317 | current_drive = 0; |
4349 | floppy_release_irq_and_dma(); | ||
4350 | initialising = 0; | 4318 | initialising = 0; |
4351 | if (have_no_fdc) { | 4319 | if (have_no_fdc) { |
4352 | DPRINT("no floppy controllers found\n"); | 4320 | DPRINT("no floppy controllers found\n"); |
@@ -4504,7 +4472,7 @@ static void floppy_release_irq_and_dma(void) | |||
4504 | if (irqdma_allocated) { | 4472 | if (irqdma_allocated) { |
4505 | fd_disable_dma(); | 4473 | fd_disable_dma(); |
4506 | fd_free_dma(); | 4474 | fd_free_dma(); |
4507 | schedule_work(&fd_free_irq_work); | 4475 | fd_free_irq(); |
4508 | irqdma_allocated = 0; | 4476 | irqdma_allocated = 0; |
4509 | } | 4477 | } |
4510 | set_dor(0, ~0, 8); | 4478 | set_dor(0, ~0, 8); |
@@ -4600,8 +4568,6 @@ void cleanup_module(void) | |||
4600 | /* eject disk, if any */ | 4568 | /* eject disk, if any */ |
4601 | fd_eject(0); | 4569 | fd_eject(0); |
4602 | 4570 | ||
4603 | flush_scheduled_work(); /* fd_free_irq() might be pending */ | ||
4604 | |||
4605 | wait_for_completion(&device_release); | 4571 | wait_for_completion(&device_release); |
4606 | } | 4572 | } |
4607 | 4573 | ||
diff --git a/drivers/block/swim3.c b/drivers/block/swim3.c index 3721e12135d9..cc42e762396f 100644 --- a/drivers/block/swim3.c +++ b/drivers/block/swim3.c | |||
@@ -250,8 +250,6 @@ static int floppy_open(struct inode *inode, struct file *filp); | |||
250 | static int floppy_release(struct inode *inode, struct file *filp); | 250 | static int floppy_release(struct inode *inode, struct file *filp); |
251 | static int floppy_check_change(struct gendisk *disk); | 251 | static int floppy_check_change(struct gendisk *disk); |
252 | static int floppy_revalidate(struct gendisk *disk); | 252 | static int floppy_revalidate(struct gendisk *disk); |
253 | static int swim3_add_device(struct device_node *swims); | ||
254 | int swim3_init(void); | ||
255 | 253 | ||
256 | #ifndef CONFIG_PMAC_MEDIABAY | 254 | #ifndef CONFIG_PMAC_MEDIABAY |
257 | #define check_media_bay(which, what) 1 | 255 | #define check_media_bay(which, what) 1 |
@@ -1011,114 +1009,63 @@ static struct block_device_operations floppy_fops = { | |||
1011 | .revalidate_disk= floppy_revalidate, | 1009 | .revalidate_disk= floppy_revalidate, |
1012 | }; | 1010 | }; |
1013 | 1011 | ||
1014 | int swim3_init(void) | 1012 | static int swim3_add_device(struct macio_dev *mdev, int index) |
1015 | { | ||
1016 | struct device_node *swim; | ||
1017 | int err = -ENOMEM; | ||
1018 | int i; | ||
1019 | |||
1020 | swim = find_devices("floppy"); | ||
1021 | while (swim && (floppy_count < MAX_FLOPPIES)) | ||
1022 | { | ||
1023 | swim3_add_device(swim); | ||
1024 | swim = swim->next; | ||
1025 | } | ||
1026 | |||
1027 | swim = find_devices("swim3"); | ||
1028 | while (swim && (floppy_count < MAX_FLOPPIES)) | ||
1029 | { | ||
1030 | swim3_add_device(swim); | ||
1031 | swim = swim->next; | ||
1032 | } | ||
1033 | |||
1034 | if (!floppy_count) | ||
1035 | return -ENODEV; | ||
1036 | |||
1037 | for (i = 0; i < floppy_count; i++) { | ||
1038 | disks[i] = alloc_disk(1); | ||
1039 | if (!disks[i]) | ||
1040 | goto out; | ||
1041 | } | ||
1042 | |||
1043 | if (register_blkdev(FLOPPY_MAJOR, "fd")) { | ||
1044 | err = -EBUSY; | ||
1045 | goto out; | ||
1046 | } | ||
1047 | |||
1048 | swim3_queue = blk_init_queue(do_fd_request, &swim3_lock); | ||
1049 | if (!swim3_queue) { | ||
1050 | err = -ENOMEM; | ||
1051 | goto out_queue; | ||
1052 | } | ||
1053 | |||
1054 | for (i = 0; i < floppy_count; i++) { | ||
1055 | struct gendisk *disk = disks[i]; | ||
1056 | disk->major = FLOPPY_MAJOR; | ||
1057 | disk->first_minor = i; | ||
1058 | disk->fops = &floppy_fops; | ||
1059 | disk->private_data = &floppy_states[i]; | ||
1060 | disk->queue = swim3_queue; | ||
1061 | disk->flags |= GENHD_FL_REMOVABLE; | ||
1062 | sprintf(disk->disk_name, "fd%d", i); | ||
1063 | set_capacity(disk, 2880); | ||
1064 | add_disk(disk); | ||
1065 | } | ||
1066 | return 0; | ||
1067 | |||
1068 | out_queue: | ||
1069 | unregister_blkdev(FLOPPY_MAJOR, "fd"); | ||
1070 | out: | ||
1071 | while (i--) | ||
1072 | put_disk(disks[i]); | ||
1073 | /* shouldn't we do something with results of swim_add_device()? */ | ||
1074 | return err; | ||
1075 | } | ||
1076 | |||
1077 | static int swim3_add_device(struct device_node *swim) | ||
1078 | { | 1013 | { |
1014 | struct device_node *swim = mdev->ofdev.node; | ||
1079 | struct device_node *mediabay; | 1015 | struct device_node *mediabay; |
1080 | struct floppy_state *fs = &floppy_states[floppy_count]; | 1016 | struct floppy_state *fs = &floppy_states[index]; |
1081 | struct resource res_reg, res_dma; | 1017 | int rc = -EBUSY; |
1082 | 1018 | ||
1083 | if (of_address_to_resource(swim, 0, &res_reg) || | 1019 | /* Check & Request resources */ |
1084 | of_address_to_resource(swim, 1, &res_dma)) { | 1020 | if (macio_resource_count(mdev) < 2) { |
1085 | printk(KERN_ERR "swim3: Can't get addresses\n"); | 1021 | printk(KERN_WARNING "ifd%d: no address for %s\n", |
1086 | return -EINVAL; | 1022 | index, swim->full_name); |
1023 | return -ENXIO; | ||
1087 | } | 1024 | } |
1088 | if (request_mem_region(res_reg.start, res_reg.end - res_reg.start + 1, | 1025 | if (macio_irq_count(mdev) < 2) { |
1089 | " (reg)") == NULL) { | 1026 | printk(KERN_WARNING "fd%d: no intrs for device %s\n", |
1090 | printk(KERN_ERR "swim3: Can't request register space\n"); | 1027 | index, swim->full_name); |
1091 | return -EINVAL; | ||
1092 | } | 1028 | } |
1093 | if (request_mem_region(res_dma.start, res_dma.end - res_dma.start + 1, | 1029 | if (macio_request_resource(mdev, 0, "swim3 (mmio)")) { |
1094 | " (dma)") == NULL) { | 1030 | printk(KERN_ERR "fd%d: can't request mmio resource for %s\n", |
1095 | release_mem_region(res_reg.start, | 1031 | index, swim->full_name); |
1096 | res_reg.end - res_reg.start + 1); | 1032 | return -EBUSY; |
1097 | printk(KERN_ERR "swim3: Can't request DMA space\n"); | ||
1098 | return -EINVAL; | ||
1099 | } | 1033 | } |
1100 | 1034 | if (macio_request_resource(mdev, 1, "swim3 (dma)")) { | |
1101 | if (swim->n_intrs < 2) { | 1035 | printk(KERN_ERR "fd%d: can't request dma resource for %s\n", |
1102 | printk(KERN_INFO "swim3: expecting 2 intrs (n_intrs:%d)\n", | 1036 | index, swim->full_name); |
1103 | swim->n_intrs); | 1037 | macio_release_resource(mdev, 0); |
1104 | release_mem_region(res_reg.start, | 1038 | return -EBUSY; |
1105 | res_reg.end - res_reg.start + 1); | ||
1106 | release_mem_region(res_dma.start, | ||
1107 | res_dma.end - res_dma.start + 1); | ||
1108 | return -EINVAL; | ||
1109 | } | 1039 | } |
1040 | dev_set_drvdata(&mdev->ofdev.dev, fs); | ||
1110 | 1041 | ||
1111 | mediabay = (strcasecmp(swim->parent->type, "media-bay") == 0) ? swim->parent : NULL; | 1042 | mediabay = (strcasecmp(swim->parent->type, "media-bay") == 0) ? |
1043 | swim->parent : NULL; | ||
1112 | if (mediabay == NULL) | 1044 | if (mediabay == NULL) |
1113 | pmac_call_feature(PMAC_FTR_SWIM3_ENABLE, swim, 0, 1); | 1045 | pmac_call_feature(PMAC_FTR_SWIM3_ENABLE, swim, 0, 1); |
1114 | 1046 | ||
1115 | memset(fs, 0, sizeof(*fs)); | 1047 | memset(fs, 0, sizeof(*fs)); |
1116 | spin_lock_init(&fs->lock); | 1048 | spin_lock_init(&fs->lock); |
1117 | fs->state = idle; | 1049 | fs->state = idle; |
1118 | fs->swim3 = (struct swim3 __iomem *)ioremap(res_reg.start, 0x200); | 1050 | fs->swim3 = (struct swim3 __iomem *) |
1119 | fs->dma = (struct dbdma_regs __iomem *)ioremap(res_dma.start, 0x200); | 1051 | ioremap(macio_resource_start(mdev, 0), 0x200); |
1120 | fs->swim3_intr = swim->intrs[0].line; | 1052 | if (fs->swim3 == NULL) { |
1121 | fs->dma_intr = swim->intrs[1].line; | 1053 | printk("fd%d: couldn't map registers for %s\n", |
1054 | index, swim->full_name); | ||
1055 | rc = -ENOMEM; | ||
1056 | goto out_release; | ||
1057 | } | ||
1058 | fs->dma = (struct dbdma_regs __iomem *) | ||
1059 | ioremap(macio_resource_start(mdev, 1), 0x200); | ||
1060 | if (fs->dma == NULL) { | ||
1061 | printk("fd%d: couldn't map DMA for %s\n", | ||
1062 | index, swim->full_name); | ||
1063 | iounmap(fs->swim3); | ||
1064 | rc = -ENOMEM; | ||
1065 | goto out_release; | ||
1066 | } | ||
1067 | fs->swim3_intr = macio_irq(mdev, 0); | ||
1068 | fs->dma_intr = macio_irq(mdev, 1);; | ||
1122 | fs->cur_cyl = -1; | 1069 | fs->cur_cyl = -1; |
1123 | fs->cur_sector = -1; | 1070 | fs->cur_sector = -1; |
1124 | fs->secpercyl = 36; | 1071 | fs->secpercyl = 36; |
@@ -1132,15 +1079,16 @@ static int swim3_add_device(struct device_node *swim) | |||
1132 | st_le16(&fs->dma_cmd[1].command, DBDMA_STOP); | 1079 | st_le16(&fs->dma_cmd[1].command, DBDMA_STOP); |
1133 | 1080 | ||
1134 | if (request_irq(fs->swim3_intr, swim3_interrupt, 0, "SWIM3", fs)) { | 1081 | if (request_irq(fs->swim3_intr, swim3_interrupt, 0, "SWIM3", fs)) { |
1135 | printk(KERN_ERR "Couldn't get irq %d for SWIM3\n", fs->swim3_intr); | 1082 | printk(KERN_ERR "fd%d: couldn't request irq %d for %s\n", |
1083 | index, fs->swim3_intr, swim->full_name); | ||
1136 | pmac_call_feature(PMAC_FTR_SWIM3_ENABLE, swim, 0, 0); | 1084 | pmac_call_feature(PMAC_FTR_SWIM3_ENABLE, swim, 0, 0); |
1085 | goto out_unmap; | ||
1137 | return -EBUSY; | 1086 | return -EBUSY; |
1138 | } | 1087 | } |
1139 | /* | 1088 | /* |
1140 | if (request_irq(fs->dma_intr, fd_dma_interrupt, 0, "SWIM3-dma", fs)) { | 1089 | if (request_irq(fs->dma_intr, fd_dma_interrupt, 0, "SWIM3-dma", fs)) { |
1141 | printk(KERN_ERR "Couldn't get irq %d for SWIM3 DMA", | 1090 | printk(KERN_ERR "Couldn't get irq %d for SWIM3 DMA", |
1142 | fs->dma_intr); | 1091 | fs->dma_intr); |
1143 | pmac_call_feature(PMAC_FTR_SWIM3_ENABLE, swim, 0, 0); | ||
1144 | return -EBUSY; | 1092 | return -EBUSY; |
1145 | } | 1093 | } |
1146 | */ | 1094 | */ |
@@ -1150,8 +1098,90 @@ static int swim3_add_device(struct device_node *swim) | |||
1150 | printk(KERN_INFO "fd%d: SWIM3 floppy controller %s\n", floppy_count, | 1098 | printk(KERN_INFO "fd%d: SWIM3 floppy controller %s\n", floppy_count, |
1151 | mediabay ? "in media bay" : ""); | 1099 | mediabay ? "in media bay" : ""); |
1152 | 1100 | ||
1153 | floppy_count++; | 1101 | return 0; |
1154 | 1102 | ||
1103 | out_unmap: | ||
1104 | iounmap(fs->dma); | ||
1105 | iounmap(fs->swim3); | ||
1106 | |||
1107 | out_release: | ||
1108 | macio_release_resource(mdev, 0); | ||
1109 | macio_release_resource(mdev, 1); | ||
1110 | |||
1111 | return rc; | ||
1112 | } | ||
1113 | |||
1114 | static int __devinit swim3_attach(struct macio_dev *mdev, const struct of_device_id *match) | ||
1115 | { | ||
1116 | int i, rc; | ||
1117 | struct gendisk *disk; | ||
1118 | |||
1119 | /* Add the drive */ | ||
1120 | rc = swim3_add_device(mdev, floppy_count); | ||
1121 | if (rc) | ||
1122 | return rc; | ||
1123 | |||
1124 | /* Now create the queue if not there yet */ | ||
1125 | if (swim3_queue == NULL) { | ||
1126 | /* If we failed, there isn't much we can do as the driver is still | ||
1127 | * too dumb to remove the device, just bail out | ||
1128 | */ | ||
1129 | if (register_blkdev(FLOPPY_MAJOR, "fd")) | ||
1130 | return 0; | ||
1131 | swim3_queue = blk_init_queue(do_fd_request, &swim3_lock); | ||
1132 | if (swim3_queue == NULL) { | ||
1133 | unregister_blkdev(FLOPPY_MAJOR, "fd"); | ||
1134 | return 0; | ||
1135 | } | ||
1136 | } | ||
1137 | |||
1138 | /* Now register that disk. Same comment about failure handling */ | ||
1139 | i = floppy_count++; | ||
1140 | disk = disks[i] = alloc_disk(1); | ||
1141 | if (disk == NULL) | ||
1142 | return 0; | ||
1143 | |||
1144 | disk->major = FLOPPY_MAJOR; | ||
1145 | disk->first_minor = i; | ||
1146 | disk->fops = &floppy_fops; | ||
1147 | disk->private_data = &floppy_states[i]; | ||
1148 | disk->queue = swim3_queue; | ||
1149 | disk->flags |= GENHD_FL_REMOVABLE; | ||
1150 | sprintf(disk->disk_name, "fd%d", i); | ||
1151 | set_capacity(disk, 2880); | ||
1152 | add_disk(disk); | ||
1153 | |||
1154 | return 0; | ||
1155 | } | ||
1156 | |||
1157 | static struct of_device_id swim3_match[] = | ||
1158 | { | ||
1159 | { | ||
1160 | .name = "swim3", | ||
1161 | }, | ||
1162 | { | ||
1163 | .compatible = "ohare-swim3" | ||
1164 | }, | ||
1165 | { | ||
1166 | .compatible = "swim3" | ||
1167 | }, | ||
1168 | }; | ||
1169 | |||
1170 | static struct macio_driver swim3_driver = | ||
1171 | { | ||
1172 | .name = "swim3", | ||
1173 | .match_table = swim3_match, | ||
1174 | .probe = swim3_attach, | ||
1175 | #if 0 | ||
1176 | .suspend = swim3_suspend, | ||
1177 | .resume = swim3_resume, | ||
1178 | #endif | ||
1179 | }; | ||
1180 | |||
1181 | |||
1182 | int swim3_init(void) | ||
1183 | { | ||
1184 | macio_register_driver(&swim3_driver); | ||
1155 | return 0; | 1185 | return 0; |
1156 | } | 1186 | } |
1157 | 1187 | ||
diff --git a/drivers/bluetooth/bluecard_cs.c b/drivers/bluetooth/bluecard_cs.c index 2830f58d6f77..8eebf9ca3786 100644 --- a/drivers/bluetooth/bluecard_cs.c +++ b/drivers/bluetooth/bluecard_cs.c | |||
@@ -739,6 +739,7 @@ static int bluecard_open(bluecard_info_t *info) | |||
739 | 739 | ||
740 | hdev->type = HCI_PCCARD; | 740 | hdev->type = HCI_PCCARD; |
741 | hdev->driver_data = info; | 741 | hdev->driver_data = info; |
742 | SET_HCIDEV_DEV(hdev, &info->p_dev->dev); | ||
742 | 743 | ||
743 | hdev->open = bluecard_hci_open; | 744 | hdev->open = bluecard_hci_open; |
744 | hdev->close = bluecard_hci_close; | 745 | hdev->close = bluecard_hci_close; |
diff --git a/drivers/bluetooth/bt3c_cs.c b/drivers/bluetooth/bt3c_cs.c index c9dba5565cac..df7bb016df49 100644 --- a/drivers/bluetooth/bt3c_cs.c +++ b/drivers/bluetooth/bt3c_cs.c | |||
@@ -582,6 +582,7 @@ static int bt3c_open(bt3c_info_t *info) | |||
582 | 582 | ||
583 | hdev->type = HCI_PCCARD; | 583 | hdev->type = HCI_PCCARD; |
584 | hdev->driver_data = info; | 584 | hdev->driver_data = info; |
585 | SET_HCIDEV_DEV(hdev, &info->p_dev->dev); | ||
585 | 586 | ||
586 | hdev->open = bt3c_hci_open; | 587 | hdev->open = bt3c_hci_open; |
587 | hdev->close = bt3c_hci_close; | 588 | hdev->close = bt3c_hci_close; |
diff --git a/drivers/bluetooth/btuart_cs.c b/drivers/bluetooth/btuart_cs.c index c889bf8109a1..746ccca97f6f 100644 --- a/drivers/bluetooth/btuart_cs.c +++ b/drivers/bluetooth/btuart_cs.c | |||
@@ -502,6 +502,7 @@ static int btuart_open(btuart_info_t *info) | |||
502 | 502 | ||
503 | hdev->type = HCI_PCCARD; | 503 | hdev->type = HCI_PCCARD; |
504 | hdev->driver_data = info; | 504 | hdev->driver_data = info; |
505 | SET_HCIDEV_DEV(hdev, &info->p_dev->dev); | ||
505 | 506 | ||
506 | hdev->open = btuart_hci_open; | 507 | hdev->open = btuart_hci_open; |
507 | hdev->close = btuart_hci_close; | 508 | hdev->close = btuart_hci_close; |
diff --git a/drivers/bluetooth/dtl1_cs.c b/drivers/bluetooth/dtl1_cs.c index be6eed175aa3..0e99def8a1e3 100644 --- a/drivers/bluetooth/dtl1_cs.c +++ b/drivers/bluetooth/dtl1_cs.c | |||
@@ -484,6 +484,7 @@ static int dtl1_open(dtl1_info_t *info) | |||
484 | 484 | ||
485 | hdev->type = HCI_PCCARD; | 485 | hdev->type = HCI_PCCARD; |
486 | hdev->driver_data = info; | 486 | hdev->driver_data = info; |
487 | SET_HCIDEV_DEV(hdev, &info->p_dev->dev); | ||
487 | 488 | ||
488 | hdev->open = dtl1_hci_open; | 489 | hdev->open = dtl1_hci_open; |
489 | hdev->close = dtl1_hci_close; | 490 | hdev->close = dtl1_hci_close; |
diff --git a/drivers/bluetooth/hci_usb.c b/drivers/bluetooth/hci_usb.c index a7d9d7e99e72..6a0c2230f82f 100644 --- a/drivers/bluetooth/hci_usb.c +++ b/drivers/bluetooth/hci_usb.c | |||
@@ -122,6 +122,9 @@ static struct usb_device_id blacklist_ids[] = { | |||
122 | /* RTX Telecom based adapter with buggy SCO support */ | 122 | /* RTX Telecom based adapter with buggy SCO support */ |
123 | { USB_DEVICE(0x0400, 0x0807), .driver_info = HCI_BROKEN_ISOC }, | 123 | { USB_DEVICE(0x0400, 0x0807), .driver_info = HCI_BROKEN_ISOC }, |
124 | 124 | ||
125 | /* Belkin F8T012 */ | ||
126 | { USB_DEVICE(0x050d, 0x0012), .driver_info = HCI_WRONG_SCO_MTU }, | ||
127 | |||
125 | /* Digianswer devices */ | 128 | /* Digianswer devices */ |
126 | { USB_DEVICE(0x08fd, 0x0001), .driver_info = HCI_DIGIANSWER }, | 129 | { USB_DEVICE(0x08fd, 0x0001), .driver_info = HCI_DIGIANSWER }, |
127 | { USB_DEVICE(0x08fd, 0x0002), .driver_info = HCI_IGNORE }, | 130 | { USB_DEVICE(0x08fd, 0x0002), .driver_info = HCI_IGNORE }, |
@@ -129,6 +132,9 @@ static struct usb_device_id blacklist_ids[] = { | |||
129 | /* CSR BlueCore Bluetooth Sniffer */ | 132 | /* CSR BlueCore Bluetooth Sniffer */ |
130 | { USB_DEVICE(0x0a12, 0x0002), .driver_info = HCI_SNIFFER }, | 133 | { USB_DEVICE(0x0a12, 0x0002), .driver_info = HCI_SNIFFER }, |
131 | 134 | ||
135 | /* Frontline ComProbe Bluetooth Sniffer */ | ||
136 | { USB_DEVICE(0x16d3, 0x0002), .driver_info = HCI_SNIFFER }, | ||
137 | |||
132 | { } /* Terminating entry */ | 138 | { } /* Terminating entry */ |
133 | }; | 139 | }; |
134 | 140 | ||
@@ -984,6 +990,9 @@ static int hci_usb_probe(struct usb_interface *intf, const struct usb_device_id | |||
984 | if (reset || id->driver_info & HCI_RESET) | 990 | if (reset || id->driver_info & HCI_RESET) |
985 | set_bit(HCI_QUIRK_RESET_ON_INIT, &hdev->quirks); | 991 | set_bit(HCI_QUIRK_RESET_ON_INIT, &hdev->quirks); |
986 | 992 | ||
993 | if (id->driver_info & HCI_WRONG_SCO_MTU) | ||
994 | set_bit(HCI_QUIRK_FIXUP_BUFFER_SIZE, &hdev->quirks); | ||
995 | |||
987 | if (id->driver_info & HCI_SNIFFER) { | 996 | if (id->driver_info & HCI_SNIFFER) { |
988 | if (le16_to_cpu(udev->descriptor.bcdDevice) > 0x997) | 997 | if (le16_to_cpu(udev->descriptor.bcdDevice) > 0x997) |
989 | set_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks); | 998 | set_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks); |
@@ -1042,10 +1051,81 @@ static void hci_usb_disconnect(struct usb_interface *intf) | |||
1042 | hci_free_dev(hdev); | 1051 | hci_free_dev(hdev); |
1043 | } | 1052 | } |
1044 | 1053 | ||
1054 | static int hci_usb_suspend(struct usb_interface *intf, pm_message_t message) | ||
1055 | { | ||
1056 | struct hci_usb *husb = usb_get_intfdata(intf); | ||
1057 | struct list_head killed; | ||
1058 | unsigned long flags; | ||
1059 | int i; | ||
1060 | |||
1061 | if (!husb || intf == husb->isoc_iface) | ||
1062 | return 0; | ||
1063 | |||
1064 | hci_suspend_dev(husb->hdev); | ||
1065 | |||
1066 | INIT_LIST_HEAD(&killed); | ||
1067 | |||
1068 | for (i = 0; i < 4; i++) { | ||
1069 | struct _urb_queue *q = &husb->pending_q[i]; | ||
1070 | struct _urb *_urb, *_tmp; | ||
1071 | |||
1072 | while ((_urb = _urb_dequeue(q))) { | ||
1073 | /* reset queue since _urb_dequeue sets it to NULL */ | ||
1074 | _urb->queue = q; | ||
1075 | usb_kill_urb(&_urb->urb); | ||
1076 | list_add(&_urb->list, &killed); | ||
1077 | } | ||
1078 | |||
1079 | spin_lock_irqsave(&q->lock, flags); | ||
1080 | |||
1081 | list_for_each_entry_safe(_urb, _tmp, &killed, list) { | ||
1082 | list_move_tail(&_urb->list, &q->head); | ||
1083 | } | ||
1084 | |||
1085 | spin_unlock_irqrestore(&q->lock, flags); | ||
1086 | } | ||
1087 | |||
1088 | return 0; | ||
1089 | } | ||
1090 | |||
1091 | static int hci_usb_resume(struct usb_interface *intf) | ||
1092 | { | ||
1093 | struct hci_usb *husb = usb_get_intfdata(intf); | ||
1094 | unsigned long flags; | ||
1095 | int i, err = 0; | ||
1096 | |||
1097 | if (!husb || intf == husb->isoc_iface) | ||
1098 | return 0; | ||
1099 | |||
1100 | for (i = 0; i < 4; i++) { | ||
1101 | struct _urb_queue *q = &husb->pending_q[i]; | ||
1102 | struct _urb *_urb; | ||
1103 | |||
1104 | spin_lock_irqsave(&q->lock, flags); | ||
1105 | |||
1106 | list_for_each_entry(_urb, &q->head, list) { | ||
1107 | err = usb_submit_urb(&_urb->urb, GFP_ATOMIC); | ||
1108 | if (err) | ||
1109 | break; | ||
1110 | } | ||
1111 | |||
1112 | spin_unlock_irqrestore(&q->lock, flags); | ||
1113 | |||
1114 | if (err) | ||
1115 | return -EIO; | ||
1116 | } | ||
1117 | |||
1118 | hci_resume_dev(husb->hdev); | ||
1119 | |||
1120 | return 0; | ||
1121 | } | ||
1122 | |||
1045 | static struct usb_driver hci_usb_driver = { | 1123 | static struct usb_driver hci_usb_driver = { |
1046 | .name = "hci_usb", | 1124 | .name = "hci_usb", |
1047 | .probe = hci_usb_probe, | 1125 | .probe = hci_usb_probe, |
1048 | .disconnect = hci_usb_disconnect, | 1126 | .disconnect = hci_usb_disconnect, |
1127 | .suspend = hci_usb_suspend, | ||
1128 | .resume = hci_usb_resume, | ||
1049 | .id_table = bluetooth_ids, | 1129 | .id_table = bluetooth_ids, |
1050 | }; | 1130 | }; |
1051 | 1131 | ||
diff --git a/drivers/bluetooth/hci_usb.h b/drivers/bluetooth/hci_usb.h index 37100a6ea1a8..963fc55cdc85 100644 --- a/drivers/bluetooth/hci_usb.h +++ b/drivers/bluetooth/hci_usb.h | |||
@@ -35,6 +35,7 @@ | |||
35 | #define HCI_SNIFFER 0x10 | 35 | #define HCI_SNIFFER 0x10 |
36 | #define HCI_BCM92035 0x20 | 36 | #define HCI_BCM92035 0x20 |
37 | #define HCI_BROKEN_ISOC 0x40 | 37 | #define HCI_BROKEN_ISOC 0x40 |
38 | #define HCI_WRONG_SCO_MTU 0x80 | ||
38 | 39 | ||
39 | #define HCI_MAX_IFACE_NUM 3 | 40 | #define HCI_MAX_IFACE_NUM 3 |
40 | 41 | ||
diff --git a/drivers/bluetooth/hci_vhci.c b/drivers/bluetooth/hci_vhci.c index ea589007fa26..aac67a3a6019 100644 --- a/drivers/bluetooth/hci_vhci.c +++ b/drivers/bluetooth/hci_vhci.c | |||
@@ -277,7 +277,6 @@ static int vhci_open(struct inode *inode, struct file *file) | |||
277 | 277 | ||
278 | hdev->type = HCI_VHCI; | 278 | hdev->type = HCI_VHCI; |
279 | hdev->driver_data = vhci; | 279 | hdev->driver_data = vhci; |
280 | SET_HCIDEV_DEV(hdev, vhci_miscdev.dev); | ||
281 | 280 | ||
282 | hdev->open = vhci_open_dev; | 281 | hdev->open = vhci_open_dev; |
283 | hdev->close = vhci_close_dev; | 282 | hdev->close = vhci_close_dev; |
diff --git a/drivers/char/agp/frontend.c b/drivers/char/agp/frontend.c index ffcf15c30e90..d9c5a9142ad1 100644 --- a/drivers/char/agp/frontend.c +++ b/drivers/char/agp/frontend.c | |||
@@ -1059,7 +1059,7 @@ ioctl_out: | |||
1059 | return ret_val; | 1059 | return ret_val; |
1060 | } | 1060 | } |
1061 | 1061 | ||
1062 | static struct file_operations agp_fops = | 1062 | static const struct file_operations agp_fops = |
1063 | { | 1063 | { |
1064 | .owner = THIS_MODULE, | 1064 | .owner = THIS_MODULE, |
1065 | .llseek = no_llseek, | 1065 | .llseek = no_llseek, |
diff --git a/drivers/char/applicom.c b/drivers/char/applicom.c index bcc4668835b5..10a389dafd60 100644 --- a/drivers/char/applicom.c +++ b/drivers/char/applicom.c | |||
@@ -112,7 +112,7 @@ static int ac_ioctl(struct inode *, struct file *, unsigned int, | |||
112 | unsigned long); | 112 | unsigned long); |
113 | static irqreturn_t ac_interrupt(int, void *, struct pt_regs *); | 113 | static irqreturn_t ac_interrupt(int, void *, struct pt_regs *); |
114 | 114 | ||
115 | static struct file_operations ac_fops = { | 115 | static const struct file_operations ac_fops = { |
116 | .owner = THIS_MODULE, | 116 | .owner = THIS_MODULE, |
117 | .llseek = no_llseek, | 117 | .llseek = no_llseek, |
118 | .read = ac_read, | 118 | .read = ac_read, |
diff --git a/drivers/char/cs5535_gpio.c b/drivers/char/cs5535_gpio.c index 46d66037b917..8ce3f34cfc22 100644 --- a/drivers/char/cs5535_gpio.c +++ b/drivers/char/cs5535_gpio.c | |||
@@ -158,7 +158,7 @@ static int cs5535_gpio_open(struct inode *inode, struct file *file) | |||
158 | return nonseekable_open(inode, file); | 158 | return nonseekable_open(inode, file); |
159 | } | 159 | } |
160 | 160 | ||
161 | static struct file_operations cs5535_gpio_fops = { | 161 | static const struct file_operations cs5535_gpio_fops = { |
162 | .owner = THIS_MODULE, | 162 | .owner = THIS_MODULE, |
163 | .write = cs5535_gpio_write, | 163 | .write = cs5535_gpio_write, |
164 | .read = cs5535_gpio_read, | 164 | .read = cs5535_gpio_read, |
diff --git a/drivers/char/ds1286.c b/drivers/char/ds1286.c index d755cac14bc1..21c8229f5443 100644 --- a/drivers/char/ds1286.c +++ b/drivers/char/ds1286.c | |||
@@ -281,7 +281,7 @@ static unsigned int ds1286_poll(struct file *file, poll_table *wait) | |||
281 | * The various file operations we support. | 281 | * The various file operations we support. |
282 | */ | 282 | */ |
283 | 283 | ||
284 | static struct file_operations ds1286_fops = { | 284 | static const struct file_operations ds1286_fops = { |
285 | .llseek = no_llseek, | 285 | .llseek = no_llseek, |
286 | .read = ds1286_read, | 286 | .read = ds1286_read, |
287 | .poll = ds1286_poll, | 287 | .poll = ds1286_poll, |
diff --git a/drivers/char/ds1302.c b/drivers/char/ds1302.c index 625e8b517005..bcdb107aa967 100644 --- a/drivers/char/ds1302.c +++ b/drivers/char/ds1302.c | |||
@@ -282,7 +282,7 @@ get_rtc_status(char *buf) | |||
282 | 282 | ||
283 | /* The various file operations we support. */ | 283 | /* The various file operations we support. */ |
284 | 284 | ||
285 | static struct file_operations rtc_fops = { | 285 | static const struct file_operations rtc_fops = { |
286 | .owner = THIS_MODULE, | 286 | .owner = THIS_MODULE, |
287 | .ioctl = rtc_ioctl, | 287 | .ioctl = rtc_ioctl, |
288 | }; | 288 | }; |
diff --git a/drivers/char/ds1620.c b/drivers/char/ds1620.c index 953e670dcd09..48cb8f0e8ebf 100644 --- a/drivers/char/ds1620.c +++ b/drivers/char/ds1620.c | |||
@@ -336,7 +336,7 @@ proc_therm_ds1620_read(char *buf, char **start, off_t offset, | |||
336 | static struct proc_dir_entry *proc_therm_ds1620; | 336 | static struct proc_dir_entry *proc_therm_ds1620; |
337 | #endif | 337 | #endif |
338 | 338 | ||
339 | static struct file_operations ds1620_fops = { | 339 | static const struct file_operations ds1620_fops = { |
340 | .owner = THIS_MODULE, | 340 | .owner = THIS_MODULE, |
341 | .open = nonseekable_open, | 341 | .open = nonseekable_open, |
342 | .read = ds1620_read, | 342 | .read = ds1620_read, |
diff --git a/drivers/char/dsp56k.c b/drivers/char/dsp56k.c index 09b413618b57..9b1bf60ffbe7 100644 --- a/drivers/char/dsp56k.c +++ b/drivers/char/dsp56k.c | |||
@@ -483,7 +483,7 @@ static int dsp56k_release(struct inode *inode, struct file *file) | |||
483 | return 0; | 483 | return 0; |
484 | } | 484 | } |
485 | 485 | ||
486 | static struct file_operations dsp56k_fops = { | 486 | static const struct file_operations dsp56k_fops = { |
487 | .owner = THIS_MODULE, | 487 | .owner = THIS_MODULE, |
488 | .read = dsp56k_read, | 488 | .read = dsp56k_read, |
489 | .write = dsp56k_write, | 489 | .write = dsp56k_write, |
diff --git a/drivers/char/dtlk.c b/drivers/char/dtlk.c index da2c89f1b8bc..5e82c3bad2e3 100644 --- a/drivers/char/dtlk.c +++ b/drivers/char/dtlk.c | |||
@@ -94,7 +94,7 @@ static int dtlk_release(struct inode *, struct file *); | |||
94 | static int dtlk_ioctl(struct inode *inode, struct file *file, | 94 | static int dtlk_ioctl(struct inode *inode, struct file *file, |
95 | unsigned int cmd, unsigned long arg); | 95 | unsigned int cmd, unsigned long arg); |
96 | 96 | ||
97 | static struct file_operations dtlk_fops = | 97 | static const struct file_operations dtlk_fops = |
98 | { | 98 | { |
99 | .owner = THIS_MODULE, | 99 | .owner = THIS_MODULE, |
100 | .read = dtlk_read, | 100 | .read = dtlk_read, |
diff --git a/drivers/char/efirtc.c b/drivers/char/efirtc.c index 0090e7a4fcd3..004141d535a2 100644 --- a/drivers/char/efirtc.c +++ b/drivers/char/efirtc.c | |||
@@ -285,7 +285,7 @@ efi_rtc_close(struct inode *inode, struct file *file) | |||
285 | * The various file operations we support. | 285 | * The various file operations we support. |
286 | */ | 286 | */ |
287 | 287 | ||
288 | static struct file_operations efi_rtc_fops = { | 288 | static const struct file_operations efi_rtc_fops = { |
289 | .owner = THIS_MODULE, | 289 | .owner = THIS_MODULE, |
290 | .ioctl = efi_rtc_ioctl, | 290 | .ioctl = efi_rtc_ioctl, |
291 | .open = efi_rtc_open, | 291 | .open = efi_rtc_open, |
diff --git a/drivers/char/ftape/zftape/zftape-init.c b/drivers/char/ftape/zftape/zftape-init.c index 55272566b740..164a1aa77a2f 100644 --- a/drivers/char/ftape/zftape/zftape-init.c +++ b/drivers/char/ftape/zftape/zftape-init.c | |||
@@ -86,7 +86,7 @@ static ssize_t zft_read (struct file *fp, char __user *buff, | |||
86 | static ssize_t zft_write(struct file *fp, const char __user *buff, | 86 | static ssize_t zft_write(struct file *fp, const char __user *buff, |
87 | size_t req_len, loff_t *ppos); | 87 | size_t req_len, loff_t *ppos); |
88 | 88 | ||
89 | static struct file_operations zft_cdev = | 89 | static const struct file_operations zft_cdev = |
90 | { | 90 | { |
91 | .owner = THIS_MODULE, | 91 | .owner = THIS_MODULE, |
92 | .read = zft_read, | 92 | .read = zft_read, |
diff --git a/drivers/char/genrtc.c b/drivers/char/genrtc.c index bebd7e34f792..817dc409ac20 100644 --- a/drivers/char/genrtc.c +++ b/drivers/char/genrtc.c | |||
@@ -482,7 +482,7 @@ static inline int gen_rtc_proc_init(void) { return 0; } | |||
482 | * The various file operations we support. | 482 | * The various file operations we support. |
483 | */ | 483 | */ |
484 | 484 | ||
485 | static struct file_operations gen_rtc_fops = { | 485 | static const struct file_operations gen_rtc_fops = { |
486 | .owner = THIS_MODULE, | 486 | .owner = THIS_MODULE, |
487 | #ifdef CONFIG_GEN_RTC_X | 487 | #ifdef CONFIG_GEN_RTC_X |
488 | .read = gen_rtc_read, | 488 | .read = gen_rtc_read, |
diff --git a/drivers/char/hpet.c b/drivers/char/hpet.c index e5643f3aa73f..8afba339f05a 100644 --- a/drivers/char/hpet.c +++ b/drivers/char/hpet.c | |||
@@ -553,7 +553,7 @@ hpet_ioctl_common(struct hpet_dev *devp, int cmd, unsigned long arg, int kernel) | |||
553 | return err; | 553 | return err; |
554 | } | 554 | } |
555 | 555 | ||
556 | static struct file_operations hpet_fops = { | 556 | static const struct file_operations hpet_fops = { |
557 | .owner = THIS_MODULE, | 557 | .owner = THIS_MODULE, |
558 | .llseek = no_llseek, | 558 | .llseek = no_llseek, |
559 | .read = hpet_read, | 559 | .read = hpet_read, |
diff --git a/drivers/char/hvsi.c b/drivers/char/hvsi.c index 8dc205b275e3..56612a2dca6b 100644 --- a/drivers/char/hvsi.c +++ b/drivers/char/hvsi.c | |||
@@ -1299,13 +1299,12 @@ static int __init hvsi_console_init(void) | |||
1299 | hp->inbuf_end = hp->inbuf; | 1299 | hp->inbuf_end = hp->inbuf; |
1300 | hp->state = HVSI_CLOSED; | 1300 | hp->state = HVSI_CLOSED; |
1301 | hp->vtermno = *vtermno; | 1301 | hp->vtermno = *vtermno; |
1302 | hp->virq = virt_irq_create_mapping(irq[0]); | 1302 | hp->virq = irq_create_mapping(NULL, irq[0], 0); |
1303 | if (hp->virq == NO_IRQ) { | 1303 | if (hp->virq == NO_IRQ) { |
1304 | printk(KERN_ERR "%s: couldn't create irq mapping for 0x%x\n", | 1304 | printk(KERN_ERR "%s: couldn't create irq mapping for 0x%x\n", |
1305 | __FUNCTION__, hp->virq); | 1305 | __FUNCTION__, irq[0]); |
1306 | continue; | 1306 | continue; |
1307 | } else | 1307 | } |
1308 | hp->virq = irq_offset_up(hp->virq); | ||
1309 | 1308 | ||
1310 | hvsi_count++; | 1309 | hvsi_count++; |
1311 | } | 1310 | } |
diff --git a/drivers/char/hw_random/core.c b/drivers/char/hw_random/core.c index 88b026639f10..154a81d328c1 100644 --- a/drivers/char/hw_random/core.c +++ b/drivers/char/hw_random/core.c | |||
@@ -149,7 +149,7 @@ out: | |||
149 | } | 149 | } |
150 | 150 | ||
151 | 151 | ||
152 | static struct file_operations rng_chrdev_ops = { | 152 | static const struct file_operations rng_chrdev_ops = { |
153 | .owner = THIS_MODULE, | 153 | .owner = THIS_MODULE, |
154 | .open = rng_dev_open, | 154 | .open = rng_dev_open, |
155 | .read = rng_dev_read, | 155 | .read = rng_dev_read, |
diff --git a/drivers/char/i8k.c b/drivers/char/i8k.c index f3c3aaf4560e..353d9f3cf8d7 100644 --- a/drivers/char/i8k.c +++ b/drivers/char/i8k.c | |||
@@ -80,7 +80,7 @@ static int i8k_open_fs(struct inode *inode, struct file *file); | |||
80 | static int i8k_ioctl(struct inode *, struct file *, unsigned int, | 80 | static int i8k_ioctl(struct inode *, struct file *, unsigned int, |
81 | unsigned long); | 81 | unsigned long); |
82 | 82 | ||
83 | static struct file_operations i8k_fops = { | 83 | static const struct file_operations i8k_fops = { |
84 | .open = i8k_open_fs, | 84 | .open = i8k_open_fs, |
85 | .read = seq_read, | 85 | .read = seq_read, |
86 | .llseek = seq_lseek, | 86 | .llseek = seq_lseek, |
diff --git a/drivers/char/ip2/ip2main.c b/drivers/char/ip2/ip2main.c index a4200a2b0811..518ece7ac656 100644 --- a/drivers/char/ip2/ip2main.c +++ b/drivers/char/ip2/ip2main.c | |||
@@ -233,7 +233,7 @@ static void *DevTableMem[IP2_MAX_BOARDS]; | |||
233 | /* This is the driver descriptor for the ip2ipl device, which is used to | 233 | /* This is the driver descriptor for the ip2ipl device, which is used to |
234 | * download the loadware to the boards. | 234 | * download the loadware to the boards. |
235 | */ | 235 | */ |
236 | static struct file_operations ip2_ipl = { | 236 | static const struct file_operations ip2_ipl = { |
237 | .owner = THIS_MODULE, | 237 | .owner = THIS_MODULE, |
238 | .read = ip2_ipl_read, | 238 | .read = ip2_ipl_read, |
239 | .write = ip2_ipl_write, | 239 | .write = ip2_ipl_write, |
diff --git a/drivers/char/ip27-rtc.c b/drivers/char/ip27-rtc.c index 3acdac3c967e..a48da02aad2f 100644 --- a/drivers/char/ip27-rtc.c +++ b/drivers/char/ip27-rtc.c | |||
@@ -196,7 +196,7 @@ static int rtc_release(struct inode *inode, struct file *file) | |||
196 | * The various file operations we support. | 196 | * The various file operations we support. |
197 | */ | 197 | */ |
198 | 198 | ||
199 | static struct file_operations rtc_fops = { | 199 | static const struct file_operations rtc_fops = { |
200 | .owner = THIS_MODULE, | 200 | .owner = THIS_MODULE, |
201 | .ioctl = rtc_ioctl, | 201 | .ioctl = rtc_ioctl, |
202 | .open = rtc_open, | 202 | .open = rtc_open, |
diff --git a/drivers/char/ipmi/ipmi_devintf.c b/drivers/char/ipmi/ipmi_devintf.c index 2fc894fef1cb..68d7c61a864e 100644 --- a/drivers/char/ipmi/ipmi_devintf.c +++ b/drivers/char/ipmi/ipmi_devintf.c | |||
@@ -765,7 +765,7 @@ static long compat_ipmi_ioctl(struct file *filep, unsigned int cmd, | |||
765 | } | 765 | } |
766 | #endif | 766 | #endif |
767 | 767 | ||
768 | static struct file_operations ipmi_fops = { | 768 | static const struct file_operations ipmi_fops = { |
769 | .owner = THIS_MODULE, | 769 | .owner = THIS_MODULE, |
770 | .ioctl = ipmi_ioctl, | 770 | .ioctl = ipmi_ioctl, |
771 | #ifdef CONFIG_COMPAT | 771 | #ifdef CONFIG_COMPAT |
diff --git a/drivers/char/ipmi/ipmi_watchdog.c b/drivers/char/ipmi/ipmi_watchdog.c index 74a889c58333..accaaf1a6b69 100644 --- a/drivers/char/ipmi/ipmi_watchdog.c +++ b/drivers/char/ipmi/ipmi_watchdog.c | |||
@@ -807,7 +807,7 @@ static int ipmi_close(struct inode *ino, struct file *filep) | |||
807 | return 0; | 807 | return 0; |
808 | } | 808 | } |
809 | 809 | ||
810 | static struct file_operations ipmi_wdog_fops = { | 810 | static const struct file_operations ipmi_wdog_fops = { |
811 | .owner = THIS_MODULE, | 811 | .owner = THIS_MODULE, |
812 | .read = ipmi_read, | 812 | .read = ipmi_read, |
813 | .poll = ipmi_poll, | 813 | .poll = ipmi_poll, |
diff --git a/drivers/char/istallion.c b/drivers/char/istallion.c index fbce2f0669d6..84dfc4278139 100644 --- a/drivers/char/istallion.c +++ b/drivers/char/istallion.c | |||
@@ -748,7 +748,7 @@ static int stli_initpcibrd(int brdtype, struct pci_dev *devp); | |||
748 | * will give access to the shared memory on the Stallion intelligent | 748 | * will give access to the shared memory on the Stallion intelligent |
749 | * board. This is also a very useful debugging tool. | 749 | * board. This is also a very useful debugging tool. |
750 | */ | 750 | */ |
751 | static struct file_operations stli_fsiomem = { | 751 | static const struct file_operations stli_fsiomem = { |
752 | .owner = THIS_MODULE, | 752 | .owner = THIS_MODULE, |
753 | .read = stli_memread, | 753 | .read = stli_memread, |
754 | .write = stli_memwrite, | 754 | .write = stli_memwrite, |
diff --git a/drivers/char/ite_gpio.c b/drivers/char/ite_gpio.c index 747ba45e50e5..cde562d70c4f 100644 --- a/drivers/char/ite_gpio.c +++ b/drivers/char/ite_gpio.c | |||
@@ -357,7 +357,7 @@ DEB(printk("interrupt 0x%x %d\n",ITE_GPAISR, i)); | |||
357 | } | 357 | } |
358 | } | 358 | } |
359 | 359 | ||
360 | static struct file_operations ite_gpio_fops = { | 360 | static const struct file_operations ite_gpio_fops = { |
361 | .owner = THIS_MODULE, | 361 | .owner = THIS_MODULE, |
362 | .ioctl = ite_gpio_ioctl, | 362 | .ioctl = ite_gpio_ioctl, |
363 | .open = ite_gpio_open, | 363 | .open = ite_gpio_open, |
diff --git a/drivers/char/lcd.c b/drivers/char/lcd.c index 7d49b241de56..da601fd6c07a 100644 --- a/drivers/char/lcd.c +++ b/drivers/char/lcd.c | |||
@@ -598,7 +598,7 @@ static ssize_t lcd_read(struct file *file, char *buf, | |||
598 | * The various file operations we support. | 598 | * The various file operations we support. |
599 | */ | 599 | */ |
600 | 600 | ||
601 | static struct file_operations lcd_fops = { | 601 | static const struct file_operations lcd_fops = { |
602 | .read = lcd_read, | 602 | .read = lcd_read, |
603 | .ioctl = lcd_ioctl, | 603 | .ioctl = lcd_ioctl, |
604 | .open = lcd_open, | 604 | .open = lcd_open, |
diff --git a/drivers/char/lp.c b/drivers/char/lp.c index 582cdbdb0c42..f875fda3b089 100644 --- a/drivers/char/lp.c +++ b/drivers/char/lp.c | |||
@@ -666,7 +666,7 @@ static int lp_ioctl(struct inode *inode, struct file *file, | |||
666 | return retval; | 666 | return retval; |
667 | } | 667 | } |
668 | 668 | ||
669 | static struct file_operations lp_fops = { | 669 | static const struct file_operations lp_fops = { |
670 | .owner = THIS_MODULE, | 670 | .owner = THIS_MODULE, |
671 | .write = lp_write, | 671 | .write = lp_write, |
672 | .ioctl = lp_ioctl, | 672 | .ioctl = lp_ioctl, |
diff --git a/drivers/char/mem.c b/drivers/char/mem.c index 70f3954d6dfd..e97c32ceb796 100644 --- a/drivers/char/mem.c +++ b/drivers/char/mem.c | |||
@@ -776,7 +776,7 @@ static int open_port(struct inode * inode, struct file * filp) | |||
776 | #define open_kmem open_mem | 776 | #define open_kmem open_mem |
777 | #define open_oldmem open_mem | 777 | #define open_oldmem open_mem |
778 | 778 | ||
779 | static struct file_operations mem_fops = { | 779 | static const struct file_operations mem_fops = { |
780 | .llseek = memory_lseek, | 780 | .llseek = memory_lseek, |
781 | .read = read_mem, | 781 | .read = read_mem, |
782 | .write = write_mem, | 782 | .write = write_mem, |
@@ -784,7 +784,7 @@ static struct file_operations mem_fops = { | |||
784 | .open = open_mem, | 784 | .open = open_mem, |
785 | }; | 785 | }; |
786 | 786 | ||
787 | static struct file_operations kmem_fops = { | 787 | static const struct file_operations kmem_fops = { |
788 | .llseek = memory_lseek, | 788 | .llseek = memory_lseek, |
789 | .read = read_kmem, | 789 | .read = read_kmem, |
790 | .write = write_kmem, | 790 | .write = write_kmem, |
@@ -792,7 +792,7 @@ static struct file_operations kmem_fops = { | |||
792 | .open = open_kmem, | 792 | .open = open_kmem, |
793 | }; | 793 | }; |
794 | 794 | ||
795 | static struct file_operations null_fops = { | 795 | static const struct file_operations null_fops = { |
796 | .llseek = null_lseek, | 796 | .llseek = null_lseek, |
797 | .read = read_null, | 797 | .read = read_null, |
798 | .write = write_null, | 798 | .write = write_null, |
@@ -800,7 +800,7 @@ static struct file_operations null_fops = { | |||
800 | }; | 800 | }; |
801 | 801 | ||
802 | #if defined(CONFIG_ISA) || !defined(__mc68000__) | 802 | #if defined(CONFIG_ISA) || !defined(__mc68000__) |
803 | static struct file_operations port_fops = { | 803 | static const struct file_operations port_fops = { |
804 | .llseek = memory_lseek, | 804 | .llseek = memory_lseek, |
805 | .read = read_port, | 805 | .read = read_port, |
806 | .write = write_port, | 806 | .write = write_port, |
@@ -808,7 +808,7 @@ static struct file_operations port_fops = { | |||
808 | }; | 808 | }; |
809 | #endif | 809 | #endif |
810 | 810 | ||
811 | static struct file_operations zero_fops = { | 811 | static const struct file_operations zero_fops = { |
812 | .llseek = zero_lseek, | 812 | .llseek = zero_lseek, |
813 | .read = read_zero, | 813 | .read = read_zero, |
814 | .write = write_zero, | 814 | .write = write_zero, |
@@ -819,14 +819,14 @@ static struct backing_dev_info zero_bdi = { | |||
819 | .capabilities = BDI_CAP_MAP_COPY, | 819 | .capabilities = BDI_CAP_MAP_COPY, |
820 | }; | 820 | }; |
821 | 821 | ||
822 | static struct file_operations full_fops = { | 822 | static const struct file_operations full_fops = { |
823 | .llseek = full_lseek, | 823 | .llseek = full_lseek, |
824 | .read = read_full, | 824 | .read = read_full, |
825 | .write = write_full, | 825 | .write = write_full, |
826 | }; | 826 | }; |
827 | 827 | ||
828 | #ifdef CONFIG_CRASH_DUMP | 828 | #ifdef CONFIG_CRASH_DUMP |
829 | static struct file_operations oldmem_fops = { | 829 | static const struct file_operations oldmem_fops = { |
830 | .read = read_oldmem, | 830 | .read = read_oldmem, |
831 | .open = open_oldmem, | 831 | .open = open_oldmem, |
832 | }; | 832 | }; |
@@ -853,7 +853,7 @@ static ssize_t kmsg_write(struct file * file, const char __user * buf, | |||
853 | return ret; | 853 | return ret; |
854 | } | 854 | } |
855 | 855 | ||
856 | static struct file_operations kmsg_fops = { | 856 | static const struct file_operations kmsg_fops = { |
857 | .write = kmsg_write, | 857 | .write = kmsg_write, |
858 | }; | 858 | }; |
859 | 859 | ||
@@ -903,7 +903,7 @@ static int memory_open(struct inode * inode, struct file * filp) | |||
903 | return 0; | 903 | return 0; |
904 | } | 904 | } |
905 | 905 | ||
906 | static struct file_operations memory_fops = { | 906 | static const struct file_operations memory_fops = { |
907 | .open = memory_open, /* just a selector for the real open */ | 907 | .open = memory_open, /* just a selector for the real open */ |
908 | }; | 908 | }; |
909 | 909 | ||
diff --git a/drivers/char/misc.c b/drivers/char/misc.c index d5fa19da330b..62ebe09656e3 100644 --- a/drivers/char/misc.c +++ b/drivers/char/misc.c | |||
@@ -113,7 +113,7 @@ static int misc_seq_open(struct inode *inode, struct file *file) | |||
113 | return seq_open(file, &misc_seq_ops); | 113 | return seq_open(file, &misc_seq_ops); |
114 | } | 114 | } |
115 | 115 | ||
116 | static struct file_operations misc_proc_fops = { | 116 | static const struct file_operations misc_proc_fops = { |
117 | .owner = THIS_MODULE, | 117 | .owner = THIS_MODULE, |
118 | .open = misc_seq_open, | 118 | .open = misc_seq_open, |
119 | .read = seq_read, | 119 | .read = seq_read, |
@@ -176,7 +176,7 @@ fail: | |||
176 | */ | 176 | */ |
177 | static struct class *misc_class; | 177 | static struct class *misc_class; |
178 | 178 | ||
179 | static struct file_operations misc_fops = { | 179 | static const struct file_operations misc_fops = { |
180 | .owner = THIS_MODULE, | 180 | .owner = THIS_MODULE, |
181 | .open = misc_open, | 181 | .open = misc_open, |
182 | }; | 182 | }; |
diff --git a/drivers/char/mmtimer.c b/drivers/char/mmtimer.c index 70b774ff5aa4..1f0f2b6dae26 100644 --- a/drivers/char/mmtimer.c +++ b/drivers/char/mmtimer.c | |||
@@ -63,7 +63,7 @@ static int mmtimer_mmap(struct file *file, struct vm_area_struct *vma); | |||
63 | */ | 63 | */ |
64 | static unsigned long mmtimer_femtoperiod = 0; | 64 | static unsigned long mmtimer_femtoperiod = 0; |
65 | 65 | ||
66 | static struct file_operations mmtimer_fops = { | 66 | static const struct file_operations mmtimer_fops = { |
67 | .owner = THIS_MODULE, | 67 | .owner = THIS_MODULE, |
68 | .mmap = mmtimer_mmap, | 68 | .mmap = mmtimer_mmap, |
69 | .ioctl = mmtimer_ioctl, | 69 | .ioctl = mmtimer_ioctl, |
diff --git a/drivers/char/mwave/mwavedd.c b/drivers/char/mwave/mwavedd.c index d3ba2f860ef0..39a2e661ff55 100644 --- a/drivers/char/mwave/mwavedd.c +++ b/drivers/char/mwave/mwavedd.c | |||
@@ -454,7 +454,7 @@ static int register_serial_portandirq(unsigned int port, int irq) | |||
454 | } | 454 | } |
455 | 455 | ||
456 | 456 | ||
457 | static struct file_operations mwave_fops = { | 457 | static const struct file_operations mwave_fops = { |
458 | .owner = THIS_MODULE, | 458 | .owner = THIS_MODULE, |
459 | .read = mwave_read, | 459 | .read = mwave_read, |
460 | .write = mwave_write, | 460 | .write = mwave_write, |
diff --git a/drivers/char/nvram.c b/drivers/char/nvram.c index 8c5f102622b6..a39f19c35a6a 100644 --- a/drivers/char/nvram.c +++ b/drivers/char/nvram.c | |||
@@ -437,7 +437,7 @@ nvram_read_proc(char *buffer, char **start, off_t offset, | |||
437 | 437 | ||
438 | #endif /* CONFIG_PROC_FS */ | 438 | #endif /* CONFIG_PROC_FS */ |
439 | 439 | ||
440 | static struct file_operations nvram_fops = { | 440 | static const struct file_operations nvram_fops = { |
441 | .owner = THIS_MODULE, | 441 | .owner = THIS_MODULE, |
442 | .llseek = nvram_llseek, | 442 | .llseek = nvram_llseek, |
443 | .read = nvram_read, | 443 | .read = nvram_read, |
diff --git a/drivers/char/nwbutton.c b/drivers/char/nwbutton.c index f240a104d250..7c57ebfa8640 100644 --- a/drivers/char/nwbutton.c +++ b/drivers/char/nwbutton.c | |||
@@ -183,7 +183,7 @@ static int button_read (struct file *filp, char __user *buffer, | |||
183 | * attempts to perform these operations on the device. | 183 | * attempts to perform these operations on the device. |
184 | */ | 184 | */ |
185 | 185 | ||
186 | static struct file_operations button_fops = { | 186 | static const struct file_operations button_fops = { |
187 | .owner = THIS_MODULE, | 187 | .owner = THIS_MODULE, |
188 | .read = button_read, | 188 | .read = button_read, |
189 | }; | 189 | }; |
diff --git a/drivers/char/nwflash.c b/drivers/char/nwflash.c index 8865387d3448..206cf6f50695 100644 --- a/drivers/char/nwflash.c +++ b/drivers/char/nwflash.c | |||
@@ -642,7 +642,7 @@ static void kick_open(void) | |||
642 | udelay(25); | 642 | udelay(25); |
643 | } | 643 | } |
644 | 644 | ||
645 | static struct file_operations flash_fops = | 645 | static const struct file_operations flash_fops = |
646 | { | 646 | { |
647 | .owner = THIS_MODULE, | 647 | .owner = THIS_MODULE, |
648 | .llseek = flash_llseek, | 648 | .llseek = flash_llseek, |
diff --git a/drivers/char/pc8736x_gpio.c b/drivers/char/pc8736x_gpio.c index c860de6a6fde..4005ee0aa11e 100644 --- a/drivers/char/pc8736x_gpio.c +++ b/drivers/char/pc8736x_gpio.c | |||
@@ -236,7 +236,7 @@ static int pc8736x_gpio_open(struct inode *inode, struct file *file) | |||
236 | return nonseekable_open(inode, file); | 236 | return nonseekable_open(inode, file); |
237 | } | 237 | } |
238 | 238 | ||
239 | static struct file_operations pc8736x_gpio_fops = { | 239 | static const struct file_operations pc8736x_gpio_fops = { |
240 | .owner = THIS_MODULE, | 240 | .owner = THIS_MODULE, |
241 | .open = pc8736x_gpio_open, | 241 | .open = pc8736x_gpio_open, |
242 | .write = nsc_gpio_write, | 242 | .write = nsc_gpio_write, |
diff --git a/drivers/char/pcmcia/cm4000_cs.c b/drivers/char/pcmcia/cm4000_cs.c index 31c8a21f9d87..50d20aafeb18 100644 --- a/drivers/char/pcmcia/cm4000_cs.c +++ b/drivers/char/pcmcia/cm4000_cs.c | |||
@@ -1938,7 +1938,7 @@ static void cm4000_detach(struct pcmcia_device *link) | |||
1938 | return; | 1938 | return; |
1939 | } | 1939 | } |
1940 | 1940 | ||
1941 | static struct file_operations cm4000_fops = { | 1941 | static const struct file_operations cm4000_fops = { |
1942 | .owner = THIS_MODULE, | 1942 | .owner = THIS_MODULE, |
1943 | .read = cmm_read, | 1943 | .read = cmm_read, |
1944 | .write = cmm_write, | 1944 | .write = cmm_write, |
diff --git a/drivers/char/pcmcia/cm4040_cs.c b/drivers/char/pcmcia/cm4040_cs.c index 47a8465bf95b..55cf4be42976 100644 --- a/drivers/char/pcmcia/cm4040_cs.c +++ b/drivers/char/pcmcia/cm4040_cs.c | |||
@@ -688,7 +688,7 @@ static void reader_detach(struct pcmcia_device *link) | |||
688 | return; | 688 | return; |
689 | } | 689 | } |
690 | 690 | ||
691 | static struct file_operations reader_fops = { | 691 | static const struct file_operations reader_fops = { |
692 | .owner = THIS_MODULE, | 692 | .owner = THIS_MODULE, |
693 | .read = cm4040_read, | 693 | .read = cm4040_read, |
694 | .write = cm4040_write, | 694 | .write = cm4040_write, |
diff --git a/drivers/char/ppdev.c b/drivers/char/ppdev.c index 24231d9743dc..520d2cf82bc0 100644 --- a/drivers/char/ppdev.c +++ b/drivers/char/ppdev.c | |||
@@ -739,7 +739,7 @@ static unsigned int pp_poll (struct file * file, poll_table * wait) | |||
739 | 739 | ||
740 | static struct class *ppdev_class; | 740 | static struct class *ppdev_class; |
741 | 741 | ||
742 | static struct file_operations pp_fops = { | 742 | static const struct file_operations pp_fops = { |
743 | .owner = THIS_MODULE, | 743 | .owner = THIS_MODULE, |
744 | .llseek = no_llseek, | 744 | .llseek = no_llseek, |
745 | .read = pp_read, | 745 | .read = pp_read, |
diff --git a/drivers/char/random.c b/drivers/char/random.c index 164bddae047f..4c3a5ca9d8f7 100644 --- a/drivers/char/random.c +++ b/drivers/char/random.c | |||
@@ -416,7 +416,7 @@ static struct entropy_store input_pool = { | |||
416 | .poolinfo = &poolinfo_table[0], | 416 | .poolinfo = &poolinfo_table[0], |
417 | .name = "input", | 417 | .name = "input", |
418 | .limit = 1, | 418 | .limit = 1, |
419 | .lock = SPIN_LOCK_UNLOCKED, | 419 | .lock = __SPIN_LOCK_UNLOCKED(&input_pool.lock), |
420 | .pool = input_pool_data | 420 | .pool = input_pool_data |
421 | }; | 421 | }; |
422 | 422 | ||
@@ -425,7 +425,7 @@ static struct entropy_store blocking_pool = { | |||
425 | .name = "blocking", | 425 | .name = "blocking", |
426 | .limit = 1, | 426 | .limit = 1, |
427 | .pull = &input_pool, | 427 | .pull = &input_pool, |
428 | .lock = SPIN_LOCK_UNLOCKED, | 428 | .lock = __SPIN_LOCK_UNLOCKED(&blocking_pool.lock), |
429 | .pool = blocking_pool_data | 429 | .pool = blocking_pool_data |
430 | }; | 430 | }; |
431 | 431 | ||
@@ -433,7 +433,7 @@ static struct entropy_store nonblocking_pool = { | |||
433 | .poolinfo = &poolinfo_table[1], | 433 | .poolinfo = &poolinfo_table[1], |
434 | .name = "nonblocking", | 434 | .name = "nonblocking", |
435 | .pull = &input_pool, | 435 | .pull = &input_pool, |
436 | .lock = SPIN_LOCK_UNLOCKED, | 436 | .lock = __SPIN_LOCK_UNLOCKED(&nonblocking_pool.lock), |
437 | .pool = nonblocking_pool_data | 437 | .pool = nonblocking_pool_data |
438 | }; | 438 | }; |
439 | 439 | ||
diff --git a/drivers/char/raw.c b/drivers/char/raw.c index 9bf97c5e38c0..579868af4a54 100644 --- a/drivers/char/raw.c +++ b/drivers/char/raw.c | |||
@@ -30,7 +30,7 @@ struct raw_device_data { | |||
30 | static struct class *raw_class; | 30 | static struct class *raw_class; |
31 | static struct raw_device_data raw_devices[MAX_RAW_MINORS]; | 31 | static struct raw_device_data raw_devices[MAX_RAW_MINORS]; |
32 | static DEFINE_MUTEX(raw_mutex); | 32 | static DEFINE_MUTEX(raw_mutex); |
33 | static struct file_operations raw_ctl_fops; /* forward declaration */ | 33 | static const struct file_operations raw_ctl_fops; /* forward declaration */ |
34 | 34 | ||
35 | /* | 35 | /* |
36 | * Open/close code for raw IO. | 36 | * Open/close code for raw IO. |
@@ -261,7 +261,7 @@ static ssize_t raw_file_aio_write(struct kiocb *iocb, const char __user *buf, | |||
261 | } | 261 | } |
262 | 262 | ||
263 | 263 | ||
264 | static struct file_operations raw_fops = { | 264 | static const struct file_operations raw_fops = { |
265 | .read = generic_file_read, | 265 | .read = generic_file_read, |
266 | .aio_read = generic_file_aio_read, | 266 | .aio_read = generic_file_aio_read, |
267 | .write = raw_file_write, | 267 | .write = raw_file_write, |
@@ -274,7 +274,7 @@ static struct file_operations raw_fops = { | |||
274 | .owner = THIS_MODULE, | 274 | .owner = THIS_MODULE, |
275 | }; | 275 | }; |
276 | 276 | ||
277 | static struct file_operations raw_ctl_fops = { | 277 | static const struct file_operations raw_ctl_fops = { |
278 | .ioctl = raw_ctl_ioctl, | 278 | .ioctl = raw_ctl_ioctl, |
279 | .open = raw_open, | 279 | .open = raw_open, |
280 | .owner = THIS_MODULE, | 280 | .owner = THIS_MODULE, |
diff --git a/drivers/char/rio/rio_linux.c b/drivers/char/rio/rio_linux.c index 3afc6a47ebbc..3fa80aaf4527 100644 --- a/drivers/char/rio/rio_linux.c +++ b/drivers/char/rio/rio_linux.c | |||
@@ -243,7 +243,7 @@ static struct real_driver rio_real_driver = { | |||
243 | * | 243 | * |
244 | */ | 244 | */ |
245 | 245 | ||
246 | static struct file_operations rio_fw_fops = { | 246 | static const struct file_operations rio_fw_fops = { |
247 | .owner = THIS_MODULE, | 247 | .owner = THIS_MODULE, |
248 | .ioctl = rio_fw_ioctl, | 248 | .ioctl = rio_fw_ioctl, |
249 | }; | 249 | }; |
diff --git a/drivers/char/rtc.c b/drivers/char/rtc.c index aefac4ac0bf5..cc7bd1a3095b 100644 --- a/drivers/char/rtc.c +++ b/drivers/char/rtc.c | |||
@@ -877,7 +877,7 @@ int rtc_control(rtc_task_t *task, unsigned int cmd, unsigned long arg) | |||
877 | * The various file operations we support. | 877 | * The various file operations we support. |
878 | */ | 878 | */ |
879 | 879 | ||
880 | static struct file_operations rtc_fops = { | 880 | static const struct file_operations rtc_fops = { |
881 | .owner = THIS_MODULE, | 881 | .owner = THIS_MODULE, |
882 | .llseek = no_llseek, | 882 | .llseek = no_llseek, |
883 | .read = rtc_read, | 883 | .read = rtc_read, |
@@ -896,7 +896,7 @@ static struct miscdevice rtc_dev = { | |||
896 | .fops = &rtc_fops, | 896 | .fops = &rtc_fops, |
897 | }; | 897 | }; |
898 | 898 | ||
899 | static struct file_operations rtc_proc_fops = { | 899 | static const struct file_operations rtc_proc_fops = { |
900 | .owner = THIS_MODULE, | 900 | .owner = THIS_MODULE, |
901 | .open = rtc_proc_open, | 901 | .open = rtc_proc_open, |
902 | .read = seq_read, | 902 | .read = seq_read, |
diff --git a/drivers/char/scx200_gpio.c b/drivers/char/scx200_gpio.c index 45083e5dd23b..425c58719db6 100644 --- a/drivers/char/scx200_gpio.c +++ b/drivers/char/scx200_gpio.c | |||
@@ -63,7 +63,7 @@ static int scx200_gpio_release(struct inode *inode, struct file *file) | |||
63 | } | 63 | } |
64 | 64 | ||
65 | 65 | ||
66 | static struct file_operations scx200_gpio_fops = { | 66 | static const struct file_operations scx200_gpio_fops = { |
67 | .owner = THIS_MODULE, | 67 | .owner = THIS_MODULE, |
68 | .write = nsc_gpio_write, | 68 | .write = nsc_gpio_write, |
69 | .read = nsc_gpio_read, | 69 | .read = nsc_gpio_read, |
diff --git a/drivers/char/snsc.c b/drivers/char/snsc.c index 203240b6c08f..afc6eda602f7 100644 --- a/drivers/char/snsc.c +++ b/drivers/char/snsc.c | |||
@@ -347,7 +347,7 @@ scdrv_poll(struct file *file, struct poll_table_struct *wait) | |||
347 | return mask; | 347 | return mask; |
348 | } | 348 | } |
349 | 349 | ||
350 | static struct file_operations scdrv_fops = { | 350 | static const struct file_operations scdrv_fops = { |
351 | .owner = THIS_MODULE, | 351 | .owner = THIS_MODULE, |
352 | .read = scdrv_read, | 352 | .read = scdrv_read, |
353 | .write = scdrv_write, | 353 | .write = scdrv_write, |
diff --git a/drivers/char/sonypi.c b/drivers/char/sonypi.c index 45508a039508..d4e434d694b7 100644 --- a/drivers/char/sonypi.c +++ b/drivers/char/sonypi.c | |||
@@ -1106,7 +1106,7 @@ static int sonypi_misc_ioctl(struct inode *ip, struct file *fp, | |||
1106 | return ret; | 1106 | return ret; |
1107 | } | 1107 | } |
1108 | 1108 | ||
1109 | static struct file_operations sonypi_misc_fops = { | 1109 | static const struct file_operations sonypi_misc_fops = { |
1110 | .owner = THIS_MODULE, | 1110 | .owner = THIS_MODULE, |
1111 | .read = sonypi_misc_read, | 1111 | .read = sonypi_misc_read, |
1112 | .poll = sonypi_misc_poll, | 1112 | .poll = sonypi_misc_poll, |
diff --git a/drivers/char/stallion.c b/drivers/char/stallion.c index ed7b8eaf0367..3beb2203d24b 100644 --- a/drivers/char/stallion.c +++ b/drivers/char/stallion.c | |||
@@ -707,7 +707,7 @@ static unsigned int sc26198_baudtable[] = { | |||
707 | * Define the driver info for a user level control device. Used mainly | 707 | * Define the driver info for a user level control device. Used mainly |
708 | * to get at port stats - only not using the port device itself. | 708 | * to get at port stats - only not using the port device itself. |
709 | */ | 709 | */ |
710 | static struct file_operations stl_fsiomem = { | 710 | static const struct file_operations stl_fsiomem = { |
711 | .owner = THIS_MODULE, | 711 | .owner = THIS_MODULE, |
712 | .ioctl = stl_memioctl, | 712 | .ioctl = stl_memioctl, |
713 | }; | 713 | }; |
diff --git a/drivers/char/sx.c b/drivers/char/sx.c index 45c193aa11db..e1cd2bc4b1e4 100644 --- a/drivers/char/sx.c +++ b/drivers/char/sx.c | |||
@@ -410,7 +410,7 @@ static struct real_driver sx_real_driver = { | |||
410 | * | 410 | * |
411 | */ | 411 | */ |
412 | 412 | ||
413 | static struct file_operations sx_fw_fops = { | 413 | static const struct file_operations sx_fw_fops = { |
414 | .owner = THIS_MODULE, | 414 | .owner = THIS_MODULE, |
415 | .ioctl = sx_fw_ioctl, | 415 | .ioctl = sx_fw_ioctl, |
416 | }; | 416 | }; |
diff --git a/drivers/char/sysrq.c b/drivers/char/sysrq.c index a064ee9181c0..ee3ca8f1768e 100644 --- a/drivers/char/sysrq.c +++ b/drivers/char/sysrq.c | |||
@@ -147,12 +147,13 @@ static struct sysrq_key_op sysrq_mountro_op = { | |||
147 | .enable_mask = SYSRQ_ENABLE_REMOUNT, | 147 | .enable_mask = SYSRQ_ENABLE_REMOUNT, |
148 | }; | 148 | }; |
149 | 149 | ||
150 | #ifdef CONFIG_DEBUG_MUTEXES | 150 | #ifdef CONFIG_LOCKDEP |
151 | static void sysrq_handle_showlocks(int key, struct pt_regs *pt_regs, | 151 | static void sysrq_handle_showlocks(int key, struct pt_regs *pt_regs, |
152 | struct tty_struct *tty) | 152 | struct tty_struct *tty) |
153 | { | 153 | { |
154 | mutex_debug_show_all_locks(); | 154 | debug_show_all_locks(); |
155 | } | 155 | } |
156 | |||
156 | static struct sysrq_key_op sysrq_showlocks_op = { | 157 | static struct sysrq_key_op sysrq_showlocks_op = { |
157 | .handler = sysrq_handle_showlocks, | 158 | .handler = sysrq_handle_showlocks, |
158 | .help_msg = "show-all-locks(D)", | 159 | .help_msg = "show-all-locks(D)", |
diff --git a/drivers/char/tb0219.c b/drivers/char/tb0219.c index a80c83210872..bb1bad4c18f9 100644 --- a/drivers/char/tb0219.c +++ b/drivers/char/tb0219.c | |||
@@ -255,7 +255,7 @@ static int tanbac_tb0219_release(struct inode *inode, struct file *file) | |||
255 | return 0; | 255 | return 0; |
256 | } | 256 | } |
257 | 257 | ||
258 | static struct file_operations tb0219_fops = { | 258 | static const struct file_operations tb0219_fops = { |
259 | .owner = THIS_MODULE, | 259 | .owner = THIS_MODULE, |
260 | .read = tanbac_tb0219_read, | 260 | .read = tanbac_tb0219_read, |
261 | .write = tanbac_tb0219_write, | 261 | .write = tanbac_tb0219_write, |
diff --git a/drivers/char/tipar.c b/drivers/char/tipar.c index e0633a119d29..d30dc09dbbc9 100644 --- a/drivers/char/tipar.c +++ b/drivers/char/tipar.c | |||
@@ -381,7 +381,7 @@ tipar_ioctl(struct inode *inode, struct file *file, | |||
381 | 381 | ||
382 | /* ----- kernel module registering ------------------------------------ */ | 382 | /* ----- kernel module registering ------------------------------------ */ |
383 | 383 | ||
384 | static struct file_operations tipar_fops = { | 384 | static const struct file_operations tipar_fops = { |
385 | .owner = THIS_MODULE, | 385 | .owner = THIS_MODULE, |
386 | .llseek = no_llseek, | 386 | .llseek = no_llseek, |
387 | .read = tipar_read, | 387 | .read = tipar_read, |
diff --git a/drivers/char/tlclk.c b/drivers/char/tlclk.c index 952b829e2cb4..d2c5ba4e83b8 100644 --- a/drivers/char/tlclk.c +++ b/drivers/char/tlclk.c | |||
@@ -247,7 +247,7 @@ static ssize_t tlclk_write(struct file *filp, const char __user *buf, size_t cou | |||
247 | return 0; | 247 | return 0; |
248 | } | 248 | } |
249 | 249 | ||
250 | static struct file_operations tlclk_fops = { | 250 | static const struct file_operations tlclk_fops = { |
251 | .read = tlclk_read, | 251 | .read = tlclk_read, |
252 | .write = tlclk_write, | 252 | .write = tlclk_write, |
253 | .open = tlclk_open, | 253 | .open = tlclk_open, |
diff --git a/drivers/char/toshiba.c b/drivers/char/toshiba.c index e2fb234dee40..dd36fd04a842 100644 --- a/drivers/char/toshiba.c +++ b/drivers/char/toshiba.c | |||
@@ -92,7 +92,7 @@ static int tosh_ioctl(struct inode *, struct file *, unsigned int, | |||
92 | unsigned long); | 92 | unsigned long); |
93 | 93 | ||
94 | 94 | ||
95 | static struct file_operations tosh_fops = { | 95 | static const struct file_operations tosh_fops = { |
96 | .owner = THIS_MODULE, | 96 | .owner = THIS_MODULE, |
97 | .ioctl = tosh_ioctl, | 97 | .ioctl = tosh_ioctl, |
98 | }; | 98 | }; |
diff --git a/drivers/char/tpm/tpm_atmel.c b/drivers/char/tpm/tpm_atmel.c index 58a258cec153..ad8ffe49256f 100644 --- a/drivers/char/tpm/tpm_atmel.c +++ b/drivers/char/tpm/tpm_atmel.c | |||
@@ -116,7 +116,7 @@ static u8 tpm_atml_status(struct tpm_chip *chip) | |||
116 | return ioread8(chip->vendor.iobase + 1); | 116 | return ioread8(chip->vendor.iobase + 1); |
117 | } | 117 | } |
118 | 118 | ||
119 | static struct file_operations atmel_ops = { | 119 | static const struct file_operations atmel_ops = { |
120 | .owner = THIS_MODULE, | 120 | .owner = THIS_MODULE, |
121 | .llseek = no_llseek, | 121 | .llseek = no_llseek, |
122 | .open = tpm_open, | 122 | .open = tpm_open, |
diff --git a/drivers/char/tpm/tpm_infineon.c b/drivers/char/tpm/tpm_infineon.c index adfff21beb21..1353b5a6bae8 100644 --- a/drivers/char/tpm/tpm_infineon.c +++ b/drivers/char/tpm/tpm_infineon.c | |||
@@ -338,7 +338,7 @@ static struct attribute *inf_attrs[] = { | |||
338 | 338 | ||
339 | static struct attribute_group inf_attr_grp = {.attrs = inf_attrs }; | 339 | static struct attribute_group inf_attr_grp = {.attrs = inf_attrs }; |
340 | 340 | ||
341 | static struct file_operations inf_ops = { | 341 | static const struct file_operations inf_ops = { |
342 | .owner = THIS_MODULE, | 342 | .owner = THIS_MODULE, |
343 | .llseek = no_llseek, | 343 | .llseek = no_llseek, |
344 | .open = tpm_open, | 344 | .open = tpm_open, |
diff --git a/drivers/char/tpm/tpm_nsc.c b/drivers/char/tpm/tpm_nsc.c index 4c8bc06c7d95..26287aace87d 100644 --- a/drivers/char/tpm/tpm_nsc.c +++ b/drivers/char/tpm/tpm_nsc.c | |||
@@ -226,7 +226,7 @@ static u8 tpm_nsc_status(struct tpm_chip *chip) | |||
226 | return inb(chip->vendor.base + NSC_STATUS); | 226 | return inb(chip->vendor.base + NSC_STATUS); |
227 | } | 227 | } |
228 | 228 | ||
229 | static struct file_operations nsc_ops = { | 229 | static const struct file_operations nsc_ops = { |
230 | .owner = THIS_MODULE, | 230 | .owner = THIS_MODULE, |
231 | .llseek = no_llseek, | 231 | .llseek = no_llseek, |
232 | .open = tpm_open, | 232 | .open = tpm_open, |
diff --git a/drivers/char/tpm/tpm_tis.c b/drivers/char/tpm/tpm_tis.c index abb0f2aeae66..3232b1932597 100644 --- a/drivers/char/tpm/tpm_tis.c +++ b/drivers/char/tpm/tpm_tis.c | |||
@@ -330,7 +330,7 @@ out_err: | |||
330 | return rc; | 330 | return rc; |
331 | } | 331 | } |
332 | 332 | ||
333 | static struct file_operations tis_ops = { | 333 | static const struct file_operations tis_ops = { |
334 | .owner = THIS_MODULE, | 334 | .owner = THIS_MODULE, |
335 | .llseek = no_llseek, | 335 | .llseek = no_llseek, |
336 | .open = tpm_open, | 336 | .open = tpm_open, |
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c index 615e934da05f..bfdb90242a90 100644 --- a/drivers/char/tty_io.c +++ b/drivers/char/tty_io.c | |||
@@ -912,7 +912,7 @@ static int hung_up_tty_ioctl(struct inode * inode, struct file * file, | |||
912 | return cmd == TIOCSPGRP ? -ENOTTY : -EIO; | 912 | return cmd == TIOCSPGRP ? -ENOTTY : -EIO; |
913 | } | 913 | } |
914 | 914 | ||
915 | static struct file_operations tty_fops = { | 915 | static const struct file_operations tty_fops = { |
916 | .llseek = no_llseek, | 916 | .llseek = no_llseek, |
917 | .read = tty_read, | 917 | .read = tty_read, |
918 | .write = tty_write, | 918 | .write = tty_write, |
@@ -924,7 +924,7 @@ static struct file_operations tty_fops = { | |||
924 | }; | 924 | }; |
925 | 925 | ||
926 | #ifdef CONFIG_UNIX98_PTYS | 926 | #ifdef CONFIG_UNIX98_PTYS |
927 | static struct file_operations ptmx_fops = { | 927 | static const struct file_operations ptmx_fops = { |
928 | .llseek = no_llseek, | 928 | .llseek = no_llseek, |
929 | .read = tty_read, | 929 | .read = tty_read, |
930 | .write = tty_write, | 930 | .write = tty_write, |
@@ -936,7 +936,7 @@ static struct file_operations ptmx_fops = { | |||
936 | }; | 936 | }; |
937 | #endif | 937 | #endif |
938 | 938 | ||
939 | static struct file_operations console_fops = { | 939 | static const struct file_operations console_fops = { |
940 | .llseek = no_llseek, | 940 | .llseek = no_llseek, |
941 | .read = tty_read, | 941 | .read = tty_read, |
942 | .write = redirected_tty_write, | 942 | .write = redirected_tty_write, |
@@ -947,7 +947,7 @@ static struct file_operations console_fops = { | |||
947 | .fasync = tty_fasync, | 947 | .fasync = tty_fasync, |
948 | }; | 948 | }; |
949 | 949 | ||
950 | static struct file_operations hung_up_tty_fops = { | 950 | static const struct file_operations hung_up_tty_fops = { |
951 | .llseek = no_llseek, | 951 | .llseek = no_llseek, |
952 | .read = hung_up_tty_read, | 952 | .read = hung_up_tty_read, |
953 | .write = hung_up_tty_write, | 953 | .write = hung_up_tty_write, |
@@ -2336,7 +2336,7 @@ static int fionbio(struct file *file, int __user *p) | |||
2336 | 2336 | ||
2337 | static int tiocsctty(struct tty_struct *tty, int arg) | 2337 | static int tiocsctty(struct tty_struct *tty, int arg) |
2338 | { | 2338 | { |
2339 | task_t *p; | 2339 | struct task_struct *p; |
2340 | 2340 | ||
2341 | if (current->signal->leader && | 2341 | if (current->signal->leader && |
2342 | (current->signal->session == tty->session)) | 2342 | (current->signal->session == tty->session)) |
diff --git a/drivers/char/vc_screen.c b/drivers/char/vc_screen.c index 45e9bd81bc0e..a9247b5213d5 100644 --- a/drivers/char/vc_screen.c +++ b/drivers/char/vc_screen.c | |||
@@ -465,7 +465,7 @@ vcs_open(struct inode *inode, struct file *filp) | |||
465 | return 0; | 465 | return 0; |
466 | } | 466 | } |
467 | 467 | ||
468 | static struct file_operations vcs_fops = { | 468 | static const struct file_operations vcs_fops = { |
469 | .llseek = vcs_lseek, | 469 | .llseek = vcs_lseek, |
470 | .read = vcs_read, | 470 | .read = vcs_read, |
471 | .write = vcs_write, | 471 | .write = vcs_write, |
diff --git a/drivers/char/viotape.c b/drivers/char/viotape.c index 7d42c8ec8dbc..b72b2049aaae 100644 --- a/drivers/char/viotape.c +++ b/drivers/char/viotape.c | |||
@@ -292,7 +292,7 @@ static int proc_viotape_open(struct inode *inode, struct file *file) | |||
292 | return single_open(file, proc_viotape_show, NULL); | 292 | return single_open(file, proc_viotape_show, NULL); |
293 | } | 293 | } |
294 | 294 | ||
295 | static struct file_operations proc_viotape_operations = { | 295 | static const struct file_operations proc_viotape_operations = { |
296 | .open = proc_viotape_open, | 296 | .open = proc_viotape_open, |
297 | .read = seq_read, | 297 | .read = seq_read, |
298 | .llseek = seq_lseek, | 298 | .llseek = seq_lseek, |
diff --git a/drivers/char/vr41xx_giu.c b/drivers/char/vr41xx_giu.c index 073da48c092e..1b9b1f1d4c49 100644 --- a/drivers/char/vr41xx_giu.c +++ b/drivers/char/vr41xx_giu.c | |||
@@ -605,7 +605,7 @@ static int gpio_release(struct inode *inode, struct file *file) | |||
605 | return 0; | 605 | return 0; |
606 | } | 606 | } |
607 | 607 | ||
608 | static struct file_operations gpio_fops = { | 608 | static const struct file_operations gpio_fops = { |
609 | .owner = THIS_MODULE, | 609 | .owner = THIS_MODULE, |
610 | .read = gpio_read, | 610 | .read = gpio_read, |
611 | .write = gpio_write, | 611 | .write = gpio_write, |
diff --git a/drivers/char/vt.c b/drivers/char/vt.c index 3ef823d7d255..da7e66a2a38b 100644 --- a/drivers/char/vt.c +++ b/drivers/char/vt.c | |||
@@ -886,6 +886,7 @@ void vc_disallocate(unsigned int currcons) | |||
886 | if (vc_cons_allocated(currcons)) { | 886 | if (vc_cons_allocated(currcons)) { |
887 | struct vc_data *vc = vc_cons[currcons].d; | 887 | struct vc_data *vc = vc_cons[currcons].d; |
888 | vc->vc_sw->con_deinit(vc); | 888 | vc->vc_sw->con_deinit(vc); |
889 | module_put(vc->vc_sw->owner); | ||
889 | if (vc->vc_kmalloced) | 890 | if (vc->vc_kmalloced) |
890 | kfree(vc->vc_screenbuf); | 891 | kfree(vc->vc_screenbuf); |
891 | if (currcons >= MIN_NR_CONSOLES) | 892 | if (currcons >= MIN_NR_CONSOLES) |
diff --git a/drivers/char/watchdog/acquirewdt.c b/drivers/char/watchdog/acquirewdt.c index 7289f4af93d0..c77fe3cf2852 100644 --- a/drivers/char/watchdog/acquirewdt.c +++ b/drivers/char/watchdog/acquirewdt.c | |||
@@ -231,7 +231,7 @@ static int acq_notify_sys(struct notifier_block *this, unsigned long code, | |||
231 | * Kernel Interfaces | 231 | * Kernel Interfaces |
232 | */ | 232 | */ |
233 | 233 | ||
234 | static struct file_operations acq_fops = { | 234 | static const struct file_operations acq_fops = { |
235 | .owner = THIS_MODULE, | 235 | .owner = THIS_MODULE, |
236 | .llseek = no_llseek, | 236 | .llseek = no_llseek, |
237 | .write = acq_write, | 237 | .write = acq_write, |
diff --git a/drivers/char/watchdog/advantechwdt.c b/drivers/char/watchdog/advantechwdt.c index 194a3fd36b91..8069be445edc 100644 --- a/drivers/char/watchdog/advantechwdt.c +++ b/drivers/char/watchdog/advantechwdt.c | |||
@@ -227,7 +227,7 @@ advwdt_notify_sys(struct notifier_block *this, unsigned long code, | |||
227 | * Kernel Interfaces | 227 | * Kernel Interfaces |
228 | */ | 228 | */ |
229 | 229 | ||
230 | static struct file_operations advwdt_fops = { | 230 | static const struct file_operations advwdt_fops = { |
231 | .owner = THIS_MODULE, | 231 | .owner = THIS_MODULE, |
232 | .llseek = no_llseek, | 232 | .llseek = no_llseek, |
233 | .write = advwdt_write, | 233 | .write = advwdt_write, |
diff --git a/drivers/char/watchdog/alim1535_wdt.c b/drivers/char/watchdog/alim1535_wdt.c index 8338ca300e2e..c5c94e4c9495 100644 --- a/drivers/char/watchdog/alim1535_wdt.c +++ b/drivers/char/watchdog/alim1535_wdt.c | |||
@@ -362,7 +362,7 @@ static int __init ali_find_watchdog(void) | |||
362 | * Kernel Interfaces | 362 | * Kernel Interfaces |
363 | */ | 363 | */ |
364 | 364 | ||
365 | static struct file_operations ali_fops = { | 365 | static const struct file_operations ali_fops = { |
366 | .owner = THIS_MODULE, | 366 | .owner = THIS_MODULE, |
367 | .llseek = no_llseek, | 367 | .llseek = no_llseek, |
368 | .write = ali_write, | 368 | .write = ali_write, |
diff --git a/drivers/char/watchdog/alim7101_wdt.c b/drivers/char/watchdog/alim7101_wdt.c index c05ac188a4d7..ffd7684f999b 100644 --- a/drivers/char/watchdog/alim7101_wdt.c +++ b/drivers/char/watchdog/alim7101_wdt.c | |||
@@ -281,7 +281,7 @@ static int fop_ioctl(struct inode *inode, struct file *file, unsigned int cmd, u | |||
281 | } | 281 | } |
282 | } | 282 | } |
283 | 283 | ||
284 | static struct file_operations wdt_fops = { | 284 | static const struct file_operations wdt_fops = { |
285 | .owner= THIS_MODULE, | 285 | .owner= THIS_MODULE, |
286 | .llseek= no_llseek, | 286 | .llseek= no_llseek, |
287 | .write= fop_write, | 287 | .write= fop_write, |
diff --git a/drivers/char/watchdog/at91_wdt.c b/drivers/char/watchdog/at91_wdt.c index f61dedc3c96c..cc266715ea32 100644 --- a/drivers/char/watchdog/at91_wdt.c +++ b/drivers/char/watchdog/at91_wdt.c | |||
@@ -183,7 +183,7 @@ static ssize_t at91_wdt_write(struct file *file, const char *data, size_t len, l | |||
183 | 183 | ||
184 | /* ......................................................................... */ | 184 | /* ......................................................................... */ |
185 | 185 | ||
186 | static struct file_operations at91wdt_fops = { | 186 | static const struct file_operations at91wdt_fops = { |
187 | .owner = THIS_MODULE, | 187 | .owner = THIS_MODULE, |
188 | .llseek = no_llseek, | 188 | .llseek = no_llseek, |
189 | .ioctl = at91_wdt_ioctl, | 189 | .ioctl = at91_wdt_ioctl, |
diff --git a/drivers/char/watchdog/booke_wdt.c b/drivers/char/watchdog/booke_wdt.c index 537f5c6729bf..e3cefc538b40 100644 --- a/drivers/char/watchdog/booke_wdt.c +++ b/drivers/char/watchdog/booke_wdt.c | |||
@@ -145,7 +145,7 @@ static int booke_wdt_open (struct inode *inode, struct file *file) | |||
145 | return 0; | 145 | return 0; |
146 | } | 146 | } |
147 | 147 | ||
148 | static struct file_operations booke_wdt_fops = { | 148 | static const struct file_operations booke_wdt_fops = { |
149 | .owner = THIS_MODULE, | 149 | .owner = THIS_MODULE, |
150 | .llseek = no_llseek, | 150 | .llseek = no_llseek, |
151 | .write = booke_wdt_write, | 151 | .write = booke_wdt_write, |
diff --git a/drivers/char/watchdog/cpu5wdt.c b/drivers/char/watchdog/cpu5wdt.c index 3e8410b5a65e..04c7e49918db 100644 --- a/drivers/char/watchdog/cpu5wdt.c +++ b/drivers/char/watchdog/cpu5wdt.c | |||
@@ -198,7 +198,7 @@ static ssize_t cpu5wdt_write(struct file *file, const char __user *buf, size_t c | |||
198 | return count; | 198 | return count; |
199 | } | 199 | } |
200 | 200 | ||
201 | static struct file_operations cpu5wdt_fops = { | 201 | static const struct file_operations cpu5wdt_fops = { |
202 | .owner = THIS_MODULE, | 202 | .owner = THIS_MODULE, |
203 | .llseek = no_llseek, | 203 | .llseek = no_llseek, |
204 | .ioctl = cpu5wdt_ioctl, | 204 | .ioctl = cpu5wdt_ioctl, |
diff --git a/drivers/char/watchdog/ep93xx_wdt.c b/drivers/char/watchdog/ep93xx_wdt.c index 9021dbb78299..77c8a955ae9e 100644 --- a/drivers/char/watchdog/ep93xx_wdt.c +++ b/drivers/char/watchdog/ep93xx_wdt.c | |||
@@ -187,7 +187,7 @@ static int ep93xx_wdt_release(struct inode *inode, struct file *file) | |||
187 | return 0; | 187 | return 0; |
188 | } | 188 | } |
189 | 189 | ||
190 | static struct file_operations ep93xx_wdt_fops = { | 190 | static const struct file_operations ep93xx_wdt_fops = { |
191 | .owner = THIS_MODULE, | 191 | .owner = THIS_MODULE, |
192 | .write = ep93xx_wdt_write, | 192 | .write = ep93xx_wdt_write, |
193 | .ioctl = ep93xx_wdt_ioctl, | 193 | .ioctl = ep93xx_wdt_ioctl, |
diff --git a/drivers/char/watchdog/eurotechwdt.c b/drivers/char/watchdog/eurotechwdt.c index ea670de4fab7..62dbccb2f6df 100644 --- a/drivers/char/watchdog/eurotechwdt.c +++ b/drivers/char/watchdog/eurotechwdt.c | |||
@@ -356,7 +356,7 @@ static int eurwdt_notify_sys(struct notifier_block *this, unsigned long code, | |||
356 | */ | 356 | */ |
357 | 357 | ||
358 | 358 | ||
359 | static struct file_operations eurwdt_fops = { | 359 | static const struct file_operations eurwdt_fops = { |
360 | .owner = THIS_MODULE, | 360 | .owner = THIS_MODULE, |
361 | .llseek = no_llseek, | 361 | .llseek = no_llseek, |
362 | .write = eurwdt_write, | 362 | .write = eurwdt_write, |
diff --git a/drivers/char/watchdog/i6300esb.c b/drivers/char/watchdog/i6300esb.c index 93785f13242e..870539eabbf3 100644 --- a/drivers/char/watchdog/i6300esb.c +++ b/drivers/char/watchdog/i6300esb.c | |||
@@ -337,7 +337,7 @@ static int esb_notify_sys (struct notifier_block *this, unsigned long code, void | |||
337 | * Kernel Interfaces | 337 | * Kernel Interfaces |
338 | */ | 338 | */ |
339 | 339 | ||
340 | static struct file_operations esb_fops = { | 340 | static const struct file_operations esb_fops = { |
341 | .owner = THIS_MODULE, | 341 | .owner = THIS_MODULE, |
342 | .llseek = no_llseek, | 342 | .llseek = no_llseek, |
343 | .write = esb_write, | 343 | .write = esb_write, |
diff --git a/drivers/char/watchdog/i8xx_tco.c b/drivers/char/watchdog/i8xx_tco.c index bfbdbbf3c2f2..8385dd36eefe 100644 --- a/drivers/char/watchdog/i8xx_tco.c +++ b/drivers/char/watchdog/i8xx_tco.c | |||
@@ -378,7 +378,7 @@ static int i8xx_tco_notify_sys (struct notifier_block *this, unsigned long code, | |||
378 | * Kernel Interfaces | 378 | * Kernel Interfaces |
379 | */ | 379 | */ |
380 | 380 | ||
381 | static struct file_operations i8xx_tco_fops = { | 381 | static const struct file_operations i8xx_tco_fops = { |
382 | .owner = THIS_MODULE, | 382 | .owner = THIS_MODULE, |
383 | .llseek = no_llseek, | 383 | .llseek = no_llseek, |
384 | .write = i8xx_tco_write, | 384 | .write = i8xx_tco_write, |
diff --git a/drivers/char/watchdog/ib700wdt.c b/drivers/char/watchdog/ib700wdt.c index a2e53c715b36..fd95f7327798 100644 --- a/drivers/char/watchdog/ib700wdt.c +++ b/drivers/char/watchdog/ib700wdt.c | |||
@@ -255,7 +255,7 @@ ibwdt_notify_sys(struct notifier_block *this, unsigned long code, | |||
255 | * Kernel Interfaces | 255 | * Kernel Interfaces |
256 | */ | 256 | */ |
257 | 257 | ||
258 | static struct file_operations ibwdt_fops = { | 258 | static const struct file_operations ibwdt_fops = { |
259 | .owner = THIS_MODULE, | 259 | .owner = THIS_MODULE, |
260 | .llseek = no_llseek, | 260 | .llseek = no_llseek, |
261 | .write = ibwdt_write, | 261 | .write = ibwdt_write, |
diff --git a/drivers/char/watchdog/ibmasr.c b/drivers/char/watchdog/ibmasr.c index b0741cbdc139..26ceee7a4df0 100644 --- a/drivers/char/watchdog/ibmasr.c +++ b/drivers/char/watchdog/ibmasr.c | |||
@@ -322,7 +322,7 @@ static int asr_release(struct inode *inode, struct file *file) | |||
322 | return 0; | 322 | return 0; |
323 | } | 323 | } |
324 | 324 | ||
325 | static struct file_operations asr_fops = { | 325 | static const struct file_operations asr_fops = { |
326 | .owner = THIS_MODULE, | 326 | .owner = THIS_MODULE, |
327 | .llseek = no_llseek, | 327 | .llseek = no_llseek, |
328 | .write = asr_write, | 328 | .write = asr_write, |
diff --git a/drivers/char/watchdog/indydog.c b/drivers/char/watchdog/indydog.c index d387979b2434..dacc1c20a310 100644 --- a/drivers/char/watchdog/indydog.c +++ b/drivers/char/watchdog/indydog.c | |||
@@ -154,7 +154,7 @@ static int indydog_notify_sys(struct notifier_block *this, unsigned long code, v | |||
154 | return NOTIFY_DONE; | 154 | return NOTIFY_DONE; |
155 | } | 155 | } |
156 | 156 | ||
157 | static struct file_operations indydog_fops = { | 157 | static const struct file_operations indydog_fops = { |
158 | .owner = THIS_MODULE, | 158 | .owner = THIS_MODULE, |
159 | .llseek = no_llseek, | 159 | .llseek = no_llseek, |
160 | .write = indydog_write, | 160 | .write = indydog_write, |
diff --git a/drivers/char/watchdog/ixp2000_wdt.c b/drivers/char/watchdog/ixp2000_wdt.c index aa29a7d68759..692908819e26 100644 --- a/drivers/char/watchdog/ixp2000_wdt.c +++ b/drivers/char/watchdog/ixp2000_wdt.c | |||
@@ -168,7 +168,7 @@ ixp2000_wdt_release(struct inode *inode, struct file *file) | |||
168 | } | 168 | } |
169 | 169 | ||
170 | 170 | ||
171 | static struct file_operations ixp2000_wdt_fops = | 171 | static const struct file_operations ixp2000_wdt_fops = |
172 | { | 172 | { |
173 | .owner = THIS_MODULE, | 173 | .owner = THIS_MODULE, |
174 | .llseek = no_llseek, | 174 | .llseek = no_llseek, |
diff --git a/drivers/char/watchdog/ixp4xx_wdt.c b/drivers/char/watchdog/ixp4xx_wdt.c index e6a3fe83fa01..9db5cf2c38c3 100644 --- a/drivers/char/watchdog/ixp4xx_wdt.c +++ b/drivers/char/watchdog/ixp4xx_wdt.c | |||
@@ -162,7 +162,7 @@ ixp4xx_wdt_release(struct inode *inode, struct file *file) | |||
162 | } | 162 | } |
163 | 163 | ||
164 | 164 | ||
165 | static struct file_operations ixp4xx_wdt_fops = | 165 | static const struct file_operations ixp4xx_wdt_fops = |
166 | { | 166 | { |
167 | .owner = THIS_MODULE, | 167 | .owner = THIS_MODULE, |
168 | .llseek = no_llseek, | 168 | .llseek = no_llseek, |
diff --git a/drivers/char/watchdog/machzwd.c b/drivers/char/watchdog/machzwd.c index b67b4878ae0f..23734e07fb22 100644 --- a/drivers/char/watchdog/machzwd.c +++ b/drivers/char/watchdog/machzwd.c | |||
@@ -388,7 +388,7 @@ static int zf_notify_sys(struct notifier_block *this, unsigned long code, | |||
388 | 388 | ||
389 | 389 | ||
390 | 390 | ||
391 | static struct file_operations zf_fops = { | 391 | static const struct file_operations zf_fops = { |
392 | .owner = THIS_MODULE, | 392 | .owner = THIS_MODULE, |
393 | .llseek = no_llseek, | 393 | .llseek = no_llseek, |
394 | .write = zf_write, | 394 | .write = zf_write, |
diff --git a/drivers/char/watchdog/mixcomwd.c b/drivers/char/watchdog/mixcomwd.c index 433c27f98159..ae943324d251 100644 --- a/drivers/char/watchdog/mixcomwd.c +++ b/drivers/char/watchdog/mixcomwd.c | |||
@@ -190,7 +190,7 @@ static int mixcomwd_ioctl(struct inode *inode, struct file *file, | |||
190 | return 0; | 190 | return 0; |
191 | } | 191 | } |
192 | 192 | ||
193 | static struct file_operations mixcomwd_fops= | 193 | static const struct file_operations mixcomwd_fops= |
194 | { | 194 | { |
195 | .owner = THIS_MODULE, | 195 | .owner = THIS_MODULE, |
196 | .llseek = no_llseek, | 196 | .llseek = no_llseek, |
diff --git a/drivers/char/watchdog/mpc83xx_wdt.c b/drivers/char/watchdog/mpc83xx_wdt.c index dac1381af364..a480903ee1a5 100644 --- a/drivers/char/watchdog/mpc83xx_wdt.c +++ b/drivers/char/watchdog/mpc83xx_wdt.c | |||
@@ -129,7 +129,7 @@ static int mpc83xx_wdt_ioctl(struct inode *inode, struct file *file, | |||
129 | } | 129 | } |
130 | } | 130 | } |
131 | 131 | ||
132 | static struct file_operations mpc83xx_wdt_fops = { | 132 | static const struct file_operations mpc83xx_wdt_fops = { |
133 | .owner = THIS_MODULE, | 133 | .owner = THIS_MODULE, |
134 | .llseek = no_llseek, | 134 | .llseek = no_llseek, |
135 | .write = mpc83xx_wdt_write, | 135 | .write = mpc83xx_wdt_write, |
diff --git a/drivers/char/watchdog/mpc8xx_wdt.c b/drivers/char/watchdog/mpc8xx_wdt.c index 11f0ccd4c4d4..35dd9e6e1140 100644 --- a/drivers/char/watchdog/mpc8xx_wdt.c +++ b/drivers/char/watchdog/mpc8xx_wdt.c | |||
@@ -132,7 +132,7 @@ static int mpc8xx_wdt_ioctl(struct inode *inode, struct file *file, | |||
132 | return 0; | 132 | return 0; |
133 | } | 133 | } |
134 | 134 | ||
135 | static struct file_operations mpc8xx_wdt_fops = { | 135 | static const struct file_operations mpc8xx_wdt_fops = { |
136 | .owner = THIS_MODULE, | 136 | .owner = THIS_MODULE, |
137 | .llseek = no_llseek, | 137 | .llseek = no_llseek, |
138 | .write = mpc8xx_wdt_write, | 138 | .write = mpc8xx_wdt_write, |
diff --git a/drivers/char/watchdog/mpcore_wdt.c b/drivers/char/watchdog/mpcore_wdt.c index c2d492c852fc..54b3c56ead0d 100644 --- a/drivers/char/watchdog/mpcore_wdt.c +++ b/drivers/char/watchdog/mpcore_wdt.c | |||
@@ -297,7 +297,7 @@ static void mpcore_wdt_shutdown(struct platform_device *dev) | |||
297 | /* | 297 | /* |
298 | * Kernel Interfaces | 298 | * Kernel Interfaces |
299 | */ | 299 | */ |
300 | static struct file_operations mpcore_wdt_fops = { | 300 | static const struct file_operations mpcore_wdt_fops = { |
301 | .owner = THIS_MODULE, | 301 | .owner = THIS_MODULE, |
302 | .llseek = no_llseek, | 302 | .llseek = no_llseek, |
303 | .write = mpcore_wdt_write, | 303 | .write = mpcore_wdt_write, |
diff --git a/drivers/char/watchdog/mv64x60_wdt.c b/drivers/char/watchdog/mv64x60_wdt.c index 20a6cbb0fbb8..5c8fab345b40 100644 --- a/drivers/char/watchdog/mv64x60_wdt.c +++ b/drivers/char/watchdog/mv64x60_wdt.c | |||
@@ -166,7 +166,7 @@ static int mv64x60_wdt_ioctl(struct inode *inode, struct file *file, | |||
166 | return 0; | 166 | return 0; |
167 | } | 167 | } |
168 | 168 | ||
169 | static struct file_operations mv64x60_wdt_fops = { | 169 | static const struct file_operations mv64x60_wdt_fops = { |
170 | .owner = THIS_MODULE, | 170 | .owner = THIS_MODULE, |
171 | .llseek = no_llseek, | 171 | .llseek = no_llseek, |
172 | .write = mv64x60_wdt_write, | 172 | .write = mv64x60_wdt_write, |
diff --git a/drivers/char/watchdog/pcwd.c b/drivers/char/watchdog/pcwd.c index 6d44ca68312d..cd7d1b6a5d9f 100644 --- a/drivers/char/watchdog/pcwd.c +++ b/drivers/char/watchdog/pcwd.c | |||
@@ -740,7 +740,7 @@ static int pcwd_notify_sys(struct notifier_block *this, unsigned long code, void | |||
740 | * Kernel Interfaces | 740 | * Kernel Interfaces |
741 | */ | 741 | */ |
742 | 742 | ||
743 | static struct file_operations pcwd_fops = { | 743 | static const struct file_operations pcwd_fops = { |
744 | .owner = THIS_MODULE, | 744 | .owner = THIS_MODULE, |
745 | .llseek = no_llseek, | 745 | .llseek = no_llseek, |
746 | .write = pcwd_write, | 746 | .write = pcwd_write, |
@@ -755,7 +755,7 @@ static struct miscdevice pcwd_miscdev = { | |||
755 | .fops = &pcwd_fops, | 755 | .fops = &pcwd_fops, |
756 | }; | 756 | }; |
757 | 757 | ||
758 | static struct file_operations pcwd_temp_fops = { | 758 | static const struct file_operations pcwd_temp_fops = { |
759 | .owner = THIS_MODULE, | 759 | .owner = THIS_MODULE, |
760 | .llseek = no_llseek, | 760 | .llseek = no_llseek, |
761 | .read = pcwd_temp_read, | 761 | .read = pcwd_temp_read, |
diff --git a/drivers/char/watchdog/pcwd_pci.c b/drivers/char/watchdog/pcwd_pci.c index 1f40ecefbf72..c7cfd6dbfe1b 100644 --- a/drivers/char/watchdog/pcwd_pci.c +++ b/drivers/char/watchdog/pcwd_pci.c | |||
@@ -625,7 +625,7 @@ static int pcipcwd_notify_sys(struct notifier_block *this, unsigned long code, v | |||
625 | * Kernel Interfaces | 625 | * Kernel Interfaces |
626 | */ | 626 | */ |
627 | 627 | ||
628 | static struct file_operations pcipcwd_fops = { | 628 | static const struct file_operations pcipcwd_fops = { |
629 | .owner = THIS_MODULE, | 629 | .owner = THIS_MODULE, |
630 | .llseek = no_llseek, | 630 | .llseek = no_llseek, |
631 | .write = pcipcwd_write, | 631 | .write = pcipcwd_write, |
@@ -640,7 +640,7 @@ static struct miscdevice pcipcwd_miscdev = { | |||
640 | .fops = &pcipcwd_fops, | 640 | .fops = &pcipcwd_fops, |
641 | }; | 641 | }; |
642 | 642 | ||
643 | static struct file_operations pcipcwd_temp_fops = { | 643 | static const struct file_operations pcipcwd_temp_fops = { |
644 | .owner = THIS_MODULE, | 644 | .owner = THIS_MODULE, |
645 | .llseek = no_llseek, | 645 | .llseek = no_llseek, |
646 | .read = pcipcwd_temp_read, | 646 | .read = pcipcwd_temp_read, |
diff --git a/drivers/char/watchdog/pcwd_usb.c b/drivers/char/watchdog/pcwd_usb.c index 92bf8c1a0f0d..b7ae73dcdd08 100644 --- a/drivers/char/watchdog/pcwd_usb.c +++ b/drivers/char/watchdog/pcwd_usb.c | |||
@@ -523,7 +523,7 @@ static int usb_pcwd_notify_sys(struct notifier_block *this, unsigned long code, | |||
523 | * Kernel Interfaces | 523 | * Kernel Interfaces |
524 | */ | 524 | */ |
525 | 525 | ||
526 | static struct file_operations usb_pcwd_fops = { | 526 | static const struct file_operations usb_pcwd_fops = { |
527 | .owner = THIS_MODULE, | 527 | .owner = THIS_MODULE, |
528 | .llseek = no_llseek, | 528 | .llseek = no_llseek, |
529 | .write = usb_pcwd_write, | 529 | .write = usb_pcwd_write, |
@@ -538,7 +538,7 @@ static struct miscdevice usb_pcwd_miscdev = { | |||
538 | .fops = &usb_pcwd_fops, | 538 | .fops = &usb_pcwd_fops, |
539 | }; | 539 | }; |
540 | 540 | ||
541 | static struct file_operations usb_pcwd_temperature_fops = { | 541 | static const struct file_operations usb_pcwd_temperature_fops = { |
542 | .owner = THIS_MODULE, | 542 | .owner = THIS_MODULE, |
543 | .llseek = no_llseek, | 543 | .llseek = no_llseek, |
544 | .read = usb_pcwd_temperature_read, | 544 | .read = usb_pcwd_temperature_read, |
diff --git a/drivers/char/watchdog/s3c2410_wdt.c b/drivers/char/watchdog/s3c2410_wdt.c index f267dad26071..be978e8ed754 100644 --- a/drivers/char/watchdog/s3c2410_wdt.c +++ b/drivers/char/watchdog/s3c2410_wdt.c | |||
@@ -319,7 +319,7 @@ static int s3c2410wdt_ioctl(struct inode *inode, struct file *file, | |||
319 | 319 | ||
320 | /* kernel interface */ | 320 | /* kernel interface */ |
321 | 321 | ||
322 | static struct file_operations s3c2410wdt_fops = { | 322 | static const struct file_operations s3c2410wdt_fops = { |
323 | .owner = THIS_MODULE, | 323 | .owner = THIS_MODULE, |
324 | .llseek = no_llseek, | 324 | .llseek = no_llseek, |
325 | .write = s3c2410wdt_write, | 325 | .write = s3c2410wdt_write, |
diff --git a/drivers/char/watchdog/sa1100_wdt.c b/drivers/char/watchdog/sa1100_wdt.c index b22e95c5470c..1fc16d995788 100644 --- a/drivers/char/watchdog/sa1100_wdt.c +++ b/drivers/char/watchdog/sa1100_wdt.c | |||
@@ -135,7 +135,7 @@ static int sa1100dog_ioctl(struct inode *inode, struct file *file, | |||
135 | return ret; | 135 | return ret; |
136 | } | 136 | } |
137 | 137 | ||
138 | static struct file_operations sa1100dog_fops = | 138 | static const struct file_operations sa1100dog_fops = |
139 | { | 139 | { |
140 | .owner = THIS_MODULE, | 140 | .owner = THIS_MODULE, |
141 | .llseek = no_llseek, | 141 | .llseek = no_llseek, |
diff --git a/drivers/char/watchdog/sbc60xxwdt.c b/drivers/char/watchdog/sbc60xxwdt.c index ed0bd55fbfc1..4663c2fd53cd 100644 --- a/drivers/char/watchdog/sbc60xxwdt.c +++ b/drivers/char/watchdog/sbc60xxwdt.c | |||
@@ -282,7 +282,7 @@ static int fop_ioctl(struct inode *inode, struct file *file, unsigned int cmd, | |||
282 | } | 282 | } |
283 | } | 283 | } |
284 | 284 | ||
285 | static struct file_operations wdt_fops = { | 285 | static const struct file_operations wdt_fops = { |
286 | .owner = THIS_MODULE, | 286 | .owner = THIS_MODULE, |
287 | .llseek = no_llseek, | 287 | .llseek = no_llseek, |
288 | .write = fop_write, | 288 | .write = fop_write, |
diff --git a/drivers/char/watchdog/sbc8360.c b/drivers/char/watchdog/sbc8360.c index 6562aa910ace..1035be5b5019 100644 --- a/drivers/char/watchdog/sbc8360.c +++ b/drivers/char/watchdog/sbc8360.c | |||
@@ -305,7 +305,7 @@ static int sbc8360_notify_sys(struct notifier_block *this, unsigned long code, | |||
305 | * Kernel Interfaces | 305 | * Kernel Interfaces |
306 | */ | 306 | */ |
307 | 307 | ||
308 | static struct file_operations sbc8360_fops = { | 308 | static const struct file_operations sbc8360_fops = { |
309 | .owner = THIS_MODULE, | 309 | .owner = THIS_MODULE, |
310 | .llseek = no_llseek, | 310 | .llseek = no_llseek, |
311 | .write = sbc8360_write, | 311 | .write = sbc8360_write, |
diff --git a/drivers/char/watchdog/sbc_epx_c3.c b/drivers/char/watchdog/sbc_epx_c3.c index 09867fadc720..bfc475dabe6d 100644 --- a/drivers/char/watchdog/sbc_epx_c3.c +++ b/drivers/char/watchdog/sbc_epx_c3.c | |||
@@ -154,7 +154,7 @@ static int epx_c3_notify_sys(struct notifier_block *this, unsigned long code, | |||
154 | return NOTIFY_DONE; | 154 | return NOTIFY_DONE; |
155 | } | 155 | } |
156 | 156 | ||
157 | static struct file_operations epx_c3_fops = { | 157 | static const struct file_operations epx_c3_fops = { |
158 | .owner = THIS_MODULE, | 158 | .owner = THIS_MODULE, |
159 | .llseek = no_llseek, | 159 | .llseek = no_llseek, |
160 | .write = epx_c3_write, | 160 | .write = epx_c3_write, |
diff --git a/drivers/char/watchdog/sc1200wdt.c b/drivers/char/watchdog/sc1200wdt.c index 78ef6333c181..7c3cf293a5af 100644 --- a/drivers/char/watchdog/sc1200wdt.c +++ b/drivers/char/watchdog/sc1200wdt.c | |||
@@ -292,7 +292,7 @@ static struct notifier_block sc1200wdt_notifier = | |||
292 | .notifier_call = sc1200wdt_notify_sys, | 292 | .notifier_call = sc1200wdt_notify_sys, |
293 | }; | 293 | }; |
294 | 294 | ||
295 | static struct file_operations sc1200wdt_fops = | 295 | static const struct file_operations sc1200wdt_fops = |
296 | { | 296 | { |
297 | .owner = THIS_MODULE, | 297 | .owner = THIS_MODULE, |
298 | .llseek = no_llseek, | 298 | .llseek = no_llseek, |
diff --git a/drivers/char/watchdog/sc520_wdt.c b/drivers/char/watchdog/sc520_wdt.c index 4ee9974ad8cb..2c7c9db71be8 100644 --- a/drivers/char/watchdog/sc520_wdt.c +++ b/drivers/char/watchdog/sc520_wdt.c | |||
@@ -336,7 +336,7 @@ static int fop_ioctl(struct inode *inode, struct file *file, unsigned int cmd, | |||
336 | } | 336 | } |
337 | } | 337 | } |
338 | 338 | ||
339 | static struct file_operations wdt_fops = { | 339 | static const struct file_operations wdt_fops = { |
340 | .owner = THIS_MODULE, | 340 | .owner = THIS_MODULE, |
341 | .llseek = no_llseek, | 341 | .llseek = no_llseek, |
342 | .write = fop_write, | 342 | .write = fop_write, |
diff --git a/drivers/char/watchdog/scx200_wdt.c b/drivers/char/watchdog/scx200_wdt.c index c0b4754e8de0..c561299a5537 100644 --- a/drivers/char/watchdog/scx200_wdt.c +++ b/drivers/char/watchdog/scx200_wdt.c | |||
@@ -194,7 +194,7 @@ static int scx200_wdt_ioctl(struct inode *inode, struct file *file, | |||
194 | } | 194 | } |
195 | } | 195 | } |
196 | 196 | ||
197 | static struct file_operations scx200_wdt_fops = { | 197 | static const struct file_operations scx200_wdt_fops = { |
198 | .owner = THIS_MODULE, | 198 | .owner = THIS_MODULE, |
199 | .llseek = no_llseek, | 199 | .llseek = no_llseek, |
200 | .write = scx200_wdt_write, | 200 | .write = scx200_wdt_write, |
diff --git a/drivers/char/watchdog/shwdt.c b/drivers/char/watchdog/shwdt.c index 803701b675c0..1355038f1044 100644 --- a/drivers/char/watchdog/shwdt.c +++ b/drivers/char/watchdog/shwdt.c | |||
@@ -344,7 +344,7 @@ static int sh_wdt_notify_sys(struct notifier_block *this, | |||
344 | return NOTIFY_DONE; | 344 | return NOTIFY_DONE; |
345 | } | 345 | } |
346 | 346 | ||
347 | static struct file_operations sh_wdt_fops = { | 347 | static const struct file_operations sh_wdt_fops = { |
348 | .owner = THIS_MODULE, | 348 | .owner = THIS_MODULE, |
349 | .llseek = no_llseek, | 349 | .llseek = no_llseek, |
350 | .write = sh_wdt_write, | 350 | .write = sh_wdt_write, |
diff --git a/drivers/char/watchdog/softdog.c b/drivers/char/watchdog/softdog.c index 79ce5c655428..ef8da517545a 100644 --- a/drivers/char/watchdog/softdog.c +++ b/drivers/char/watchdog/softdog.c | |||
@@ -243,7 +243,7 @@ static int softdog_notify_sys(struct notifier_block *this, unsigned long code, | |||
243 | * Kernel Interfaces | 243 | * Kernel Interfaces |
244 | */ | 244 | */ |
245 | 245 | ||
246 | static struct file_operations softdog_fops = { | 246 | static const struct file_operations softdog_fops = { |
247 | .owner = THIS_MODULE, | 247 | .owner = THIS_MODULE, |
248 | .llseek = no_llseek, | 248 | .llseek = no_llseek, |
249 | .write = softdog_write, | 249 | .write = softdog_write, |
diff --git a/drivers/char/watchdog/w83627hf_wdt.c b/drivers/char/watchdog/w83627hf_wdt.c index d15ca9a3986f..13f16d41c2fd 100644 --- a/drivers/char/watchdog/w83627hf_wdt.c +++ b/drivers/char/watchdog/w83627hf_wdt.c | |||
@@ -274,7 +274,7 @@ wdt_notify_sys(struct notifier_block *this, unsigned long code, | |||
274 | * Kernel Interfaces | 274 | * Kernel Interfaces |
275 | */ | 275 | */ |
276 | 276 | ||
277 | static struct file_operations wdt_fops = { | 277 | static const struct file_operations wdt_fops = { |
278 | .owner = THIS_MODULE, | 278 | .owner = THIS_MODULE, |
279 | .llseek = no_llseek, | 279 | .llseek = no_llseek, |
280 | .write = wdt_write, | 280 | .write = wdt_write, |
diff --git a/drivers/char/watchdog/w83877f_wdt.c b/drivers/char/watchdog/w83877f_wdt.c index 52a8bd0a5988..ccf6c0915945 100644 --- a/drivers/char/watchdog/w83877f_wdt.c +++ b/drivers/char/watchdog/w83877f_wdt.c | |||
@@ -299,7 +299,7 @@ static int fop_ioctl(struct inode *inode, struct file *file, unsigned int cmd, | |||
299 | } | 299 | } |
300 | } | 300 | } |
301 | 301 | ||
302 | static struct file_operations wdt_fops = { | 302 | static const struct file_operations wdt_fops = { |
303 | .owner = THIS_MODULE, | 303 | .owner = THIS_MODULE, |
304 | .llseek = no_llseek, | 304 | .llseek = no_llseek, |
305 | .write = fop_write, | 305 | .write = fop_write, |
diff --git a/drivers/char/watchdog/w83977f_wdt.c b/drivers/char/watchdog/w83977f_wdt.c index c31849e4c5c2..98f4e17db70a 100644 --- a/drivers/char/watchdog/w83977f_wdt.c +++ b/drivers/char/watchdog/w83977f_wdt.c | |||
@@ -449,7 +449,7 @@ static int wdt_notify_sys(struct notifier_block *this, unsigned long code, | |||
449 | return NOTIFY_DONE; | 449 | return NOTIFY_DONE; |
450 | } | 450 | } |
451 | 451 | ||
452 | static struct file_operations wdt_fops= | 452 | static const struct file_operations wdt_fops= |
453 | { | 453 | { |
454 | .owner = THIS_MODULE, | 454 | .owner = THIS_MODULE, |
455 | .llseek = no_llseek, | 455 | .llseek = no_llseek, |
diff --git a/drivers/char/watchdog/wafer5823wdt.c b/drivers/char/watchdog/wafer5823wdt.c index 7cf6c9bbf486..2bb6a9d6ad28 100644 --- a/drivers/char/watchdog/wafer5823wdt.c +++ b/drivers/char/watchdog/wafer5823wdt.c | |||
@@ -222,7 +222,7 @@ static int wafwdt_notify_sys(struct notifier_block *this, unsigned long code, vo | |||
222 | * Kernel Interfaces | 222 | * Kernel Interfaces |
223 | */ | 223 | */ |
224 | 224 | ||
225 | static struct file_operations wafwdt_fops = { | 225 | static const struct file_operations wafwdt_fops = { |
226 | .owner = THIS_MODULE, | 226 | .owner = THIS_MODULE, |
227 | .llseek = no_llseek, | 227 | .llseek = no_llseek, |
228 | .write = wafwdt_write, | 228 | .write = wafwdt_write, |
diff --git a/drivers/char/watchdog/wdrtas.c b/drivers/char/watchdog/wdrtas.c index 3a462c34b92a..5c38cdf41731 100644 --- a/drivers/char/watchdog/wdrtas.c +++ b/drivers/char/watchdog/wdrtas.c | |||
@@ -520,7 +520,7 @@ wdrtas_reboot(struct notifier_block *this, unsigned long code, void *ptr) | |||
520 | 520 | ||
521 | /*** initialization stuff */ | 521 | /*** initialization stuff */ |
522 | 522 | ||
523 | static struct file_operations wdrtas_fops = { | 523 | static const struct file_operations wdrtas_fops = { |
524 | .owner = THIS_MODULE, | 524 | .owner = THIS_MODULE, |
525 | .llseek = no_llseek, | 525 | .llseek = no_llseek, |
526 | .write = wdrtas_write, | 526 | .write = wdrtas_write, |
@@ -535,7 +535,7 @@ static struct miscdevice wdrtas_miscdev = { | |||
535 | .fops = &wdrtas_fops, | 535 | .fops = &wdrtas_fops, |
536 | }; | 536 | }; |
537 | 537 | ||
538 | static struct file_operations wdrtas_temp_fops = { | 538 | static const struct file_operations wdrtas_temp_fops = { |
539 | .owner = THIS_MODULE, | 539 | .owner = THIS_MODULE, |
540 | .llseek = no_llseek, | 540 | .llseek = no_llseek, |
541 | .read = wdrtas_temp_read, | 541 | .read = wdrtas_temp_read, |
diff --git a/drivers/char/watchdog/wdt.c b/drivers/char/watchdog/wdt.c index a1d972c8f44c..70be81e39a61 100644 --- a/drivers/char/watchdog/wdt.c +++ b/drivers/char/watchdog/wdt.c | |||
@@ -494,7 +494,7 @@ static int wdt_notify_sys(struct notifier_block *this, unsigned long code, | |||
494 | */ | 494 | */ |
495 | 495 | ||
496 | 496 | ||
497 | static struct file_operations wdt_fops = { | 497 | static const struct file_operations wdt_fops = { |
498 | .owner = THIS_MODULE, | 498 | .owner = THIS_MODULE, |
499 | .llseek = no_llseek, | 499 | .llseek = no_llseek, |
500 | .write = wdt_write, | 500 | .write = wdt_write, |
@@ -510,7 +510,7 @@ static struct miscdevice wdt_miscdev = { | |||
510 | }; | 510 | }; |
511 | 511 | ||
512 | #ifdef CONFIG_WDT_501 | 512 | #ifdef CONFIG_WDT_501 |
513 | static struct file_operations wdt_temp_fops = { | 513 | static const struct file_operations wdt_temp_fops = { |
514 | .owner = THIS_MODULE, | 514 | .owner = THIS_MODULE, |
515 | .llseek = no_llseek, | 515 | .llseek = no_llseek, |
516 | .read = wdt_temp_read, | 516 | .read = wdt_temp_read, |
diff --git a/drivers/char/watchdog/wdt285.c b/drivers/char/watchdog/wdt285.c index 52825a1f1779..6555fb844f23 100644 --- a/drivers/char/watchdog/wdt285.c +++ b/drivers/char/watchdog/wdt285.c | |||
@@ -178,7 +178,7 @@ watchdog_ioctl(struct inode *inode, struct file *file, unsigned int cmd, | |||
178 | return ret; | 178 | return ret; |
179 | } | 179 | } |
180 | 180 | ||
181 | static struct file_operations watchdog_fops = { | 181 | static const struct file_operations watchdog_fops = { |
182 | .owner = THIS_MODULE, | 182 | .owner = THIS_MODULE, |
183 | .llseek = no_llseek, | 183 | .llseek = no_llseek, |
184 | .write = watchdog_write, | 184 | .write = watchdog_write, |
diff --git a/drivers/char/watchdog/wdt977.c b/drivers/char/watchdog/wdt977.c index 3cde2b9bb763..a0935bc775f8 100644 --- a/drivers/char/watchdog/wdt977.c +++ b/drivers/char/watchdog/wdt977.c | |||
@@ -418,7 +418,7 @@ static int wdt977_notify_sys(struct notifier_block *this, unsigned long code, | |||
418 | return NOTIFY_DONE; | 418 | return NOTIFY_DONE; |
419 | } | 419 | } |
420 | 420 | ||
421 | static struct file_operations wdt977_fops= | 421 | static const struct file_operations wdt977_fops= |
422 | { | 422 | { |
423 | .owner = THIS_MODULE, | 423 | .owner = THIS_MODULE, |
424 | .llseek = no_llseek, | 424 | .llseek = no_llseek, |
diff --git a/drivers/char/watchdog/wdt_pci.c b/drivers/char/watchdog/wdt_pci.c index 7529ecdbabae..5918ca2c9c35 100644 --- a/drivers/char/watchdog/wdt_pci.c +++ b/drivers/char/watchdog/wdt_pci.c | |||
@@ -543,7 +543,7 @@ static int wdtpci_notify_sys(struct notifier_block *this, unsigned long code, | |||
543 | */ | 543 | */ |
544 | 544 | ||
545 | 545 | ||
546 | static struct file_operations wdtpci_fops = { | 546 | static const struct file_operations wdtpci_fops = { |
547 | .owner = THIS_MODULE, | 547 | .owner = THIS_MODULE, |
548 | .llseek = no_llseek, | 548 | .llseek = no_llseek, |
549 | .write = wdtpci_write, | 549 | .write = wdtpci_write, |
@@ -559,7 +559,7 @@ static struct miscdevice wdtpci_miscdev = { | |||
559 | }; | 559 | }; |
560 | 560 | ||
561 | #ifdef CONFIG_WDT_501_PCI | 561 | #ifdef CONFIG_WDT_501_PCI |
562 | static struct file_operations wdtpci_temp_fops = { | 562 | static const struct file_operations wdtpci_temp_fops = { |
563 | .owner = THIS_MODULE, | 563 | .owner = THIS_MODULE, |
564 | .llseek = no_llseek, | 564 | .llseek = no_llseek, |
565 | .read = wdtpci_temp_read, | 565 | .read = wdtpci_temp_read, |
diff --git a/drivers/cpufreq/cpufreq_ondemand.c b/drivers/cpufreq/cpufreq_ondemand.c index 693e540481b4..87299924e735 100644 --- a/drivers/cpufreq/cpufreq_ondemand.c +++ b/drivers/cpufreq/cpufreq_ondemand.c | |||
@@ -12,22 +12,11 @@ | |||
12 | 12 | ||
13 | #include <linux/kernel.h> | 13 | #include <linux/kernel.h> |
14 | #include <linux/module.h> | 14 | #include <linux/module.h> |
15 | #include <linux/smp.h> | ||
16 | #include <linux/init.h> | 15 | #include <linux/init.h> |
17 | #include <linux/interrupt.h> | ||
18 | #include <linux/ctype.h> | ||
19 | #include <linux/cpufreq.h> | 16 | #include <linux/cpufreq.h> |
20 | #include <linux/sysctl.h> | ||
21 | #include <linux/types.h> | ||
22 | #include <linux/fs.h> | ||
23 | #include <linux/sysfs.h> | ||
24 | #include <linux/cpu.h> | 17 | #include <linux/cpu.h> |
25 | #include <linux/sched.h> | ||
26 | #include <linux/kmod.h> | ||
27 | #include <linux/workqueue.h> | ||
28 | #include <linux/jiffies.h> | 18 | #include <linux/jiffies.h> |
29 | #include <linux/kernel_stat.h> | 19 | #include <linux/kernel_stat.h> |
30 | #include <linux/percpu.h> | ||
31 | #include <linux/mutex.h> | 20 | #include <linux/mutex.h> |
32 | 21 | ||
33 | /* | 22 | /* |
@@ -56,16 +45,15 @@ static unsigned int def_sampling_rate; | |||
56 | #define MIN_SAMPLING_RATE (def_sampling_rate / MIN_SAMPLING_RATE_RATIO) | 45 | #define MIN_SAMPLING_RATE (def_sampling_rate / MIN_SAMPLING_RATE_RATIO) |
57 | #define MAX_SAMPLING_RATE (500 * def_sampling_rate) | 46 | #define MAX_SAMPLING_RATE (500 * def_sampling_rate) |
58 | #define DEF_SAMPLING_RATE_LATENCY_MULTIPLIER (1000) | 47 | #define DEF_SAMPLING_RATE_LATENCY_MULTIPLIER (1000) |
59 | #define DEF_SAMPLING_DOWN_FACTOR (1) | ||
60 | #define MAX_SAMPLING_DOWN_FACTOR (10) | ||
61 | #define TRANSITION_LATENCY_LIMIT (10 * 1000) | 48 | #define TRANSITION_LATENCY_LIMIT (10 * 1000) |
62 | 49 | ||
63 | static void do_dbs_timer(void *data); | 50 | static void do_dbs_timer(void *data); |
64 | 51 | ||
65 | struct cpu_dbs_info_s { | 52 | struct cpu_dbs_info_s { |
53 | cputime64_t prev_cpu_idle; | ||
54 | cputime64_t prev_cpu_wall; | ||
66 | struct cpufreq_policy *cur_policy; | 55 | struct cpufreq_policy *cur_policy; |
67 | unsigned int prev_cpu_idle_up; | 56 | struct work_struct work; |
68 | unsigned int prev_cpu_idle_down; | ||
69 | unsigned int enable; | 57 | unsigned int enable; |
70 | }; | 58 | }; |
71 | static DEFINE_PER_CPU(struct cpu_dbs_info_s, cpu_dbs_info); | 59 | static DEFINE_PER_CPU(struct cpu_dbs_info_s, cpu_dbs_info); |
@@ -80,31 +68,32 @@ static unsigned int dbs_enable; /* number of CPUs using this policy */ | |||
80 | * cpu_hotplug lock should be taken before that. Note that cpu_hotplug lock | 68 | * cpu_hotplug lock should be taken before that. Note that cpu_hotplug lock |
81 | * is recursive for the same process. -Venki | 69 | * is recursive for the same process. -Venki |
82 | */ | 70 | */ |
83 | static DEFINE_MUTEX (dbs_mutex); | 71 | static DEFINE_MUTEX(dbs_mutex); |
84 | static DECLARE_WORK (dbs_work, do_dbs_timer, NULL); | ||
85 | 72 | ||
86 | static struct workqueue_struct *dbs_workq; | 73 | static struct workqueue_struct *kondemand_wq; |
87 | 74 | ||
88 | struct dbs_tuners { | 75 | struct dbs_tuners { |
89 | unsigned int sampling_rate; | 76 | unsigned int sampling_rate; |
90 | unsigned int sampling_down_factor; | ||
91 | unsigned int up_threshold; | 77 | unsigned int up_threshold; |
92 | unsigned int ignore_nice; | 78 | unsigned int ignore_nice; |
93 | }; | 79 | }; |
94 | 80 | ||
95 | static struct dbs_tuners dbs_tuners_ins = { | 81 | static struct dbs_tuners dbs_tuners_ins = { |
96 | .up_threshold = DEF_FREQUENCY_UP_THRESHOLD, | 82 | .up_threshold = DEF_FREQUENCY_UP_THRESHOLD, |
97 | .sampling_down_factor = DEF_SAMPLING_DOWN_FACTOR, | ||
98 | .ignore_nice = 0, | 83 | .ignore_nice = 0, |
99 | }; | 84 | }; |
100 | 85 | ||
101 | static inline unsigned int get_cpu_idle_time(unsigned int cpu) | 86 | static inline cputime64_t get_cpu_idle_time(unsigned int cpu) |
102 | { | 87 | { |
103 | return kstat_cpu(cpu).cpustat.idle + | 88 | cputime64_t retval; |
104 | kstat_cpu(cpu).cpustat.iowait + | 89 | |
105 | ( dbs_tuners_ins.ignore_nice ? | 90 | retval = cputime64_add(kstat_cpu(cpu).cpustat.idle, |
106 | kstat_cpu(cpu).cpustat.nice : | 91 | kstat_cpu(cpu).cpustat.iowait); |
107 | 0); | 92 | |
93 | if (dbs_tuners_ins.ignore_nice) | ||
94 | retval = cputime64_add(retval, kstat_cpu(cpu).cpustat.nice); | ||
95 | |||
96 | return retval; | ||
108 | } | 97 | } |
109 | 98 | ||
110 | /************************** sysfs interface ************************/ | 99 | /************************** sysfs interface ************************/ |
@@ -133,35 +122,15 @@ static ssize_t show_##file_name \ | |||
133 | return sprintf(buf, "%u\n", dbs_tuners_ins.object); \ | 122 | return sprintf(buf, "%u\n", dbs_tuners_ins.object); \ |
134 | } | 123 | } |
135 | show_one(sampling_rate, sampling_rate); | 124 | show_one(sampling_rate, sampling_rate); |
136 | show_one(sampling_down_factor, sampling_down_factor); | ||
137 | show_one(up_threshold, up_threshold); | 125 | show_one(up_threshold, up_threshold); |
138 | show_one(ignore_nice_load, ignore_nice); | 126 | show_one(ignore_nice_load, ignore_nice); |
139 | 127 | ||
140 | static ssize_t store_sampling_down_factor(struct cpufreq_policy *unused, | ||
141 | const char *buf, size_t count) | ||
142 | { | ||
143 | unsigned int input; | ||
144 | int ret; | ||
145 | ret = sscanf (buf, "%u", &input); | ||
146 | if (ret != 1 ) | ||
147 | return -EINVAL; | ||
148 | |||
149 | if (input > MAX_SAMPLING_DOWN_FACTOR || input < 1) | ||
150 | return -EINVAL; | ||
151 | |||
152 | mutex_lock(&dbs_mutex); | ||
153 | dbs_tuners_ins.sampling_down_factor = input; | ||
154 | mutex_unlock(&dbs_mutex); | ||
155 | |||
156 | return count; | ||
157 | } | ||
158 | |||
159 | static ssize_t store_sampling_rate(struct cpufreq_policy *unused, | 128 | static ssize_t store_sampling_rate(struct cpufreq_policy *unused, |
160 | const char *buf, size_t count) | 129 | const char *buf, size_t count) |
161 | { | 130 | { |
162 | unsigned int input; | 131 | unsigned int input; |
163 | int ret; | 132 | int ret; |
164 | ret = sscanf (buf, "%u", &input); | 133 | ret = sscanf(buf, "%u", &input); |
165 | 134 | ||
166 | mutex_lock(&dbs_mutex); | 135 | mutex_lock(&dbs_mutex); |
167 | if (ret != 1 || input > MAX_SAMPLING_RATE || input < MIN_SAMPLING_RATE) { | 136 | if (ret != 1 || input > MAX_SAMPLING_RATE || input < MIN_SAMPLING_RATE) { |
@@ -180,7 +149,7 @@ static ssize_t store_up_threshold(struct cpufreq_policy *unused, | |||
180 | { | 149 | { |
181 | unsigned int input; | 150 | unsigned int input; |
182 | int ret; | 151 | int ret; |
183 | ret = sscanf (buf, "%u", &input); | 152 | ret = sscanf(buf, "%u", &input); |
184 | 153 | ||
185 | mutex_lock(&dbs_mutex); | 154 | mutex_lock(&dbs_mutex); |
186 | if (ret != 1 || input > MAX_FREQUENCY_UP_THRESHOLD || | 155 | if (ret != 1 || input > MAX_FREQUENCY_UP_THRESHOLD || |
@@ -203,7 +172,7 @@ static ssize_t store_ignore_nice_load(struct cpufreq_policy *policy, | |||
203 | 172 | ||
204 | unsigned int j; | 173 | unsigned int j; |
205 | 174 | ||
206 | ret = sscanf (buf, "%u", &input); | 175 | ret = sscanf(buf, "%u", &input); |
207 | if ( ret != 1 ) | 176 | if ( ret != 1 ) |
208 | return -EINVAL; | 177 | return -EINVAL; |
209 | 178 | ||
@@ -217,12 +186,12 @@ static ssize_t store_ignore_nice_load(struct cpufreq_policy *policy, | |||
217 | } | 186 | } |
218 | dbs_tuners_ins.ignore_nice = input; | 187 | dbs_tuners_ins.ignore_nice = input; |
219 | 188 | ||
220 | /* we need to re-evaluate prev_cpu_idle_up and prev_cpu_idle_down */ | 189 | /* we need to re-evaluate prev_cpu_idle */ |
221 | for_each_online_cpu(j) { | 190 | for_each_online_cpu(j) { |
222 | struct cpu_dbs_info_s *j_dbs_info; | 191 | struct cpu_dbs_info_s *dbs_info; |
223 | j_dbs_info = &per_cpu(cpu_dbs_info, j); | 192 | dbs_info = &per_cpu(cpu_dbs_info, j); |
224 | j_dbs_info->prev_cpu_idle_up = get_cpu_idle_time(j); | 193 | dbs_info->prev_cpu_idle = get_cpu_idle_time(j); |
225 | j_dbs_info->prev_cpu_idle_down = j_dbs_info->prev_cpu_idle_up; | 194 | dbs_info->prev_cpu_wall = get_jiffies_64(); |
226 | } | 195 | } |
227 | mutex_unlock(&dbs_mutex); | 196 | mutex_unlock(&dbs_mutex); |
228 | 197 | ||
@@ -234,7 +203,6 @@ static struct freq_attr _name = \ | |||
234 | __ATTR(_name, 0644, show_##_name, store_##_name) | 203 | __ATTR(_name, 0644, show_##_name, store_##_name) |
235 | 204 | ||
236 | define_one_rw(sampling_rate); | 205 | define_one_rw(sampling_rate); |
237 | define_one_rw(sampling_down_factor); | ||
238 | define_one_rw(up_threshold); | 206 | define_one_rw(up_threshold); |
239 | define_one_rw(ignore_nice_load); | 207 | define_one_rw(ignore_nice_load); |
240 | 208 | ||
@@ -242,7 +210,6 @@ static struct attribute * dbs_attributes[] = { | |||
242 | &sampling_rate_max.attr, | 210 | &sampling_rate_max.attr, |
243 | &sampling_rate_min.attr, | 211 | &sampling_rate_min.attr, |
244 | &sampling_rate.attr, | 212 | &sampling_rate.attr, |
245 | &sampling_down_factor.attr, | ||
246 | &up_threshold.attr, | 213 | &up_threshold.attr, |
247 | &ignore_nice_load.attr, | 214 | &ignore_nice_load.attr, |
248 | NULL | 215 | NULL |
@@ -255,26 +222,27 @@ static struct attribute_group dbs_attr_group = { | |||
255 | 222 | ||
256 | /************************** sysfs end ************************/ | 223 | /************************** sysfs end ************************/ |
257 | 224 | ||
258 | static void dbs_check_cpu(int cpu) | 225 | static void dbs_check_cpu(struct cpu_dbs_info_s *this_dbs_info) |
259 | { | 226 | { |
260 | unsigned int idle_ticks, up_idle_ticks, total_ticks; | 227 | unsigned int idle_ticks, total_ticks; |
261 | unsigned int freq_next; | 228 | unsigned int load; |
262 | unsigned int freq_down_sampling_rate; | 229 | cputime64_t cur_jiffies; |
263 | static int down_skip[NR_CPUS]; | ||
264 | struct cpu_dbs_info_s *this_dbs_info; | ||
265 | 230 | ||
266 | struct cpufreq_policy *policy; | 231 | struct cpufreq_policy *policy; |
267 | unsigned int j; | 232 | unsigned int j; |
268 | 233 | ||
269 | this_dbs_info = &per_cpu(cpu_dbs_info, cpu); | ||
270 | if (!this_dbs_info->enable) | 234 | if (!this_dbs_info->enable) |
271 | return; | 235 | return; |
272 | 236 | ||
273 | policy = this_dbs_info->cur_policy; | 237 | policy = this_dbs_info->cur_policy; |
238 | cur_jiffies = jiffies64_to_cputime64(get_jiffies_64()); | ||
239 | total_ticks = (unsigned int) cputime64_sub(cur_jiffies, | ||
240 | this_dbs_info->prev_cpu_wall); | ||
241 | this_dbs_info->prev_cpu_wall = cur_jiffies; | ||
274 | /* | 242 | /* |
275 | * Every sampling_rate, we check, if current idle time is less | 243 | * Every sampling_rate, we check, if current idle time is less |
276 | * than 20% (default), then we try to increase frequency | 244 | * than 20% (default), then we try to increase frequency |
277 | * Every sampling_rate*sampling_down_factor, we look for a the lowest | 245 | * Every sampling_rate, we look for a the lowest |
278 | * frequency which can sustain the load while keeping idle time over | 246 | * frequency which can sustain the load while keeping idle time over |
279 | * 30%. If such a frequency exist, we try to decrease to this frequency. | 247 | * 30%. If such a frequency exist, we try to decrease to this frequency. |
280 | * | 248 | * |
@@ -283,36 +251,26 @@ static void dbs_check_cpu(int cpu) | |||
283 | * 5% (default) of current frequency | 251 | * 5% (default) of current frequency |
284 | */ | 252 | */ |
285 | 253 | ||
286 | /* Check for frequency increase */ | 254 | /* Get Idle Time */ |
287 | idle_ticks = UINT_MAX; | 255 | idle_ticks = UINT_MAX; |
288 | for_each_cpu_mask(j, policy->cpus) { | 256 | for_each_cpu_mask(j, policy->cpus) { |
289 | unsigned int tmp_idle_ticks, total_idle_ticks; | 257 | cputime64_t total_idle_ticks; |
258 | unsigned int tmp_idle_ticks; | ||
290 | struct cpu_dbs_info_s *j_dbs_info; | 259 | struct cpu_dbs_info_s *j_dbs_info; |
291 | 260 | ||
292 | j_dbs_info = &per_cpu(cpu_dbs_info, j); | 261 | j_dbs_info = &per_cpu(cpu_dbs_info, j); |
293 | total_idle_ticks = get_cpu_idle_time(j); | 262 | total_idle_ticks = get_cpu_idle_time(j); |
294 | tmp_idle_ticks = total_idle_ticks - | 263 | tmp_idle_ticks = (unsigned int) cputime64_sub(total_idle_ticks, |
295 | j_dbs_info->prev_cpu_idle_up; | 264 | j_dbs_info->prev_cpu_idle); |
296 | j_dbs_info->prev_cpu_idle_up = total_idle_ticks; | 265 | j_dbs_info->prev_cpu_idle = total_idle_ticks; |
297 | 266 | ||
298 | if (tmp_idle_ticks < idle_ticks) | 267 | if (tmp_idle_ticks < idle_ticks) |
299 | idle_ticks = tmp_idle_ticks; | 268 | idle_ticks = tmp_idle_ticks; |
300 | } | 269 | } |
270 | load = (100 * (total_ticks - idle_ticks)) / total_ticks; | ||
301 | 271 | ||
302 | /* Scale idle ticks by 100 and compare with up and down ticks */ | 272 | /* Check for frequency increase */ |
303 | idle_ticks *= 100; | 273 | if (load > dbs_tuners_ins.up_threshold) { |
304 | up_idle_ticks = (100 - dbs_tuners_ins.up_threshold) * | ||
305 | usecs_to_jiffies(dbs_tuners_ins.sampling_rate); | ||
306 | |||
307 | if (idle_ticks < up_idle_ticks) { | ||
308 | down_skip[cpu] = 0; | ||
309 | for_each_cpu_mask(j, policy->cpus) { | ||
310 | struct cpu_dbs_info_s *j_dbs_info; | ||
311 | |||
312 | j_dbs_info = &per_cpu(cpu_dbs_info, j); | ||
313 | j_dbs_info->prev_cpu_idle_down = | ||
314 | j_dbs_info->prev_cpu_idle_up; | ||
315 | } | ||
316 | /* if we are already at full speed then break out early */ | 274 | /* if we are already at full speed then break out early */ |
317 | if (policy->cur == policy->max) | 275 | if (policy->cur == policy->max) |
318 | return; | 276 | return; |
@@ -323,83 +281,49 @@ static void dbs_check_cpu(int cpu) | |||
323 | } | 281 | } |
324 | 282 | ||
325 | /* Check for frequency decrease */ | 283 | /* Check for frequency decrease */ |
326 | down_skip[cpu]++; | ||
327 | if (down_skip[cpu] < dbs_tuners_ins.sampling_down_factor) | ||
328 | return; | ||
329 | |||
330 | idle_ticks = UINT_MAX; | ||
331 | for_each_cpu_mask(j, policy->cpus) { | ||
332 | unsigned int tmp_idle_ticks, total_idle_ticks; | ||
333 | struct cpu_dbs_info_s *j_dbs_info; | ||
334 | |||
335 | j_dbs_info = &per_cpu(cpu_dbs_info, j); | ||
336 | /* Check for frequency decrease */ | ||
337 | total_idle_ticks = j_dbs_info->prev_cpu_idle_up; | ||
338 | tmp_idle_ticks = total_idle_ticks - | ||
339 | j_dbs_info->prev_cpu_idle_down; | ||
340 | j_dbs_info->prev_cpu_idle_down = total_idle_ticks; | ||
341 | |||
342 | if (tmp_idle_ticks < idle_ticks) | ||
343 | idle_ticks = tmp_idle_ticks; | ||
344 | } | ||
345 | |||
346 | down_skip[cpu] = 0; | ||
347 | /* if we cannot reduce the frequency anymore, break out early */ | 284 | /* if we cannot reduce the frequency anymore, break out early */ |
348 | if (policy->cur == policy->min) | 285 | if (policy->cur == policy->min) |
349 | return; | 286 | return; |
350 | 287 | ||
351 | /* Compute how many ticks there are between two measurements */ | ||
352 | freq_down_sampling_rate = dbs_tuners_ins.sampling_rate * | ||
353 | dbs_tuners_ins.sampling_down_factor; | ||
354 | total_ticks = usecs_to_jiffies(freq_down_sampling_rate); | ||
355 | |||
356 | /* | 288 | /* |
357 | * The optimal frequency is the frequency that is the lowest that | 289 | * The optimal frequency is the frequency that is the lowest that |
358 | * can support the current CPU usage without triggering the up | 290 | * can support the current CPU usage without triggering the up |
359 | * policy. To be safe, we focus 10 points under the threshold. | 291 | * policy. To be safe, we focus 10 points under the threshold. |
360 | */ | 292 | */ |
361 | freq_next = ((total_ticks - idle_ticks) * 100) / total_ticks; | 293 | if (load < (dbs_tuners_ins.up_threshold - 10)) { |
362 | freq_next = (freq_next * policy->cur) / | 294 | unsigned int freq_next; |
295 | freq_next = (policy->cur * load) / | ||
363 | (dbs_tuners_ins.up_threshold - 10); | 296 | (dbs_tuners_ins.up_threshold - 10); |
364 | 297 | ||
365 | if (freq_next < policy->min) | ||
366 | freq_next = policy->min; | ||
367 | |||
368 | if (freq_next <= ((policy->cur * 95) / 100)) | ||
369 | __cpufreq_driver_target(policy, freq_next, CPUFREQ_RELATION_L); | 298 | __cpufreq_driver_target(policy, freq_next, CPUFREQ_RELATION_L); |
299 | } | ||
370 | } | 300 | } |
371 | 301 | ||
372 | static void do_dbs_timer(void *data) | 302 | static void do_dbs_timer(void *data) |
373 | { | 303 | { |
374 | int i; | 304 | unsigned int cpu = smp_processor_id(); |
375 | lock_cpu_hotplug(); | 305 | struct cpu_dbs_info_s *dbs_info = &per_cpu(cpu_dbs_info, cpu); |
376 | mutex_lock(&dbs_mutex); | 306 | |
377 | for_each_online_cpu(i) | 307 | dbs_check_cpu(dbs_info); |
378 | dbs_check_cpu(i); | 308 | queue_delayed_work_on(cpu, kondemand_wq, &dbs_info->work, |
379 | queue_delayed_work(dbs_workq, &dbs_work, | 309 | usecs_to_jiffies(dbs_tuners_ins.sampling_rate)); |
380 | usecs_to_jiffies(dbs_tuners_ins.sampling_rate)); | ||
381 | mutex_unlock(&dbs_mutex); | ||
382 | unlock_cpu_hotplug(); | ||
383 | } | 310 | } |
384 | 311 | ||
385 | static inline void dbs_timer_init(void) | 312 | static inline void dbs_timer_init(unsigned int cpu) |
386 | { | 313 | { |
387 | INIT_WORK(&dbs_work, do_dbs_timer, NULL); | 314 | struct cpu_dbs_info_s *dbs_info = &per_cpu(cpu_dbs_info, cpu); |
388 | if (!dbs_workq) | 315 | |
389 | dbs_workq = create_singlethread_workqueue("ondemand"); | 316 | INIT_WORK(&dbs_info->work, do_dbs_timer, 0); |
390 | if (!dbs_workq) { | 317 | queue_delayed_work_on(cpu, kondemand_wq, &dbs_info->work, |
391 | printk(KERN_ERR "ondemand: Cannot initialize kernel thread\n"); | 318 | usecs_to_jiffies(dbs_tuners_ins.sampling_rate)); |
392 | return; | ||
393 | } | ||
394 | queue_delayed_work(dbs_workq, &dbs_work, | ||
395 | usecs_to_jiffies(dbs_tuners_ins.sampling_rate)); | ||
396 | return; | 319 | return; |
397 | } | 320 | } |
398 | 321 | ||
399 | static inline void dbs_timer_exit(void) | 322 | static inline void dbs_timer_exit(unsigned int cpu) |
400 | { | 323 | { |
401 | if (dbs_workq) | 324 | struct cpu_dbs_info_s *dbs_info = &per_cpu(cpu_dbs_info, cpu); |
402 | cancel_rearming_delayed_workqueue(dbs_workq, &dbs_work); | 325 | |
326 | cancel_rearming_delayed_workqueue(kondemand_wq, &dbs_info->work); | ||
403 | } | 327 | } |
404 | 328 | ||
405 | static int cpufreq_governor_dbs(struct cpufreq_policy *policy, | 329 | static int cpufreq_governor_dbs(struct cpufreq_policy *policy, |
@@ -413,8 +337,7 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy, | |||
413 | 337 | ||
414 | switch (event) { | 338 | switch (event) { |
415 | case CPUFREQ_GOV_START: | 339 | case CPUFREQ_GOV_START: |
416 | if ((!cpu_online(cpu)) || | 340 | if ((!cpu_online(cpu)) || (!policy->cur)) |
417 | (!policy->cur)) | ||
418 | return -EINVAL; | 341 | return -EINVAL; |
419 | 342 | ||
420 | if (policy->cpuinfo.transition_latency > | 343 | if (policy->cpuinfo.transition_latency > |
@@ -427,18 +350,26 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy, | |||
427 | break; | 350 | break; |
428 | 351 | ||
429 | mutex_lock(&dbs_mutex); | 352 | mutex_lock(&dbs_mutex); |
353 | dbs_enable++; | ||
354 | if (dbs_enable == 1) { | ||
355 | kondemand_wq = create_workqueue("kondemand"); | ||
356 | if (!kondemand_wq) { | ||
357 | printk(KERN_ERR "Creation of kondemand failed\n"); | ||
358 | dbs_enable--; | ||
359 | mutex_unlock(&dbs_mutex); | ||
360 | return -ENOSPC; | ||
361 | } | ||
362 | } | ||
430 | for_each_cpu_mask(j, policy->cpus) { | 363 | for_each_cpu_mask(j, policy->cpus) { |
431 | struct cpu_dbs_info_s *j_dbs_info; | 364 | struct cpu_dbs_info_s *j_dbs_info; |
432 | j_dbs_info = &per_cpu(cpu_dbs_info, j); | 365 | j_dbs_info = &per_cpu(cpu_dbs_info, j); |
433 | j_dbs_info->cur_policy = policy; | 366 | j_dbs_info->cur_policy = policy; |
434 | 367 | ||
435 | j_dbs_info->prev_cpu_idle_up = get_cpu_idle_time(j); | 368 | j_dbs_info->prev_cpu_idle = get_cpu_idle_time(j); |
436 | j_dbs_info->prev_cpu_idle_down | 369 | j_dbs_info->prev_cpu_wall = get_jiffies_64(); |
437 | = j_dbs_info->prev_cpu_idle_up; | ||
438 | } | 370 | } |
439 | this_dbs_info->enable = 1; | 371 | this_dbs_info->enable = 1; |
440 | sysfs_create_group(&policy->kobj, &dbs_attr_group); | 372 | sysfs_create_group(&policy->kobj, &dbs_attr_group); |
441 | dbs_enable++; | ||
442 | /* | 373 | /* |
443 | * Start the timerschedule work, when this governor | 374 | * Start the timerschedule work, when this governor |
444 | * is used for first time | 375 | * is used for first time |
@@ -457,23 +388,20 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy, | |||
457 | def_sampling_rate = MIN_STAT_SAMPLING_RATE; | 388 | def_sampling_rate = MIN_STAT_SAMPLING_RATE; |
458 | 389 | ||
459 | dbs_tuners_ins.sampling_rate = def_sampling_rate; | 390 | dbs_tuners_ins.sampling_rate = def_sampling_rate; |
460 | dbs_timer_init(); | ||
461 | } | 391 | } |
392 | dbs_timer_init(policy->cpu); | ||
462 | 393 | ||
463 | mutex_unlock(&dbs_mutex); | 394 | mutex_unlock(&dbs_mutex); |
464 | break; | 395 | break; |
465 | 396 | ||
466 | case CPUFREQ_GOV_STOP: | 397 | case CPUFREQ_GOV_STOP: |
467 | mutex_lock(&dbs_mutex); | 398 | mutex_lock(&dbs_mutex); |
399 | dbs_timer_exit(policy->cpu); | ||
468 | this_dbs_info->enable = 0; | 400 | this_dbs_info->enable = 0; |
469 | sysfs_remove_group(&policy->kobj, &dbs_attr_group); | 401 | sysfs_remove_group(&policy->kobj, &dbs_attr_group); |
470 | dbs_enable--; | 402 | dbs_enable--; |
471 | /* | ||
472 | * Stop the timerschedule work, when this governor | ||
473 | * is used for first time | ||
474 | */ | ||
475 | if (dbs_enable == 0) | 403 | if (dbs_enable == 0) |
476 | dbs_timer_exit(); | 404 | destroy_workqueue(kondemand_wq); |
477 | 405 | ||
478 | mutex_unlock(&dbs_mutex); | 406 | mutex_unlock(&dbs_mutex); |
479 | 407 | ||
@@ -483,13 +411,13 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy, | |||
483 | lock_cpu_hotplug(); | 411 | lock_cpu_hotplug(); |
484 | mutex_lock(&dbs_mutex); | 412 | mutex_lock(&dbs_mutex); |
485 | if (policy->max < this_dbs_info->cur_policy->cur) | 413 | if (policy->max < this_dbs_info->cur_policy->cur) |
486 | __cpufreq_driver_target( | 414 | __cpufreq_driver_target(this_dbs_info->cur_policy, |
487 | this_dbs_info->cur_policy, | 415 | policy->max, |
488 | policy->max, CPUFREQ_RELATION_H); | 416 | CPUFREQ_RELATION_H); |
489 | else if (policy->min > this_dbs_info->cur_policy->cur) | 417 | else if (policy->min > this_dbs_info->cur_policy->cur) |
490 | __cpufreq_driver_target( | 418 | __cpufreq_driver_target(this_dbs_info->cur_policy, |
491 | this_dbs_info->cur_policy, | 419 | policy->min, |
492 | policy->min, CPUFREQ_RELATION_L); | 420 | CPUFREQ_RELATION_L); |
493 | mutex_unlock(&dbs_mutex); | 421 | mutex_unlock(&dbs_mutex); |
494 | unlock_cpu_hotplug(); | 422 | unlock_cpu_hotplug(); |
495 | break; | 423 | break; |
@@ -498,9 +426,9 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy, | |||
498 | } | 426 | } |
499 | 427 | ||
500 | static struct cpufreq_governor cpufreq_gov_dbs = { | 428 | static struct cpufreq_governor cpufreq_gov_dbs = { |
501 | .name = "ondemand", | 429 | .name = "ondemand", |
502 | .governor = cpufreq_governor_dbs, | 430 | .governor = cpufreq_governor_dbs, |
503 | .owner = THIS_MODULE, | 431 | .owner = THIS_MODULE, |
504 | }; | 432 | }; |
505 | 433 | ||
506 | static int __init cpufreq_gov_dbs_init(void) | 434 | static int __init cpufreq_gov_dbs_init(void) |
@@ -510,21 +438,15 @@ static int __init cpufreq_gov_dbs_init(void) | |||
510 | 438 | ||
511 | static void __exit cpufreq_gov_dbs_exit(void) | 439 | static void __exit cpufreq_gov_dbs_exit(void) |
512 | { | 440 | { |
513 | /* Make sure that the scheduled work is indeed not running. | ||
514 | Assumes the timer has been cancelled first. */ | ||
515 | if (dbs_workq) { | ||
516 | flush_workqueue(dbs_workq); | ||
517 | destroy_workqueue(dbs_workq); | ||
518 | } | ||
519 | |||
520 | cpufreq_unregister_governor(&cpufreq_gov_dbs); | 441 | cpufreq_unregister_governor(&cpufreq_gov_dbs); |
521 | } | 442 | } |
522 | 443 | ||
523 | 444 | ||
524 | MODULE_AUTHOR ("Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>"); | 445 | MODULE_AUTHOR("Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>"); |
525 | MODULE_DESCRIPTION ("'cpufreq_ondemand' - A dynamic cpufreq governor for " | 446 | MODULE_AUTHOR("Alexey Starikovskiy <alexey.y.starikovskiy@intel.com>"); |
526 | "Low Latency Frequency Transition capable processors"); | 447 | MODULE_DESCRIPTION("'cpufreq_ondemand' - A dynamic cpufreq governor for " |
527 | MODULE_LICENSE ("GPL"); | 448 | "Low Latency Frequency Transition capable processors"); |
449 | MODULE_LICENSE("GPL"); | ||
528 | 450 | ||
529 | module_init(cpufreq_gov_dbs_init); | 451 | module_init(cpufreq_gov_dbs_init); |
530 | module_exit(cpufreq_gov_dbs_exit); | 452 | module_exit(cpufreq_gov_dbs_exit); |
diff --git a/drivers/dma/dmaengine.c b/drivers/dma/dmaengine.c index 5829143558e1..15278044295c 100644 --- a/drivers/dma/dmaengine.c +++ b/drivers/dma/dmaengine.c | |||
@@ -166,8 +166,8 @@ static struct dma_chan *dma_client_chan_alloc(struct dma_client *client) | |||
166 | } | 166 | } |
167 | 167 | ||
168 | /** | 168 | /** |
169 | * dma_client_chan_free - release a DMA channel | 169 | * dma_chan_cleanup - release a DMA channel's resources |
170 | * @chan: &dma_chan | 170 | * @kref: kernel reference structure that contains the DMA channel device |
171 | */ | 171 | */ |
172 | void dma_chan_cleanup(struct kref *kref) | 172 | void dma_chan_cleanup(struct kref *kref) |
173 | { | 173 | { |
@@ -199,7 +199,7 @@ static void dma_client_chan_free(struct dma_chan *chan) | |||
199 | * dma_chans_rebalance - reallocate channels to clients | 199 | * dma_chans_rebalance - reallocate channels to clients |
200 | * | 200 | * |
201 | * When the number of DMA channel in the system changes, | 201 | * When the number of DMA channel in the system changes, |
202 | * channels need to be rebalanced among clients | 202 | * channels need to be rebalanced among clients. |
203 | */ | 203 | */ |
204 | static void dma_chans_rebalance(void) | 204 | static void dma_chans_rebalance(void) |
205 | { | 205 | { |
@@ -264,7 +264,7 @@ struct dma_client *dma_async_client_register(dma_event_callback event_callback) | |||
264 | 264 | ||
265 | /** | 265 | /** |
266 | * dma_async_client_unregister - unregister a client and free the &dma_client | 266 | * dma_async_client_unregister - unregister a client and free the &dma_client |
267 | * @client: | 267 | * @client: &dma_client to free |
268 | * | 268 | * |
269 | * Force frees any allocated DMA channels, frees the &dma_client memory | 269 | * Force frees any allocated DMA channels, frees the &dma_client memory |
270 | */ | 270 | */ |
@@ -306,7 +306,7 @@ void dma_async_client_chan_request(struct dma_client *client, | |||
306 | } | 306 | } |
307 | 307 | ||
308 | /** | 308 | /** |
309 | * dma_async_device_register - | 309 | * dma_async_device_register - registers DMA devices found |
310 | * @device: &dma_device | 310 | * @device: &dma_device |
311 | */ | 311 | */ |
312 | int dma_async_device_register(struct dma_device *device) | 312 | int dma_async_device_register(struct dma_device *device) |
@@ -348,8 +348,8 @@ int dma_async_device_register(struct dma_device *device) | |||
348 | } | 348 | } |
349 | 349 | ||
350 | /** | 350 | /** |
351 | * dma_async_device_unregister - | 351 | * dma_async_device_cleanup - function called when all references are released |
352 | * @device: &dma_device | 352 | * @kref: kernel reference object |
353 | */ | 353 | */ |
354 | static void dma_async_device_cleanup(struct kref *kref) | 354 | static void dma_async_device_cleanup(struct kref *kref) |
355 | { | 355 | { |
@@ -359,7 +359,11 @@ static void dma_async_device_cleanup(struct kref *kref) | |||
359 | complete(&device->done); | 359 | complete(&device->done); |
360 | } | 360 | } |
361 | 361 | ||
362 | void dma_async_device_unregister(struct dma_device* device) | 362 | /** |
363 | * dma_async_device_unregister - unregisters DMA devices | ||
364 | * @device: &dma_device | ||
365 | */ | ||
366 | void dma_async_device_unregister(struct dma_device *device) | ||
363 | { | 367 | { |
364 | struct dma_chan *chan; | 368 | struct dma_chan *chan; |
365 | unsigned long flags; | 369 | unsigned long flags; |
diff --git a/drivers/dma/ioatdma.c b/drivers/dma/ioatdma.c index ecad8f65d2d4..78bf46d917b7 100644 --- a/drivers/dma/ioatdma.c +++ b/drivers/dma/ioatdma.c | |||
@@ -217,7 +217,7 @@ static void ioat_dma_free_chan_resources(struct dma_chan *chan) | |||
217 | 217 | ||
218 | /** | 218 | /** |
219 | * do_ioat_dma_memcpy - actual function that initiates a IOAT DMA transaction | 219 | * do_ioat_dma_memcpy - actual function that initiates a IOAT DMA transaction |
220 | * @chan: IOAT DMA channel handle | 220 | * @ioat_chan: IOAT DMA channel handle |
221 | * @dest: DMA destination address | 221 | * @dest: DMA destination address |
222 | * @src: DMA source address | 222 | * @src: DMA source address |
223 | * @len: transaction length in bytes | 223 | * @len: transaction length in bytes |
@@ -383,7 +383,7 @@ static dma_cookie_t ioat_dma_memcpy_buf_to_pg(struct dma_chan *chan, | |||
383 | * @dest_off: offset into that page | 383 | * @dest_off: offset into that page |
384 | * @src_pg: pointer to the page to copy from | 384 | * @src_pg: pointer to the page to copy from |
385 | * @src_off: offset into that page | 385 | * @src_off: offset into that page |
386 | * @len: transaction length in bytes. This is guaranteed to not make a copy | 386 | * @len: transaction length in bytes. This is guaranteed not to make a copy |
387 | * across a page boundary. | 387 | * across a page boundary. |
388 | */ | 388 | */ |
389 | 389 | ||
@@ -407,7 +407,7 @@ static dma_cookie_t ioat_dma_memcpy_pg_to_pg(struct dma_chan *chan, | |||
407 | } | 407 | } |
408 | 408 | ||
409 | /** | 409 | /** |
410 | * ioat_dma_memcpy_issue_pending - push potentially unrecognoized appended descriptors to hw | 410 | * ioat_dma_memcpy_issue_pending - push potentially unrecognized appended descriptors to hw |
411 | * @chan: DMA channel handle | 411 | * @chan: DMA channel handle |
412 | */ | 412 | */ |
413 | 413 | ||
@@ -510,6 +510,8 @@ static void ioat_dma_memcpy_cleanup(struct ioat_dma_chan *chan) | |||
510 | * ioat_dma_is_complete - poll the status of a IOAT DMA transaction | 510 | * ioat_dma_is_complete - poll the status of a IOAT DMA transaction |
511 | * @chan: IOAT DMA channel handle | 511 | * @chan: IOAT DMA channel handle |
512 | * @cookie: DMA transaction identifier | 512 | * @cookie: DMA transaction identifier |
513 | * @done: if not %NULL, updated with last completed transaction | ||
514 | * @used: if not %NULL, updated with last used transaction | ||
513 | */ | 515 | */ |
514 | 516 | ||
515 | static enum dma_status ioat_dma_is_complete(struct dma_chan *chan, | 517 | static enum dma_status ioat_dma_is_complete(struct dma_chan *chan, |
@@ -826,7 +828,7 @@ static int __init ioat_init_module(void) | |||
826 | /* if forced, worst case is that rmmod hangs */ | 828 | /* if forced, worst case is that rmmod hangs */ |
827 | __unsafe(THIS_MODULE); | 829 | __unsafe(THIS_MODULE); |
828 | 830 | ||
829 | pci_module_init(&ioat_pci_drv); | 831 | return pci_module_init(&ioat_pci_drv); |
830 | } | 832 | } |
831 | 833 | ||
832 | module_init(ioat_init_module); | 834 | module_init(ioat_init_module); |
diff --git a/drivers/dma/ioatdma_registers.h b/drivers/dma/ioatdma_registers.h index 41a21ab2b000..a30c7349075a 100644 --- a/drivers/dma/ioatdma_registers.h +++ b/drivers/dma/ioatdma_registers.h | |||
@@ -76,7 +76,7 @@ | |||
76 | #define IOAT_CHANSTS_OFFSET 0x04 /* 64-bit Channel Status Register */ | 76 | #define IOAT_CHANSTS_OFFSET 0x04 /* 64-bit Channel Status Register */ |
77 | #define IOAT_CHANSTS_OFFSET_LOW 0x04 | 77 | #define IOAT_CHANSTS_OFFSET_LOW 0x04 |
78 | #define IOAT_CHANSTS_OFFSET_HIGH 0x08 | 78 | #define IOAT_CHANSTS_OFFSET_HIGH 0x08 |
79 | #define IOAT_CHANSTS_COMPLETED_DESCRIPTOR_ADDR 0xFFFFFFFFFFFFFFC0 | 79 | #define IOAT_CHANSTS_COMPLETED_DESCRIPTOR_ADDR 0xFFFFFFFFFFFFFFC0UL |
80 | #define IOAT_CHANSTS_SOFT_ERR 0x0000000000000010 | 80 | #define IOAT_CHANSTS_SOFT_ERR 0x0000000000000010 |
81 | #define IOAT_CHANSTS_DMA_TRANSFER_STATUS 0x0000000000000007 | 81 | #define IOAT_CHANSTS_DMA_TRANSFER_STATUS 0x0000000000000007 |
82 | #define IOAT_CHANSTS_DMA_TRANSFER_STATUS_ACTIVE 0x0 | 82 | #define IOAT_CHANSTS_DMA_TRANSFER_STATUS_ACTIVE 0x0 |
diff --git a/drivers/dma/iovlock.c b/drivers/dma/iovlock.c index 5ed327e453a2..d637555a833b 100644 --- a/drivers/dma/iovlock.c +++ b/drivers/dma/iovlock.c | |||
@@ -31,7 +31,7 @@ | |||
31 | #include <asm/io.h> | 31 | #include <asm/io.h> |
32 | #include <asm/uaccess.h> | 32 | #include <asm/uaccess.h> |
33 | 33 | ||
34 | int num_pages_spanned(struct iovec *iov) | 34 | static int num_pages_spanned(struct iovec *iov) |
35 | { | 35 | { |
36 | return | 36 | return |
37 | ((PAGE_ALIGN((unsigned long)iov->iov_base + iov->iov_len) - | 37 | ((PAGE_ALIGN((unsigned long)iov->iov_base + iov->iov_len) - |
diff --git a/drivers/ide/ide-floppy.c b/drivers/ide/ide-floppy.c index 6ca3476d02c7..adbe9f76a505 100644 --- a/drivers/ide/ide-floppy.c +++ b/drivers/ide/ide-floppy.c | |||
@@ -838,7 +838,7 @@ static ide_startstop_t idefloppy_pc_intr (ide_drive_t *drive) | |||
838 | "transferred\n", pc->actually_transferred); | 838 | "transferred\n", pc->actually_transferred); |
839 | clear_bit(PC_DMA_IN_PROGRESS, &pc->flags); | 839 | clear_bit(PC_DMA_IN_PROGRESS, &pc->flags); |
840 | 840 | ||
841 | local_irq_enable(); | 841 | local_irq_enable_in_hardirq(); |
842 | 842 | ||
843 | if (status.b.check || test_bit(PC_DMA_ERROR, &pc->flags)) { | 843 | if (status.b.check || test_bit(PC_DMA_ERROR, &pc->flags)) { |
844 | /* Error detected */ | 844 | /* Error detected */ |
diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c index 7dba9992ad30..fb6795236e76 100644 --- a/drivers/ide/ide-io.c +++ b/drivers/ide/ide-io.c | |||
@@ -693,7 +693,7 @@ static ide_startstop_t drive_cmd_intr (ide_drive_t *drive) | |||
693 | u8 stat = hwif->INB(IDE_STATUS_REG); | 693 | u8 stat = hwif->INB(IDE_STATUS_REG); |
694 | int retries = 10; | 694 | int retries = 10; |
695 | 695 | ||
696 | local_irq_enable(); | 696 | local_irq_enable_in_hardirq(); |
697 | if ((stat & DRQ_STAT) && args && args[3]) { | 697 | if ((stat & DRQ_STAT) && args && args[3]) { |
698 | u8 io_32bit = drive->io_32bit; | 698 | u8 io_32bit = drive->io_32bit; |
699 | drive->io_32bit = 0; | 699 | drive->io_32bit = 0; |
@@ -1286,7 +1286,7 @@ static void ide_do_request (ide_hwgroup_t *hwgroup, int masked_irq) | |||
1286 | if (masked_irq != IDE_NO_IRQ && hwif->irq != masked_irq) | 1286 | if (masked_irq != IDE_NO_IRQ && hwif->irq != masked_irq) |
1287 | disable_irq_nosync(hwif->irq); | 1287 | disable_irq_nosync(hwif->irq); |
1288 | spin_unlock(&ide_lock); | 1288 | spin_unlock(&ide_lock); |
1289 | local_irq_enable(); | 1289 | local_irq_enable_in_hardirq(); |
1290 | /* allow other IRQs while we start this request */ | 1290 | /* allow other IRQs while we start this request */ |
1291 | startstop = start_request(drive, rq); | 1291 | startstop = start_request(drive, rq); |
1292 | spin_lock_irq(&ide_lock); | 1292 | spin_lock_irq(&ide_lock); |
@@ -1631,7 +1631,7 @@ irqreturn_t ide_intr (int irq, void *dev_id, struct pt_regs *regs) | |||
1631 | spin_unlock(&ide_lock); | 1631 | spin_unlock(&ide_lock); |
1632 | 1632 | ||
1633 | if (drive->unmask) | 1633 | if (drive->unmask) |
1634 | local_irq_enable(); | 1634 | local_irq_enable_in_hardirq(); |
1635 | /* service this interrupt, may set handler for next interrupt */ | 1635 | /* service this interrupt, may set handler for next interrupt */ |
1636 | startstop = handler(drive); | 1636 | startstop = handler(drive); |
1637 | spin_lock_irq(&ide_lock); | 1637 | spin_lock_irq(&ide_lock); |
@@ -1705,7 +1705,7 @@ int ide_do_drive_cmd (ide_drive_t *drive, struct request *rq, ide_action_t actio | |||
1705 | { | 1705 | { |
1706 | unsigned long flags; | 1706 | unsigned long flags; |
1707 | ide_hwgroup_t *hwgroup = HWGROUP(drive); | 1707 | ide_hwgroup_t *hwgroup = HWGROUP(drive); |
1708 | DECLARE_COMPLETION(wait); | 1708 | DECLARE_COMPLETION_ONSTACK(wait); |
1709 | int where = ELEVATOR_INSERT_BACK, err; | 1709 | int where = ELEVATOR_INSERT_BACK, err; |
1710 | int must_wait = (action == ide_wait || action == ide_head_wait); | 1710 | int must_wait = (action == ide_wait || action == ide_head_wait); |
1711 | 1711 | ||
diff --git a/drivers/ide/ide-taskfile.c b/drivers/ide/ide-taskfile.c index 04547eb0833f..97a9244312fc 100644 --- a/drivers/ide/ide-taskfile.c +++ b/drivers/ide/ide-taskfile.c | |||
@@ -222,7 +222,7 @@ ide_startstop_t task_no_data_intr (ide_drive_t *drive) | |||
222 | ide_hwif_t *hwif = HWIF(drive); | 222 | ide_hwif_t *hwif = HWIF(drive); |
223 | u8 stat; | 223 | u8 stat; |
224 | 224 | ||
225 | local_irq_enable(); | 225 | local_irq_enable_in_hardirq(); |
226 | if (!OK_STAT(stat = hwif->INB(IDE_STATUS_REG),READY_STAT,BAD_STAT)) { | 226 | if (!OK_STAT(stat = hwif->INB(IDE_STATUS_REG),READY_STAT,BAD_STAT)) { |
227 | return ide_error(drive, "task_no_data_intr", stat); | 227 | return ide_error(drive, "task_no_data_intr", stat); |
228 | /* calls ide_end_drive_cmd */ | 228 | /* calls ide_end_drive_cmd */ |
diff --git a/drivers/ieee1394/hosts.c b/drivers/ieee1394/hosts.c index 2c669287f5bd..4feead4a35c5 100644 --- a/drivers/ieee1394/hosts.c +++ b/drivers/ieee1394/hosts.c | |||
@@ -107,6 +107,14 @@ static int alloc_hostnum_cb(struct hpsb_host *host, void *__data) | |||
107 | */ | 107 | */ |
108 | static DEFINE_MUTEX(host_num_alloc); | 108 | static DEFINE_MUTEX(host_num_alloc); |
109 | 109 | ||
110 | /* | ||
111 | * The pending_packet_queue is special in that it's processed | ||
112 | * from hardirq context too (such as hpsb_bus_reset()). Hence | ||
113 | * split the lock class from the usual networking skb-head | ||
114 | * lock class by using a separate key for it: | ||
115 | */ | ||
116 | static struct lock_class_key pending_packet_queue_key; | ||
117 | |||
110 | struct hpsb_host *hpsb_alloc_host(struct hpsb_host_driver *drv, size_t extra, | 118 | struct hpsb_host *hpsb_alloc_host(struct hpsb_host_driver *drv, size_t extra, |
111 | struct device *dev) | 119 | struct device *dev) |
112 | { | 120 | { |
@@ -128,6 +136,8 @@ struct hpsb_host *hpsb_alloc_host(struct hpsb_host_driver *drv, size_t extra, | |||
128 | h->driver = drv; | 136 | h->driver = drv; |
129 | 137 | ||
130 | skb_queue_head_init(&h->pending_packet_queue); | 138 | skb_queue_head_init(&h->pending_packet_queue); |
139 | lockdep_set_class(&h->pending_packet_queue.lock, | ||
140 | &pending_packet_queue_key); | ||
131 | INIT_LIST_HEAD(&h->addr_space); | 141 | INIT_LIST_HEAD(&h->addr_space); |
132 | 142 | ||
133 | for (i = 2; i < 16; i++) | 143 | for (i = 2; i < 16; i++) |
diff --git a/drivers/infiniband/hw/mthca/mthca_qp.c b/drivers/infiniband/hw/mthca/mthca_qp.c index 16c387d8170c..490fc783bb0c 100644 --- a/drivers/infiniband/hw/mthca/mthca_qp.c +++ b/drivers/infiniband/hw/mthca/mthca_qp.c | |||
@@ -224,7 +224,7 @@ static void *get_send_wqe(struct mthca_qp *qp, int n) | |||
224 | 224 | ||
225 | static void mthca_wq_init(struct mthca_wq *wq) | 225 | static void mthca_wq_init(struct mthca_wq *wq) |
226 | { | 226 | { |
227 | spin_lock_init(&wq->lock); | 227 | /* mthca_alloc_qp_common() initializes the locks */ |
228 | wq->next_ind = 0; | 228 | wq->next_ind = 0; |
229 | wq->last_comp = wq->max - 1; | 229 | wq->last_comp = wq->max - 1; |
230 | wq->head = 0; | 230 | wq->head = 0; |
@@ -1114,6 +1114,9 @@ static int mthca_alloc_qp_common(struct mthca_dev *dev, | |||
1114 | qp->sq_policy = send_policy; | 1114 | qp->sq_policy = send_policy; |
1115 | mthca_wq_init(&qp->sq); | 1115 | mthca_wq_init(&qp->sq); |
1116 | mthca_wq_init(&qp->rq); | 1116 | mthca_wq_init(&qp->rq); |
1117 | /* these are initialized separately so lockdep can tell them apart */ | ||
1118 | spin_lock_init(&qp->sq.lock); | ||
1119 | spin_lock_init(&qp->rq.lock); | ||
1117 | 1120 | ||
1118 | ret = mthca_map_memfree(dev, qp); | 1121 | ret = mthca_map_memfree(dev, qp); |
1119 | if (ret) | 1122 | if (ret) |
diff --git a/drivers/infiniband/ulp/iser/iscsi_iser.c b/drivers/infiniband/ulp/iser/iscsi_iser.c index b2c033edb03c..34b0da5cfa0a 100644 --- a/drivers/infiniband/ulp/iser/iscsi_iser.c +++ b/drivers/infiniband/ulp/iser/iscsi_iser.c | |||
@@ -437,159 +437,50 @@ iscsi_iser_session_create(struct iscsi_transport *iscsit, | |||
437 | } | 437 | } |
438 | 438 | ||
439 | static int | 439 | static int |
440 | iscsi_iser_conn_set_param(struct iscsi_cls_conn *cls_conn, | 440 | iscsi_iser_set_param(struct iscsi_cls_conn *cls_conn, |
441 | enum iscsi_param param, uint32_t value) | 441 | enum iscsi_param param, char *buf, int buflen) |
442 | { | 442 | { |
443 | struct iscsi_conn *conn = cls_conn->dd_data; | 443 | int value; |
444 | struct iscsi_session *session = conn->session; | ||
445 | |||
446 | spin_lock_bh(&session->lock); | ||
447 | if (conn->c_stage != ISCSI_CONN_INITIAL_STAGE && | ||
448 | conn->stop_stage != STOP_CONN_RECOVER) { | ||
449 | printk(KERN_ERR "iscsi_iser: can not change parameter [%d]\n", | ||
450 | param); | ||
451 | spin_unlock_bh(&session->lock); | ||
452 | return 0; | ||
453 | } | ||
454 | spin_unlock_bh(&session->lock); | ||
455 | 444 | ||
456 | switch (param) { | 445 | switch (param) { |
457 | case ISCSI_PARAM_MAX_RECV_DLENGTH: | 446 | case ISCSI_PARAM_MAX_RECV_DLENGTH: |
458 | /* TBD */ | 447 | /* TBD */ |
459 | break; | 448 | break; |
460 | case ISCSI_PARAM_MAX_XMIT_DLENGTH: | ||
461 | conn->max_xmit_dlength = value; | ||
462 | break; | ||
463 | case ISCSI_PARAM_HDRDGST_EN: | 449 | case ISCSI_PARAM_HDRDGST_EN: |
450 | sscanf(buf, "%d", &value); | ||
464 | if (value) { | 451 | if (value) { |
465 | printk(KERN_ERR "DataDigest wasn't negotiated to None"); | 452 | printk(KERN_ERR "DataDigest wasn't negotiated to None"); |
466 | return -EPROTO; | 453 | return -EPROTO; |
467 | } | 454 | } |
468 | break; | 455 | break; |
469 | case ISCSI_PARAM_DATADGST_EN: | 456 | case ISCSI_PARAM_DATADGST_EN: |
457 | sscanf(buf, "%d", &value); | ||
470 | if (value) { | 458 | if (value) { |
471 | printk(KERN_ERR "DataDigest wasn't negotiated to None"); | 459 | printk(KERN_ERR "DataDigest wasn't negotiated to None"); |
472 | return -EPROTO; | 460 | return -EPROTO; |
473 | } | 461 | } |
474 | break; | 462 | break; |
475 | case ISCSI_PARAM_INITIAL_R2T_EN: | ||
476 | session->initial_r2t_en = value; | ||
477 | break; | ||
478 | case ISCSI_PARAM_IMM_DATA_EN: | ||
479 | session->imm_data_en = value; | ||
480 | break; | ||
481 | case ISCSI_PARAM_FIRST_BURST: | ||
482 | session->first_burst = value; | ||
483 | break; | ||
484 | case ISCSI_PARAM_MAX_BURST: | ||
485 | session->max_burst = value; | ||
486 | break; | ||
487 | case ISCSI_PARAM_PDU_INORDER_EN: | ||
488 | session->pdu_inorder_en = value; | ||
489 | break; | ||
490 | case ISCSI_PARAM_DATASEQ_INORDER_EN: | ||
491 | session->dataseq_inorder_en = value; | ||
492 | break; | ||
493 | case ISCSI_PARAM_ERL: | ||
494 | session->erl = value; | ||
495 | break; | ||
496 | case ISCSI_PARAM_IFMARKER_EN: | 463 | case ISCSI_PARAM_IFMARKER_EN: |
464 | sscanf(buf, "%d", &value); | ||
497 | if (value) { | 465 | if (value) { |
498 | printk(KERN_ERR "IFMarker wasn't negotiated to No"); | 466 | printk(KERN_ERR "IFMarker wasn't negotiated to No"); |
499 | return -EPROTO; | 467 | return -EPROTO; |
500 | } | 468 | } |
501 | break; | 469 | break; |
502 | case ISCSI_PARAM_OFMARKER_EN: | 470 | case ISCSI_PARAM_OFMARKER_EN: |
471 | sscanf(buf, "%d", &value); | ||
503 | if (value) { | 472 | if (value) { |
504 | printk(KERN_ERR "OFMarker wasn't negotiated to No"); | 473 | printk(KERN_ERR "OFMarker wasn't negotiated to No"); |
505 | return -EPROTO; | 474 | return -EPROTO; |
506 | } | 475 | } |
507 | break; | 476 | break; |
508 | default: | 477 | default: |
509 | break; | 478 | return iscsi_set_param(cls_conn, param, buf, buflen); |
510 | } | ||
511 | |||
512 | return 0; | ||
513 | } | ||
514 | |||
515 | static int | ||
516 | iscsi_iser_session_get_param(struct iscsi_cls_session *cls_session, | ||
517 | enum iscsi_param param, uint32_t *value) | ||
518 | { | ||
519 | struct Scsi_Host *shost = iscsi_session_to_shost(cls_session); | ||
520 | struct iscsi_session *session = iscsi_hostdata(shost->hostdata); | ||
521 | |||
522 | switch (param) { | ||
523 | case ISCSI_PARAM_INITIAL_R2T_EN: | ||
524 | *value = session->initial_r2t_en; | ||
525 | break; | ||
526 | case ISCSI_PARAM_MAX_R2T: | ||
527 | *value = session->max_r2t; | ||
528 | break; | ||
529 | case ISCSI_PARAM_IMM_DATA_EN: | ||
530 | *value = session->imm_data_en; | ||
531 | break; | ||
532 | case ISCSI_PARAM_FIRST_BURST: | ||
533 | *value = session->first_burst; | ||
534 | break; | ||
535 | case ISCSI_PARAM_MAX_BURST: | ||
536 | *value = session->max_burst; | ||
537 | break; | ||
538 | case ISCSI_PARAM_PDU_INORDER_EN: | ||
539 | *value = session->pdu_inorder_en; | ||
540 | break; | ||
541 | case ISCSI_PARAM_DATASEQ_INORDER_EN: | ||
542 | *value = session->dataseq_inorder_en; | ||
543 | break; | ||
544 | case ISCSI_PARAM_ERL: | ||
545 | *value = session->erl; | ||
546 | break; | ||
547 | case ISCSI_PARAM_IFMARKER_EN: | ||
548 | *value = 0; | ||
549 | break; | ||
550 | case ISCSI_PARAM_OFMARKER_EN: | ||
551 | *value = 0; | ||
552 | break; | ||
553 | default: | ||
554 | return ISCSI_ERR_PARAM_NOT_FOUND; | ||
555 | } | ||
556 | |||
557 | return 0; | ||
558 | } | ||
559 | |||
560 | static int | ||
561 | iscsi_iser_conn_get_param(struct iscsi_cls_conn *cls_conn, | ||
562 | enum iscsi_param param, uint32_t *value) | ||
563 | { | ||
564 | struct iscsi_conn *conn = cls_conn->dd_data; | ||
565 | |||
566 | switch(param) { | ||
567 | case ISCSI_PARAM_MAX_RECV_DLENGTH: | ||
568 | *value = conn->max_recv_dlength; | ||
569 | break; | ||
570 | case ISCSI_PARAM_MAX_XMIT_DLENGTH: | ||
571 | *value = conn->max_xmit_dlength; | ||
572 | break; | ||
573 | case ISCSI_PARAM_HDRDGST_EN: | ||
574 | *value = 0; | ||
575 | break; | ||
576 | case ISCSI_PARAM_DATADGST_EN: | ||
577 | *value = 0; | ||
578 | break; | ||
579 | /*case ISCSI_PARAM_TARGET_RECV_DLENGTH: | ||
580 | *value = conn->target_recv_dlength; | ||
581 | break; | ||
582 | case ISCSI_PARAM_INITIATOR_RECV_DLENGTH: | ||
583 | *value = conn->initiator_recv_dlength; | ||
584 | break;*/ | ||
585 | default: | ||
586 | return ISCSI_ERR_PARAM_NOT_FOUND; | ||
587 | } | 479 | } |
588 | 480 | ||
589 | return 0; | 481 | return 0; |
590 | } | 482 | } |
591 | 483 | ||
592 | |||
593 | static void | 484 | static void |
594 | iscsi_iser_conn_get_stats(struct iscsi_cls_conn *cls_conn, struct iscsi_stats *stats) | 485 | iscsi_iser_conn_get_stats(struct iscsi_cls_conn *cls_conn, struct iscsi_stats *stats) |
595 | { | 486 | { |
@@ -701,7 +592,12 @@ static struct iscsi_transport iscsi_iser_transport = { | |||
701 | ISCSI_FIRST_BURST | | 592 | ISCSI_FIRST_BURST | |
702 | ISCSI_MAX_BURST | | 593 | ISCSI_MAX_BURST | |
703 | ISCSI_PDU_INORDER_EN | | 594 | ISCSI_PDU_INORDER_EN | |
704 | ISCSI_DATASEQ_INORDER_EN, | 595 | ISCSI_DATASEQ_INORDER_EN | |
596 | ISCSI_EXP_STATSN | | ||
597 | ISCSI_PERSISTENT_PORT | | ||
598 | ISCSI_PERSISTENT_ADDRESS | | ||
599 | ISCSI_TARGET_NAME | | ||
600 | ISCSI_TPGT, | ||
705 | .host_template = &iscsi_iser_sht, | 601 | .host_template = &iscsi_iser_sht, |
706 | .conndata_size = sizeof(struct iscsi_conn), | 602 | .conndata_size = sizeof(struct iscsi_conn), |
707 | .max_lun = ISCSI_ISER_MAX_LUN, | 603 | .max_lun = ISCSI_ISER_MAX_LUN, |
@@ -713,9 +609,9 @@ static struct iscsi_transport iscsi_iser_transport = { | |||
713 | .create_conn = iscsi_iser_conn_create, | 609 | .create_conn = iscsi_iser_conn_create, |
714 | .bind_conn = iscsi_iser_conn_bind, | 610 | .bind_conn = iscsi_iser_conn_bind, |
715 | .destroy_conn = iscsi_iser_conn_destroy, | 611 | .destroy_conn = iscsi_iser_conn_destroy, |
716 | .set_param = iscsi_iser_conn_set_param, | 612 | .set_param = iscsi_iser_set_param, |
717 | .get_conn_param = iscsi_iser_conn_get_param, | 613 | .get_conn_param = iscsi_conn_get_param, |
718 | .get_session_param = iscsi_iser_session_get_param, | 614 | .get_session_param = iscsi_session_get_param, |
719 | .start_conn = iscsi_iser_conn_start, | 615 | .start_conn = iscsi_iser_conn_start, |
720 | .stop_conn = iscsi_conn_stop, | 616 | .stop_conn = iscsi_conn_stop, |
721 | /* these are called as part of conn recovery */ | 617 | /* these are called as part of conn recovery */ |
diff --git a/drivers/input/serio/i8042-sparcio.h b/drivers/input/serio/i8042-sparcio.h index 7d9fafea9615..54adba2d8ed5 100644 --- a/drivers/input/serio/i8042-sparcio.h +++ b/drivers/input/serio/i8042-sparcio.h | |||
@@ -88,7 +88,7 @@ static struct of_device_id sparc_i8042_match[] = { | |||
88 | }, | 88 | }, |
89 | {}, | 89 | {}, |
90 | }; | 90 | }; |
91 | MODULE_DEVICE_TABLE(of, i8042_match); | 91 | MODULE_DEVICE_TABLE(of, sparc_i8042_match); |
92 | 92 | ||
93 | static struct of_platform_driver sparc_i8042_driver = { | 93 | static struct of_platform_driver sparc_i8042_driver = { |
94 | .name = "i8042", | 94 | .name = "i8042", |
diff --git a/drivers/input/serio/libps2.c b/drivers/input/serio/libps2.c index 79c97f94bcbd..61a6f977846f 100644 --- a/drivers/input/serio/libps2.c +++ b/drivers/input/serio/libps2.c | |||
@@ -177,7 +177,7 @@ int ps2_command(struct ps2dev *ps2dev, unsigned char *param, int command) | |||
177 | return -1; | 177 | return -1; |
178 | } | 178 | } |
179 | 179 | ||
180 | mutex_lock(&ps2dev->cmd_mutex); | 180 | mutex_lock_nested(&ps2dev->cmd_mutex, SINGLE_DEPTH_NESTING); |
181 | 181 | ||
182 | serio_pause_rx(ps2dev->serio); | 182 | serio_pause_rx(ps2dev->serio); |
183 | ps2dev->flags = command == PS2_CMD_GETID ? PS2_FLAG_WAITID : 0; | 183 | ps2dev->flags = command == PS2_CMD_GETID ? PS2_FLAG_WAITID : 0; |
diff --git a/drivers/macintosh/macio-adb.c b/drivers/macintosh/macio-adb.c index 314fc0830d90..4b08852c35ee 100644 --- a/drivers/macintosh/macio-adb.c +++ b/drivers/macintosh/macio-adb.c | |||
@@ -90,22 +90,12 @@ int macio_init(void) | |||
90 | { | 90 | { |
91 | struct device_node *adbs; | 91 | struct device_node *adbs; |
92 | struct resource r; | 92 | struct resource r; |
93 | unsigned int irq; | ||
93 | 94 | ||
94 | adbs = find_compatible_devices("adb", "chrp,adb0"); | 95 | adbs = find_compatible_devices("adb", "chrp,adb0"); |
95 | if (adbs == 0) | 96 | if (adbs == 0) |
96 | return -ENXIO; | 97 | return -ENXIO; |
97 | 98 | ||
98 | #if 0 | ||
99 | { int i = 0; | ||
100 | |||
101 | printk("macio_adb_init: node = %p, addrs =", adbs->node); | ||
102 | while(!of_address_to_resource(adbs, i, &r)) | ||
103 | printk(" %x(%x)", r.start, r.end - r.start); | ||
104 | printk(", intrs ="); | ||
105 | for (i = 0; i < adbs->n_intrs; ++i) | ||
106 | printk(" %x", adbs->intrs[i].line); | ||
107 | printk("\n"); } | ||
108 | #endif | ||
109 | if (of_address_to_resource(adbs, 0, &r)) | 99 | if (of_address_to_resource(adbs, 0, &r)) |
110 | return -ENXIO; | 100 | return -ENXIO; |
111 | adb = ioremap(r.start, sizeof(struct adb_regs)); | 101 | adb = ioremap(r.start, sizeof(struct adb_regs)); |
@@ -117,10 +107,9 @@ int macio_init(void) | |||
117 | out_8(&adb->active_lo.r, 0xff); | 107 | out_8(&adb->active_lo.r, 0xff); |
118 | out_8(&adb->autopoll.r, APE); | 108 | out_8(&adb->autopoll.r, APE); |
119 | 109 | ||
120 | if (request_irq(adbs->intrs[0].line, macio_adb_interrupt, | 110 | irq = irq_of_parse_and_map(adbs, 0); |
121 | 0, "ADB", (void *)0)) { | 111 | if (request_irq(irq, macio_adb_interrupt, 0, "ADB", (void *)0)) { |
122 | printk(KERN_ERR "ADB: can't get irq %d\n", | 112 | printk(KERN_ERR "ADB: can't get irq %d\n", irq); |
123 | adbs->intrs[0].line); | ||
124 | return -EAGAIN; | 113 | return -EAGAIN; |
125 | } | 114 | } |
126 | out_8(&adb->intr_enb.r, DFB | TAG); | 115 | out_8(&adb->intr_enb.r, DFB | TAG); |
diff --git a/drivers/macintosh/macio_asic.c b/drivers/macintosh/macio_asic.c index 40ae7b6a939d..80c0c665b5f6 100644 --- a/drivers/macintosh/macio_asic.c +++ b/drivers/macintosh/macio_asic.c | |||
@@ -280,75 +280,128 @@ static void macio_release_dev(struct device *dev) | |||
280 | static int macio_resource_quirks(struct device_node *np, struct resource *res, | 280 | static int macio_resource_quirks(struct device_node *np, struct resource *res, |
281 | int index) | 281 | int index) |
282 | { | 282 | { |
283 | if (res->flags & IORESOURCE_MEM) { | 283 | /* Only quirks for memory resources for now */ |
284 | /* Grand Central has too large resource 0 on some machines */ | 284 | if ((res->flags & IORESOURCE_MEM) == 0) |
285 | if (index == 0 && !strcmp(np->name, "gc")) | 285 | return 0; |
286 | res->end = res->start + 0x1ffff; | 286 | |
287 | /* Grand Central has too large resource 0 on some machines */ | ||
288 | if (index == 0 && !strcmp(np->name, "gc")) | ||
289 | res->end = res->start + 0x1ffff; | ||
287 | 290 | ||
288 | /* Airport has bogus resource 2 */ | 291 | /* Airport has bogus resource 2 */ |
289 | if (index >= 2 && !strcmp(np->name, "radio")) | 292 | if (index >= 2 && !strcmp(np->name, "radio")) |
290 | return 1; | 293 | return 1; |
291 | 294 | ||
292 | #ifndef CONFIG_PPC64 | 295 | #ifndef CONFIG_PPC64 |
293 | /* DBDMAs may have bogus sizes */ | 296 | /* DBDMAs may have bogus sizes */ |
294 | if ((res->start & 0x0001f000) == 0x00008000) | 297 | if ((res->start & 0x0001f000) == 0x00008000) |
295 | res->end = res->start + 0xff; | 298 | res->end = res->start + 0xff; |
296 | #endif /* CONFIG_PPC64 */ | 299 | #endif /* CONFIG_PPC64 */ |
297 | 300 | ||
298 | /* ESCC parent eats child resources. We could have added a | 301 | /* ESCC parent eats child resources. We could have added a |
299 | * level of hierarchy, but I don't really feel the need | 302 | * level of hierarchy, but I don't really feel the need |
300 | * for it | 303 | * for it |
301 | */ | 304 | */ |
302 | if (!strcmp(np->name, "escc")) | 305 | if (!strcmp(np->name, "escc")) |
303 | return 1; | 306 | return 1; |
304 | 307 | ||
305 | /* ESCC has bogus resources >= 3 */ | 308 | /* ESCC has bogus resources >= 3 */ |
306 | if (index >= 3 && !(strcmp(np->name, "ch-a") && | 309 | if (index >= 3 && !(strcmp(np->name, "ch-a") && |
307 | strcmp(np->name, "ch-b"))) | 310 | strcmp(np->name, "ch-b"))) |
308 | return 1; | 311 | return 1; |
309 | 312 | ||
310 | /* Media bay has too many resources, keep only first one */ | 313 | /* Media bay has too many resources, keep only first one */ |
311 | if (index > 0 && !strcmp(np->name, "media-bay")) | 314 | if (index > 0 && !strcmp(np->name, "media-bay")) |
312 | return 1; | 315 | return 1; |
313 | 316 | ||
314 | /* Some older IDE resources have bogus sizes */ | 317 | /* Some older IDE resources have bogus sizes */ |
315 | if (!(strcmp(np->name, "IDE") && strcmp(np->name, "ATA") && | 318 | if (!(strcmp(np->name, "IDE") && strcmp(np->name, "ATA") && |
316 | strcmp(np->type, "ide") && strcmp(np->type, "ata"))) { | 319 | strcmp(np->type, "ide") && strcmp(np->type, "ata"))) { |
317 | if (index == 0 && (res->end - res->start) > 0xfff) | 320 | if (index == 0 && (res->end - res->start) > 0xfff) |
318 | res->end = res->start + 0xfff; | 321 | res->end = res->start + 0xfff; |
319 | if (index == 1 && (res->end - res->start) > 0xff) | 322 | if (index == 1 && (res->end - res->start) > 0xff) |
320 | res->end = res->start + 0xff; | 323 | res->end = res->start + 0xff; |
321 | } | ||
322 | } | 324 | } |
323 | return 0; | 325 | return 0; |
324 | } | 326 | } |
325 | 327 | ||
328 | static void macio_create_fixup_irq(struct macio_dev *dev, int index, | ||
329 | unsigned int line) | ||
330 | { | ||
331 | unsigned int irq; | ||
326 | 332 | ||
327 | static void macio_setup_interrupts(struct macio_dev *dev) | 333 | irq = irq_create_mapping(NULL, line, 0); |
334 | if (irq != NO_IRQ) { | ||
335 | dev->interrupt[index].start = irq; | ||
336 | dev->interrupt[index].flags = IORESOURCE_IRQ; | ||
337 | dev->interrupt[index].name = dev->ofdev.dev.bus_id; | ||
338 | } | ||
339 | if (dev->n_interrupts <= index) | ||
340 | dev->n_interrupts = index + 1; | ||
341 | } | ||
342 | |||
343 | static void macio_add_missing_resources(struct macio_dev *dev) | ||
328 | { | 344 | { |
329 | struct device_node *np = dev->ofdev.node; | 345 | struct device_node *np = dev->ofdev.node; |
330 | int i,j; | 346 | unsigned int irq_base; |
347 | |||
348 | /* Gatwick has some missing interrupts on child nodes */ | ||
349 | if (dev->bus->chip->type != macio_gatwick) | ||
350 | return; | ||
331 | 351 | ||
332 | /* For now, we use pre-parsed entries in the device-tree for | 352 | /* irq_base is always 64 on gatwick. I have no cleaner way to get |
333 | * interrupt routing and addresses, but we should change that | 353 | * that value from here at this point |
334 | * to dynamically parsed entries and so get rid of most of the | ||
335 | * clutter in struct device_node | ||
336 | */ | 354 | */ |
337 | for (i = j = 0; i < np->n_intrs; i++) { | 355 | irq_base = 64; |
356 | |||
357 | /* Fix SCC */ | ||
358 | if (strcmp(np->name, "ch-a") == 0) { | ||
359 | macio_create_fixup_irq(dev, 0, 15 + irq_base); | ||
360 | macio_create_fixup_irq(dev, 1, 4 + irq_base); | ||
361 | macio_create_fixup_irq(dev, 2, 5 + irq_base); | ||
362 | printk(KERN_INFO "macio: fixed SCC irqs on gatwick\n"); | ||
363 | } | ||
364 | |||
365 | /* Fix media-bay */ | ||
366 | if (strcmp(np->name, "media-bay") == 0) { | ||
367 | macio_create_fixup_irq(dev, 0, 29 + irq_base); | ||
368 | printk(KERN_INFO "macio: fixed media-bay irq on gatwick\n"); | ||
369 | } | ||
370 | |||
371 | /* Fix left media bay childs */ | ||
372 | if (dev->media_bay != NULL && strcmp(np->name, "floppy") == 0) { | ||
373 | macio_create_fixup_irq(dev, 0, 19 + irq_base); | ||
374 | macio_create_fixup_irq(dev, 1, 1 + irq_base); | ||
375 | printk(KERN_INFO "macio: fixed left floppy irqs\n"); | ||
376 | } | ||
377 | if (dev->media_bay != NULL && strcasecmp(np->name, "ata4") == 0) { | ||
378 | macio_create_fixup_irq(dev, 0, 14 + irq_base); | ||
379 | macio_create_fixup_irq(dev, 0, 3 + irq_base); | ||
380 | printk(KERN_INFO "macio: fixed left ide irqs\n"); | ||
381 | } | ||
382 | } | ||
383 | |||
384 | static void macio_setup_interrupts(struct macio_dev *dev) | ||
385 | { | ||
386 | struct device_node *np = dev->ofdev.node; | ||
387 | unsigned int irq; | ||
388 | int i = 0, j = 0; | ||
389 | |||
390 | for (;;) { | ||
338 | struct resource *res = &dev->interrupt[j]; | 391 | struct resource *res = &dev->interrupt[j]; |
339 | 392 | ||
340 | if (j >= MACIO_DEV_COUNT_IRQS) | 393 | if (j >= MACIO_DEV_COUNT_IRQS) |
341 | break; | 394 | break; |
342 | res->start = np->intrs[i].line; | 395 | irq = irq_of_parse_and_map(np, i++); |
343 | res->flags = IORESOURCE_IO; | 396 | if (irq == NO_IRQ) |
344 | if (np->intrs[j].sense) | 397 | break; |
345 | res->flags |= IORESOURCE_IRQ_LOWLEVEL; | 398 | res->start = irq; |
346 | else | 399 | res->flags = IORESOURCE_IRQ; |
347 | res->flags |= IORESOURCE_IRQ_HIGHEDGE; | ||
348 | res->name = dev->ofdev.dev.bus_id; | 400 | res->name = dev->ofdev.dev.bus_id; |
349 | if (macio_resource_quirks(np, res, i)) | 401 | if (macio_resource_quirks(np, res, i - 1)) { |
350 | memset(res, 0, sizeof(struct resource)); | 402 | memset(res, 0, sizeof(struct resource)); |
351 | else | 403 | continue; |
404 | } else | ||
352 | j++; | 405 | j++; |
353 | } | 406 | } |
354 | dev->n_interrupts = j; | 407 | dev->n_interrupts = j; |
@@ -445,6 +498,7 @@ static struct macio_dev * macio_add_one_device(struct macio_chip *chip, | |||
445 | /* Setup interrupts & resources */ | 498 | /* Setup interrupts & resources */ |
446 | macio_setup_interrupts(dev); | 499 | macio_setup_interrupts(dev); |
447 | macio_setup_resources(dev, parent_res); | 500 | macio_setup_resources(dev, parent_res); |
501 | macio_add_missing_resources(dev); | ||
448 | 502 | ||
449 | /* Register with core */ | 503 | /* Register with core */ |
450 | if (of_device_register(&dev->ofdev) != 0) { | 504 | if (of_device_register(&dev->ofdev) != 0) { |
diff --git a/drivers/macintosh/smu.c b/drivers/macintosh/smu.c index ff6d9bfdc3d2..f139a74696fe 100644 --- a/drivers/macintosh/smu.c +++ b/drivers/macintosh/smu.c | |||
@@ -497,8 +497,7 @@ int __init smu_init (void) | |||
497 | smu->doorbell = *data; | 497 | smu->doorbell = *data; |
498 | if (smu->doorbell < 0x50) | 498 | if (smu->doorbell < 0x50) |
499 | smu->doorbell += 0x50; | 499 | smu->doorbell += 0x50; |
500 | if (np->n_intrs > 0) | 500 | smu->db_irq = irq_of_parse_and_map(np, 0); |
501 | smu->db_irq = np->intrs[0].line; | ||
502 | 501 | ||
503 | of_node_put(np); | 502 | of_node_put(np); |
504 | 503 | ||
@@ -515,8 +514,7 @@ int __init smu_init (void) | |||
515 | smu->msg = *data; | 514 | smu->msg = *data; |
516 | if (smu->msg < 0x50) | 515 | if (smu->msg < 0x50) |
517 | smu->msg += 0x50; | 516 | smu->msg += 0x50; |
518 | if (np->n_intrs > 0) | 517 | smu->msg_irq = irq_of_parse_and_map(np, 0); |
519 | smu->msg_irq = np->intrs[0].line; | ||
520 | of_node_put(np); | 518 | of_node_put(np); |
521 | } while(0); | 519 | } while(0); |
522 | 520 | ||
diff --git a/drivers/macintosh/via-cuda.c b/drivers/macintosh/via-cuda.c index 6501db50fb83..69d5452fd22f 100644 --- a/drivers/macintosh/via-cuda.c +++ b/drivers/macintosh/via-cuda.c | |||
@@ -34,13 +34,6 @@ | |||
34 | static volatile unsigned char __iomem *via; | 34 | static volatile unsigned char __iomem *via; |
35 | static DEFINE_SPINLOCK(cuda_lock); | 35 | static DEFINE_SPINLOCK(cuda_lock); |
36 | 36 | ||
37 | #ifdef CONFIG_MAC | ||
38 | #define CUDA_IRQ IRQ_MAC_ADB | ||
39 | #define eieio() | ||
40 | #else | ||
41 | #define CUDA_IRQ vias->intrs[0].line | ||
42 | #endif | ||
43 | |||
44 | /* VIA registers - spaced 0x200 bytes apart */ | 37 | /* VIA registers - spaced 0x200 bytes apart */ |
45 | #define RS 0x200 /* skip between registers */ | 38 | #define RS 0x200 /* skip between registers */ |
46 | #define B 0 /* B-side data */ | 39 | #define B 0 /* B-side data */ |
@@ -189,11 +182,24 @@ int __init find_via_cuda(void) | |||
189 | 182 | ||
190 | static int __init via_cuda_start(void) | 183 | static int __init via_cuda_start(void) |
191 | { | 184 | { |
185 | unsigned int irq; | ||
186 | |||
192 | if (via == NULL) | 187 | if (via == NULL) |
193 | return -ENODEV; | 188 | return -ENODEV; |
194 | 189 | ||
195 | if (request_irq(CUDA_IRQ, cuda_interrupt, 0, "ADB", cuda_interrupt)) { | 190 | #ifdef CONFIG_MAC |
196 | printk(KERN_ERR "cuda_init: can't get irq %d\n", CUDA_IRQ); | 191 | irq = IRQ_MAC_ADB; |
192 | #else /* CONFIG_MAC */ | ||
193 | irq = irq_of_parse_and_map(vias, 0); | ||
194 | if (irq == NO_IRQ) { | ||
195 | printk(KERN_ERR "via-cuda: can't map interrupts for %s\n", | ||
196 | vias->full_name); | ||
197 | return -ENODEV; | ||
198 | } | ||
199 | #endif /* CONFIG_MAP */ | ||
200 | |||
201 | if (request_irq(irq, cuda_interrupt, 0, "ADB", cuda_interrupt)) { | ||
202 | printk(KERN_ERR "via-cuda: can't request irq %d\n", irq); | ||
197 | return -EAGAIN; | 203 | return -EAGAIN; |
198 | } | 204 | } |
199 | 205 | ||
diff --git a/drivers/macintosh/via-pmu.c b/drivers/macintosh/via-pmu.c index c1193d34ec9e..06ca80bfd6b9 100644 --- a/drivers/macintosh/via-pmu.c +++ b/drivers/macintosh/via-pmu.c | |||
@@ -64,10 +64,6 @@ | |||
64 | #include <asm/backlight.h> | 64 | #include <asm/backlight.h> |
65 | #endif | 65 | #endif |
66 | 66 | ||
67 | #ifdef CONFIG_PPC32 | ||
68 | #include <asm/open_pic.h> | ||
69 | #endif | ||
70 | |||
71 | #include "via-pmu-event.h" | 67 | #include "via-pmu-event.h" |
72 | 68 | ||
73 | /* Some compile options */ | 69 | /* Some compile options */ |
@@ -151,7 +147,7 @@ static int pmu_fully_inited = 0; | |||
151 | static int pmu_has_adb; | 147 | static int pmu_has_adb; |
152 | static struct device_node *gpio_node; | 148 | static struct device_node *gpio_node; |
153 | static unsigned char __iomem *gpio_reg = NULL; | 149 | static unsigned char __iomem *gpio_reg = NULL; |
154 | static int gpio_irq = -1; | 150 | static int gpio_irq = NO_IRQ; |
155 | static int gpio_irq_enabled = -1; | 151 | static int gpio_irq_enabled = -1; |
156 | static volatile int pmu_suspended = 0; | 152 | static volatile int pmu_suspended = 0; |
157 | static spinlock_t pmu_lock; | 153 | static spinlock_t pmu_lock; |
@@ -403,22 +399,21 @@ static int __init pmu_init(void) | |||
403 | */ | 399 | */ |
404 | static int __init via_pmu_start(void) | 400 | static int __init via_pmu_start(void) |
405 | { | 401 | { |
402 | unsigned int irq; | ||
403 | |||
406 | if (vias == NULL) | 404 | if (vias == NULL) |
407 | return -ENODEV; | 405 | return -ENODEV; |
408 | 406 | ||
409 | batt_req.complete = 1; | 407 | batt_req.complete = 1; |
410 | 408 | ||
411 | #ifndef CONFIG_PPC_MERGE | 409 | irq = irq_of_parse_and_map(vias, 0); |
412 | if (pmu_kind == PMU_KEYLARGO_BASED) | 410 | if (irq == NO_IRQ) { |
413 | openpic_set_irq_priority(vias->intrs[0].line, | 411 | printk(KERN_ERR "via-pmu: can't map interruptn"); |
414 | OPENPIC_PRIORITY_DEFAULT + 1); | 412 | return -ENODEV; |
415 | #endif | 413 | } |
416 | 414 | if (request_irq(irq, via_pmu_interrupt, 0, "VIA-PMU", (void *)0)) { | |
417 | if (request_irq(vias->intrs[0].line, via_pmu_interrupt, 0, "VIA-PMU", | 415 | printk(KERN_ERR "via-pmu: can't request irq %d\n", irq); |
418 | (void *)0)) { | 416 | return -ENODEV; |
419 | printk(KERN_ERR "VIA-PMU: can't get irq %d\n", | ||
420 | vias->intrs[0].line); | ||
421 | return -EAGAIN; | ||
422 | } | 417 | } |
423 | 418 | ||
424 | if (pmu_kind == PMU_KEYLARGO_BASED) { | 419 | if (pmu_kind == PMU_KEYLARGO_BASED) { |
@@ -426,10 +421,10 @@ static int __init via_pmu_start(void) | |||
426 | if (gpio_node == NULL) | 421 | if (gpio_node == NULL) |
427 | gpio_node = of_find_node_by_name(NULL, | 422 | gpio_node = of_find_node_by_name(NULL, |
428 | "pmu-interrupt"); | 423 | "pmu-interrupt"); |
429 | if (gpio_node && gpio_node->n_intrs > 0) | 424 | if (gpio_node) |
430 | gpio_irq = gpio_node->intrs[0].line; | 425 | gpio_irq = irq_of_parse_and_map(gpio_node, 0); |
431 | 426 | ||
432 | if (gpio_irq != -1) { | 427 | if (gpio_irq != NO_IRQ) { |
433 | if (request_irq(gpio_irq, gpio1_interrupt, 0, | 428 | if (request_irq(gpio_irq, gpio1_interrupt, 0, |
434 | "GPIO1 ADB", (void *)0)) | 429 | "GPIO1 ADB", (void *)0)) |
435 | printk(KERN_ERR "pmu: can't get irq %d" | 430 | printk(KERN_ERR "pmu: can't get irq %d" |
diff --git a/drivers/md/md.c b/drivers/md/md.c index 2fe32c261922..e4e161372a3e 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c | |||
@@ -1404,7 +1404,7 @@ static int lock_rdev(mdk_rdev_t *rdev, dev_t dev) | |||
1404 | struct block_device *bdev; | 1404 | struct block_device *bdev; |
1405 | char b[BDEVNAME_SIZE]; | 1405 | char b[BDEVNAME_SIZE]; |
1406 | 1406 | ||
1407 | bdev = open_by_devnum(dev, FMODE_READ|FMODE_WRITE); | 1407 | bdev = open_partition_by_devnum(dev, FMODE_READ|FMODE_WRITE); |
1408 | if (IS_ERR(bdev)) { | 1408 | if (IS_ERR(bdev)) { |
1409 | printk(KERN_ERR "md: could not open %s.\n", | 1409 | printk(KERN_ERR "md: could not open %s.\n", |
1410 | __bdevname(dev, b)); | 1410 | __bdevname(dev, b)); |
@@ -1414,7 +1414,7 @@ static int lock_rdev(mdk_rdev_t *rdev, dev_t dev) | |||
1414 | if (err) { | 1414 | if (err) { |
1415 | printk(KERN_ERR "md: could not bd_claim %s.\n", | 1415 | printk(KERN_ERR "md: could not bd_claim %s.\n", |
1416 | bdevname(bdev, b)); | 1416 | bdevname(bdev, b)); |
1417 | blkdev_put(bdev); | 1417 | blkdev_put_partition(bdev); |
1418 | return err; | 1418 | return err; |
1419 | } | 1419 | } |
1420 | rdev->bdev = bdev; | 1420 | rdev->bdev = bdev; |
@@ -1428,7 +1428,7 @@ static void unlock_rdev(mdk_rdev_t *rdev) | |||
1428 | if (!bdev) | 1428 | if (!bdev) |
1429 | MD_BUG(); | 1429 | MD_BUG(); |
1430 | bd_release(bdev); | 1430 | bd_release(bdev); |
1431 | blkdev_put(bdev); | 1431 | blkdev_put_partition(bdev); |
1432 | } | 1432 | } |
1433 | 1433 | ||
1434 | void md_autodetect_dev(dev_t dev); | 1434 | void md_autodetect_dev(dev_t dev); |
diff --git a/drivers/message/fusion/Makefile b/drivers/message/fusion/Makefile index 51740b346224..b114236f4395 100644 --- a/drivers/message/fusion/Makefile +++ b/drivers/message/fusion/Makefile | |||
@@ -33,6 +33,11 @@ | |||
33 | # For mptfc: | 33 | # For mptfc: |
34 | #CFLAGS_mptfc.o += -DMPT_DEBUG_FC | 34 | #CFLAGS_mptfc.o += -DMPT_DEBUG_FC |
35 | 35 | ||
36 | # For mptsas: | ||
37 | #CFLAGS_mptsas.o += -DMPT_DEBUG_SAS | ||
38 | #CFLAGS_mptsas.o += -DMPT_DEBUG_SAS_WIDE | ||
39 | |||
40 | |||
36 | #=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-} LSI_LOGIC | 41 | #=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-} LSI_LOGIC |
37 | 42 | ||
38 | obj-$(CONFIG_FUSION_SPI) += mptbase.o mptscsih.o mptspi.o | 43 | obj-$(CONFIG_FUSION_SPI) += mptbase.o mptscsih.o mptspi.o |
diff --git a/drivers/message/fusion/lsi/fc_log.h b/drivers/message/fusion/lsi/fc_log.h deleted file mode 100644 index dc98d46f9071..000000000000 --- a/drivers/message/fusion/lsi/fc_log.h +++ /dev/null | |||
@@ -1,89 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2000-2001 LSI Logic Corporation. All rights reserved. | ||
3 | * | ||
4 | * NAME: fc_log.h | ||
5 | * SUMMARY: MPI IocLogInfo definitions for the SYMFC9xx chips | ||
6 | * DESCRIPTION: Contains the enumerated list of values that may be returned | ||
7 | * in the IOCLogInfo field of a MPI Default Reply Message. | ||
8 | * | ||
9 | * CREATION DATE: 6/02/2000 | ||
10 | * ID: $Id: fc_log.h,v 4.6 2001/07/26 14:41:33 sschremm Exp $ | ||
11 | */ | ||
12 | |||
13 | |||
14 | /* | ||
15 | * MpiIocLogInfo_t enum | ||
16 | * | ||
17 | * These 32 bit values are used in the IOCLogInfo field of the MPI reply | ||
18 | * messages. | ||
19 | * The value is 0xabcccccc where | ||
20 | * a = The type of log info as per the MPI spec. Since these codes are | ||
21 | * all for Fibre Channel this value will always be 2. | ||
22 | * b = Specifies a subclass of the firmware where | ||
23 | * 0 = FCP Initiator | ||
24 | * 1 = FCP Target | ||
25 | * 2 = LAN | ||
26 | * 3 = MPI Message Layer | ||
27 | * 4 = FC Link | ||
28 | * 5 = Context Manager | ||
29 | * 6 = Invalid Field Offset | ||
30 | * 7 = State Change Info | ||
31 | * all others are reserved for future use | ||
32 | * c = A specific value within the subclass. | ||
33 | * | ||
34 | * NOTE: Any new values should be added to the end of each subclass so that the | ||
35 | * codes remain consistent across firmware releases. | ||
36 | */ | ||
37 | typedef enum _MpiIocLogInfoFc | ||
38 | { | ||
39 | MPI_IOCLOGINFO_FC_INIT_BASE = 0x20000000, | ||
40 | MPI_IOCLOGINFO_FC_INIT_ERROR_OUT_OF_ORDER_FRAME = 0x20000001, /* received an out of order frame - unsupported */ | ||
41 | MPI_IOCLOGINFO_FC_INIT_ERROR_BAD_START_OF_FRAME = 0x20000002, /* Bad Rx Frame, bad start of frame primative */ | ||
42 | MPI_IOCLOGINFO_FC_INIT_ERROR_BAD_END_OF_FRAME = 0x20000003, /* Bad Rx Frame, bad end of frame primative */ | ||
43 | MPI_IOCLOGINFO_FC_INIT_ERROR_OVER_RUN = 0x20000004, /* Bad Rx Frame, overrun */ | ||
44 | MPI_IOCLOGINFO_FC_INIT_ERROR_RX_OTHER = 0x20000005, /* Other errors caught by IOC which require retries */ | ||
45 | MPI_IOCLOGINFO_FC_INIT_ERROR_SUBPROC_DEAD = 0x20000006, /* Main processor could not initialize sub-processor */ | ||
46 | MPI_IOCLOGINFO_FC_INIT_ERROR_RX_OVERRUN = 0x20000007, /* Scatter Gather overrun */ | ||
47 | MPI_IOCLOGINFO_FC_INIT_ERROR_RX_BAD_STATUS = 0x20000008, /* Receiver detected context mismatch via invalid header */ | ||
48 | MPI_IOCLOGINFO_FC_INIT_ERROR_RX_UNEXPECTED_FRAME= 0x20000009, /* CtxMgr detected unsupported frame type */ | ||
49 | MPI_IOCLOGINFO_FC_INIT_ERROR_LINK_FAILURE = 0x2000000A, /* Link failure occurred */ | ||
50 | MPI_IOCLOGINFO_FC_INIT_ERROR_TX_TIMEOUT = 0x2000000B, /* Transmitter timeout error */ | ||
51 | |||
52 | MPI_IOCLOGINFO_FC_TARGET_BASE = 0x21000000, | ||
53 | MPI_IOCLOGINFO_FC_TARGET_NO_PDISC = 0x21000001, /* not sent because we are waiting for a PDISC from the initiator */ | ||
54 | MPI_IOCLOGINFO_FC_TARGET_NO_LOGIN = 0x21000002, /* not sent because we are not logged in to the remote node */ | ||
55 | MPI_IOCLOGINFO_FC_TARGET_DOAR_KILLED_BY_LIP = 0x21000003, /* Data Out, Auto Response, not sent due to a LIP */ | ||
56 | MPI_IOCLOGINFO_FC_TARGET_DIAR_KILLED_BY_LIP = 0x21000004, /* Data In, Auto Response, not sent due to a LIP */ | ||
57 | MPI_IOCLOGINFO_FC_TARGET_DIAR_MISSING_DATA = 0x21000005, /* Data In, Auto Response, missing data frames */ | ||
58 | MPI_IOCLOGINFO_FC_TARGET_DONR_KILLED_BY_LIP = 0x21000006, /* Data Out, No Response, not sent due to a LIP */ | ||
59 | MPI_IOCLOGINFO_FC_TARGET_WRSP_KILLED_BY_LIP = 0x21000007, /* Auto-response after a write not sent due to a LIP */ | ||
60 | MPI_IOCLOGINFO_FC_TARGET_DINR_KILLED_BY_LIP = 0x21000008, /* Data In, No Response, not completed due to a LIP */ | ||
61 | MPI_IOCLOGINFO_FC_TARGET_DINR_MISSING_DATA = 0x21000009, /* Data In, No Response, missing data frames */ | ||
62 | MPI_IOCLOGINFO_FC_TARGET_MRSP_KILLED_BY_LIP = 0x2100000a, /* Manual Response not sent due to a LIP */ | ||
63 | MPI_IOCLOGINFO_FC_TARGET_NO_CLASS_3 = 0x2100000b, /* not sent because remote node does not support Class 3 */ | ||
64 | MPI_IOCLOGINFO_FC_TARGET_LOGIN_NOT_VALID = 0x2100000c, /* not sent because login to remote node not validated */ | ||
65 | MPI_IOCLOGINFO_FC_TARGET_FROM_OUTBOUND = 0x2100000e, /* cleared from the outbound queue after a logout */ | ||
66 | MPI_IOCLOGINFO_FC_TARGET_WAITING_FOR_DATA_IN = 0x2100000f, /* cleared waiting for data after a logout */ | ||
67 | |||
68 | MPI_IOCLOGINFO_FC_LAN_BASE = 0x22000000, | ||
69 | MPI_IOCLOGINFO_FC_LAN_TRANS_SGL_MISSING = 0x22000001, /* Transaction Context Sgl Missing */ | ||
70 | MPI_IOCLOGINFO_FC_LAN_TRANS_WRONG_PLACE = 0x22000002, /* Transaction Context found before an EOB */ | ||
71 | MPI_IOCLOGINFO_FC_LAN_TRANS_RES_BITS_SET = 0x22000003, /* Transaction Context value has reserved bits set */ | ||
72 | MPI_IOCLOGINFO_FC_LAN_WRONG_SGL_FLAG = 0x22000004, /* Invalid SGL Flags */ | ||
73 | |||
74 | MPI_IOCLOGINFO_FC_MSG_BASE = 0x23000000, | ||
75 | |||
76 | MPI_IOCLOGINFO_FC_LINK_BASE = 0x24000000, | ||
77 | MPI_IOCLOGINFO_FC_LINK_LOOP_INIT_TIMEOUT = 0x24000001, /* Loop initialization timed out */ | ||
78 | MPI_IOCLOGINFO_FC_LINK_ALREADY_INITIALIZED = 0x24000002, /* Another system controller already initialized the loop */ | ||
79 | MPI_IOCLOGINFO_FC_LINK_LINK_NOT_ESTABLISHED = 0x24000003, /* Not synchronized to signal or still negotiating (possible cable problem) */ | ||
80 | MPI_IOCLOGINFO_FC_LINK_CRC_ERROR = 0x24000004, /* CRC check detected error on received frame */ | ||
81 | |||
82 | MPI_IOCLOGINFO_FC_CTX_BASE = 0x25000000, | ||
83 | |||
84 | MPI_IOCLOGINFO_FC_INVALID_FIELD_BYTE_OFFSET = 0x26000000, /* The lower 24 bits give the byte offset of the field in the request message that is invalid */ | ||
85 | MPI_IOCLOGINFO_FC_INVALID_FIELD_MAX_OFFSET = 0x26ffffff, | ||
86 | |||
87 | MPI_IOCLOGINFO_FC_STATE_CHANGE = 0x27000000 /* The lower 24 bits give additional information concerning state change */ | ||
88 | |||
89 | } MpiIocLogInfoFc_t; | ||
diff --git a/drivers/message/fusion/lsi/mpi.h b/drivers/message/fusion/lsi/mpi.h index 02cdc840a06b..81ad77622dac 100644 --- a/drivers/message/fusion/lsi/mpi.h +++ b/drivers/message/fusion/lsi/mpi.h | |||
@@ -6,7 +6,7 @@ | |||
6 | * Title: MPI Message independent structures and definitions | 6 | * Title: MPI Message independent structures and definitions |
7 | * Creation Date: July 27, 2000 | 7 | * Creation Date: July 27, 2000 |
8 | * | 8 | * |
9 | * mpi.h Version: 01.05.10 | 9 | * mpi.h Version: 01.05.11 |
10 | * | 10 | * |
11 | * Version History | 11 | * Version History |
12 | * --------------- | 12 | * --------------- |
@@ -76,6 +76,7 @@ | |||
76 | * Added EEDP IOCStatus codes. | 76 | * Added EEDP IOCStatus codes. |
77 | * 08-03-05 01.05.09 Bumped MPI_HEADER_VERSION_UNIT. | 77 | * 08-03-05 01.05.09 Bumped MPI_HEADER_VERSION_UNIT. |
78 | * 08-30-05 01.05.10 Added 2 new IOCStatus codes for Target. | 78 | * 08-30-05 01.05.10 Added 2 new IOCStatus codes for Target. |
79 | * 03-27-06 01.05.11 Bumped MPI_HEADER_VERSION_UNIT. | ||
79 | * -------------------------------------------------------------------------- | 80 | * -------------------------------------------------------------------------- |
80 | */ | 81 | */ |
81 | 82 | ||
@@ -106,7 +107,7 @@ | |||
106 | /* Note: The major versions of 0xe0 through 0xff are reserved */ | 107 | /* Note: The major versions of 0xe0 through 0xff are reserved */ |
107 | 108 | ||
108 | /* versioning for this MPI header set */ | 109 | /* versioning for this MPI header set */ |
109 | #define MPI_HEADER_VERSION_UNIT (0x0C) | 110 | #define MPI_HEADER_VERSION_UNIT (0x0D) |
110 | #define MPI_HEADER_VERSION_DEV (0x00) | 111 | #define MPI_HEADER_VERSION_DEV (0x00) |
111 | #define MPI_HEADER_VERSION_UNIT_MASK (0xFF00) | 112 | #define MPI_HEADER_VERSION_UNIT_MASK (0xFF00) |
112 | #define MPI_HEADER_VERSION_UNIT_SHIFT (8) | 113 | #define MPI_HEADER_VERSION_UNIT_SHIFT (8) |
diff --git a/drivers/message/fusion/lsi/mpi_cnfg.h b/drivers/message/fusion/lsi/mpi_cnfg.h index b1becec27e1b..47e13e360c10 100644 --- a/drivers/message/fusion/lsi/mpi_cnfg.h +++ b/drivers/message/fusion/lsi/mpi_cnfg.h | |||
@@ -6,7 +6,7 @@ | |||
6 | * Title: MPI Config message, structures, and Pages | 6 | * Title: MPI Config message, structures, and Pages |
7 | * Creation Date: July 27, 2000 | 7 | * Creation Date: July 27, 2000 |
8 | * | 8 | * |
9 | * mpi_cnfg.h Version: 01.05.11 | 9 | * mpi_cnfg.h Version: 01.05.12 |
10 | * | 10 | * |
11 | * Version History | 11 | * Version History |
12 | * --------------- | 12 | * --------------- |
@@ -266,6 +266,16 @@ | |||
266 | * Added postpone SATA Init bit to SAS IO Unit Page 1 | 266 | * Added postpone SATA Init bit to SAS IO Unit Page 1 |
267 | * ControlFlags. | 267 | * ControlFlags. |
268 | * Changed LogEntry format for Log Page 0. | 268 | * Changed LogEntry format for Log Page 0. |
269 | * 03-27-06 01.05.12 Added two new Flags defines for Manufacturing Page 4. | ||
270 | * Added Manufacturing Page 7. | ||
271 | * Added MPI_IOCPAGE2_CAP_FLAGS_RAID_64_BIT_ADDRESSING. | ||
272 | * Added IOC Page 6. | ||
273 | * Added PrevBootDeviceForm field to CONFIG_PAGE_BIOS_2. | ||
274 | * Added MaxLBAHigh field to RAID Volume Page 0. | ||
275 | * Added Nvdata version fields to SAS IO Unit Page 0. | ||
276 | * Added AdditionalControlFlags, MaxTargetPortConnectTime, | ||
277 | * ReportDeviceMissingDelay, and IODeviceMissingDelay | ||
278 | * fields to SAS IO Unit Page 1. | ||
269 | * -------------------------------------------------------------------------- | 279 | * -------------------------------------------------------------------------- |
270 | */ | 280 | */ |
271 | 281 | ||
@@ -631,9 +641,11 @@ typedef struct _CONFIG_PAGE_MANUFACTURING_4 | |||
631 | } CONFIG_PAGE_MANUFACTURING_4, MPI_POINTER PTR_CONFIG_PAGE_MANUFACTURING_4, | 641 | } CONFIG_PAGE_MANUFACTURING_4, MPI_POINTER PTR_CONFIG_PAGE_MANUFACTURING_4, |
632 | ManufacturingPage4_t, MPI_POINTER pManufacturingPage4_t; | 642 | ManufacturingPage4_t, MPI_POINTER pManufacturingPage4_t; |
633 | 643 | ||
634 | #define MPI_MANUFACTURING4_PAGEVERSION (0x03) | 644 | #define MPI_MANUFACTURING4_PAGEVERSION (0x04) |
635 | 645 | ||
636 | /* defines for the Flags field */ | 646 | /* defines for the Flags field */ |
647 | #define MPI_MANPAGE4_FORCE_BAD_BLOCK_TABLE (0x80) | ||
648 | #define MPI_MANPAGE4_FORCE_OFFLINE_FAILOVER (0x40) | ||
637 | #define MPI_MANPAGE4_IME_DISABLE (0x20) | 649 | #define MPI_MANPAGE4_IME_DISABLE (0x20) |
638 | #define MPI_MANPAGE4_IM_DISABLE (0x10) | 650 | #define MPI_MANPAGE4_IM_DISABLE (0x10) |
639 | #define MPI_MANPAGE4_IS_DISABLE (0x08) | 651 | #define MPI_MANPAGE4_IS_DISABLE (0x08) |
@@ -668,6 +680,66 @@ typedef struct _CONFIG_PAGE_MANUFACTURING_6 | |||
668 | #define MPI_MANUFACTURING6_PAGEVERSION (0x00) | 680 | #define MPI_MANUFACTURING6_PAGEVERSION (0x00) |
669 | 681 | ||
670 | 682 | ||
683 | typedef struct _MPI_MANPAGE7_CONNECTOR_INFO | ||
684 | { | ||
685 | U32 Pinout; /* 00h */ | ||
686 | U8 Connector[16]; /* 04h */ | ||
687 | U8 Location; /* 14h */ | ||
688 | U8 Reserved1; /* 15h */ | ||
689 | U16 Slot; /* 16h */ | ||
690 | U32 Reserved2; /* 18h */ | ||
691 | } MPI_MANPAGE7_CONNECTOR_INFO, MPI_POINTER PTR_MPI_MANPAGE7_CONNECTOR_INFO, | ||
692 | MpiManPage7ConnectorInfo_t, MPI_POINTER pMpiManPage7ConnectorInfo_t; | ||
693 | |||
694 | /* defines for the Pinout field */ | ||
695 | #define MPI_MANPAGE7_PINOUT_SFF_8484_L4 (0x00080000) | ||
696 | #define MPI_MANPAGE7_PINOUT_SFF_8484_L3 (0x00040000) | ||
697 | #define MPI_MANPAGE7_PINOUT_SFF_8484_L2 (0x00020000) | ||
698 | #define MPI_MANPAGE7_PINOUT_SFF_8484_L1 (0x00010000) | ||
699 | #define MPI_MANPAGE7_PINOUT_SFF_8470_L4 (0x00000800) | ||
700 | #define MPI_MANPAGE7_PINOUT_SFF_8470_L3 (0x00000400) | ||
701 | #define MPI_MANPAGE7_PINOUT_SFF_8470_L2 (0x00000200) | ||
702 | #define MPI_MANPAGE7_PINOUT_SFF_8470_L1 (0x00000100) | ||
703 | #define MPI_MANPAGE7_PINOUT_SFF_8482 (0x00000002) | ||
704 | #define MPI_MANPAGE7_PINOUT_CONNECTION_UNKNOWN (0x00000001) | ||
705 | |||
706 | /* defines for the Location field */ | ||
707 | #define MPI_MANPAGE7_LOCATION_UNKNOWN (0x01) | ||
708 | #define MPI_MANPAGE7_LOCATION_INTERNAL (0x02) | ||
709 | #define MPI_MANPAGE7_LOCATION_EXTERNAL (0x04) | ||
710 | #define MPI_MANPAGE7_LOCATION_SWITCHABLE (0x08) | ||
711 | #define MPI_MANPAGE7_LOCATION_AUTO (0x10) | ||
712 | #define MPI_MANPAGE7_LOCATION_NOT_PRESENT (0x20) | ||
713 | #define MPI_MANPAGE7_LOCATION_NOT_CONNECTED (0x80) | ||
714 | |||
715 | /* | ||
716 | * Host code (drivers, BIOS, utilities, etc.) should leave this define set to | ||
717 | * one and check NumPhys at runtime. | ||
718 | */ | ||
719 | #ifndef MPI_MANPAGE7_CONNECTOR_INFO_MAX | ||
720 | #define MPI_MANPAGE7_CONNECTOR_INFO_MAX (1) | ||
721 | #endif | ||
722 | |||
723 | typedef struct _CONFIG_PAGE_MANUFACTURING_7 | ||
724 | { | ||
725 | CONFIG_PAGE_HEADER Header; /* 00h */ | ||
726 | U32 Reserved1; /* 04h */ | ||
727 | U32 Reserved2; /* 08h */ | ||
728 | U32 Flags; /* 0Ch */ | ||
729 | U8 EnclosureName[16]; /* 10h */ | ||
730 | U8 NumPhys; /* 20h */ | ||
731 | U8 Reserved3; /* 21h */ | ||
732 | U16 Reserved4; /* 22h */ | ||
733 | MPI_MANPAGE7_CONNECTOR_INFO ConnectorInfo[MPI_MANPAGE7_CONNECTOR_INFO_MAX]; /* 24h */ | ||
734 | } CONFIG_PAGE_MANUFACTURING_7, MPI_POINTER PTR_CONFIG_PAGE_MANUFACTURING_7, | ||
735 | ManufacturingPage7_t, MPI_POINTER pManufacturingPage7_t; | ||
736 | |||
737 | #define MPI_MANUFACTURING7_PAGEVERSION (0x00) | ||
738 | |||
739 | /* defines for the Flags field */ | ||
740 | #define MPI_MANPAGE7_FLAG_USE_SLOT_INFO (0x00000001) | ||
741 | |||
742 | |||
671 | /**************************************************************************** | 743 | /**************************************************************************** |
672 | * IO Unit Config Pages | 744 | * IO Unit Config Pages |
673 | ****************************************************************************/ | 745 | ****************************************************************************/ |
@@ -867,7 +939,7 @@ typedef struct _CONFIG_PAGE_IOC_2 | |||
867 | } CONFIG_PAGE_IOC_2, MPI_POINTER PTR_CONFIG_PAGE_IOC_2, | 939 | } CONFIG_PAGE_IOC_2, MPI_POINTER PTR_CONFIG_PAGE_IOC_2, |
868 | IOCPage2_t, MPI_POINTER pIOCPage2_t; | 940 | IOCPage2_t, MPI_POINTER pIOCPage2_t; |
869 | 941 | ||
870 | #define MPI_IOCPAGE2_PAGEVERSION (0x03) | 942 | #define MPI_IOCPAGE2_PAGEVERSION (0x04) |
871 | 943 | ||
872 | /* IOC Page 2 Capabilities flags */ | 944 | /* IOC Page 2 Capabilities flags */ |
873 | 945 | ||
@@ -878,6 +950,7 @@ typedef struct _CONFIG_PAGE_IOC_2 | |||
878 | #define MPI_IOCPAGE2_CAP_FLAGS_RAID_6_SUPPORT (0x00000010) | 950 | #define MPI_IOCPAGE2_CAP_FLAGS_RAID_6_SUPPORT (0x00000010) |
879 | #define MPI_IOCPAGE2_CAP_FLAGS_RAID_10_SUPPORT (0x00000020) | 951 | #define MPI_IOCPAGE2_CAP_FLAGS_RAID_10_SUPPORT (0x00000020) |
880 | #define MPI_IOCPAGE2_CAP_FLAGS_RAID_50_SUPPORT (0x00000040) | 952 | #define MPI_IOCPAGE2_CAP_FLAGS_RAID_50_SUPPORT (0x00000040) |
953 | #define MPI_IOCPAGE2_CAP_FLAGS_RAID_64_BIT_ADDRESSING (0x10000000) | ||
881 | #define MPI_IOCPAGE2_CAP_FLAGS_SES_SUPPORT (0x20000000) | 954 | #define MPI_IOCPAGE2_CAP_FLAGS_SES_SUPPORT (0x20000000) |
882 | #define MPI_IOCPAGE2_CAP_FLAGS_SAFTE_SUPPORT (0x40000000) | 955 | #define MPI_IOCPAGE2_CAP_FLAGS_SAFTE_SUPPORT (0x40000000) |
883 | #define MPI_IOCPAGE2_CAP_FLAGS_CROSS_CHANNEL_SUPPORT (0x80000000) | 956 | #define MPI_IOCPAGE2_CAP_FLAGS_CROSS_CHANNEL_SUPPORT (0x80000000) |
@@ -975,6 +1048,44 @@ typedef struct _CONFIG_PAGE_IOC_5 | |||
975 | 1048 | ||
976 | #define MPI_IOCPAGE5_PAGEVERSION (0x00) | 1049 | #define MPI_IOCPAGE5_PAGEVERSION (0x00) |
977 | 1050 | ||
1051 | typedef struct _CONFIG_PAGE_IOC_6 | ||
1052 | { | ||
1053 | CONFIG_PAGE_HEADER Header; /* 00h */ | ||
1054 | U32 CapabilitiesFlags; /* 04h */ | ||
1055 | U8 MaxDrivesIS; /* 08h */ | ||
1056 | U8 MaxDrivesIM; /* 09h */ | ||
1057 | U8 MaxDrivesIME; /* 0Ah */ | ||
1058 | U8 Reserved1; /* 0Bh */ | ||
1059 | U8 MinDrivesIS; /* 0Ch */ | ||
1060 | U8 MinDrivesIM; /* 0Dh */ | ||
1061 | U8 MinDrivesIME; /* 0Eh */ | ||
1062 | U8 Reserved2; /* 0Fh */ | ||
1063 | U8 MaxGlobalHotSpares; /* 10h */ | ||
1064 | U8 Reserved3; /* 11h */ | ||
1065 | U16 Reserved4; /* 12h */ | ||
1066 | U32 Reserved5; /* 14h */ | ||
1067 | U32 SupportedStripeSizeMapIS; /* 18h */ | ||
1068 | U32 SupportedStripeSizeMapIME; /* 1Ch */ | ||
1069 | U32 Reserved6; /* 20h */ | ||
1070 | U8 MetadataSize; /* 24h */ | ||
1071 | U8 Reserved7; /* 25h */ | ||
1072 | U16 Reserved8; /* 26h */ | ||
1073 | U16 MaxBadBlockTableEntries; /* 28h */ | ||
1074 | U16 Reserved9; /* 2Ah */ | ||
1075 | U16 IRNvsramUsage; /* 2Ch */ | ||
1076 | U16 Reserved10; /* 2Eh */ | ||
1077 | U32 IRNvsramVersion; /* 30h */ | ||
1078 | U32 Reserved11; /* 34h */ | ||
1079 | U32 Reserved12; /* 38h */ | ||
1080 | } CONFIG_PAGE_IOC_6, MPI_POINTER PTR_CONFIG_PAGE_IOC_6, | ||
1081 | IOCPage6_t, MPI_POINTER pIOCPage6_t; | ||
1082 | |||
1083 | #define MPI_IOCPAGE6_PAGEVERSION (0x00) | ||
1084 | |||
1085 | /* IOC Page 6 Capabilities Flags */ | ||
1086 | |||
1087 | #define MPI_IOCPAGE6_CAP_FLAGS_GLOBAL_HOT_SPARE (0x00000001) | ||
1088 | |||
978 | 1089 | ||
979 | /**************************************************************************** | 1090 | /**************************************************************************** |
980 | * BIOS Config Pages | 1091 | * BIOS Config Pages |
@@ -1218,13 +1329,13 @@ typedef struct _CONFIG_PAGE_BIOS_2 | |||
1218 | U32 Reserved5; /* 14h */ | 1329 | U32 Reserved5; /* 14h */ |
1219 | U32 Reserved6; /* 18h */ | 1330 | U32 Reserved6; /* 18h */ |
1220 | U8 BootDeviceForm; /* 1Ch */ | 1331 | U8 BootDeviceForm; /* 1Ch */ |
1221 | U8 Reserved7; /* 1Dh */ | 1332 | U8 PrevBootDeviceForm; /* 1Ch */ |
1222 | U16 Reserved8; /* 1Eh */ | 1333 | U16 Reserved8; /* 1Eh */ |
1223 | MPI_BIOSPAGE2_BOOT_DEVICE BootDevice; /* 20h */ | 1334 | MPI_BIOSPAGE2_BOOT_DEVICE BootDevice; /* 20h */ |
1224 | } CONFIG_PAGE_BIOS_2, MPI_POINTER PTR_CONFIG_PAGE_BIOS_2, | 1335 | } CONFIG_PAGE_BIOS_2, MPI_POINTER PTR_CONFIG_PAGE_BIOS_2, |
1225 | BIOSPage2_t, MPI_POINTER pBIOSPage2_t; | 1336 | BIOSPage2_t, MPI_POINTER pBIOSPage2_t; |
1226 | 1337 | ||
1227 | #define MPI_BIOSPAGE2_PAGEVERSION (0x01) | 1338 | #define MPI_BIOSPAGE2_PAGEVERSION (0x02) |
1228 | 1339 | ||
1229 | #define MPI_BIOSPAGE2_FORM_MASK (0x0F) | 1340 | #define MPI_BIOSPAGE2_FORM_MASK (0x0F) |
1230 | #define MPI_BIOSPAGE2_FORM_ADAPTER_ORDER (0x00) | 1341 | #define MPI_BIOSPAGE2_FORM_ADAPTER_ORDER (0x00) |
@@ -2080,7 +2191,7 @@ typedef struct _CONFIG_PAGE_RAID_VOL_0 | |||
2080 | RAID_VOL0_STATUS VolumeStatus; /* 08h */ | 2191 | RAID_VOL0_STATUS VolumeStatus; /* 08h */ |
2081 | RAID_VOL0_SETTINGS VolumeSettings; /* 0Ch */ | 2192 | RAID_VOL0_SETTINGS VolumeSettings; /* 0Ch */ |
2082 | U32 MaxLBA; /* 10h */ | 2193 | U32 MaxLBA; /* 10h */ |
2083 | U32 Reserved1; /* 14h */ | 2194 | U32 MaxLBAHigh; /* 14h */ |
2084 | U32 StripeSize; /* 18h */ | 2195 | U32 StripeSize; /* 18h */ |
2085 | U32 Reserved2; /* 1Ch */ | 2196 | U32 Reserved2; /* 1Ch */ |
2086 | U32 Reserved3; /* 20h */ | 2197 | U32 Reserved3; /* 20h */ |
@@ -2092,7 +2203,7 @@ typedef struct _CONFIG_PAGE_RAID_VOL_0 | |||
2092 | } CONFIG_PAGE_RAID_VOL_0, MPI_POINTER PTR_CONFIG_PAGE_RAID_VOL_0, | 2203 | } CONFIG_PAGE_RAID_VOL_0, MPI_POINTER PTR_CONFIG_PAGE_RAID_VOL_0, |
2093 | RaidVolumePage0_t, MPI_POINTER pRaidVolumePage0_t; | 2204 | RaidVolumePage0_t, MPI_POINTER pRaidVolumePage0_t; |
2094 | 2205 | ||
2095 | #define MPI_RAIDVOLPAGE0_PAGEVERSION (0x05) | 2206 | #define MPI_RAIDVOLPAGE0_PAGEVERSION (0x06) |
2096 | 2207 | ||
2097 | /* values for RAID Volume Page 0 InactiveStatus field */ | 2208 | /* values for RAID Volume Page 0 InactiveStatus field */ |
2098 | #define MPI_RAIDVOLPAGE0_UNKNOWN_INACTIVE (0x00) | 2209 | #define MPI_RAIDVOLPAGE0_UNKNOWN_INACTIVE (0x00) |
@@ -2324,7 +2435,8 @@ typedef struct _MPI_SAS_IO_UNIT0_PHY_DATA | |||
2324 | typedef struct _CONFIG_PAGE_SAS_IO_UNIT_0 | 2435 | typedef struct _CONFIG_PAGE_SAS_IO_UNIT_0 |
2325 | { | 2436 | { |
2326 | CONFIG_EXTENDED_PAGE_HEADER Header; /* 00h */ | 2437 | CONFIG_EXTENDED_PAGE_HEADER Header; /* 00h */ |
2327 | U32 Reserved1; /* 08h */ | 2438 | U16 NvdataVersionDefault; /* 08h */ |
2439 | U16 NvdataVersionPersistent; /* 0Ah */ | ||
2328 | U8 NumPhys; /* 0Ch */ | 2440 | U8 NumPhys; /* 0Ch */ |
2329 | U8 Reserved2; /* 0Dh */ | 2441 | U8 Reserved2; /* 0Dh */ |
2330 | U16 Reserved3; /* 0Eh */ | 2442 | U16 Reserved3; /* 0Eh */ |
@@ -2332,7 +2444,7 @@ typedef struct _CONFIG_PAGE_SAS_IO_UNIT_0 | |||
2332 | } CONFIG_PAGE_SAS_IO_UNIT_0, MPI_POINTER PTR_CONFIG_PAGE_SAS_IO_UNIT_0, | 2444 | } CONFIG_PAGE_SAS_IO_UNIT_0, MPI_POINTER PTR_CONFIG_PAGE_SAS_IO_UNIT_0, |
2333 | SasIOUnitPage0_t, MPI_POINTER pSasIOUnitPage0_t; | 2445 | SasIOUnitPage0_t, MPI_POINTER pSasIOUnitPage0_t; |
2334 | 2446 | ||
2335 | #define MPI_SASIOUNITPAGE0_PAGEVERSION (0x03) | 2447 | #define MPI_SASIOUNITPAGE0_PAGEVERSION (0x04) |
2336 | 2448 | ||
2337 | /* values for SAS IO Unit Page 0 PortFlags */ | 2449 | /* values for SAS IO Unit Page 0 PortFlags */ |
2338 | #define MPI_SAS_IOUNIT0_PORT_FLAGS_DISCOVERY_IN_PROGRESS (0x08) | 2450 | #define MPI_SAS_IOUNIT0_PORT_FLAGS_DISCOVERY_IN_PROGRESS (0x08) |
@@ -2373,12 +2485,13 @@ typedef struct _CONFIG_PAGE_SAS_IO_UNIT_0 | |||
2373 | 2485 | ||
2374 | typedef struct _MPI_SAS_IO_UNIT1_PHY_DATA | 2486 | typedef struct _MPI_SAS_IO_UNIT1_PHY_DATA |
2375 | { | 2487 | { |
2376 | U8 Port; /* 00h */ | 2488 | U8 Port; /* 00h */ |
2377 | U8 PortFlags; /* 01h */ | 2489 | U8 PortFlags; /* 01h */ |
2378 | U8 PhyFlags; /* 02h */ | 2490 | U8 PhyFlags; /* 02h */ |
2379 | U8 MaxMinLinkRate; /* 03h */ | 2491 | U8 MaxMinLinkRate; /* 03h */ |
2380 | U32 ControllerPhyDeviceInfo;/* 04h */ | 2492 | U32 ControllerPhyDeviceInfo; /* 04h */ |
2381 | U32 Reserved1; /* 08h */ | 2493 | U16 MaxTargetPortConnectTime; /* 08h */ |
2494 | U16 Reserved1; /* 0Ah */ | ||
2382 | } MPI_SAS_IO_UNIT1_PHY_DATA, MPI_POINTER PTR_MPI_SAS_IO_UNIT1_PHY_DATA, | 2495 | } MPI_SAS_IO_UNIT1_PHY_DATA, MPI_POINTER PTR_MPI_SAS_IO_UNIT1_PHY_DATA, |
2383 | SasIOUnit1PhyData, MPI_POINTER pSasIOUnit1PhyData; | 2496 | SasIOUnit1PhyData, MPI_POINTER pSasIOUnit1PhyData; |
2384 | 2497 | ||
@@ -2395,15 +2508,17 @@ typedef struct _CONFIG_PAGE_SAS_IO_UNIT_1 | |||
2395 | CONFIG_EXTENDED_PAGE_HEADER Header; /* 00h */ | 2508 | CONFIG_EXTENDED_PAGE_HEADER Header; /* 00h */ |
2396 | U16 ControlFlags; /* 08h */ | 2509 | U16 ControlFlags; /* 08h */ |
2397 | U16 MaxNumSATATargets; /* 0Ah */ | 2510 | U16 MaxNumSATATargets; /* 0Ah */ |
2398 | U32 Reserved1; /* 0Ch */ | 2511 | U16 AdditionalControlFlags; /* 0Ch */ |
2512 | U16 Reserved1; /* 0Eh */ | ||
2399 | U8 NumPhys; /* 10h */ | 2513 | U8 NumPhys; /* 10h */ |
2400 | U8 SATAMaxQDepth; /* 11h */ | 2514 | U8 SATAMaxQDepth; /* 11h */ |
2401 | U16 Reserved2; /* 12h */ | 2515 | U8 ReportDeviceMissingDelay; /* 12h */ |
2516 | U8 IODeviceMissingDelay; /* 13h */ | ||
2402 | MPI_SAS_IO_UNIT1_PHY_DATA PhyData[MPI_SAS_IOUNIT1_PHY_MAX]; /* 14h */ | 2517 | MPI_SAS_IO_UNIT1_PHY_DATA PhyData[MPI_SAS_IOUNIT1_PHY_MAX]; /* 14h */ |
2403 | } CONFIG_PAGE_SAS_IO_UNIT_1, MPI_POINTER PTR_CONFIG_PAGE_SAS_IO_UNIT_1, | 2518 | } CONFIG_PAGE_SAS_IO_UNIT_1, MPI_POINTER PTR_CONFIG_PAGE_SAS_IO_UNIT_1, |
2404 | SasIOUnitPage1_t, MPI_POINTER pSasIOUnitPage1_t; | 2519 | SasIOUnitPage1_t, MPI_POINTER pSasIOUnitPage1_t; |
2405 | 2520 | ||
2406 | #define MPI_SASIOUNITPAGE1_PAGEVERSION (0x05) | 2521 | #define MPI_SASIOUNITPAGE1_PAGEVERSION (0x06) |
2407 | 2522 | ||
2408 | /* values for SAS IO Unit Page 1 ControlFlags */ | 2523 | /* values for SAS IO Unit Page 1 ControlFlags */ |
2409 | #define MPI_SAS_IOUNIT1_CONTROL_DEVICE_SELF_TEST (0x8000) | 2524 | #define MPI_SAS_IOUNIT1_CONTROL_DEVICE_SELF_TEST (0x8000) |
@@ -2428,6 +2543,13 @@ typedef struct _CONFIG_PAGE_SAS_IO_UNIT_1 | |||
2428 | #define MPI_SAS_IOUNIT1_CONTROL_FIRST_LVL_DISC_ONLY (0x0002) | 2543 | #define MPI_SAS_IOUNIT1_CONTROL_FIRST_LVL_DISC_ONLY (0x0002) |
2429 | #define MPI_SAS_IOUNIT1_CONTROL_CLEAR_AFFILIATION (0x0001) | 2544 | #define MPI_SAS_IOUNIT1_CONTROL_CLEAR_AFFILIATION (0x0001) |
2430 | 2545 | ||
2546 | /* values for SAS IO Unit Page 1 AdditionalControlFlags */ | ||
2547 | #define MPI_SAS_IOUNIT1_ACONTROL_ALLOW_TABLE_TO_TABLE (0x0001) | ||
2548 | |||
2549 | /* defines for SAS IO Unit Page 1 ReportDeviceMissingDelay */ | ||
2550 | #define MPI_SAS_IOUNIT1_REPORT_MISSING_TIMEOUT_MASK (0x7F) | ||
2551 | #define MPI_SAS_IOUNIT1_REPORT_MISSING_UNIT_16 (0x80) | ||
2552 | |||
2431 | /* values for SAS IO Unit Page 1 PortFlags */ | 2553 | /* values for SAS IO Unit Page 1 PortFlags */ |
2432 | #define MPI_SAS_IOUNIT1_PORT_FLAGS_0_TARGET_IOC_NUM (0x00) | 2554 | #define MPI_SAS_IOUNIT1_PORT_FLAGS_0_TARGET_IOC_NUM (0x00) |
2433 | #define MPI_SAS_IOUNIT1_PORT_FLAGS_1_TARGET_IOC_NUM (0x04) | 2555 | #define MPI_SAS_IOUNIT1_PORT_FLAGS_1_TARGET_IOC_NUM (0x04) |
diff --git a/drivers/message/fusion/lsi/mpi_history.txt b/drivers/message/fusion/lsi/mpi_history.txt index 4a5f8dd1d766..582cfe7c2aa1 100644 --- a/drivers/message/fusion/lsi/mpi_history.txt +++ b/drivers/message/fusion/lsi/mpi_history.txt | |||
@@ -6,25 +6,25 @@ | |||
6 | Copyright (c) 2000-2005 LSI Logic Corporation. | 6 | Copyright (c) 2000-2005 LSI Logic Corporation. |
7 | 7 | ||
8 | --------------------------------------- | 8 | --------------------------------------- |
9 | Header Set Release Version: 01.05.12 | 9 | Header Set Release Version: 01.05.13 |
10 | Header Set Release Date: 08-30-05 | 10 | Header Set Release Date: 03-27-06 |
11 | --------------------------------------- | 11 | --------------------------------------- |
12 | 12 | ||
13 | Filename Current version Prior version | 13 | Filename Current version Prior version |
14 | ---------- --------------- ------------- | 14 | ---------- --------------- ------------- |
15 | mpi.h 01.05.10 01.05.09 | 15 | mpi.h 01.05.11 01.05.10 |
16 | mpi_ioc.h 01.05.10 01.05.09 | 16 | mpi_ioc.h 01.05.11 01.05.10 |
17 | mpi_cnfg.h 01.05.11 01.05.10 | 17 | mpi_cnfg.h 01.05.12 01.05.11 |
18 | mpi_init.h 01.05.06 01.05.06 | 18 | mpi_init.h 01.05.07 01.05.06 |
19 | mpi_targ.h 01.05.05 01.05.05 | 19 | mpi_targ.h 01.05.06 01.05.05 |
20 | mpi_fc.h 01.05.01 01.05.01 | 20 | mpi_fc.h 01.05.01 01.05.01 |
21 | mpi_lan.h 01.05.01 01.05.01 | 21 | mpi_lan.h 01.05.01 01.05.01 |
22 | mpi_raid.h 01.05.02 01.05.02 | 22 | mpi_raid.h 01.05.02 01.05.02 |
23 | mpi_tool.h 01.05.03 01.05.03 | 23 | mpi_tool.h 01.05.03 01.05.03 |
24 | mpi_inb.h 01.05.01 01.05.01 | 24 | mpi_inb.h 01.05.01 01.05.01 |
25 | mpi_sas.h 01.05.02 01.05.01 | 25 | mpi_sas.h 01.05.03 01.05.02 |
26 | mpi_type.h 01.05.02 01.05.01 | 26 | mpi_type.h 01.05.02 01.05.02 |
27 | mpi_history.txt 01.05.12 01.05.11 | 27 | mpi_history.txt 01.05.13 01.05.12 |
28 | 28 | ||
29 | 29 | ||
30 | * Date Version Description | 30 | * Date Version Description |
@@ -93,6 +93,7 @@ mpi.h | |||
93 | * Added EEDP IOCStatus codes. | 93 | * Added EEDP IOCStatus codes. |
94 | * 08-03-05 01.05.09 Bumped MPI_HEADER_VERSION_UNIT. | 94 | * 08-03-05 01.05.09 Bumped MPI_HEADER_VERSION_UNIT. |
95 | * 08-30-05 01.05.10 Added 2 new IOCStatus codes for Target. | 95 | * 08-30-05 01.05.10 Added 2 new IOCStatus codes for Target. |
96 | * 03-27-06 01.05.11 Bumped MPI_HEADER_VERSION_UNIT. | ||
96 | * -------------------------------------------------------------------------- | 97 | * -------------------------------------------------------------------------- |
97 | 98 | ||
98 | mpi_ioc.h | 99 | mpi_ioc.h |
@@ -170,6 +171,17 @@ mpi_ioc.h | |||
170 | * Added new ReasonCode value for SAS Device Status Change | 171 | * Added new ReasonCode value for SAS Device Status Change |
171 | * event. | 172 | * event. |
172 | * Added new family code for FC949E. | 173 | * Added new family code for FC949E. |
174 | * 03-27-06 01.05.11 Added MPI_IOCFACTS_CAPABILITY_TLR. | ||
175 | * Added additional Reason Codes and more event data fields | ||
176 | * to EVENT_DATA_SAS_DEVICE_STATUS_CHANGE. | ||
177 | * Added EVENT_DATA_SAS_BROADCAST_PRIMITIVE structure and | ||
178 | * new event. | ||
179 | * Added MPI_EVENT_SAS_SMP_ERROR and event data structure. | ||
180 | * Added MPI_EVENT_SAS_INIT_DEVICE_STATUS_CHANGE and event | ||
181 | * data structure. | ||
182 | * Added MPI_EVENT_SAS_INIT_TABLE_OVERFLOW and event | ||
183 | * data structure. | ||
184 | * Added MPI_EXT_IMAGE_TYPE_INITIALIZATION. | ||
173 | * -------------------------------------------------------------------------- | 185 | * -------------------------------------------------------------------------- |
174 | 186 | ||
175 | mpi_cnfg.h | 187 | mpi_cnfg.h |
@@ -425,6 +437,16 @@ mpi_cnfg.h | |||
425 | * Added postpone SATA Init bit to SAS IO Unit Page 1 | 437 | * Added postpone SATA Init bit to SAS IO Unit Page 1 |
426 | * ControlFlags. | 438 | * ControlFlags. |
427 | * Changed LogEntry format for Log Page 0. | 439 | * Changed LogEntry format for Log Page 0. |
440 | * 03-27-06 01.05.12 Added two new Flags defines for Manufacturing Page 4. | ||
441 | * Added Manufacturing Page 7. | ||
442 | * Added MPI_IOCPAGE2_CAP_FLAGS_RAID_64_BIT_ADDRESSING. | ||
443 | * Added IOC Page 6. | ||
444 | * Added PrevBootDeviceForm field to CONFIG_PAGE_BIOS_2. | ||
445 | * Added MaxLBAHigh field to RAID Volume Page 0. | ||
446 | * Added Nvdata version fields to SAS IO Unit Page 0. | ||
447 | * Added AdditionalControlFlags, MaxTargetPortConnectTime, | ||
448 | * ReportDeviceMissingDelay, and IODeviceMissingDelay | ||
449 | * fields to SAS IO Unit Page 1. | ||
428 | * -------------------------------------------------------------------------- | 450 | * -------------------------------------------------------------------------- |
429 | 451 | ||
430 | mpi_init.h | 452 | mpi_init.h |
@@ -467,6 +489,7 @@ mpi_init.h | |||
467 | * Added four new defines for SEP SlotStatus. | 489 | * Added four new defines for SEP SlotStatus. |
468 | * 08-03-05 01.05.06 Fixed some MPI_SCSIIO32_MSGFLGS_ defines to make them | 490 | * 08-03-05 01.05.06 Fixed some MPI_SCSIIO32_MSGFLGS_ defines to make them |
469 | * unique in the first 32 characters. | 491 | * unique in the first 32 characters. |
492 | * 03-27-06 01.05.07 Added Task Management type of Clear ACA. | ||
470 | * -------------------------------------------------------------------------- | 493 | * -------------------------------------------------------------------------- |
471 | 494 | ||
472 | mpi_targ.h | 495 | mpi_targ.h |
@@ -511,6 +534,7 @@ mpi_targ.h | |||
511 | * 02-22-05 01.05.03 Changed a comment. | 534 | * 02-22-05 01.05.03 Changed a comment. |
512 | * 03-11-05 01.05.04 Removed TargetAssistExtended Request. | 535 | * 03-11-05 01.05.04 Removed TargetAssistExtended Request. |
513 | * 06-24-05 01.05.05 Added TargetAssistExtended structures and defines. | 536 | * 06-24-05 01.05.05 Added TargetAssistExtended structures and defines. |
537 | * 03-27-06 01.05.06 Added a comment. | ||
514 | * -------------------------------------------------------------------------- | 538 | * -------------------------------------------------------------------------- |
515 | 539 | ||
516 | mpi_fc.h | 540 | mpi_fc.h |
@@ -610,6 +634,10 @@ mpi_sas.h | |||
610 | * 08-30-05 01.05.02 Added DeviceInfo bit for SEP. | 634 | * 08-30-05 01.05.02 Added DeviceInfo bit for SEP. |
611 | * Added PrimFlags and Primitive field to SAS IO Unit | 635 | * Added PrimFlags and Primitive field to SAS IO Unit |
612 | * Control request, and added a new operation code. | 636 | * Control request, and added a new operation code. |
637 | * 03-27-06 01.05.03 Added Force Full Discovery, Transmit Port Select Signal, | ||
638 | * and Remove Device operations to SAS IO Unit Control. | ||
639 | * Added DevHandle field to SAS IO Unit Control request and | ||
640 | * reply. | ||
613 | * -------------------------------------------------------------------------- | 641 | * -------------------------------------------------------------------------- |
614 | 642 | ||
615 | mpi_type.h | 643 | mpi_type.h |
@@ -625,20 +653,20 @@ mpi_type.h | |||
625 | 653 | ||
626 | mpi_history.txt Parts list history | 654 | mpi_history.txt Parts list history |
627 | 655 | ||
628 | Filename 01.05.12 01.05.11 01.05.10 01.05.09 | 656 | Filename 01.05.13 01.05.12 01.05.11 01.05.10 01.05.09 |
629 | ---------- -------- -------- -------- -------- | 657 | ---------- -------- -------- -------- -------- -------- |
630 | mpi.h 01.05.10 01.05.09 01.05.08 01.05.07 | 658 | mpi.h 01.05.11 01.05.10 01.05.09 01.05.08 01.05.07 |
631 | mpi_ioc.h 01.05.10 01.05.09 01.05.09 01.05.08 | 659 | mpi_ioc.h 01.05.11 01.05.10 01.05.09 01.05.09 01.05.08 |
632 | mpi_cnfg.h 01.05.11 01.05.10 01.05.09 01.05.08 | 660 | mpi_cnfg.h 01.05.12 01.05.11 01.05.10 01.05.09 01.05.08 |
633 | mpi_init.h 01.05.06 01.05.06 01.05.05 01.05.04 | 661 | mpi_init.h 01.05.07 01.05.06 01.05.06 01.05.05 01.05.04 |
634 | mpi_targ.h 01.05.05 01.05.05 01.05.05 01.05.04 | 662 | mpi_targ.h 01.05.06 01.05.05 01.05.05 01.05.05 01.05.04 |
635 | mpi_fc.h 01.05.01 01.05.01 01.05.01 01.05.01 | 663 | mpi_fc.h 01.05.01 01.05.01 01.05.01 01.05.01 01.05.01 |
636 | mpi_lan.h 01.05.01 01.05.01 01.05.01 01.05.01 | 664 | mpi_lan.h 01.05.01 01.05.01 01.05.01 01.05.01 01.05.01 |
637 | mpi_raid.h 01.05.02 01.05.02 01.05.02 01.05.02 | 665 | mpi_raid.h 01.05.02 01.05.02 01.05.02 01.05.02 01.05.02 |
638 | mpi_tool.h 01.05.03 01.05.03 01.05.03 01.05.03 | 666 | mpi_tool.h 01.05.03 01.05.03 01.05.03 01.05.03 01.05.03 |
639 | mpi_inb.h 01.05.01 01.05.01 01.05.01 01.05.01 | 667 | mpi_inb.h 01.05.01 01.05.01 01.05.01 01.05.01 01.05.01 |
640 | mpi_sas.h 01.05.02 01.05.01 01.05.01 01.05.01 | 668 | mpi_sas.h 01.05.03 01.05.02 01.05.01 01.05.01 01.05.01 |
641 | mpi_type.h 01.05.02 01.05.01 01.05.01 01.05.01 | 669 | mpi_type.h 01.05.02 01.05.02 01.05.01 01.05.01 01.05.01 |
642 | 670 | ||
643 | Filename 01.05.08 01.05.07 01.05.06 01.05.05 01.05.04 01.05.03 | 671 | Filename 01.05.08 01.05.07 01.05.06 01.05.05 01.05.04 01.05.03 |
644 | ---------- -------- -------- -------- -------- -------- -------- | 672 | ---------- -------- -------- -------- -------- -------- -------- |
diff --git a/drivers/message/fusion/lsi/mpi_init.h b/drivers/message/fusion/lsi/mpi_init.h index 68941f459ca3..c1c678989a23 100644 --- a/drivers/message/fusion/lsi/mpi_init.h +++ b/drivers/message/fusion/lsi/mpi_init.h | |||
@@ -6,7 +6,7 @@ | |||
6 | * Title: MPI initiator mode messages and structures | 6 | * Title: MPI initiator mode messages and structures |
7 | * Creation Date: June 8, 2000 | 7 | * Creation Date: June 8, 2000 |
8 | * | 8 | * |
9 | * mpi_init.h Version: 01.05.06 | 9 | * mpi_init.h Version: 01.05.07 |
10 | * | 10 | * |
11 | * Version History | 11 | * Version History |
12 | * --------------- | 12 | * --------------- |
@@ -52,6 +52,7 @@ | |||
52 | * Added four new defines for SEP SlotStatus. | 52 | * Added four new defines for SEP SlotStatus. |
53 | * 08-03-05 01.05.06 Fixed some MPI_SCSIIO32_MSGFLGS_ defines to make them | 53 | * 08-03-05 01.05.06 Fixed some MPI_SCSIIO32_MSGFLGS_ defines to make them |
54 | * unique in the first 32 characters. | 54 | * unique in the first 32 characters. |
55 | * 03-27-06 01.05.07 Added Task Management type of Clear ACA. | ||
55 | * -------------------------------------------------------------------------- | 56 | * -------------------------------------------------------------------------- |
56 | */ | 57 | */ |
57 | 58 | ||
@@ -427,6 +428,7 @@ typedef struct _MSG_SCSI_TASK_MGMT | |||
427 | #define MPI_SCSITASKMGMT_TASKTYPE_LOGICAL_UNIT_RESET (0x05) | 428 | #define MPI_SCSITASKMGMT_TASKTYPE_LOGICAL_UNIT_RESET (0x05) |
428 | #define MPI_SCSITASKMGMT_TASKTYPE_CLEAR_TASK_SET (0x06) | 429 | #define MPI_SCSITASKMGMT_TASKTYPE_CLEAR_TASK_SET (0x06) |
429 | #define MPI_SCSITASKMGMT_TASKTYPE_QUERY_TASK (0x07) | 430 | #define MPI_SCSITASKMGMT_TASKTYPE_QUERY_TASK (0x07) |
431 | #define MPI_SCSITASKMGMT_TASKTYPE_CLEAR_ACA (0x08) | ||
430 | 432 | ||
431 | /* MsgFlags bits */ | 433 | /* MsgFlags bits */ |
432 | #define MPI_SCSITASKMGMT_MSGFLAGS_TARGET_RESET_OPTION (0x00) | 434 | #define MPI_SCSITASKMGMT_MSGFLAGS_TARGET_RESET_OPTION (0x00) |
diff --git a/drivers/message/fusion/lsi/mpi_ioc.h b/drivers/message/fusion/lsi/mpi_ioc.h index 2c5f43fa7c73..18ba407fd399 100644 --- a/drivers/message/fusion/lsi/mpi_ioc.h +++ b/drivers/message/fusion/lsi/mpi_ioc.h | |||
@@ -6,7 +6,7 @@ | |||
6 | * Title: MPI IOC, Port, Event, FW Download, and FW Upload messages | 6 | * Title: MPI IOC, Port, Event, FW Download, and FW Upload messages |
7 | * Creation Date: August 11, 2000 | 7 | * Creation Date: August 11, 2000 |
8 | * | 8 | * |
9 | * mpi_ioc.h Version: 01.05.10 | 9 | * mpi_ioc.h Version: 01.05.11 |
10 | * | 10 | * |
11 | * Version History | 11 | * Version History |
12 | * --------------- | 12 | * --------------- |
@@ -87,6 +87,17 @@ | |||
87 | * Added new ReasonCode value for SAS Device Status Change | 87 | * Added new ReasonCode value for SAS Device Status Change |
88 | * event. | 88 | * event. |
89 | * Added new family code for FC949E. | 89 | * Added new family code for FC949E. |
90 | * 03-27-06 01.05.11 Added MPI_IOCFACTS_CAPABILITY_TLR. | ||
91 | * Added additional Reason Codes and more event data fields | ||
92 | * to EVENT_DATA_SAS_DEVICE_STATUS_CHANGE. | ||
93 | * Added EVENT_DATA_SAS_BROADCAST_PRIMITIVE structure and | ||
94 | * new event. | ||
95 | * Added MPI_EVENT_SAS_SMP_ERROR and event data structure. | ||
96 | * Added MPI_EVENT_SAS_INIT_DEVICE_STATUS_CHANGE and event | ||
97 | * data structure. | ||
98 | * Added MPI_EVENT_SAS_INIT_TABLE_OVERFLOW and event | ||
99 | * data structure. | ||
100 | * Added MPI_EXT_IMAGE_TYPE_INITIALIZATION. | ||
90 | * -------------------------------------------------------------------------- | 101 | * -------------------------------------------------------------------------- |
91 | */ | 102 | */ |
92 | 103 | ||
@@ -272,6 +283,7 @@ typedef struct _MSG_IOC_FACTS_REPLY | |||
272 | #define MPI_IOCFACTS_CAPABILITY_MULTICAST (0x00000100) | 283 | #define MPI_IOCFACTS_CAPABILITY_MULTICAST (0x00000100) |
273 | #define MPI_IOCFACTS_CAPABILITY_SCSIIO32 (0x00000200) | 284 | #define MPI_IOCFACTS_CAPABILITY_SCSIIO32 (0x00000200) |
274 | #define MPI_IOCFACTS_CAPABILITY_NO_SCSIIO16 (0x00000400) | 285 | #define MPI_IOCFACTS_CAPABILITY_NO_SCSIIO16 (0x00000400) |
286 | #define MPI_IOCFACTS_CAPABILITY_TLR (0x00000800) | ||
275 | 287 | ||
276 | 288 | ||
277 | /***************************************************************************** | 289 | /***************************************************************************** |
@@ -448,30 +460,34 @@ typedef struct _MSG_EVENT_ACK_REPLY | |||
448 | 460 | ||
449 | /* Event */ | 461 | /* Event */ |
450 | 462 | ||
451 | #define MPI_EVENT_NONE (0x00000000) | 463 | #define MPI_EVENT_NONE (0x00000000) |
452 | #define MPI_EVENT_LOG_DATA (0x00000001) | 464 | #define MPI_EVENT_LOG_DATA (0x00000001) |
453 | #define MPI_EVENT_STATE_CHANGE (0x00000002) | 465 | #define MPI_EVENT_STATE_CHANGE (0x00000002) |
454 | #define MPI_EVENT_UNIT_ATTENTION (0x00000003) | 466 | #define MPI_EVENT_UNIT_ATTENTION (0x00000003) |
455 | #define MPI_EVENT_IOC_BUS_RESET (0x00000004) | 467 | #define MPI_EVENT_IOC_BUS_RESET (0x00000004) |
456 | #define MPI_EVENT_EXT_BUS_RESET (0x00000005) | 468 | #define MPI_EVENT_EXT_BUS_RESET (0x00000005) |
457 | #define MPI_EVENT_RESCAN (0x00000006) | 469 | #define MPI_EVENT_RESCAN (0x00000006) |
458 | #define MPI_EVENT_LINK_STATUS_CHANGE (0x00000007) | 470 | #define MPI_EVENT_LINK_STATUS_CHANGE (0x00000007) |
459 | #define MPI_EVENT_LOOP_STATE_CHANGE (0x00000008) | 471 | #define MPI_EVENT_LOOP_STATE_CHANGE (0x00000008) |
460 | #define MPI_EVENT_LOGOUT (0x00000009) | 472 | #define MPI_EVENT_LOGOUT (0x00000009) |
461 | #define MPI_EVENT_EVENT_CHANGE (0x0000000A) | 473 | #define MPI_EVENT_EVENT_CHANGE (0x0000000A) |
462 | #define MPI_EVENT_INTEGRATED_RAID (0x0000000B) | 474 | #define MPI_EVENT_INTEGRATED_RAID (0x0000000B) |
463 | #define MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE (0x0000000C) | 475 | #define MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE (0x0000000C) |
464 | #define MPI_EVENT_ON_BUS_TIMER_EXPIRED (0x0000000D) | 476 | #define MPI_EVENT_ON_BUS_TIMER_EXPIRED (0x0000000D) |
465 | #define MPI_EVENT_QUEUE_FULL (0x0000000E) | 477 | #define MPI_EVENT_QUEUE_FULL (0x0000000E) |
466 | #define MPI_EVENT_SAS_DEVICE_STATUS_CHANGE (0x0000000F) | 478 | #define MPI_EVENT_SAS_DEVICE_STATUS_CHANGE (0x0000000F) |
467 | #define MPI_EVENT_SAS_SES (0x00000010) | 479 | #define MPI_EVENT_SAS_SES (0x00000010) |
468 | #define MPI_EVENT_PERSISTENT_TABLE_FULL (0x00000011) | 480 | #define MPI_EVENT_PERSISTENT_TABLE_FULL (0x00000011) |
469 | #define MPI_EVENT_SAS_PHY_LINK_STATUS (0x00000012) | 481 | #define MPI_EVENT_SAS_PHY_LINK_STATUS (0x00000012) |
470 | #define MPI_EVENT_SAS_DISCOVERY_ERROR (0x00000013) | 482 | #define MPI_EVENT_SAS_DISCOVERY_ERROR (0x00000013) |
471 | #define MPI_EVENT_IR_RESYNC_UPDATE (0x00000014) | 483 | #define MPI_EVENT_IR_RESYNC_UPDATE (0x00000014) |
472 | #define MPI_EVENT_IR2 (0x00000015) | 484 | #define MPI_EVENT_IR2 (0x00000015) |
473 | #define MPI_EVENT_SAS_DISCOVERY (0x00000016) | 485 | #define MPI_EVENT_SAS_DISCOVERY (0x00000016) |
474 | #define MPI_EVENT_LOG_ENTRY_ADDED (0x00000021) | 486 | #define MPI_EVENT_SAS_BROADCAST_PRIMITIVE (0x00000017) |
487 | #define MPI_EVENT_SAS_INIT_DEVICE_STATUS_CHANGE (0x00000018) | ||
488 | #define MPI_EVENT_SAS_INIT_TABLE_OVERFLOW (0x00000019) | ||
489 | #define MPI_EVENT_SAS_SMP_ERROR (0x0000001A) | ||
490 | #define MPI_EVENT_LOG_ENTRY_ADDED (0x00000021) | ||
475 | 491 | ||
476 | /* AckRequired field values */ | 492 | /* AckRequired field values */ |
477 | 493 | ||
@@ -558,18 +574,25 @@ typedef struct _EVENT_DATA_SAS_DEVICE_STATUS_CHANGE | |||
558 | U8 PhyNum; /* 0Eh */ | 574 | U8 PhyNum; /* 0Eh */ |
559 | U8 Reserved1; /* 0Fh */ | 575 | U8 Reserved1; /* 0Fh */ |
560 | U64 SASAddress; /* 10h */ | 576 | U64 SASAddress; /* 10h */ |
577 | U8 LUN[8]; /* 18h */ | ||
578 | U16 TaskTag; /* 20h */ | ||
579 | U16 Reserved2; /* 22h */ | ||
561 | } EVENT_DATA_SAS_DEVICE_STATUS_CHANGE, | 580 | } EVENT_DATA_SAS_DEVICE_STATUS_CHANGE, |
562 | MPI_POINTER PTR_EVENT_DATA_SAS_DEVICE_STATUS_CHANGE, | 581 | MPI_POINTER PTR_EVENT_DATA_SAS_DEVICE_STATUS_CHANGE, |
563 | MpiEventDataSasDeviceStatusChange_t, | 582 | MpiEventDataSasDeviceStatusChange_t, |
564 | MPI_POINTER pMpiEventDataSasDeviceStatusChange_t; | 583 | MPI_POINTER pMpiEventDataSasDeviceStatusChange_t; |
565 | 584 | ||
566 | /* MPI SAS Device Status Change Event data ReasonCode values */ | 585 | /* MPI SAS Device Status Change Event data ReasonCode values */ |
567 | #define MPI_EVENT_SAS_DEV_STAT_RC_ADDED (0x03) | 586 | #define MPI_EVENT_SAS_DEV_STAT_RC_ADDED (0x03) |
568 | #define MPI_EVENT_SAS_DEV_STAT_RC_NOT_RESPONDING (0x04) | 587 | #define MPI_EVENT_SAS_DEV_STAT_RC_NOT_RESPONDING (0x04) |
569 | #define MPI_EVENT_SAS_DEV_STAT_RC_SMART_DATA (0x05) | 588 | #define MPI_EVENT_SAS_DEV_STAT_RC_SMART_DATA (0x05) |
570 | #define MPI_EVENT_SAS_DEV_STAT_RC_NO_PERSIST_ADDED (0x06) | 589 | #define MPI_EVENT_SAS_DEV_STAT_RC_NO_PERSIST_ADDED (0x06) |
571 | #define MPI_EVENT_SAS_DEV_STAT_RC_UNSUPPORTED (0x07) | 590 | #define MPI_EVENT_SAS_DEV_STAT_RC_UNSUPPORTED (0x07) |
572 | #define MPI_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET (0x08) | 591 | #define MPI_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET (0x08) |
592 | #define MPI_EVENT_SAS_DEV_STAT_RC_TASK_ABORT_INTERNAL (0x09) | ||
593 | #define MPI_EVENT_SAS_DEV_STAT_RC_ABORT_TASK_SET_INTERNAL (0x0A) | ||
594 | #define MPI_EVENT_SAS_DEV_STAT_RC_CLEAR_TASK_SET_INTERNAL (0x0B) | ||
595 | #define MPI_EVENT_SAS_DEV_STAT_RC_QUERY_TASK_INTERNAL (0x0C) | ||
573 | 596 | ||
574 | 597 | ||
575 | /* SCSI Event data for Queue Full event */ | 598 | /* SCSI Event data for Queue Full event */ |
@@ -742,6 +765,27 @@ typedef struct _EVENT_DATA_SAS_SES | |||
742 | } EVENT_DATA_SAS_SES, MPI_POINTER PTR_EVENT_DATA_SAS_SES, | 765 | } EVENT_DATA_SAS_SES, MPI_POINTER PTR_EVENT_DATA_SAS_SES, |
743 | MpiEventDataSasSes_t, MPI_POINTER pMpiEventDataSasSes_t; | 766 | MpiEventDataSasSes_t, MPI_POINTER pMpiEventDataSasSes_t; |
744 | 767 | ||
768 | /* SAS Broadcast Primitive Event data */ | ||
769 | |||
770 | typedef struct _EVENT_DATA_SAS_BROADCAST_PRIMITIVE | ||
771 | { | ||
772 | U8 PhyNum; /* 00h */ | ||
773 | U8 Port; /* 01h */ | ||
774 | U8 PortWidth; /* 02h */ | ||
775 | U8 Primitive; /* 04h */ | ||
776 | } EVENT_DATA_SAS_BROADCAST_PRIMITIVE, | ||
777 | MPI_POINTER PTR_EVENT_DATA_SAS_BROADCAST_PRIMITIVE, | ||
778 | MpiEventDataSasBroadcastPrimitive_t, | ||
779 | MPI_POINTER pMpiEventDataSasBroadcastPrimitive_t; | ||
780 | |||
781 | #define MPI_EVENT_PRIMITIVE_CHANGE (0x01) | ||
782 | #define MPI_EVENT_PRIMITIVE_EXPANDER (0x03) | ||
783 | #define MPI_EVENT_PRIMITIVE_RESERVED2 (0x04) | ||
784 | #define MPI_EVENT_PRIMITIVE_RESERVED3 (0x05) | ||
785 | #define MPI_EVENT_PRIMITIVE_RESERVED4 (0x06) | ||
786 | #define MPI_EVENT_PRIMITIVE_CHANGE0_RESERVED (0x07) | ||
787 | #define MPI_EVENT_PRIMITIVE_CHANGE1_RESERVED (0x08) | ||
788 | |||
745 | /* SAS Phy Link Status Event data */ | 789 | /* SAS Phy Link Status Event data */ |
746 | 790 | ||
747 | typedef struct _EVENT_DATA_SAS_PHY_LINK_STATUS | 791 | typedef struct _EVENT_DATA_SAS_PHY_LINK_STATUS |
@@ -804,6 +848,53 @@ typedef struct _EVENT_DATA_DISCOVERY_ERROR | |||
804 | #define MPI_EVENT_DSCVRY_ERR_DS_MULTPL_PATHS (0x00000800) | 848 | #define MPI_EVENT_DSCVRY_ERR_DS_MULTPL_PATHS (0x00000800) |
805 | #define MPI_EVENT_DSCVRY_ERR_DS_MAX_SATA_TARGETS (0x00001000) | 849 | #define MPI_EVENT_DSCVRY_ERR_DS_MAX_SATA_TARGETS (0x00001000) |
806 | 850 | ||
851 | /* SAS SMP Error Event data */ | ||
852 | |||
853 | typedef struct _EVENT_DATA_SAS_SMP_ERROR | ||
854 | { | ||
855 | U8 Status; /* 00h */ | ||
856 | U8 Port; /* 01h */ | ||
857 | U8 SMPFunctionResult; /* 02h */ | ||
858 | U8 Reserved1; /* 03h */ | ||
859 | U64 SASAddress; /* 04h */ | ||
860 | } EVENT_DATA_SAS_SMP_ERROR, MPI_POINTER PTR_EVENT_DATA_SAS_SMP_ERROR, | ||
861 | MpiEventDataSasSmpError_t, MPI_POINTER pMpiEventDataSasSmpError_t; | ||
862 | |||
863 | /* defines for the Status field of the SAS SMP Error event */ | ||
864 | #define MPI_EVENT_SAS_SMP_FUNCTION_RESULT_VALID (0x00) | ||
865 | #define MPI_EVENT_SAS_SMP_CRC_ERROR (0x01) | ||
866 | #define MPI_EVENT_SAS_SMP_TIMEOUT (0x02) | ||
867 | #define MPI_EVENT_SAS_SMP_NO_DESTINATION (0x03) | ||
868 | #define MPI_EVENT_SAS_SMP_BAD_DESTINATION (0x04) | ||
869 | |||
870 | /* SAS Initiator Device Status Change Event data */ | ||
871 | |||
872 | typedef struct _EVENT_DATA_SAS_INIT_DEV_STATUS_CHANGE | ||
873 | { | ||
874 | U8 ReasonCode; /* 00h */ | ||
875 | U8 Port; /* 01h */ | ||
876 | U16 DevHandle; /* 02h */ | ||
877 | U64 SASAddress; /* 04h */ | ||
878 | } EVENT_DATA_SAS_INIT_DEV_STATUS_CHANGE, | ||
879 | MPI_POINTER PTR_EVENT_DATA_SAS_INIT_DEV_STATUS_CHANGE, | ||
880 | MpiEventDataSasInitDevStatusChange_t, | ||
881 | MPI_POINTER pMpiEventDataSasInitDevStatusChange_t; | ||
882 | |||
883 | /* defines for the ReasonCode field of the SAS Initiator Device Status Change event */ | ||
884 | #define MPI_EVENT_SAS_INIT_RC_ADDED (0x01) | ||
885 | |||
886 | /* SAS Initiator Device Table Overflow Event data */ | ||
887 | |||
888 | typedef struct _EVENT_DATA_SAS_INIT_TABLE_OVERFLOW | ||
889 | { | ||
890 | U8 MaxInit; /* 00h */ | ||
891 | U8 CurrentInit; /* 01h */ | ||
892 | U16 Reserved1; /* 02h */ | ||
893 | } EVENT_DATA_SAS_INIT_TABLE_OVERFLOW, | ||
894 | MPI_POINTER PTR_EVENT_DATA_SAS_INIT_TABLE_OVERFLOW, | ||
895 | MpiEventDataSasInitTableOverflow_t, | ||
896 | MPI_POINTER pMpiEventDataSasInitTableOverflow_t; | ||
897 | |||
807 | 898 | ||
808 | /***************************************************************************** | 899 | /***************************************************************************** |
809 | * | 900 | * |
@@ -1013,5 +1104,6 @@ typedef struct _MPI_EXT_IMAGE_HEADER | |||
1013 | #define MPI_EXT_IMAGE_TYPE_FW (0x01) | 1104 | #define MPI_EXT_IMAGE_TYPE_FW (0x01) |
1014 | #define MPI_EXT_IMAGE_TYPE_NVDATA (0x03) | 1105 | #define MPI_EXT_IMAGE_TYPE_NVDATA (0x03) |
1015 | #define MPI_EXT_IMAGE_TYPE_BOOTLOADER (0x04) | 1106 | #define MPI_EXT_IMAGE_TYPE_BOOTLOADER (0x04) |
1107 | #define MPI_EXT_IMAGE_TYPE_INITIALIZATION (0x05) | ||
1016 | 1108 | ||
1017 | #endif | 1109 | #endif |
diff --git a/drivers/message/fusion/lsi/mpi_log_sas.h b/drivers/message/fusion/lsi/mpi_log_sas.h index a9c14ad132ce..871ebc08b706 100644 --- a/drivers/message/fusion/lsi/mpi_log_sas.h +++ b/drivers/message/fusion/lsi/mpi_log_sas.h | |||
@@ -13,6 +13,8 @@ | |||
13 | #ifndef IOPI_IOCLOGINFO_H_INCLUDED | 13 | #ifndef IOPI_IOCLOGINFO_H_INCLUDED |
14 | #define IOPI_IOCLOGINFO_H_INCLUDED | 14 | #define IOPI_IOCLOGINFO_H_INCLUDED |
15 | 15 | ||
16 | #define SAS_LOGINFO_NEXUS_LOSS 0x31170000 | ||
17 | #define SAS_LOGINFO_MASK 0xFFFF0000 | ||
16 | 18 | ||
17 | /****************************************************************************/ | 19 | /****************************************************************************/ |
18 | /* IOC LOGINFO defines, 0x00000000 - 0x0FFFFFFF */ | 20 | /* IOC LOGINFO defines, 0x00000000 - 0x0FFFFFFF */ |
@@ -51,6 +53,9 @@ | |||
51 | #define IOP_LOGINFO_CODE_CONFIG_INVALID_PAGE_DNM (0x00030500) /* Device Not Mapped */ | 53 | #define IOP_LOGINFO_CODE_CONFIG_INVALID_PAGE_DNM (0x00030500) /* Device Not Mapped */ |
52 | #define IOP_LOGINFO_CODE_CONFIG_INVALID_PAGE_PERSIST (0x00030600) /* Persistent Page not found */ | 54 | #define IOP_LOGINFO_CODE_CONFIG_INVALID_PAGE_PERSIST (0x00030600) /* Persistent Page not found */ |
53 | #define IOP_LOGINFO_CODE_CONFIG_INVALID_PAGE_DEFAULT (0x00030700) /* Default Page not found */ | 55 | #define IOP_LOGINFO_CODE_CONFIG_INVALID_PAGE_DEFAULT (0x00030700) /* Default Page not found */ |
56 | |||
57 | #define IOP_LOGINFO_CODE_DIAG_MSG_ERROR (0x00040000) /* Error handling diag msg - or'd with diag status */ | ||
58 | |||
54 | #define IOP_LOGINFO_CODE_TASK_TERMINATED (0x00050000) | 59 | #define IOP_LOGINFO_CODE_TASK_TERMINATED (0x00050000) |
55 | 60 | ||
56 | #define IOP_LOGINFO_CODE_ENCL_MGMT_READ_ACTION_ERR0R (0x00060001) /* Read Action not supported for SEP msg */ | 61 | #define IOP_LOGINFO_CODE_ENCL_MGMT_READ_ACTION_ERR0R (0x00060001) /* Read Action not supported for SEP msg */ |
@@ -103,6 +108,7 @@ | |||
103 | #define PL_LOGINFO_CODE_IO_EXECUTED (0x00140000) | 108 | #define PL_LOGINFO_CODE_IO_EXECUTED (0x00140000) |
104 | #define PL_LOGINFO_CODE_PERS_RESV_OUT_NOT_AFFIL_OWNER (0x00150000) | 109 | #define PL_LOGINFO_CODE_PERS_RESV_OUT_NOT_AFFIL_OWNER (0x00150000) |
105 | #define PL_LOGINFO_CODE_OPEN_TXDMA_ABORT (0x00160000) | 110 | #define PL_LOGINFO_CODE_OPEN_TXDMA_ABORT (0x00160000) |
111 | #define PL_LOGINFO_CODE_IO_DEVICE_MISSING_DELAY_RETRY (0x00170000) | ||
106 | #define PL_LOGINFO_SUB_CODE_OPEN_FAILURE (0x00000100) | 112 | #define PL_LOGINFO_SUB_CODE_OPEN_FAILURE (0x00000100) |
107 | #define PL_LOGINFO_SUB_CODE_OPEN_FAILURE_NO_DEST_TIMEOUT (0x00000101) | 113 | #define PL_LOGINFO_SUB_CODE_OPEN_FAILURE_NO_DEST_TIMEOUT (0x00000101) |
108 | #define PL_LOGINFO_SUB_CODE_OPEN_FAILURE_ORR_TIMEOUT (0x0000011A) /* Open Reject (Retry) Timeout */ | 114 | #define PL_LOGINFO_SUB_CODE_OPEN_FAILURE_ORR_TIMEOUT (0x0000011A) /* Open Reject (Retry) Timeout */ |
@@ -165,11 +171,81 @@ | |||
165 | /****************************************************************************/ | 171 | /****************************************************************************/ |
166 | /* IR LOGINFO_CODE defines, valid if IOC_LOGINFO_ORIGINATOR = IR */ | 172 | /* IR LOGINFO_CODE defines, valid if IOC_LOGINFO_ORIGINATOR = IR */ |
167 | /****************************************************************************/ | 173 | /****************************************************************************/ |
168 | #define IR_LOGINFO_CODE_UNUSED1 (0x00010000) | 174 | #define IR_LOGINFO_RAID_ACTION_ERROR (0x00010000) |
169 | #define IR_LOGINFO_CODE_UNUSED2 (0x00020000) | 175 | #define IR_LOGINFO_CODE_UNUSED2 (0x00020000) |
176 | |||
177 | /* Amount of information passed down for Create Volume is too large */ | ||
178 | #define IR_LOGINFO_VOLUME_CREATE_INVALID_LENGTH (0x00010001) | ||
179 | /* Creation of duplicate volume attempted (Bus/Target ID checked) */ | ||
180 | #define IR_LOGINFO_VOLUME_CREATE_DUPLICATE (0x00010002) | ||
181 | /* Creation failed due to maximum number of supported volumes exceeded */ | ||
182 | #define IR_LOGINFO_VOLUME_CREATE_NO_SLOTS (0x00010003) | ||
183 | /* Creation failed due to DMA error in trying to read from host */ | ||
184 | #define IR_LOGINFO_VOLUME_CREATE_DMA_ERROR (0x00010004) | ||
185 | /* Creation failed due to invalid volume type passed down */ | ||
186 | #define IR_LOGINFO_VOLUME_CREATE_INVALID_VOLUME_TYPE (0x00010005) | ||
187 | /* Creation failed due to error reading MFG Page 4 */ | ||
188 | #define IR_LOGINFO_VOLUME_MFG_PAGE4_ERROR (0x00010006) | ||
189 | /* Creation failed when trying to create internal structures */ | ||
190 | #define IR_LOGINFO_VOLUME_INTERNAL_CONFIG_STRUCTURE_ERROR (0x00010007) | ||
191 | |||
192 | /* Activation failed due to trying to activate an already active volume */ | ||
193 | #define IR_LOGINFO_VOLUME_ACTIVATING_AN_ACTIVE_VOLUME (0x00010010) | ||
194 | /* Activation failed due to trying to active unsupported volume type */ | ||
195 | #define IR_LOGINFO_VOLUME_ACTIVATING_INVALID_VOLUME_TYPE (0x00010011) | ||
196 | /* Activation failed due to trying to active too many volumes */ | ||
197 | #define IR_LOGINFO_VOLUME_ACTIVATING_TOO_MANY_VOLUMES (0x00010012) | ||
198 | /* Activation failed due to Volume ID in use already */ | ||
199 | #define IR_LOGINFO_VOLUME_ACTIVATING_VOLUME_ID_IN_USE (0x00010013) | ||
200 | /* Activation failed call to activateVolume returned failure */ | ||
201 | #define IR_LOGINFO_VOLUME_ACTIVATE_VOLUME_FAILED (0x00010014) | ||
202 | /* Activation failed trying to import the volume */ | ||
203 | #define IR_LOGINFO_VOLUME_ACTIVATING_IMPORT_VOLUME_FAILED (0x00010015) | ||
204 | |||
205 | /* Phys Disk failed, too many phys disks */ | ||
206 | #define IR_LOGINFO_PHYSDISK_CREATE_TOO_MANY_DISKS (0x00010020) | ||
207 | /* Amount of information passed down for Create Pnysdisk is too large */ | ||
208 | #define IR_LOGINFO_PHYSDISK_CREATE_INVALID_LENGTH (0x00010021) | ||
209 | /* Creation failed due to DMA error in trying to read from host */ | ||
210 | #define IR_LOGINFO_PHYSDISK_CREATE_DMA_ERROR (0x00010022) | ||
211 | /* Creation failed due to invalid Bus TargetID passed down */ | ||
212 | #define IR_LOGINFO_PHYSDISK_CREATE_BUS_TID_INVALID (0x00010023) | ||
213 | /* Creation failed due to error in creating RAID Phys Disk Config Page */ | ||
214 | #define IR_LOGINFO_PHYSDISK_CREATE_CONFIG_PAGE_ERROR (0x00010024) | ||
215 | |||
216 | |||
217 | /* Compatibility Error : IR Disabled */ | ||
218 | #define IR_LOGINFO_COMPAT_ERROR_RAID_DISABLED (0x00010030) | ||
219 | /* Compatibility Error : Inquiry Comand failed */ | ||
220 | #define IR_LOGINFO_COMPAT_ERROR_INQUIRY_FAILED (0x00010031) | ||
221 | /* Compatibility Error : Device not direct access device */ | ||
222 | #define IR_LOGINFO_COMPAT_ERROR_NOT_DIRECT_ACCESS (0x00010032) | ||
223 | /* Compatibility Error : Removable device found */ | ||
224 | #define IR_LOGINFO_COMPAT_ERROR_REMOVABLE_FOUND (0x00010033) | ||
225 | /* Compatibility Error : Device SCSI Version not 2 or higher */ | ||
226 | #define IR_LOGINFO_COMPAT_ERROR_NEED_SCSI_2_OR_HIGHER (0x00010034) | ||
227 | /* Compatibility Error : SATA device, 48 BIT LBA not supported */ | ||
228 | #define IR_LOGINFO_COMPAT_ERROR_SATA_48BIT_LBA_NOT_SUPPORTED (0x00010035) | ||
229 | /* Compatibility Error : Device does not have 512 byte block sizes */ | ||
230 | #define IR_LOGINFO_COMPAT_ERROR_DEVICE_NOT_512_BYTE_BLOCK (0x00010036) | ||
231 | /* Compatibility Error : Volume Type check failed */ | ||
232 | #define IR_LOGINFO_COMPAT_ERROR_VOLUME_TYPE_CHECK_FAILED (0x00010037) | ||
233 | /* Compatibility Error : Volume Type is unsupported by FW */ | ||
234 | #define IR_LOGINFO_COMPAT_ERROR_UNSUPPORTED_VOLUME_TYPE (0x00010038) | ||
235 | /* Compatibility Error : Disk drive too small for use in volume */ | ||
236 | #define IR_LOGINFO_COMPAT_ERROR_DISK_TOO_SMALL (0x00010039) | ||
237 | /* Compatibility Error : Phys disk for Create Volume not found */ | ||
238 | #define IR_LOGINFO_COMPAT_ERROR_PHYS_DISK_NOT_FOUND (0x0001003A) | ||
239 | /* Compatibility Error : membership count error, too many or too few disks for volume type */ | ||
240 | #define IR_LOGINFO_COMPAT_ERROR_MEMBERSHIP_COUNT (0x0001003B) | ||
241 | /* Compatibility Error : Disk stripe sizes must be 64KB */ | ||
242 | #define IR_LOGINFO_COMPAT_ERROR_NON_64K_STRIPE_SIZE (0x0001003C) | ||
243 | /* Compatibility Error : IME size limited to < 2TB */ | ||
244 | #define IR_LOGINFO_COMPAT_ERROR_IME_VOL_NOT_CURRENTLY_SUPPORTED (0x0001003D) | ||
245 | |||
170 | 246 | ||
171 | /****************************************************************************/ | 247 | /****************************************************************************/ |
172 | /* Defines for convienence */ | 248 | /* Defines for convenience */ |
173 | /****************************************************************************/ | 249 | /****************************************************************************/ |
174 | #define IOC_LOGINFO_PREFIX_IOP ((MPI_IOCLOGINFO_TYPE_SAS << MPI_IOCLOGINFO_TYPE_SHIFT) | IOC_LOGINFO_ORIGINATOR_IOP) | 250 | #define IOC_LOGINFO_PREFIX_IOP ((MPI_IOCLOGINFO_TYPE_SAS << MPI_IOCLOGINFO_TYPE_SHIFT) | IOC_LOGINFO_ORIGINATOR_IOP) |
175 | #define IOC_LOGINFO_PREFIX_PL ((MPI_IOCLOGINFO_TYPE_SAS << MPI_IOCLOGINFO_TYPE_SHIFT) | IOC_LOGINFO_ORIGINATOR_PL) | 251 | #define IOC_LOGINFO_PREFIX_PL ((MPI_IOCLOGINFO_TYPE_SAS << MPI_IOCLOGINFO_TYPE_SHIFT) | IOC_LOGINFO_ORIGINATOR_PL) |
diff --git a/drivers/message/fusion/lsi/mpi_sas.h b/drivers/message/fusion/lsi/mpi_sas.h index 70514867bddf..50b8f0a8f456 100644 --- a/drivers/message/fusion/lsi/mpi_sas.h +++ b/drivers/message/fusion/lsi/mpi_sas.h | |||
@@ -6,7 +6,7 @@ | |||
6 | * Title: MPI Serial Attached SCSI structures and definitions | 6 | * Title: MPI Serial Attached SCSI structures and definitions |
7 | * Creation Date: August 19, 2004 | 7 | * Creation Date: August 19, 2004 |
8 | * | 8 | * |
9 | * mpi_sas.h Version: 01.05.02 | 9 | * mpi_sas.h Version: 01.05.03 |
10 | * | 10 | * |
11 | * Version History | 11 | * Version History |
12 | * --------------- | 12 | * --------------- |
@@ -17,6 +17,10 @@ | |||
17 | * 08-30-05 01.05.02 Added DeviceInfo bit for SEP. | 17 | * 08-30-05 01.05.02 Added DeviceInfo bit for SEP. |
18 | * Added PrimFlags and Primitive field to SAS IO Unit | 18 | * Added PrimFlags and Primitive field to SAS IO Unit |
19 | * Control request, and added a new operation code. | 19 | * Control request, and added a new operation code. |
20 | * 03-27-06 01.05.03 Added Force Full Discovery, Transmit Port Select Signal, | ||
21 | * and Remove Device operations to SAS IO Unit Control. | ||
22 | * Added DevHandle field to SAS IO Unit Control request and | ||
23 | * reply. | ||
20 | * -------------------------------------------------------------------------- | 24 | * -------------------------------------------------------------------------- |
21 | */ | 25 | */ |
22 | 26 | ||
@@ -209,7 +213,7 @@ typedef struct _MSG_SAS_IOUNIT_CONTROL_REQUEST | |||
209 | U8 Reserved1; /* 01h */ | 213 | U8 Reserved1; /* 01h */ |
210 | U8 ChainOffset; /* 02h */ | 214 | U8 ChainOffset; /* 02h */ |
211 | U8 Function; /* 03h */ | 215 | U8 Function; /* 03h */ |
212 | U16 Reserved2; /* 04h */ | 216 | U16 DevHandle; /* 04h */ |
213 | U8 Reserved3; /* 06h */ | 217 | U8 Reserved3; /* 06h */ |
214 | U8 MsgFlags; /* 07h */ | 218 | U8 MsgFlags; /* 07h */ |
215 | U32 MsgContext; /* 08h */ | 219 | U32 MsgContext; /* 08h */ |
@@ -231,6 +235,9 @@ typedef struct _MSG_SAS_IOUNIT_CONTROL_REQUEST | |||
231 | #define MPI_SAS_OP_PHY_CLEAR_ERROR_LOG (0x08) | 235 | #define MPI_SAS_OP_PHY_CLEAR_ERROR_LOG (0x08) |
232 | #define MPI_SAS_OP_MAP_CURRENT (0x09) | 236 | #define MPI_SAS_OP_MAP_CURRENT (0x09) |
233 | #define MPI_SAS_OP_SEND_PRIMITIVE (0x0A) | 237 | #define MPI_SAS_OP_SEND_PRIMITIVE (0x0A) |
238 | #define MPI_SAS_OP_FORCE_FULL_DISCOVERY (0x0B) | ||
239 | #define MPI_SAS_OP_TRANSMIT_PORT_SELECT_SIGNAL (0x0C) | ||
240 | #define MPI_SAS_OP_TRANSMIT_REMOVE_DEVICE (0x0D) | ||
234 | 241 | ||
235 | /* values for the PrimFlags field */ | 242 | /* values for the PrimFlags field */ |
236 | #define MPI_SAS_PRIMFLAGS_SINGLE (0x08) | 243 | #define MPI_SAS_PRIMFLAGS_SINGLE (0x08) |
@@ -245,7 +252,7 @@ typedef struct _MSG_SAS_IOUNIT_CONTROL_REPLY | |||
245 | U8 Reserved1; /* 01h */ | 252 | U8 Reserved1; /* 01h */ |
246 | U8 MsgLength; /* 02h */ | 253 | U8 MsgLength; /* 02h */ |
247 | U8 Function; /* 03h */ | 254 | U8 Function; /* 03h */ |
248 | U16 Reserved2; /* 04h */ | 255 | U16 DevHandle; /* 04h */ |
249 | U8 Reserved3; /* 06h */ | 256 | U8 Reserved3; /* 06h */ |
250 | U8 MsgFlags; /* 07h */ | 257 | U8 MsgFlags; /* 07h */ |
251 | U32 MsgContext; /* 08h */ | 258 | U32 MsgContext; /* 08h */ |
diff --git a/drivers/message/fusion/lsi/mpi_targ.h b/drivers/message/fusion/lsi/mpi_targ.h index 3f462859ceea..20b667315773 100644 --- a/drivers/message/fusion/lsi/mpi_targ.h +++ b/drivers/message/fusion/lsi/mpi_targ.h | |||
@@ -6,7 +6,7 @@ | |||
6 | * Title: MPI Target mode messages and structures | 6 | * Title: MPI Target mode messages and structures |
7 | * Creation Date: June 22, 2000 | 7 | * Creation Date: June 22, 2000 |
8 | * | 8 | * |
9 | * mpi_targ.h Version: 01.05.05 | 9 | * mpi_targ.h Version: 01.05.06 |
10 | * | 10 | * |
11 | * Version History | 11 | * Version History |
12 | * --------------- | 12 | * --------------- |
@@ -54,6 +54,7 @@ | |||
54 | * 02-22-05 01.05.03 Changed a comment. | 54 | * 02-22-05 01.05.03 Changed a comment. |
55 | * 03-11-05 01.05.04 Removed TargetAssistExtended Request. | 55 | * 03-11-05 01.05.04 Removed TargetAssistExtended Request. |
56 | * 06-24-05 01.05.05 Added TargetAssistExtended structures and defines. | 56 | * 06-24-05 01.05.05 Added TargetAssistExtended structures and defines. |
57 | * 03-27-06 01.05.06 Added a comment. | ||
57 | * -------------------------------------------------------------------------- | 58 | * -------------------------------------------------------------------------- |
58 | */ | 59 | */ |
59 | 60 | ||
@@ -351,7 +352,7 @@ typedef struct _MSG_TARGET_ASSIST_REQUEST | |||
351 | #define TARGET_ASSIST_FLAGS_CONFIRMED (0x08) | 352 | #define TARGET_ASSIST_FLAGS_CONFIRMED (0x08) |
352 | #define TARGET_ASSIST_FLAGS_REPOST_CMD_BUFFER (0x80) | 353 | #define TARGET_ASSIST_FLAGS_REPOST_CMD_BUFFER (0x80) |
353 | 354 | ||
354 | 355 | /* Standard Target Mode Reply message */ | |
355 | typedef struct _MSG_TARGET_ERROR_REPLY | 356 | typedef struct _MSG_TARGET_ERROR_REPLY |
356 | { | 357 | { |
357 | U16 Reserved; /* 00h */ | 358 | U16 Reserved; /* 00h */ |
diff --git a/drivers/message/fusion/mptbase.c b/drivers/message/fusion/mptbase.c index 57543603d6c8..43308df64623 100644 --- a/drivers/message/fusion/mptbase.c +++ b/drivers/message/fusion/mptbase.c | |||
@@ -368,20 +368,21 @@ static irqreturn_t | |||
368 | mpt_interrupt(int irq, void *bus_id, struct pt_regs *r) | 368 | mpt_interrupt(int irq, void *bus_id, struct pt_regs *r) |
369 | { | 369 | { |
370 | MPT_ADAPTER *ioc = bus_id; | 370 | MPT_ADAPTER *ioc = bus_id; |
371 | u32 pa; | 371 | u32 pa = CHIPREG_READ32_dmasync(&ioc->chip->ReplyFifo); |
372 | |||
373 | if (pa == 0xFFFFFFFF) | ||
374 | return IRQ_NONE; | ||
372 | 375 | ||
373 | /* | 376 | /* |
374 | * Drain the reply FIFO! | 377 | * Drain the reply FIFO! |
375 | */ | 378 | */ |
376 | while (1) { | 379 | do { |
377 | pa = CHIPREG_READ32_dmasync(&ioc->chip->ReplyFifo); | 380 | if (pa & MPI_ADDRESS_REPLY_A_BIT) |
378 | if (pa == 0xFFFFFFFF) | ||
379 | return IRQ_HANDLED; | ||
380 | else if (pa & MPI_ADDRESS_REPLY_A_BIT) | ||
381 | mpt_reply(ioc, pa); | 381 | mpt_reply(ioc, pa); |
382 | else | 382 | else |
383 | mpt_turbo_reply(ioc, pa); | 383 | mpt_turbo_reply(ioc, pa); |
384 | } | 384 | pa = CHIPREG_READ32_dmasync(&ioc->chip->ReplyFifo); |
385 | } while (pa != 0xFFFFFFFF); | ||
385 | 386 | ||
386 | return IRQ_HANDLED; | 387 | return IRQ_HANDLED; |
387 | } | 388 | } |
@@ -1219,31 +1220,25 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id) | |||
1219 | port = psize = 0; | 1220 | port = psize = 0; |
1220 | for (ii=0; ii < DEVICE_COUNT_RESOURCE; ii++) { | 1221 | for (ii=0; ii < DEVICE_COUNT_RESOURCE; ii++) { |
1221 | if (pci_resource_flags(pdev, ii) & PCI_BASE_ADDRESS_SPACE_IO) { | 1222 | if (pci_resource_flags(pdev, ii) & PCI_BASE_ADDRESS_SPACE_IO) { |
1223 | if (psize) | ||
1224 | continue; | ||
1222 | /* Get I/O space! */ | 1225 | /* Get I/O space! */ |
1223 | port = pci_resource_start(pdev, ii); | 1226 | port = pci_resource_start(pdev, ii); |
1224 | psize = pci_resource_len(pdev,ii); | 1227 | psize = pci_resource_len(pdev,ii); |
1225 | } else { | 1228 | } else { |
1229 | if (msize) | ||
1230 | continue; | ||
1226 | /* Get memmap */ | 1231 | /* Get memmap */ |
1227 | mem_phys = pci_resource_start(pdev, ii); | 1232 | mem_phys = pci_resource_start(pdev, ii); |
1228 | msize = pci_resource_len(pdev,ii); | 1233 | msize = pci_resource_len(pdev,ii); |
1229 | break; | ||
1230 | } | 1234 | } |
1231 | } | 1235 | } |
1232 | ioc->mem_size = msize; | 1236 | ioc->mem_size = msize; |
1233 | 1237 | ||
1234 | if (ii == DEVICE_COUNT_RESOURCE) { | ||
1235 | printk(KERN_ERR MYNAM ": ERROR - MPT adapter has no memory regions defined!\n"); | ||
1236 | kfree(ioc); | ||
1237 | return -EINVAL; | ||
1238 | } | ||
1239 | |||
1240 | dinitprintk((KERN_INFO MYNAM ": MPT adapter @ %lx, msize=%dd bytes\n", mem_phys, msize)); | ||
1241 | dinitprintk((KERN_INFO MYNAM ": (port i/o @ %lx, psize=%dd bytes)\n", port, psize)); | ||
1242 | |||
1243 | mem = NULL; | 1238 | mem = NULL; |
1244 | /* Get logical ptr for PciMem0 space */ | 1239 | /* Get logical ptr for PciMem0 space */ |
1245 | /*mem = ioremap(mem_phys, msize);*/ | 1240 | /*mem = ioremap(mem_phys, msize);*/ |
1246 | mem = ioremap(mem_phys, 0x100); | 1241 | mem = ioremap(mem_phys, msize); |
1247 | if (mem == NULL) { | 1242 | if (mem == NULL) { |
1248 | printk(KERN_ERR MYNAM ": ERROR - Unable to map adapter memory!\n"); | 1243 | printk(KERN_ERR MYNAM ": ERROR - Unable to map adapter memory!\n"); |
1249 | kfree(ioc); | 1244 | kfree(ioc); |
@@ -1343,11 +1338,6 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id) | |||
1343 | ioc->bus_type = SAS; | 1338 | ioc->bus_type = SAS; |
1344 | ioc->errata_flag_1064 = 1; | 1339 | ioc->errata_flag_1064 = 1; |
1345 | } | 1340 | } |
1346 | else if (pdev->device == MPI_MANUFACTPAGE_DEVID_SAS1066) { | ||
1347 | ioc->prod_name = "LSISAS1066"; | ||
1348 | ioc->bus_type = SAS; | ||
1349 | ioc->errata_flag_1064 = 1; | ||
1350 | } | ||
1351 | else if (pdev->device == MPI_MANUFACTPAGE_DEVID_SAS1068) { | 1341 | else if (pdev->device == MPI_MANUFACTPAGE_DEVID_SAS1068) { |
1352 | ioc->prod_name = "LSISAS1068"; | 1342 | ioc->prod_name = "LSISAS1068"; |
1353 | ioc->bus_type = SAS; | 1343 | ioc->bus_type = SAS; |
@@ -1357,14 +1347,14 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id) | |||
1357 | ioc->prod_name = "LSISAS1064E"; | 1347 | ioc->prod_name = "LSISAS1064E"; |
1358 | ioc->bus_type = SAS; | 1348 | ioc->bus_type = SAS; |
1359 | } | 1349 | } |
1360 | else if (pdev->device == MPI_MANUFACTPAGE_DEVID_SAS1066E) { | ||
1361 | ioc->prod_name = "LSISAS1066E"; | ||
1362 | ioc->bus_type = SAS; | ||
1363 | } | ||
1364 | else if (pdev->device == MPI_MANUFACTPAGE_DEVID_SAS1068E) { | 1350 | else if (pdev->device == MPI_MANUFACTPAGE_DEVID_SAS1068E) { |
1365 | ioc->prod_name = "LSISAS1068E"; | 1351 | ioc->prod_name = "LSISAS1068E"; |
1366 | ioc->bus_type = SAS; | 1352 | ioc->bus_type = SAS; |
1367 | } | 1353 | } |
1354 | else if (pdev->device == MPI_MANUFACTPAGE_DEVID_SAS1078) { | ||
1355 | ioc->prod_name = "LSISAS1078"; | ||
1356 | ioc->bus_type = SAS; | ||
1357 | } | ||
1368 | 1358 | ||
1369 | if (ioc->errata_flag_1064) | 1359 | if (ioc->errata_flag_1064) |
1370 | pci_disable_io_access(pdev); | 1360 | pci_disable_io_access(pdev); |
@@ -3184,6 +3174,37 @@ mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag) | |||
3184 | u32 diag1val = 0; | 3174 | u32 diag1val = 0; |
3185 | #endif | 3175 | #endif |
3186 | 3176 | ||
3177 | if (ioc->pcidev->device == MPI_MANUFACTPAGE_DEVID_SAS1078) { | ||
3178 | drsprintk((MYIOC_s_WARN_FMT "%s: Doorbell=%p; 1078 reset " | ||
3179 | "address=%p\n", ioc->name, __FUNCTION__, | ||
3180 | &ioc->chip->Doorbell, &ioc->chip->Reset_1078)); | ||
3181 | CHIPREG_WRITE32(&ioc->chip->Reset_1078, 0x07); | ||
3182 | if (sleepFlag == CAN_SLEEP) | ||
3183 | msleep(1); | ||
3184 | else | ||
3185 | mdelay(1); | ||
3186 | |||
3187 | for (count = 0; count < 60; count ++) { | ||
3188 | doorbell = CHIPREG_READ32(&ioc->chip->Doorbell); | ||
3189 | doorbell &= MPI_IOC_STATE_MASK; | ||
3190 | |||
3191 | drsprintk((MYIOC_s_INFO_FMT | ||
3192 | "looking for READY STATE: doorbell=%x" | ||
3193 | " count=%d\n", | ||
3194 | ioc->name, doorbell, count)); | ||
3195 | if (doorbell == MPI_IOC_STATE_READY) { | ||
3196 | return 0; | ||
3197 | } | ||
3198 | |||
3199 | /* wait 1 sec */ | ||
3200 | if (sleepFlag == CAN_SLEEP) | ||
3201 | msleep(1000); | ||
3202 | else | ||
3203 | mdelay(1000); | ||
3204 | } | ||
3205 | return -1; | ||
3206 | } | ||
3207 | |||
3187 | /* Clear any existing interrupts */ | 3208 | /* Clear any existing interrupts */ |
3188 | CHIPREG_WRITE32(&ioc->chip->IntStatus, 0); | 3209 | CHIPREG_WRITE32(&ioc->chip->IntStatus, 0); |
3189 | 3210 | ||
diff --git a/drivers/message/fusion/mptbase.h b/drivers/message/fusion/mptbase.h index 32ae4d664545..a5ce10b67d02 100644 --- a/drivers/message/fusion/mptbase.h +++ b/drivers/message/fusion/mptbase.h | |||
@@ -75,8 +75,8 @@ | |||
75 | #define COPYRIGHT "Copyright (c) 1999-2005 " MODULEAUTHOR | 75 | #define COPYRIGHT "Copyright (c) 1999-2005 " MODULEAUTHOR |
76 | #endif | 76 | #endif |
77 | 77 | ||
78 | #define MPT_LINUX_VERSION_COMMON "3.03.10" | 78 | #define MPT_LINUX_VERSION_COMMON "3.04.00" |
79 | #define MPT_LINUX_PACKAGE_NAME "@(#)mptlinux-3.03.10" | 79 | #define MPT_LINUX_PACKAGE_NAME "@(#)mptlinux-3.04.00" |
80 | #define WHAT_MAGIC_STRING "@" "(" "#" ")" | 80 | #define WHAT_MAGIC_STRING "@" "(" "#" ")" |
81 | 81 | ||
82 | #define show_mptmod_ver(s,ver) \ | 82 | #define show_mptmod_ver(s,ver) \ |
@@ -307,7 +307,8 @@ typedef struct _SYSIF_REGS | |||
307 | u32 HostIndex; /* 50 Host Index register */ | 307 | u32 HostIndex; /* 50 Host Index register */ |
308 | u32 Reserved4[15]; /* 54-8F */ | 308 | u32 Reserved4[15]; /* 54-8F */ |
309 | u32 Fubar; /* 90 For Fubar usage */ | 309 | u32 Fubar; /* 90 For Fubar usage */ |
310 | u32 Reserved5[27]; /* 94-FF */ | 310 | u32 Reserved5[1050];/* 94-10F8 */ |
311 | u32 Reset_1078; /* 10FC Reset 1078 */ | ||
311 | } SYSIF_REGS; | 312 | } SYSIF_REGS; |
312 | 313 | ||
313 | /* | 314 | /* |
@@ -341,6 +342,7 @@ typedef struct _VirtTarget { | |||
341 | u8 negoFlags; /* bit field, see above */ | 342 | u8 negoFlags; /* bit field, see above */ |
342 | u8 raidVolume; /* set, if RAID Volume */ | 343 | u8 raidVolume; /* set, if RAID Volume */ |
343 | u8 type; /* byte 0 of Inquiry data */ | 344 | u8 type; /* byte 0 of Inquiry data */ |
345 | u8 deleted; /* target in process of being removed */ | ||
344 | u32 num_luns; | 346 | u32 num_luns; |
345 | u32 luns[8]; /* Max LUNs is 256 */ | 347 | u32 luns[8]; /* Max LUNs is 256 */ |
346 | } VirtTarget; | 348 | } VirtTarget; |
@@ -629,10 +631,11 @@ typedef struct _MPT_ADAPTER | |||
629 | struct mutex sas_discovery_mutex; | 631 | struct mutex sas_discovery_mutex; |
630 | u8 sas_discovery_runtime; | 632 | u8 sas_discovery_runtime; |
631 | u8 sas_discovery_ignore_events; | 633 | u8 sas_discovery_ignore_events; |
634 | u16 handle; | ||
632 | int sas_index; /* index refrencing */ | 635 | int sas_index; /* index refrencing */ |
633 | MPT_SAS_MGMT sas_mgmt; | 636 | MPT_SAS_MGMT sas_mgmt; |
634 | int num_ports; | 637 | int num_ports; |
635 | struct work_struct mptscsih_persistTask; | 638 | struct work_struct sas_persist_task; |
636 | 639 | ||
637 | struct work_struct fc_setup_reset_work; | 640 | struct work_struct fc_setup_reset_work; |
638 | struct list_head fc_rports; | 641 | struct list_head fc_rports; |
@@ -641,6 +644,7 @@ typedef struct _MPT_ADAPTER | |||
641 | struct work_struct fc_rescan_work; | 644 | struct work_struct fc_rescan_work; |
642 | char fc_rescan_work_q_name[KOBJ_NAME_LEN]; | 645 | char fc_rescan_work_q_name[KOBJ_NAME_LEN]; |
643 | struct workqueue_struct *fc_rescan_work_q; | 646 | struct workqueue_struct *fc_rescan_work_q; |
647 | u8 port_serial_number; | ||
644 | } MPT_ADAPTER; | 648 | } MPT_ADAPTER; |
645 | 649 | ||
646 | /* | 650 | /* |
@@ -892,6 +896,13 @@ typedef struct _mpt_sge { | |||
892 | #define DBG_DUMP_REQUEST_FRAME_HDR(mfp) | 896 | #define DBG_DUMP_REQUEST_FRAME_HDR(mfp) |
893 | #endif | 897 | #endif |
894 | 898 | ||
899 | // debug sas wide ports | ||
900 | #ifdef MPT_DEBUG_SAS_WIDE | ||
901 | #define dsaswideprintk(x) printk x | ||
902 | #else | ||
903 | #define dsaswideprintk(x) | ||
904 | #endif | ||
905 | |||
895 | 906 | ||
896 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ | 907 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ |
897 | 908 | ||
diff --git a/drivers/message/fusion/mptfc.c b/drivers/message/fusion/mptfc.c index 3ff8378ea660..a8f2fa985455 100644 --- a/drivers/message/fusion/mptfc.c +++ b/drivers/message/fusion/mptfc.c | |||
@@ -132,21 +132,21 @@ static struct scsi_host_template mptfc_driver_template = { | |||
132 | */ | 132 | */ |
133 | 133 | ||
134 | static struct pci_device_id mptfc_pci_table[] = { | 134 | static struct pci_device_id mptfc_pci_table[] = { |
135 | { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_FC909, | 135 | { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVICEID_FC909, |
136 | PCI_ANY_ID, PCI_ANY_ID }, | 136 | PCI_ANY_ID, PCI_ANY_ID }, |
137 | { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_FC919, | 137 | { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVICEID_FC919, |
138 | PCI_ANY_ID, PCI_ANY_ID }, | 138 | PCI_ANY_ID, PCI_ANY_ID }, |
139 | { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_FC929, | 139 | { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVICEID_FC929, |
140 | PCI_ANY_ID, PCI_ANY_ID }, | 140 | PCI_ANY_ID, PCI_ANY_ID }, |
141 | { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_FC919X, | 141 | { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVICEID_FC919X, |
142 | PCI_ANY_ID, PCI_ANY_ID }, | 142 | PCI_ANY_ID, PCI_ANY_ID }, |
143 | { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_FC929X, | 143 | { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVICEID_FC929X, |
144 | PCI_ANY_ID, PCI_ANY_ID }, | 144 | PCI_ANY_ID, PCI_ANY_ID }, |
145 | { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_FC939X, | 145 | { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVICEID_FC939X, |
146 | PCI_ANY_ID, PCI_ANY_ID }, | 146 | PCI_ANY_ID, PCI_ANY_ID }, |
147 | { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_FC949X, | 147 | { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVICEID_FC949X, |
148 | PCI_ANY_ID, PCI_ANY_ID }, | 148 | PCI_ANY_ID, PCI_ANY_ID }, |
149 | { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_FC949ES, | 149 | { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVICEID_FC949E, |
150 | PCI_ANY_ID, PCI_ANY_ID }, | 150 | PCI_ANY_ID, PCI_ANY_ID }, |
151 | {0} /* Terminating entry */ | 151 | {0} /* Terminating entry */ |
152 | }; | 152 | }; |
diff --git a/drivers/message/fusion/mptsas.c b/drivers/message/fusion/mptsas.c index 85689ab46cbc..f7bd8b11ed3b 100644 --- a/drivers/message/fusion/mptsas.c +++ b/drivers/message/fusion/mptsas.c | |||
@@ -50,11 +50,14 @@ | |||
50 | #include <linux/errno.h> | 50 | #include <linux/errno.h> |
51 | #include <linux/sched.h> | 51 | #include <linux/sched.h> |
52 | #include <linux/workqueue.h> | 52 | #include <linux/workqueue.h> |
53 | #include <linux/delay.h> /* for mdelay */ | ||
53 | 54 | ||
55 | #include <scsi/scsi.h> | ||
54 | #include <scsi/scsi_cmnd.h> | 56 | #include <scsi/scsi_cmnd.h> |
55 | #include <scsi/scsi_device.h> | 57 | #include <scsi/scsi_device.h> |
56 | #include <scsi/scsi_host.h> | 58 | #include <scsi/scsi_host.h> |
57 | #include <scsi/scsi_transport_sas.h> | 59 | #include <scsi/scsi_transport_sas.h> |
60 | #include <scsi/scsi_dbg.h> | ||
58 | 61 | ||
59 | #include "mptbase.h" | 62 | #include "mptbase.h" |
60 | #include "mptscsih.h" | 63 | #include "mptscsih.h" |
@@ -137,23 +140,37 @@ struct mptsas_devinfo { | |||
137 | u32 device_info; /* bitfield detailed info about this device */ | 140 | u32 device_info; /* bitfield detailed info about this device */ |
138 | }; | 141 | }; |
139 | 142 | ||
143 | /* | ||
144 | * Specific details on ports, wide/narrow | ||
145 | */ | ||
146 | struct mptsas_portinfo_details{ | ||
147 | u8 port_id; /* port number provided to transport */ | ||
148 | u16 num_phys; /* number of phys belong to this port */ | ||
149 | u64 phy_bitmask; /* TODO, extend support for 255 phys */ | ||
150 | struct sas_rphy *rphy; /* transport layer rphy object */ | ||
151 | struct sas_port *port; /* transport layer port object */ | ||
152 | struct scsi_target *starget; | ||
153 | struct mptsas_portinfo *port_info; | ||
154 | }; | ||
155 | |||
140 | struct mptsas_phyinfo { | 156 | struct mptsas_phyinfo { |
141 | u8 phy_id; /* phy index */ | 157 | u8 phy_id; /* phy index */ |
142 | u8 port_id; /* port number this phy is part of */ | 158 | u8 port_id; /* firmware port identifier */ |
143 | u8 negotiated_link_rate; /* nego'd link rate for this phy */ | 159 | u8 negotiated_link_rate; /* nego'd link rate for this phy */ |
144 | u8 hw_link_rate; /* hardware max/min phys link rate */ | 160 | u8 hw_link_rate; /* hardware max/min phys link rate */ |
145 | u8 programmed_link_rate; /* programmed max/min phy link rate */ | 161 | u8 programmed_link_rate; /* programmed max/min phy link rate */ |
162 | u8 sas_port_add_phy; /* flag to request sas_port_add_phy*/ | ||
146 | struct mptsas_devinfo identify; /* point to phy device info */ | 163 | struct mptsas_devinfo identify; /* point to phy device info */ |
147 | struct mptsas_devinfo attached; /* point to attached device info */ | 164 | struct mptsas_devinfo attached; /* point to attached device info */ |
148 | struct sas_phy *phy; | 165 | struct sas_phy *phy; /* transport layer phy object */ |
149 | struct sas_rphy *rphy; | 166 | struct mptsas_portinfo *portinfo; |
150 | struct scsi_target *starget; | 167 | struct mptsas_portinfo_details * port_details; |
151 | }; | 168 | }; |
152 | 169 | ||
153 | struct mptsas_portinfo { | 170 | struct mptsas_portinfo { |
154 | struct list_head list; | 171 | struct list_head list; |
155 | u16 handle; /* unique id to address this */ | 172 | u16 handle; /* unique id to address this */ |
156 | u8 num_phys; /* number of phys */ | 173 | u16 num_phys; /* number of phys */ |
157 | struct mptsas_phyinfo *phy_info; | 174 | struct mptsas_phyinfo *phy_info; |
158 | }; | 175 | }; |
159 | 176 | ||
@@ -169,7 +186,7 @@ struct mptsas_enclosure { | |||
169 | u8 sep_channel; /* SEP channel logical channel id */ | 186 | u8 sep_channel; /* SEP channel logical channel id */ |
170 | }; | 187 | }; |
171 | 188 | ||
172 | #ifdef SASDEBUG | 189 | #ifdef MPT_DEBUG_SAS |
173 | static void mptsas_print_phy_data(MPI_SAS_IO_UNIT0_PHY_DATA *phy_data) | 190 | static void mptsas_print_phy_data(MPI_SAS_IO_UNIT0_PHY_DATA *phy_data) |
174 | { | 191 | { |
175 | printk("---- IO UNIT PAGE 0 ------------\n"); | 192 | printk("---- IO UNIT PAGE 0 ------------\n"); |
@@ -305,7 +322,7 @@ mptsas_find_portinfo_by_handle(MPT_ADAPTER *ioc, u16 handle) | |||
305 | static inline int | 322 | static inline int |
306 | mptsas_is_end_device(struct mptsas_devinfo * attached) | 323 | mptsas_is_end_device(struct mptsas_devinfo * attached) |
307 | { | 324 | { |
308 | if ((attached->handle) && | 325 | if ((attached->sas_address) && |
309 | (attached->device_info & | 326 | (attached->device_info & |
310 | MPI_SAS_DEVICE_INFO_END_DEVICE) && | 327 | MPI_SAS_DEVICE_INFO_END_DEVICE) && |
311 | ((attached->device_info & | 328 | ((attached->device_info & |
@@ -319,6 +336,253 @@ mptsas_is_end_device(struct mptsas_devinfo * attached) | |||
319 | return 0; | 336 | return 0; |
320 | } | 337 | } |
321 | 338 | ||
339 | /* no mutex */ | ||
340 | static void | ||
341 | mptsas_port_delete(struct mptsas_portinfo_details * port_details) | ||
342 | { | ||
343 | struct mptsas_portinfo *port_info; | ||
344 | struct mptsas_phyinfo *phy_info; | ||
345 | u8 i; | ||
346 | |||
347 | if (!port_details) | ||
348 | return; | ||
349 | |||
350 | port_info = port_details->port_info; | ||
351 | phy_info = port_info->phy_info; | ||
352 | |||
353 | dsaswideprintk((KERN_DEBUG "%s: [%p]: port=%02d num_phys=%02d " | ||
354 | "bitmask=0x%016llX\n", | ||
355 | __FUNCTION__, port_details, port_details->port_id, | ||
356 | port_details->num_phys, port_details->phy_bitmask)); | ||
357 | |||
358 | for (i = 0; i < port_info->num_phys; i++, phy_info++) { | ||
359 | if(phy_info->port_details != port_details) | ||
360 | continue; | ||
361 | memset(&phy_info->attached, 0, sizeof(struct mptsas_devinfo)); | ||
362 | phy_info->port_details = NULL; | ||
363 | } | ||
364 | kfree(port_details); | ||
365 | } | ||
366 | |||
367 | static inline struct sas_rphy * | ||
368 | mptsas_get_rphy(struct mptsas_phyinfo *phy_info) | ||
369 | { | ||
370 | if (phy_info->port_details) | ||
371 | return phy_info->port_details->rphy; | ||
372 | else | ||
373 | return NULL; | ||
374 | } | ||
375 | |||
376 | static inline void | ||
377 | mptsas_set_rphy(struct mptsas_phyinfo *phy_info, struct sas_rphy *rphy) | ||
378 | { | ||
379 | if (phy_info->port_details) { | ||
380 | phy_info->port_details->rphy = rphy; | ||
381 | dsaswideprintk((KERN_DEBUG "sas_rphy_add: rphy=%p\n", rphy)); | ||
382 | } | ||
383 | |||
384 | #ifdef MPT_DEBUG_SAS_WIDE | ||
385 | if (rphy) { | ||
386 | dev_printk(KERN_DEBUG, &rphy->dev, "add:"); | ||
387 | printk("rphy=%p release=%p\n", | ||
388 | rphy, rphy->dev.release); | ||
389 | } | ||
390 | #endif | ||
391 | } | ||
392 | |||
393 | static inline struct sas_port * | ||
394 | mptsas_get_port(struct mptsas_phyinfo *phy_info) | ||
395 | { | ||
396 | if (phy_info->port_details) | ||
397 | return phy_info->port_details->port; | ||
398 | else | ||
399 | return NULL; | ||
400 | } | ||
401 | |||
402 | static inline void | ||
403 | mptsas_set_port(struct mptsas_phyinfo *phy_info, struct sas_port *port) | ||
404 | { | ||
405 | if (phy_info->port_details) | ||
406 | phy_info->port_details->port = port; | ||
407 | |||
408 | #ifdef MPT_DEBUG_SAS_WIDE | ||
409 | if (port) { | ||
410 | dev_printk(KERN_DEBUG, &port->dev, "add: "); | ||
411 | printk("port=%p release=%p\n", | ||
412 | port, port->dev.release); | ||
413 | } | ||
414 | #endif | ||
415 | } | ||
416 | |||
417 | static inline struct scsi_target * | ||
418 | mptsas_get_starget(struct mptsas_phyinfo *phy_info) | ||
419 | { | ||
420 | if (phy_info->port_details) | ||
421 | return phy_info->port_details->starget; | ||
422 | else | ||
423 | return NULL; | ||
424 | } | ||
425 | |||
426 | static inline void | ||
427 | mptsas_set_starget(struct mptsas_phyinfo *phy_info, struct scsi_target * | ||
428 | starget) | ||
429 | { | ||
430 | if (phy_info->port_details) | ||
431 | phy_info->port_details->starget = starget; | ||
432 | } | ||
433 | |||
434 | |||
435 | /* | ||
436 | * mptsas_setup_wide_ports | ||
437 | * | ||
438 | * Updates for new and existing narrow/wide port configuration | ||
439 | * in the sas_topology | ||
440 | */ | ||
441 | static void | ||
442 | mptsas_setup_wide_ports(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info) | ||
443 | { | ||
444 | struct mptsas_portinfo_details * port_details; | ||
445 | struct mptsas_phyinfo *phy_info, *phy_info_cmp; | ||
446 | u64 sas_address; | ||
447 | int i, j; | ||
448 | |||
449 | mutex_lock(&ioc->sas_topology_mutex); | ||
450 | |||
451 | phy_info = port_info->phy_info; | ||
452 | for (i = 0 ; i < port_info->num_phys ; i++, phy_info++) { | ||
453 | if (phy_info->attached.handle) | ||
454 | continue; | ||
455 | port_details = phy_info->port_details; | ||
456 | if (!port_details) | ||
457 | continue; | ||
458 | if (port_details->num_phys < 2) | ||
459 | continue; | ||
460 | /* | ||
461 | * Removing a phy from a port, letting the last | ||
462 | * phy be removed by firmware events. | ||
463 | */ | ||
464 | dsaswideprintk((KERN_DEBUG | ||
465 | "%s: [%p]: port=%d deleting phy = %d\n", | ||
466 | __FUNCTION__, port_details, | ||
467 | port_details->port_id, i)); | ||
468 | port_details->num_phys--; | ||
469 | port_details->phy_bitmask &= ~ (1 << phy_info->phy_id); | ||
470 | memset(&phy_info->attached, 0, sizeof(struct mptsas_devinfo)); | ||
471 | sas_port_delete_phy(port_details->port, phy_info->phy); | ||
472 | phy_info->port_details = NULL; | ||
473 | } | ||
474 | |||
475 | /* | ||
476 | * Populate and refresh the tree | ||
477 | */ | ||
478 | phy_info = port_info->phy_info; | ||
479 | for (i = 0 ; i < port_info->num_phys ; i++, phy_info++) { | ||
480 | sas_address = phy_info->attached.sas_address; | ||
481 | dsaswideprintk((KERN_DEBUG "phy_id=%d sas_address=0x%018llX\n", | ||
482 | i, sas_address)); | ||
483 | if (!sas_address) | ||
484 | continue; | ||
485 | port_details = phy_info->port_details; | ||
486 | /* | ||
487 | * Forming a port | ||
488 | */ | ||
489 | if (!port_details) { | ||
490 | port_details = kzalloc(sizeof(*port_details), | ||
491 | GFP_KERNEL); | ||
492 | if (!port_details) | ||
493 | goto out; | ||
494 | port_details->num_phys = 1; | ||
495 | port_details->port_info = port_info; | ||
496 | port_details->port_id = ioc->port_serial_number++; | ||
497 | if (phy_info->phy_id < 64 ) | ||
498 | port_details->phy_bitmask |= | ||
499 | (1 << phy_info->phy_id); | ||
500 | phy_info->sas_port_add_phy=1; | ||
501 | dsaswideprintk((KERN_DEBUG "\t\tForming port\n\t\t" | ||
502 | "phy_id=%d sas_address=0x%018llX\n", | ||
503 | i, sas_address)); | ||
504 | phy_info->port_details = port_details; | ||
505 | } | ||
506 | |||
507 | if (i == port_info->num_phys - 1) | ||
508 | continue; | ||
509 | phy_info_cmp = &port_info->phy_info[i + 1]; | ||
510 | for (j = i + 1 ; j < port_info->num_phys ; j++, | ||
511 | phy_info_cmp++) { | ||
512 | if (!phy_info_cmp->attached.sas_address) | ||
513 | continue; | ||
514 | if (sas_address != phy_info_cmp->attached.sas_address) | ||
515 | continue; | ||
516 | if (phy_info_cmp->port_details == port_details ) | ||
517 | continue; | ||
518 | dsaswideprintk((KERN_DEBUG | ||
519 | "\t\tphy_id=%d sas_address=0x%018llX\n", | ||
520 | j, phy_info_cmp->attached.sas_address)); | ||
521 | if (phy_info_cmp->port_details) { | ||
522 | port_details->rphy = | ||
523 | mptsas_get_rphy(phy_info_cmp); | ||
524 | port_details->port = | ||
525 | mptsas_get_port(phy_info_cmp); | ||
526 | port_details->starget = | ||
527 | mptsas_get_starget(phy_info_cmp); | ||
528 | port_details->port_id = | ||
529 | phy_info_cmp->port_details->port_id; | ||
530 | port_details->num_phys = | ||
531 | phy_info_cmp->port_details->num_phys; | ||
532 | // port_info->port_serial_number--; | ||
533 | ioc->port_serial_number--; | ||
534 | if (!phy_info_cmp->port_details->num_phys) | ||
535 | kfree(phy_info_cmp->port_details); | ||
536 | } else | ||
537 | phy_info_cmp->sas_port_add_phy=1; | ||
538 | /* | ||
539 | * Adding a phy to a port | ||
540 | */ | ||
541 | phy_info_cmp->port_details = port_details; | ||
542 | if (phy_info_cmp->phy_id < 64 ) | ||
543 | port_details->phy_bitmask |= | ||
544 | (1 << phy_info_cmp->phy_id); | ||
545 | port_details->num_phys++; | ||
546 | } | ||
547 | } | ||
548 | |||
549 | out: | ||
550 | |||
551 | #ifdef MPT_DEBUG_SAS_WIDE | ||
552 | for (i = 0; i < port_info->num_phys; i++) { | ||
553 | port_details = port_info->phy_info[i].port_details; | ||
554 | if (!port_details) | ||
555 | continue; | ||
556 | dsaswideprintk((KERN_DEBUG | ||
557 | "%s: [%p]: phy_id=%02d port_id=%02d num_phys=%02d " | ||
558 | "bitmask=0x%016llX\n", | ||
559 | __FUNCTION__, | ||
560 | port_details, i, port_details->port_id, | ||
561 | port_details->num_phys, port_details->phy_bitmask)); | ||
562 | dsaswideprintk((KERN_DEBUG"\t\tport = %p rphy=%p\n", | ||
563 | port_details->port, port_details->rphy)); | ||
564 | } | ||
565 | dsaswideprintk((KERN_DEBUG"\n")); | ||
566 | #endif | ||
567 | mutex_unlock(&ioc->sas_topology_mutex); | ||
568 | } | ||
569 | |||
570 | static void | ||
571 | mptsas_target_reset(MPT_ADAPTER *ioc, VirtTarget * vtarget) | ||
572 | { | ||
573 | MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)ioc->sh->hostdata; | ||
574 | |||
575 | if (mptscsih_TMHandler(hd, | ||
576 | MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET, | ||
577 | vtarget->bus_id, vtarget->target_id, 0, 0, 5) < 0) { | ||
578 | hd->tmPending = 0; | ||
579 | hd->tmState = TM_STATE_NONE; | ||
580 | printk(MYIOC_s_WARN_FMT | ||
581 | "Error processing TaskMgmt id=%d TARGET_RESET\n", | ||
582 | ioc->name, vtarget->target_id); | ||
583 | } | ||
584 | } | ||
585 | |||
322 | static int | 586 | static int |
323 | mptsas_sas_enclosure_pg0(MPT_ADAPTER *ioc, struct mptsas_enclosure *enclosure, | 587 | mptsas_sas_enclosure_pg0(MPT_ADAPTER *ioc, struct mptsas_enclosure *enclosure, |
324 | u32 form, u32 form_specific) | 588 | u32 form, u32 form_specific) |
@@ -400,11 +664,105 @@ mptsas_slave_configure(struct scsi_device *sdev) | |||
400 | return mptscsih_slave_configure(sdev); | 664 | return mptscsih_slave_configure(sdev); |
401 | } | 665 | } |
402 | 666 | ||
403 | /* | 667 | static int |
404 | * This is pretty ugly. We will be able to seriously clean it up | 668 | mptsas_target_alloc(struct scsi_target *starget) |
405 | * once the DV code in mptscsih goes away and we can properly | 669 | { |
406 | * implement ->target_alloc. | 670 | struct Scsi_Host *host = dev_to_shost(&starget->dev); |
407 | */ | 671 | MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata; |
672 | VirtTarget *vtarget; | ||
673 | u32 target_id; | ||
674 | u32 channel; | ||
675 | struct sas_rphy *rphy; | ||
676 | struct mptsas_portinfo *p; | ||
677 | int i; | ||
678 | |||
679 | vtarget = kzalloc(sizeof(VirtTarget), GFP_KERNEL); | ||
680 | if (!vtarget) | ||
681 | return -ENOMEM; | ||
682 | |||
683 | vtarget->starget = starget; | ||
684 | vtarget->ioc_id = hd->ioc->id; | ||
685 | vtarget->tflags = MPT_TARGET_FLAGS_Q_YES|MPT_TARGET_FLAGS_VALID_INQUIRY; | ||
686 | |||
687 | target_id = starget->id; | ||
688 | channel = 0; | ||
689 | |||
690 | hd->Targets[target_id] = vtarget; | ||
691 | |||
692 | /* | ||
693 | * RAID volumes placed beyond the last expected port. | ||
694 | */ | ||
695 | if (starget->channel == hd->ioc->num_ports) | ||
696 | goto out; | ||
697 | |||
698 | rphy = dev_to_rphy(starget->dev.parent); | ||
699 | mutex_lock(&hd->ioc->sas_topology_mutex); | ||
700 | list_for_each_entry(p, &hd->ioc->sas_topology, list) { | ||
701 | for (i = 0; i < p->num_phys; i++) { | ||
702 | if (p->phy_info[i].attached.sas_address != | ||
703 | rphy->identify.sas_address) | ||
704 | continue; | ||
705 | target_id = p->phy_info[i].attached.id; | ||
706 | channel = p->phy_info[i].attached.channel; | ||
707 | mptsas_set_starget(&p->phy_info[i], starget); | ||
708 | |||
709 | /* | ||
710 | * Exposing hidden raid components | ||
711 | */ | ||
712 | if (mptscsih_is_phys_disk(hd->ioc, target_id)) { | ||
713 | target_id = mptscsih_raid_id_to_num(hd, | ||
714 | target_id); | ||
715 | vtarget->tflags |= | ||
716 | MPT_TARGET_FLAGS_RAID_COMPONENT; | ||
717 | } | ||
718 | mutex_unlock(&hd->ioc->sas_topology_mutex); | ||
719 | goto out; | ||
720 | } | ||
721 | } | ||
722 | mutex_unlock(&hd->ioc->sas_topology_mutex); | ||
723 | |||
724 | kfree(vtarget); | ||
725 | return -ENXIO; | ||
726 | |||
727 | out: | ||
728 | vtarget->target_id = target_id; | ||
729 | vtarget->bus_id = channel; | ||
730 | starget->hostdata = vtarget; | ||
731 | return 0; | ||
732 | } | ||
733 | |||
734 | static void | ||
735 | mptsas_target_destroy(struct scsi_target *starget) | ||
736 | { | ||
737 | struct Scsi_Host *host = dev_to_shost(&starget->dev); | ||
738 | MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata; | ||
739 | struct sas_rphy *rphy; | ||
740 | struct mptsas_portinfo *p; | ||
741 | int i; | ||
742 | |||
743 | if (!starget->hostdata) | ||
744 | return; | ||
745 | |||
746 | if (starget->channel == hd->ioc->num_ports) | ||
747 | goto out; | ||
748 | |||
749 | rphy = dev_to_rphy(starget->dev.parent); | ||
750 | list_for_each_entry(p, &hd->ioc->sas_topology, list) { | ||
751 | for (i = 0; i < p->num_phys; i++) { | ||
752 | if (p->phy_info[i].attached.sas_address != | ||
753 | rphy->identify.sas_address) | ||
754 | continue; | ||
755 | mptsas_set_starget(&p->phy_info[i], NULL); | ||
756 | goto out; | ||
757 | } | ||
758 | } | ||
759 | |||
760 | out: | ||
761 | kfree(starget->hostdata); | ||
762 | starget->hostdata = NULL; | ||
763 | } | ||
764 | |||
765 | |||
408 | static int | 766 | static int |
409 | mptsas_slave_alloc(struct scsi_device *sdev) | 767 | mptsas_slave_alloc(struct scsi_device *sdev) |
410 | { | 768 | { |
@@ -412,61 +770,41 @@ mptsas_slave_alloc(struct scsi_device *sdev) | |||
412 | MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata; | 770 | MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata; |
413 | struct sas_rphy *rphy; | 771 | struct sas_rphy *rphy; |
414 | struct mptsas_portinfo *p; | 772 | struct mptsas_portinfo *p; |
415 | VirtTarget *vtarget; | ||
416 | VirtDevice *vdev; | 773 | VirtDevice *vdev; |
417 | struct scsi_target *starget; | 774 | struct scsi_target *starget; |
418 | u32 target_id; | 775 | int i; |
419 | int i; | ||
420 | 776 | ||
421 | vdev = kzalloc(sizeof(VirtDevice), GFP_KERNEL); | 777 | vdev = kzalloc(sizeof(VirtDevice), GFP_KERNEL); |
422 | if (!vdev) { | 778 | if (!vdev) { |
423 | printk(MYIOC_s_ERR_FMT "slave_alloc kmalloc(%zd) FAILED!\n", | 779 | printk(MYIOC_s_ERR_FMT "slave_alloc kzalloc(%zd) FAILED!\n", |
424 | hd->ioc->name, sizeof(VirtDevice)); | 780 | hd->ioc->name, sizeof(VirtDevice)); |
425 | return -ENOMEM; | 781 | return -ENOMEM; |
426 | } | 782 | } |
427 | sdev->hostdata = vdev; | ||
428 | starget = scsi_target(sdev); | 783 | starget = scsi_target(sdev); |
429 | vtarget = starget->hostdata; | 784 | vdev->vtarget = starget->hostdata; |
430 | vtarget->ioc_id = hd->ioc->id; | ||
431 | vdev->vtarget = vtarget; | ||
432 | if (vtarget->num_luns == 0) { | ||
433 | vtarget->tflags = MPT_TARGET_FLAGS_Q_YES|MPT_TARGET_FLAGS_VALID_INQUIRY; | ||
434 | hd->Targets[sdev->id] = vtarget; | ||
435 | } | ||
436 | 785 | ||
437 | /* | 786 | /* |
438 | RAID volumes placed beyond the last expected port. | 787 | * RAID volumes placed beyond the last expected port. |
439 | */ | 788 | */ |
440 | if (sdev->channel == hd->ioc->num_ports) { | 789 | if (sdev->channel == hd->ioc->num_ports) |
441 | target_id = sdev->id; | ||
442 | vtarget->bus_id = 0; | ||
443 | vdev->lun = 0; | ||
444 | goto out; | 790 | goto out; |
445 | } | ||
446 | 791 | ||
447 | rphy = dev_to_rphy(sdev->sdev_target->dev.parent); | 792 | rphy = dev_to_rphy(sdev->sdev_target->dev.parent); |
448 | mutex_lock(&hd->ioc->sas_topology_mutex); | 793 | mutex_lock(&hd->ioc->sas_topology_mutex); |
449 | list_for_each_entry(p, &hd->ioc->sas_topology, list) { | 794 | list_for_each_entry(p, &hd->ioc->sas_topology, list) { |
450 | for (i = 0; i < p->num_phys; i++) { | 795 | for (i = 0; i < p->num_phys; i++) { |
451 | if (p->phy_info[i].attached.sas_address == | 796 | if (p->phy_info[i].attached.sas_address != |
452 | rphy->identify.sas_address) { | 797 | rphy->identify.sas_address) |
453 | target_id = p->phy_info[i].attached.id; | 798 | continue; |
454 | vtarget->bus_id = p->phy_info[i].attached.channel; | 799 | vdev->lun = sdev->lun; |
455 | vdev->lun = sdev->lun; | 800 | /* |
456 | p->phy_info[i].starget = sdev->sdev_target; | 801 | * Exposing hidden raid components |
457 | /* | 802 | */ |
458 | * Exposing hidden disk (RAID) | 803 | if (mptscsih_is_phys_disk(hd->ioc, |
459 | */ | 804 | p->phy_info[i].attached.id)) |
460 | if (mptscsih_is_phys_disk(hd->ioc, target_id)) { | 805 | sdev->no_uld_attach = 1; |
461 | target_id = mptscsih_raid_id_to_num(hd, | 806 | mutex_unlock(&hd->ioc->sas_topology_mutex); |
462 | target_id); | 807 | goto out; |
463 | vdev->vtarget->tflags |= | ||
464 | MPT_TARGET_FLAGS_RAID_COMPONENT; | ||
465 | sdev->no_uld_attach = 1; | ||
466 | } | ||
467 | mutex_unlock(&hd->ioc->sas_topology_mutex); | ||
468 | goto out; | ||
469 | } | ||
470 | } | 808 | } |
471 | } | 809 | } |
472 | mutex_unlock(&hd->ioc->sas_topology_mutex); | 810 | mutex_unlock(&hd->ioc->sas_topology_mutex); |
@@ -475,57 +813,39 @@ mptsas_slave_alloc(struct scsi_device *sdev) | |||
475 | return -ENXIO; | 813 | return -ENXIO; |
476 | 814 | ||
477 | out: | 815 | out: |
478 | vtarget->target_id = target_id; | 816 | vdev->vtarget->num_luns++; |
479 | vtarget->num_luns++; | 817 | sdev->hostdata = vdev; |
480 | return 0; | 818 | return 0; |
481 | } | 819 | } |
482 | 820 | ||
483 | static void | 821 | static int |
484 | mptsas_slave_destroy(struct scsi_device *sdev) | 822 | mptsas_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *)) |
485 | { | 823 | { |
486 | struct Scsi_Host *host = sdev->host; | 824 | VirtDevice *vdev = SCpnt->device->hostdata; |
487 | MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata; | ||
488 | VirtDevice *vdev; | ||
489 | 825 | ||
490 | /* | 826 | // scsi_print_command(SCpnt); |
491 | * Issue target reset to flush firmware outstanding commands. | 827 | if (vdev->vtarget->deleted) { |
492 | */ | 828 | SCpnt->result = DID_NO_CONNECT << 16; |
493 | vdev = sdev->hostdata; | 829 | done(SCpnt); |
494 | if (vdev->configured_lun){ | 830 | return 0; |
495 | if (mptscsih_TMHandler(hd, | ||
496 | MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET, | ||
497 | vdev->vtarget->bus_id, | ||
498 | vdev->vtarget->target_id, | ||
499 | 0, 0, 5 /* 5 second timeout */) | ||
500 | < 0){ | ||
501 | |||
502 | /* The TM request failed! | ||
503 | * Fatal error case. | ||
504 | */ | ||
505 | printk(MYIOC_s_WARN_FMT | ||
506 | "Error processing TaskMgmt id=%d TARGET_RESET\n", | ||
507 | hd->ioc->name, | ||
508 | vdev->vtarget->target_id); | ||
509 | |||
510 | hd->tmPending = 0; | ||
511 | hd->tmState = TM_STATE_NONE; | ||
512 | } | ||
513 | } | 831 | } |
514 | mptscsih_slave_destroy(sdev); | 832 | |
833 | return mptscsih_qcmd(SCpnt,done); | ||
515 | } | 834 | } |
516 | 835 | ||
836 | |||
517 | static struct scsi_host_template mptsas_driver_template = { | 837 | static struct scsi_host_template mptsas_driver_template = { |
518 | .module = THIS_MODULE, | 838 | .module = THIS_MODULE, |
519 | .proc_name = "mptsas", | 839 | .proc_name = "mptsas", |
520 | .proc_info = mptscsih_proc_info, | 840 | .proc_info = mptscsih_proc_info, |
521 | .name = "MPT SPI Host", | 841 | .name = "MPT SPI Host", |
522 | .info = mptscsih_info, | 842 | .info = mptscsih_info, |
523 | .queuecommand = mptscsih_qcmd, | 843 | .queuecommand = mptsas_qcmd, |
524 | .target_alloc = mptscsih_target_alloc, | 844 | .target_alloc = mptsas_target_alloc, |
525 | .slave_alloc = mptsas_slave_alloc, | 845 | .slave_alloc = mptsas_slave_alloc, |
526 | .slave_configure = mptsas_slave_configure, | 846 | .slave_configure = mptsas_slave_configure, |
527 | .target_destroy = mptscsih_target_destroy, | 847 | .target_destroy = mptsas_target_destroy, |
528 | .slave_destroy = mptsas_slave_destroy, | 848 | .slave_destroy = mptscsih_slave_destroy, |
529 | .change_queue_depth = mptscsih_change_queue_depth, | 849 | .change_queue_depth = mptscsih_change_queue_depth, |
530 | .eh_abort_handler = mptscsih_abort, | 850 | .eh_abort_handler = mptscsih_abort, |
531 | .eh_device_reset_handler = mptscsih_dev_reset, | 851 | .eh_device_reset_handler = mptscsih_dev_reset, |
@@ -795,7 +1115,7 @@ mptsas_sas_io_unit_pg0(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info) | |||
795 | 1115 | ||
796 | port_info->num_phys = buffer->NumPhys; | 1116 | port_info->num_phys = buffer->NumPhys; |
797 | port_info->phy_info = kcalloc(port_info->num_phys, | 1117 | port_info->phy_info = kcalloc(port_info->num_phys, |
798 | sizeof(struct mptsas_phyinfo),GFP_KERNEL); | 1118 | sizeof(*port_info->phy_info),GFP_KERNEL); |
799 | if (!port_info->phy_info) { | 1119 | if (!port_info->phy_info) { |
800 | error = -ENOMEM; | 1120 | error = -ENOMEM; |
801 | goto out_free_consistent; | 1121 | goto out_free_consistent; |
@@ -811,6 +1131,7 @@ mptsas_sas_io_unit_pg0(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info) | |||
811 | buffer->PhyData[i].Port; | 1131 | buffer->PhyData[i].Port; |
812 | port_info->phy_info[i].negotiated_link_rate = | 1132 | port_info->phy_info[i].negotiated_link_rate = |
813 | buffer->PhyData[i].NegotiatedLinkRate; | 1133 | buffer->PhyData[i].NegotiatedLinkRate; |
1134 | port_info->phy_info[i].portinfo = port_info; | ||
814 | } | 1135 | } |
815 | 1136 | ||
816 | out_free_consistent: | 1137 | out_free_consistent: |
@@ -968,7 +1289,7 @@ mptsas_sas_expander_pg0(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info, | |||
968 | CONFIGPARMS cfg; | 1289 | CONFIGPARMS cfg; |
969 | SasExpanderPage0_t *buffer; | 1290 | SasExpanderPage0_t *buffer; |
970 | dma_addr_t dma_handle; | 1291 | dma_addr_t dma_handle; |
971 | int error; | 1292 | int i, error; |
972 | 1293 | ||
973 | hdr.PageVersion = MPI_SASEXPANDER0_PAGEVERSION; | 1294 | hdr.PageVersion = MPI_SASEXPANDER0_PAGEVERSION; |
974 | hdr.ExtPageLength = 0; | 1295 | hdr.ExtPageLength = 0; |
@@ -1013,12 +1334,15 @@ mptsas_sas_expander_pg0(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info, | |||
1013 | port_info->num_phys = buffer->NumPhys; | 1334 | port_info->num_phys = buffer->NumPhys; |
1014 | port_info->handle = le16_to_cpu(buffer->DevHandle); | 1335 | port_info->handle = le16_to_cpu(buffer->DevHandle); |
1015 | port_info->phy_info = kcalloc(port_info->num_phys, | 1336 | port_info->phy_info = kcalloc(port_info->num_phys, |
1016 | sizeof(struct mptsas_phyinfo),GFP_KERNEL); | 1337 | sizeof(*port_info->phy_info),GFP_KERNEL); |
1017 | if (!port_info->phy_info) { | 1338 | if (!port_info->phy_info) { |
1018 | error = -ENOMEM; | 1339 | error = -ENOMEM; |
1019 | goto out_free_consistent; | 1340 | goto out_free_consistent; |
1020 | } | 1341 | } |
1021 | 1342 | ||
1343 | for (i = 0; i < port_info->num_phys; i++) | ||
1344 | port_info->phy_info[i].portinfo = port_info; | ||
1345 | |||
1022 | out_free_consistent: | 1346 | out_free_consistent: |
1023 | pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4, | 1347 | pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4, |
1024 | buffer, dma_handle); | 1348 | buffer, dma_handle); |
@@ -1161,19 +1485,23 @@ static int mptsas_probe_one_phy(struct device *dev, | |||
1161 | { | 1485 | { |
1162 | MPT_ADAPTER *ioc; | 1486 | MPT_ADAPTER *ioc; |
1163 | struct sas_phy *phy; | 1487 | struct sas_phy *phy; |
1164 | int error; | 1488 | struct sas_port *port; |
1489 | int error = 0; | ||
1165 | 1490 | ||
1166 | if (!dev) | 1491 | if (!dev) { |
1167 | return -ENODEV; | 1492 | error = -ENODEV; |
1493 | goto out; | ||
1494 | } | ||
1168 | 1495 | ||
1169 | if (!phy_info->phy) { | 1496 | if (!phy_info->phy) { |
1170 | phy = sas_phy_alloc(dev, index); | 1497 | phy = sas_phy_alloc(dev, index); |
1171 | if (!phy) | 1498 | if (!phy) { |
1172 | return -ENOMEM; | 1499 | error = -ENOMEM; |
1500 | goto out; | ||
1501 | } | ||
1173 | } else | 1502 | } else |
1174 | phy = phy_info->phy; | 1503 | phy = phy_info->phy; |
1175 | 1504 | ||
1176 | phy->port_identifier = phy_info->port_id; | ||
1177 | mptsas_parse_device_info(&phy->identify, &phy_info->identify); | 1505 | mptsas_parse_device_info(&phy->identify, &phy_info->identify); |
1178 | 1506 | ||
1179 | /* | 1507 | /* |
@@ -1265,19 +1593,52 @@ static int mptsas_probe_one_phy(struct device *dev, | |||
1265 | error = sas_phy_add(phy); | 1593 | error = sas_phy_add(phy); |
1266 | if (error) { | 1594 | if (error) { |
1267 | sas_phy_free(phy); | 1595 | sas_phy_free(phy); |
1268 | return error; | 1596 | goto out; |
1269 | } | 1597 | } |
1270 | phy_info->phy = phy; | 1598 | phy_info->phy = phy; |
1271 | } | 1599 | } |
1272 | 1600 | ||
1273 | if ((phy_info->attached.handle) && | 1601 | if (!phy_info->attached.handle || |
1274 | (!phy_info->rphy)) { | 1602 | !phy_info->port_details) |
1603 | goto out; | ||
1604 | |||
1605 | port = mptsas_get_port(phy_info); | ||
1606 | ioc = phy_to_ioc(phy_info->phy); | ||
1607 | |||
1608 | if (phy_info->sas_port_add_phy) { | ||
1609 | |||
1610 | if (!port) { | ||
1611 | port = sas_port_alloc(dev, | ||
1612 | phy_info->port_details->port_id); | ||
1613 | dsaswideprintk((KERN_DEBUG | ||
1614 | "sas_port_alloc: port=%p dev=%p port_id=%d\n", | ||
1615 | port, dev, phy_info->port_details->port_id)); | ||
1616 | if (!port) { | ||
1617 | error = -ENOMEM; | ||
1618 | goto out; | ||
1619 | } | ||
1620 | error = sas_port_add(port); | ||
1621 | if (error) { | ||
1622 | dfailprintk((MYIOC_s_ERR_FMT | ||
1623 | "%s: exit at line=%d\n", ioc->name, | ||
1624 | __FUNCTION__, __LINE__)); | ||
1625 | goto out; | ||
1626 | } | ||
1627 | mptsas_set_port(phy_info, port); | ||
1628 | } | ||
1629 | dsaswideprintk((KERN_DEBUG "sas_port_add_phy: phy_id=%d\n", | ||
1630 | phy_info->phy_id)); | ||
1631 | sas_port_add_phy(port, phy_info->phy); | ||
1632 | phy_info->sas_port_add_phy = 0; | ||
1633 | } | ||
1634 | |||
1635 | if (!mptsas_get_rphy(phy_info) && port && !port->rphy) { | ||
1275 | 1636 | ||
1276 | struct sas_rphy *rphy; | 1637 | struct sas_rphy *rphy; |
1638 | struct device *parent; | ||
1277 | struct sas_identify identify; | 1639 | struct sas_identify identify; |
1278 | 1640 | ||
1279 | ioc = phy_to_ioc(phy_info->phy); | 1641 | parent = dev->parent->parent; |
1280 | |||
1281 | /* | 1642 | /* |
1282 | * Let the hotplug_work thread handle processing | 1643 | * Let the hotplug_work thread handle processing |
1283 | * the adding/removing of devices that occur | 1644 | * the adding/removing of devices that occur |
@@ -1285,36 +1646,63 @@ static int mptsas_probe_one_phy(struct device *dev, | |||
1285 | */ | 1646 | */ |
1286 | if (ioc->sas_discovery_runtime && | 1647 | if (ioc->sas_discovery_runtime && |
1287 | mptsas_is_end_device(&phy_info->attached)) | 1648 | mptsas_is_end_device(&phy_info->attached)) |
1288 | return 0; | 1649 | goto out; |
1289 | 1650 | ||
1290 | mptsas_parse_device_info(&identify, &phy_info->attached); | 1651 | mptsas_parse_device_info(&identify, &phy_info->attached); |
1652 | if (scsi_is_host_device(parent)) { | ||
1653 | struct mptsas_portinfo *port_info; | ||
1654 | int i; | ||
1655 | |||
1656 | mutex_lock(&ioc->sas_topology_mutex); | ||
1657 | port_info = mptsas_find_portinfo_by_handle(ioc, | ||
1658 | ioc->handle); | ||
1659 | mutex_unlock(&ioc->sas_topology_mutex); | ||
1660 | |||
1661 | for (i = 0; i < port_info->num_phys; i++) | ||
1662 | if (port_info->phy_info[i].identify.sas_address == | ||
1663 | identify.sas_address) | ||
1664 | goto out; | ||
1665 | |||
1666 | } else if (scsi_is_sas_rphy(parent)) { | ||
1667 | struct sas_rphy *parent_rphy = dev_to_rphy(parent); | ||
1668 | if (identify.sas_address == | ||
1669 | parent_rphy->identify.sas_address) | ||
1670 | goto out; | ||
1671 | } | ||
1672 | |||
1291 | switch (identify.device_type) { | 1673 | switch (identify.device_type) { |
1292 | case SAS_END_DEVICE: | 1674 | case SAS_END_DEVICE: |
1293 | rphy = sas_end_device_alloc(phy); | 1675 | rphy = sas_end_device_alloc(port); |
1294 | break; | 1676 | break; |
1295 | case SAS_EDGE_EXPANDER_DEVICE: | 1677 | case SAS_EDGE_EXPANDER_DEVICE: |
1296 | case SAS_FANOUT_EXPANDER_DEVICE: | 1678 | case SAS_FANOUT_EXPANDER_DEVICE: |
1297 | rphy = sas_expander_alloc(phy, identify.device_type); | 1679 | rphy = sas_expander_alloc(port, identify.device_type); |
1298 | break; | 1680 | break; |
1299 | default: | 1681 | default: |
1300 | rphy = NULL; | 1682 | rphy = NULL; |
1301 | break; | 1683 | break; |
1302 | } | 1684 | } |
1303 | if (!rphy) | 1685 | if (!rphy) { |
1304 | return 0; /* non-fatal: an rphy can be added later */ | 1686 | dfailprintk((MYIOC_s_ERR_FMT |
1687 | "%s: exit at line=%d\n", ioc->name, | ||
1688 | __FUNCTION__, __LINE__)); | ||
1689 | goto out; | ||
1690 | } | ||
1305 | 1691 | ||
1306 | rphy->identify = identify; | 1692 | rphy->identify = identify; |
1307 | |||
1308 | error = sas_rphy_add(rphy); | 1693 | error = sas_rphy_add(rphy); |
1309 | if (error) { | 1694 | if (error) { |
1695 | dfailprintk((MYIOC_s_ERR_FMT | ||
1696 | "%s: exit at line=%d\n", ioc->name, | ||
1697 | __FUNCTION__, __LINE__)); | ||
1310 | sas_rphy_free(rphy); | 1698 | sas_rphy_free(rphy); |
1311 | return error; | 1699 | goto out; |
1312 | } | 1700 | } |
1313 | 1701 | mptsas_set_rphy(phy_info, rphy); | |
1314 | phy_info->rphy = rphy; | ||
1315 | } | 1702 | } |
1316 | 1703 | ||
1317 | return 0; | 1704 | out: |
1705 | return error; | ||
1318 | } | 1706 | } |
1319 | 1707 | ||
1320 | static int | 1708 | static int |
@@ -1333,6 +1721,7 @@ mptsas_probe_hba_phys(MPT_ADAPTER *ioc) | |||
1333 | goto out_free_port_info; | 1721 | goto out_free_port_info; |
1334 | 1722 | ||
1335 | mutex_lock(&ioc->sas_topology_mutex); | 1723 | mutex_lock(&ioc->sas_topology_mutex); |
1724 | ioc->handle = hba->handle; | ||
1336 | port_info = mptsas_find_portinfo_by_handle(ioc, hba->handle); | 1725 | port_info = mptsas_find_portinfo_by_handle(ioc, hba->handle); |
1337 | if (!port_info) { | 1726 | if (!port_info) { |
1338 | port_info = hba; | 1727 | port_info = hba; |
@@ -1342,8 +1731,7 @@ mptsas_probe_hba_phys(MPT_ADAPTER *ioc) | |||
1342 | for (i = 0; i < hba->num_phys; i++) | 1731 | for (i = 0; i < hba->num_phys; i++) |
1343 | port_info->phy_info[i].negotiated_link_rate = | 1732 | port_info->phy_info[i].negotiated_link_rate = |
1344 | hba->phy_info[i].negotiated_link_rate; | 1733 | hba->phy_info[i].negotiated_link_rate; |
1345 | if (hba->phy_info) | 1734 | kfree(hba->phy_info); |
1346 | kfree(hba->phy_info); | ||
1347 | kfree(hba); | 1735 | kfree(hba); |
1348 | hba = NULL; | 1736 | hba = NULL; |
1349 | } | 1737 | } |
@@ -1362,18 +1750,19 @@ mptsas_probe_hba_phys(MPT_ADAPTER *ioc) | |||
1362 | port_info->phy_info[i].phy_id; | 1750 | port_info->phy_info[i].phy_id; |
1363 | handle = port_info->phy_info[i].identify.handle; | 1751 | handle = port_info->phy_info[i].identify.handle; |
1364 | 1752 | ||
1365 | if (port_info->phy_info[i].attached.handle) { | 1753 | if (port_info->phy_info[i].attached.handle) |
1366 | mptsas_sas_device_pg0(ioc, | 1754 | mptsas_sas_device_pg0(ioc, |
1367 | &port_info->phy_info[i].attached, | 1755 | &port_info->phy_info[i].attached, |
1368 | (MPI_SAS_DEVICE_PGAD_FORM_HANDLE << | 1756 | (MPI_SAS_DEVICE_PGAD_FORM_HANDLE << |
1369 | MPI_SAS_DEVICE_PGAD_FORM_SHIFT), | 1757 | MPI_SAS_DEVICE_PGAD_FORM_SHIFT), |
1370 | port_info->phy_info[i].attached.handle); | 1758 | port_info->phy_info[i].attached.handle); |
1371 | } | 1759 | } |
1760 | |||
1761 | mptsas_setup_wide_ports(ioc, port_info); | ||
1372 | 1762 | ||
1763 | for (i = 0; i < port_info->num_phys; i++, ioc->sas_index++) | ||
1373 | mptsas_probe_one_phy(&ioc->sh->shost_gendev, | 1764 | mptsas_probe_one_phy(&ioc->sh->shost_gendev, |
1374 | &port_info->phy_info[i], ioc->sas_index, 1); | 1765 | &port_info->phy_info[i], ioc->sas_index, 1); |
1375 | ioc->sas_index++; | ||
1376 | } | ||
1377 | 1766 | ||
1378 | return 0; | 1767 | return 0; |
1379 | 1768 | ||
@@ -1387,6 +1776,8 @@ static int | |||
1387 | mptsas_probe_expander_phys(MPT_ADAPTER *ioc, u32 *handle) | 1776 | mptsas_probe_expander_phys(MPT_ADAPTER *ioc, u32 *handle) |
1388 | { | 1777 | { |
1389 | struct mptsas_portinfo *port_info, *p, *ex; | 1778 | struct mptsas_portinfo *port_info, *p, *ex; |
1779 | struct device *parent; | ||
1780 | struct sas_rphy *rphy; | ||
1390 | int error = -ENOMEM, i, j; | 1781 | int error = -ENOMEM, i, j; |
1391 | 1782 | ||
1392 | ex = kzalloc(sizeof(*port_info), GFP_KERNEL); | 1783 | ex = kzalloc(sizeof(*port_info), GFP_KERNEL); |
@@ -1408,16 +1799,13 @@ mptsas_probe_expander_phys(MPT_ADAPTER *ioc, u32 *handle) | |||
1408 | list_add_tail(&port_info->list, &ioc->sas_topology); | 1799 | list_add_tail(&port_info->list, &ioc->sas_topology); |
1409 | } else { | 1800 | } else { |
1410 | port_info->handle = ex->handle; | 1801 | port_info->handle = ex->handle; |
1411 | if (ex->phy_info) | 1802 | kfree(ex->phy_info); |
1412 | kfree(ex->phy_info); | ||
1413 | kfree(ex); | 1803 | kfree(ex); |
1414 | ex = NULL; | 1804 | ex = NULL; |
1415 | } | 1805 | } |
1416 | mutex_unlock(&ioc->sas_topology_mutex); | 1806 | mutex_unlock(&ioc->sas_topology_mutex); |
1417 | 1807 | ||
1418 | for (i = 0; i < port_info->num_phys; i++) { | 1808 | for (i = 0; i < port_info->num_phys; i++) { |
1419 | struct device *parent; | ||
1420 | |||
1421 | mptsas_sas_expander_pg1(ioc, &port_info->phy_info[i], | 1809 | mptsas_sas_expander_pg1(ioc, &port_info->phy_info[i], |
1422 | (MPI_SAS_EXPAND_PGAD_FORM_HANDLE_PHY_NUM << | 1810 | (MPI_SAS_EXPAND_PGAD_FORM_HANDLE_PHY_NUM << |
1423 | MPI_SAS_EXPAND_PGAD_FORM_SHIFT), (i << 16) + *handle); | 1811 | MPI_SAS_EXPAND_PGAD_FORM_SHIFT), (i << 16) + *handle); |
@@ -1441,34 +1829,34 @@ mptsas_probe_expander_phys(MPT_ADAPTER *ioc, u32 *handle) | |||
1441 | port_info->phy_info[i].attached.phy_id = | 1829 | port_info->phy_info[i].attached.phy_id = |
1442 | port_info->phy_info[i].phy_id; | 1830 | port_info->phy_info[i].phy_id; |
1443 | } | 1831 | } |
1832 | } | ||
1444 | 1833 | ||
1445 | /* | 1834 | parent = &ioc->sh->shost_gendev; |
1446 | * If we find a parent port handle this expander is | 1835 | for (i = 0; i < port_info->num_phys; i++) { |
1447 | * attached to another expander, else it hangs of the | ||
1448 | * HBA phys. | ||
1449 | */ | ||
1450 | parent = &ioc->sh->shost_gendev; | ||
1451 | mutex_lock(&ioc->sas_topology_mutex); | 1836 | mutex_lock(&ioc->sas_topology_mutex); |
1452 | list_for_each_entry(p, &ioc->sas_topology, list) { | 1837 | list_for_each_entry(p, &ioc->sas_topology, list) { |
1453 | for (j = 0; j < p->num_phys; j++) { | 1838 | for (j = 0; j < p->num_phys; j++) { |
1454 | if (port_info->phy_info[i].identify.handle == | 1839 | if (port_info->phy_info[i].identify.handle != |
1455 | p->phy_info[j].attached.handle) | 1840 | p->phy_info[j].attached.handle) |
1456 | parent = &p->phy_info[j].rphy->dev; | 1841 | continue; |
1842 | rphy = mptsas_get_rphy(&p->phy_info[j]); | ||
1843 | parent = &rphy->dev; | ||
1457 | } | 1844 | } |
1458 | } | 1845 | } |
1459 | mutex_unlock(&ioc->sas_topology_mutex); | 1846 | mutex_unlock(&ioc->sas_topology_mutex); |
1847 | } | ||
1848 | |||
1849 | mptsas_setup_wide_ports(ioc, port_info); | ||
1460 | 1850 | ||
1851 | for (i = 0; i < port_info->num_phys; i++, ioc->sas_index++) | ||
1461 | mptsas_probe_one_phy(parent, &port_info->phy_info[i], | 1852 | mptsas_probe_one_phy(parent, &port_info->phy_info[i], |
1462 | ioc->sas_index, 0); | 1853 | ioc->sas_index, 0); |
1463 | ioc->sas_index++; | ||
1464 | } | ||
1465 | 1854 | ||
1466 | return 0; | 1855 | return 0; |
1467 | 1856 | ||
1468 | out_free_port_info: | 1857 | out_free_port_info: |
1469 | if (ex) { | 1858 | if (ex) { |
1470 | if (ex->phy_info) | 1859 | kfree(ex->phy_info); |
1471 | kfree(ex->phy_info); | ||
1472 | kfree(ex); | 1860 | kfree(ex); |
1473 | } | 1861 | } |
1474 | out: | 1862 | out: |
@@ -1487,7 +1875,12 @@ mptsas_delete_expander_phys(MPT_ADAPTER *ioc) | |||
1487 | { | 1875 | { |
1488 | struct mptsas_portinfo buffer; | 1876 | struct mptsas_portinfo buffer; |
1489 | struct mptsas_portinfo *port_info, *n, *parent; | 1877 | struct mptsas_portinfo *port_info, *n, *parent; |
1878 | struct mptsas_phyinfo *phy_info; | ||
1879 | struct scsi_target * starget; | ||
1880 | VirtTarget * vtarget; | ||
1881 | struct sas_port * port; | ||
1490 | int i; | 1882 | int i; |
1883 | u64 expander_sas_address; | ||
1491 | 1884 | ||
1492 | mutex_lock(&ioc->sas_topology_mutex); | 1885 | mutex_lock(&ioc->sas_topology_mutex); |
1493 | list_for_each_entry_safe(port_info, n, &ioc->sas_topology, list) { | 1886 | list_for_each_entry_safe(port_info, n, &ioc->sas_topology, list) { |
@@ -1502,6 +1895,25 @@ mptsas_delete_expander_phys(MPT_ADAPTER *ioc) | |||
1502 | MPI_SAS_EXPAND_PGAD_FORM_SHIFT), port_info->handle)) { | 1895 | MPI_SAS_EXPAND_PGAD_FORM_SHIFT), port_info->handle)) { |
1503 | 1896 | ||
1504 | /* | 1897 | /* |
1898 | * Issue target reset to all child end devices | ||
1899 | * then mark them deleted to prevent further | ||
1900 | * IO going to them. | ||
1901 | */ | ||
1902 | phy_info = port_info->phy_info; | ||
1903 | for (i = 0; i < port_info->num_phys; i++, phy_info++) { | ||
1904 | starget = mptsas_get_starget(phy_info); | ||
1905 | if (!starget) | ||
1906 | continue; | ||
1907 | vtarget = starget->hostdata; | ||
1908 | if(vtarget->deleted) | ||
1909 | continue; | ||
1910 | vtarget->deleted = 1; | ||
1911 | mptsas_target_reset(ioc, vtarget); | ||
1912 | sas_port_delete(mptsas_get_port(phy_info)); | ||
1913 | mptsas_port_delete(phy_info->port_details); | ||
1914 | } | ||
1915 | |||
1916 | /* | ||
1505 | * Obtain the port_info instance to the parent port | 1917 | * Obtain the port_info instance to the parent port |
1506 | */ | 1918 | */ |
1507 | parent = mptsas_find_portinfo_by_handle(ioc, | 1919 | parent = mptsas_find_portinfo_by_handle(ioc, |
@@ -1510,34 +1922,43 @@ mptsas_delete_expander_phys(MPT_ADAPTER *ioc) | |||
1510 | if (!parent) | 1922 | if (!parent) |
1511 | goto next_port; | 1923 | goto next_port; |
1512 | 1924 | ||
1925 | expander_sas_address = | ||
1926 | port_info->phy_info[0].identify.sas_address; | ||
1927 | |||
1513 | /* | 1928 | /* |
1514 | * Delete rphys in the parent that point | 1929 | * Delete rphys in the parent that point |
1515 | * to this expander. The transport layer will | 1930 | * to this expander. The transport layer will |
1516 | * cleanup all the children. | 1931 | * cleanup all the children. |
1517 | */ | 1932 | */ |
1518 | for (i = 0; i < parent->num_phys; i++) { | 1933 | phy_info = parent->phy_info; |
1519 | if ((!parent->phy_info[i].rphy) || | 1934 | for (i = 0; i < parent->num_phys; i++, phy_info++) { |
1520 | (parent->phy_info[i].attached.sas_address != | 1935 | port = mptsas_get_port(phy_info); |
1521 | port_info->phy_info[i].identify.sas_address)) | 1936 | if (!port) |
1937 | continue; | ||
1938 | if (phy_info->attached.sas_address != | ||
1939 | expander_sas_address) | ||
1522 | continue; | 1940 | continue; |
1523 | sas_rphy_delete(parent->phy_info[i].rphy); | 1941 | #ifdef MPT_DEBUG_SAS_WIDE |
1524 | memset(&parent->phy_info[i].attached, 0, | 1942 | dev_printk(KERN_DEBUG, &port->dev, "delete\n"); |
1525 | sizeof(struct mptsas_devinfo)); | 1943 | #endif |
1526 | parent->phy_info[i].rphy = NULL; | 1944 | sas_port_delete(port); |
1527 | parent->phy_info[i].starget = NULL; | 1945 | mptsas_port_delete(phy_info->port_details); |
1528 | } | 1946 | } |
1529 | next_port: | 1947 | next_port: |
1948 | |||
1949 | phy_info = port_info->phy_info; | ||
1950 | for (i = 0; i < port_info->num_phys; i++, phy_info++) | ||
1951 | mptsas_port_delete(phy_info->port_details); | ||
1952 | |||
1530 | list_del(&port_info->list); | 1953 | list_del(&port_info->list); |
1531 | if (port_info->phy_info) | 1954 | kfree(port_info->phy_info); |
1532 | kfree(port_info->phy_info); | ||
1533 | kfree(port_info); | 1955 | kfree(port_info); |
1534 | } | 1956 | } |
1535 | /* | 1957 | /* |
1536 | * Free this memory allocated from inside | 1958 | * Free this memory allocated from inside |
1537 | * mptsas_sas_expander_pg0 | 1959 | * mptsas_sas_expander_pg0 |
1538 | */ | 1960 | */ |
1539 | if (buffer.phy_info) | 1961 | kfree(buffer.phy_info); |
1540 | kfree(buffer.phy_info); | ||
1541 | } | 1962 | } |
1542 | mutex_unlock(&ioc->sas_topology_mutex); | 1963 | mutex_unlock(&ioc->sas_topology_mutex); |
1543 | } | 1964 | } |
@@ -1573,60 +1994,59 @@ mptsas_scan_sas_topology(MPT_ADAPTER *ioc) | |||
1573 | /* | 1994 | /* |
1574 | * Work queue thread to handle Runtime discovery | 1995 | * Work queue thread to handle Runtime discovery |
1575 | * Mere purpose is the hot add/delete of expanders | 1996 | * Mere purpose is the hot add/delete of expanders |
1997 | *(Mutex UNLOCKED) | ||
1576 | */ | 1998 | */ |
1577 | static void | 1999 | static void |
1578 | mptscsih_discovery_work(void * arg) | 2000 | __mptsas_discovery_work(MPT_ADAPTER *ioc) |
1579 | { | 2001 | { |
1580 | struct mptsas_discovery_event *ev = arg; | ||
1581 | MPT_ADAPTER *ioc = ev->ioc; | ||
1582 | u32 handle = 0xFFFF; | 2002 | u32 handle = 0xFFFF; |
1583 | 2003 | ||
1584 | mutex_lock(&ioc->sas_discovery_mutex); | ||
1585 | ioc->sas_discovery_runtime=1; | 2004 | ioc->sas_discovery_runtime=1; |
1586 | mptsas_delete_expander_phys(ioc); | 2005 | mptsas_delete_expander_phys(ioc); |
1587 | mptsas_probe_hba_phys(ioc); | 2006 | mptsas_probe_hba_phys(ioc); |
1588 | while (!mptsas_probe_expander_phys(ioc, &handle)) | 2007 | while (!mptsas_probe_expander_phys(ioc, &handle)) |
1589 | ; | 2008 | ; |
1590 | kfree(ev); | ||
1591 | ioc->sas_discovery_runtime=0; | 2009 | ioc->sas_discovery_runtime=0; |
2010 | } | ||
2011 | |||
2012 | /* | ||
2013 | * Work queue thread to handle Runtime discovery | ||
2014 | * Mere purpose is the hot add/delete of expanders | ||
2015 | *(Mutex LOCKED) | ||
2016 | */ | ||
2017 | static void | ||
2018 | mptsas_discovery_work(void * arg) | ||
2019 | { | ||
2020 | struct mptsas_discovery_event *ev = arg; | ||
2021 | MPT_ADAPTER *ioc = ev->ioc; | ||
2022 | |||
2023 | mutex_lock(&ioc->sas_discovery_mutex); | ||
2024 | __mptsas_discovery_work(ioc); | ||
1592 | mutex_unlock(&ioc->sas_discovery_mutex); | 2025 | mutex_unlock(&ioc->sas_discovery_mutex); |
2026 | kfree(ev); | ||
1593 | } | 2027 | } |
1594 | 2028 | ||
1595 | static struct mptsas_phyinfo * | 2029 | static struct mptsas_phyinfo * |
1596 | mptsas_find_phyinfo_by_parent(MPT_ADAPTER *ioc, u16 parent_handle, u8 phy_id) | 2030 | mptsas_find_phyinfo_by_sas_address(MPT_ADAPTER *ioc, u64 sas_address) |
1597 | { | 2031 | { |
1598 | struct mptsas_portinfo *port_info; | 2032 | struct mptsas_portinfo *port_info; |
1599 | struct mptsas_devinfo device_info; | ||
1600 | struct mptsas_phyinfo *phy_info = NULL; | 2033 | struct mptsas_phyinfo *phy_info = NULL; |
1601 | int i, error; | 2034 | int i; |
1602 | |||
1603 | /* | ||
1604 | * Retrieve the parent sas_address | ||
1605 | */ | ||
1606 | error = mptsas_sas_device_pg0(ioc, &device_info, | ||
1607 | (MPI_SAS_DEVICE_PGAD_FORM_HANDLE << | ||
1608 | MPI_SAS_DEVICE_PGAD_FORM_SHIFT), | ||
1609 | parent_handle); | ||
1610 | if (error) | ||
1611 | return NULL; | ||
1612 | 2035 | ||
1613 | /* | ||
1614 | * The phy_info structures are never deallocated during lifetime of | ||
1615 | * a host, so the code below is safe without additional refcounting. | ||
1616 | */ | ||
1617 | mutex_lock(&ioc->sas_topology_mutex); | 2036 | mutex_lock(&ioc->sas_topology_mutex); |
1618 | list_for_each_entry(port_info, &ioc->sas_topology, list) { | 2037 | list_for_each_entry(port_info, &ioc->sas_topology, list) { |
1619 | for (i = 0; i < port_info->num_phys; i++) { | 2038 | for (i = 0; i < port_info->num_phys; i++) { |
1620 | if (port_info->phy_info[i].identify.sas_address == | 2039 | if (port_info->phy_info[i].attached.sas_address |
1621 | device_info.sas_address && | 2040 | != sas_address) |
1622 | port_info->phy_info[i].phy_id == phy_id) { | 2041 | continue; |
1623 | phy_info = &port_info->phy_info[i]; | 2042 | if (!mptsas_is_end_device( |
1624 | break; | 2043 | &port_info->phy_info[i].attached)) |
1625 | } | 2044 | continue; |
2045 | phy_info = &port_info->phy_info[i]; | ||
2046 | break; | ||
1626 | } | 2047 | } |
1627 | } | 2048 | } |
1628 | mutex_unlock(&ioc->sas_topology_mutex); | 2049 | mutex_unlock(&ioc->sas_topology_mutex); |
1629 | |||
1630 | return phy_info; | 2050 | return phy_info; |
1631 | } | 2051 | } |
1632 | 2052 | ||
@@ -1637,21 +2057,19 @@ mptsas_find_phyinfo_by_target(MPT_ADAPTER *ioc, u32 id) | |||
1637 | struct mptsas_phyinfo *phy_info = NULL; | 2057 | struct mptsas_phyinfo *phy_info = NULL; |
1638 | int i; | 2058 | int i; |
1639 | 2059 | ||
1640 | /* | ||
1641 | * The phy_info structures are never deallocated during lifetime of | ||
1642 | * a host, so the code below is safe without additional refcounting. | ||
1643 | */ | ||
1644 | mutex_lock(&ioc->sas_topology_mutex); | 2060 | mutex_lock(&ioc->sas_topology_mutex); |
1645 | list_for_each_entry(port_info, &ioc->sas_topology, list) { | 2061 | list_for_each_entry(port_info, &ioc->sas_topology, list) { |
1646 | for (i = 0; i < port_info->num_phys; i++) | 2062 | for (i = 0; i < port_info->num_phys; i++) { |
1647 | if (mptsas_is_end_device(&port_info->phy_info[i].attached)) | 2063 | if (port_info->phy_info[i].attached.id != id) |
1648 | if (port_info->phy_info[i].attached.id == id) { | 2064 | continue; |
1649 | phy_info = &port_info->phy_info[i]; | 2065 | if (!mptsas_is_end_device( |
1650 | break; | 2066 | &port_info->phy_info[i].attached)) |
1651 | } | 2067 | continue; |
2068 | phy_info = &port_info->phy_info[i]; | ||
2069 | break; | ||
2070 | } | ||
1652 | } | 2071 | } |
1653 | mutex_unlock(&ioc->sas_topology_mutex); | 2072 | mutex_unlock(&ioc->sas_topology_mutex); |
1654 | |||
1655 | return phy_info; | 2073 | return phy_info; |
1656 | } | 2074 | } |
1657 | 2075 | ||
@@ -1659,7 +2077,7 @@ mptsas_find_phyinfo_by_target(MPT_ADAPTER *ioc, u32 id) | |||
1659 | * Work queue thread to clear the persitency table | 2077 | * Work queue thread to clear the persitency table |
1660 | */ | 2078 | */ |
1661 | static void | 2079 | static void |
1662 | mptscsih_sas_persist_clear_table(void * arg) | 2080 | mptsas_persist_clear_table(void * arg) |
1663 | { | 2081 | { |
1664 | MPT_ADAPTER *ioc = (MPT_ADAPTER *)arg; | 2082 | MPT_ADAPTER *ioc = (MPT_ADAPTER *)arg; |
1665 | 2083 | ||
@@ -1680,7 +2098,6 @@ mptsas_reprobe_target(struct scsi_target *starget, int uld_attach) | |||
1680 | mptsas_reprobe_lun); | 2098 | mptsas_reprobe_lun); |
1681 | } | 2099 | } |
1682 | 2100 | ||
1683 | |||
1684 | /* | 2101 | /* |
1685 | * Work queue thread to handle SAS hotplug events | 2102 | * Work queue thread to handle SAS hotplug events |
1686 | */ | 2103 | */ |
@@ -1691,14 +2108,17 @@ mptsas_hotplug_work(void *arg) | |||
1691 | MPT_ADAPTER *ioc = ev->ioc; | 2108 | MPT_ADAPTER *ioc = ev->ioc; |
1692 | struct mptsas_phyinfo *phy_info; | 2109 | struct mptsas_phyinfo *phy_info; |
1693 | struct sas_rphy *rphy; | 2110 | struct sas_rphy *rphy; |
2111 | struct sas_port *port; | ||
1694 | struct scsi_device *sdev; | 2112 | struct scsi_device *sdev; |
2113 | struct scsi_target * starget; | ||
1695 | struct sas_identify identify; | 2114 | struct sas_identify identify; |
1696 | char *ds = NULL; | 2115 | char *ds = NULL; |
1697 | struct mptsas_devinfo sas_device; | 2116 | struct mptsas_devinfo sas_device; |
1698 | VirtTarget *vtarget; | 2117 | VirtTarget *vtarget; |
2118 | VirtDevice *vdevice; | ||
1699 | 2119 | ||
1700 | mutex_lock(&ioc->sas_discovery_mutex); | ||
1701 | 2120 | ||
2121 | mutex_lock(&ioc->sas_discovery_mutex); | ||
1702 | switch (ev->event_type) { | 2122 | switch (ev->event_type) { |
1703 | case MPTSAS_DEL_DEVICE: | 2123 | case MPTSAS_DEL_DEVICE: |
1704 | 2124 | ||
@@ -1707,24 +2127,50 @@ mptsas_hotplug_work(void *arg) | |||
1707 | /* | 2127 | /* |
1708 | * Sanity checks, for non-existing phys and remote rphys. | 2128 | * Sanity checks, for non-existing phys and remote rphys. |
1709 | */ | 2129 | */ |
1710 | if (!phy_info) | 2130 | if (!phy_info || !phy_info->port_details) { |
2131 | dfailprintk((MYIOC_s_ERR_FMT | ||
2132 | "%s: exit at line=%d\n", ioc->name, | ||
2133 | __FUNCTION__, __LINE__)); | ||
1711 | break; | 2134 | break; |
1712 | if (!phy_info->rphy) | 2135 | } |
2136 | rphy = mptsas_get_rphy(phy_info); | ||
2137 | if (!rphy) { | ||
2138 | dfailprintk((MYIOC_s_ERR_FMT | ||
2139 | "%s: exit at line=%d\n", ioc->name, | ||
2140 | __FUNCTION__, __LINE__)); | ||
1713 | break; | 2141 | break; |
1714 | if (phy_info->starget) { | 2142 | } |
1715 | vtarget = phy_info->starget->hostdata; | 2143 | port = mptsas_get_port(phy_info); |
2144 | if (!port) { | ||
2145 | dfailprintk((MYIOC_s_ERR_FMT | ||
2146 | "%s: exit at line=%d\n", ioc->name, | ||
2147 | __FUNCTION__, __LINE__)); | ||
2148 | break; | ||
2149 | } | ||
1716 | 2150 | ||
1717 | if (!vtarget) | 2151 | starget = mptsas_get_starget(phy_info); |
2152 | if (starget) { | ||
2153 | vtarget = starget->hostdata; | ||
2154 | |||
2155 | if (!vtarget) { | ||
2156 | dfailprintk((MYIOC_s_ERR_FMT | ||
2157 | "%s: exit at line=%d\n", ioc->name, | ||
2158 | __FUNCTION__, __LINE__)); | ||
1718 | break; | 2159 | break; |
2160 | } | ||
2161 | |||
1719 | /* | 2162 | /* |
1720 | * Handling RAID components | 2163 | * Handling RAID components |
1721 | */ | 2164 | */ |
1722 | if (ev->phys_disk_num_valid) { | 2165 | if (ev->phys_disk_num_valid) { |
1723 | vtarget->target_id = ev->phys_disk_num; | 2166 | vtarget->target_id = ev->phys_disk_num; |
1724 | vtarget->tflags |= MPT_TARGET_FLAGS_RAID_COMPONENT; | 2167 | vtarget->tflags |= MPT_TARGET_FLAGS_RAID_COMPONENT; |
1725 | mptsas_reprobe_target(vtarget->starget, 1); | 2168 | mptsas_reprobe_target(starget, 1); |
1726 | break; | 2169 | break; |
1727 | } | 2170 | } |
2171 | |||
2172 | vtarget->deleted = 1; | ||
2173 | mptsas_target_reset(ioc, vtarget); | ||
1728 | } | 2174 | } |
1729 | 2175 | ||
1730 | if (phy_info->attached.device_info & MPI_SAS_DEVICE_INFO_SSP_TARGET) | 2176 | if (phy_info->attached.device_info & MPI_SAS_DEVICE_INFO_SSP_TARGET) |
@@ -1738,10 +2184,11 @@ mptsas_hotplug_work(void *arg) | |||
1738 | "removing %s device, channel %d, id %d, phy %d\n", | 2184 | "removing %s device, channel %d, id %d, phy %d\n", |
1739 | ioc->name, ds, ev->channel, ev->id, phy_info->phy_id); | 2185 | ioc->name, ds, ev->channel, ev->id, phy_info->phy_id); |
1740 | 2186 | ||
1741 | sas_rphy_delete(phy_info->rphy); | 2187 | #ifdef MPT_DEBUG_SAS_WIDE |
1742 | memset(&phy_info->attached, 0, sizeof(struct mptsas_devinfo)); | 2188 | dev_printk(KERN_DEBUG, &port->dev, "delete\n"); |
1743 | phy_info->rphy = NULL; | 2189 | #endif |
1744 | phy_info->starget = NULL; | 2190 | sas_port_delete(port); |
2191 | mptsas_port_delete(phy_info->port_details); | ||
1745 | break; | 2192 | break; |
1746 | case MPTSAS_ADD_DEVICE: | 2193 | case MPTSAS_ADD_DEVICE: |
1747 | 2194 | ||
@@ -1753,59 +2200,60 @@ mptsas_hotplug_work(void *arg) | |||
1753 | */ | 2200 | */ |
1754 | if (mptsas_sas_device_pg0(ioc, &sas_device, | 2201 | if (mptsas_sas_device_pg0(ioc, &sas_device, |
1755 | (MPI_SAS_DEVICE_PGAD_FORM_BUS_TARGET_ID << | 2202 | (MPI_SAS_DEVICE_PGAD_FORM_BUS_TARGET_ID << |
1756 | MPI_SAS_DEVICE_PGAD_FORM_SHIFT), ev->id)) | 2203 | MPI_SAS_DEVICE_PGAD_FORM_SHIFT), ev->id)) { |
2204 | dfailprintk((MYIOC_s_ERR_FMT | ||
2205 | "%s: exit at line=%d\n", ioc->name, | ||
2206 | __FUNCTION__, __LINE__)); | ||
1757 | break; | 2207 | break; |
2208 | } | ||
1758 | 2209 | ||
1759 | phy_info = mptsas_find_phyinfo_by_parent(ioc, | 2210 | ssleep(2); |
1760 | sas_device.handle_parent, sas_device.phy_id); | 2211 | __mptsas_discovery_work(ioc); |
1761 | 2212 | ||
1762 | if (!phy_info) { | 2213 | phy_info = mptsas_find_phyinfo_by_sas_address(ioc, |
1763 | u32 handle = 0xFFFF; | 2214 | sas_device.sas_address); |
1764 | 2215 | ||
1765 | /* | 2216 | if (!phy_info || !phy_info->port_details) { |
1766 | * Its possible when an expander has been hot added | 2217 | dfailprintk((MYIOC_s_ERR_FMT |
1767 | * containing attached devices, the sas firmware | 2218 | "%s: exit at line=%d\n", ioc->name, |
1768 | * may send a RC_ADDED event prior to the | 2219 | __FUNCTION__, __LINE__)); |
1769 | * DISCOVERY STOP event. If that occurs, our | 2220 | break; |
1770 | * view of the topology in the driver in respect to this | ||
1771 | * expander might of not been setup, and we hit this | ||
1772 | * condition. | ||
1773 | * Therefore, this code kicks off discovery to | ||
1774 | * refresh the data. | ||
1775 | * Then again, we check whether the parent phy has | ||
1776 | * been created. | ||
1777 | */ | ||
1778 | ioc->sas_discovery_runtime=1; | ||
1779 | mptsas_delete_expander_phys(ioc); | ||
1780 | mptsas_probe_hba_phys(ioc); | ||
1781 | while (!mptsas_probe_expander_phys(ioc, &handle)) | ||
1782 | ; | ||
1783 | ioc->sas_discovery_runtime=0; | ||
1784 | |||
1785 | phy_info = mptsas_find_phyinfo_by_parent(ioc, | ||
1786 | sas_device.handle_parent, sas_device.phy_id); | ||
1787 | if (!phy_info) | ||
1788 | break; | ||
1789 | } | 2221 | } |
1790 | 2222 | ||
1791 | if (phy_info->starget) { | 2223 | starget = mptsas_get_starget(phy_info); |
1792 | vtarget = phy_info->starget->hostdata; | 2224 | if (starget) { |
2225 | vtarget = starget->hostdata; | ||
1793 | 2226 | ||
1794 | if (!vtarget) | 2227 | if (!vtarget) { |
2228 | dfailprintk((MYIOC_s_ERR_FMT | ||
2229 | "%s: exit at line=%d\n", ioc->name, | ||
2230 | __FUNCTION__, __LINE__)); | ||
1795 | break; | 2231 | break; |
2232 | } | ||
1796 | /* | 2233 | /* |
1797 | * Handling RAID components | 2234 | * Handling RAID components |
1798 | */ | 2235 | */ |
1799 | if (vtarget->tflags & MPT_TARGET_FLAGS_RAID_COMPONENT) { | 2236 | if (vtarget->tflags & MPT_TARGET_FLAGS_RAID_COMPONENT) { |
1800 | vtarget->tflags &= ~MPT_TARGET_FLAGS_RAID_COMPONENT; | 2237 | vtarget->tflags &= ~MPT_TARGET_FLAGS_RAID_COMPONENT; |
1801 | vtarget->target_id = ev->id; | 2238 | vtarget->target_id = ev->id; |
1802 | mptsas_reprobe_target(phy_info->starget, 0); | 2239 | mptsas_reprobe_target(starget, 0); |
1803 | } | 2240 | } |
1804 | break; | 2241 | break; |
1805 | } | 2242 | } |
1806 | 2243 | ||
1807 | if (phy_info->rphy) | 2244 | if (mptsas_get_rphy(phy_info)) { |
2245 | dfailprintk((MYIOC_s_ERR_FMT | ||
2246 | "%s: exit at line=%d\n", ioc->name, | ||
2247 | __FUNCTION__, __LINE__)); | ||
1808 | break; | 2248 | break; |
2249 | } | ||
2250 | port = mptsas_get_port(phy_info); | ||
2251 | if (!port) { | ||
2252 | dfailprintk((MYIOC_s_ERR_FMT | ||
2253 | "%s: exit at line=%d\n", ioc->name, | ||
2254 | __FUNCTION__, __LINE__)); | ||
2255 | break; | ||
2256 | } | ||
1809 | 2257 | ||
1810 | memcpy(&phy_info->attached, &sas_device, | 2258 | memcpy(&phy_info->attached, &sas_device, |
1811 | sizeof(struct mptsas_devinfo)); | 2259 | sizeof(struct mptsas_devinfo)); |
@@ -1822,28 +2270,23 @@ mptsas_hotplug_work(void *arg) | |||
1822 | ioc->name, ds, ev->channel, ev->id, ev->phy_id); | 2270 | ioc->name, ds, ev->channel, ev->id, ev->phy_id); |
1823 | 2271 | ||
1824 | mptsas_parse_device_info(&identify, &phy_info->attached); | 2272 | mptsas_parse_device_info(&identify, &phy_info->attached); |
1825 | switch (identify.device_type) { | 2273 | rphy = sas_end_device_alloc(port); |
1826 | case SAS_END_DEVICE: | 2274 | if (!rphy) { |
1827 | rphy = sas_end_device_alloc(phy_info->phy); | 2275 | dfailprintk((MYIOC_s_ERR_FMT |
1828 | break; | 2276 | "%s: exit at line=%d\n", ioc->name, |
1829 | case SAS_EDGE_EXPANDER_DEVICE: | 2277 | __FUNCTION__, __LINE__)); |
1830 | case SAS_FANOUT_EXPANDER_DEVICE: | ||
1831 | rphy = sas_expander_alloc(phy_info->phy, identify.device_type); | ||
1832 | break; | ||
1833 | default: | ||
1834 | rphy = NULL; | ||
1835 | break; | ||
1836 | } | ||
1837 | if (!rphy) | ||
1838 | break; /* non-fatal: an rphy can be added later */ | 2278 | break; /* non-fatal: an rphy can be added later */ |
2279 | } | ||
1839 | 2280 | ||
1840 | rphy->identify = identify; | 2281 | rphy->identify = identify; |
1841 | if (sas_rphy_add(rphy)) { | 2282 | if (sas_rphy_add(rphy)) { |
2283 | dfailprintk((MYIOC_s_ERR_FMT | ||
2284 | "%s: exit at line=%d\n", ioc->name, | ||
2285 | __FUNCTION__, __LINE__)); | ||
1842 | sas_rphy_free(rphy); | 2286 | sas_rphy_free(rphy); |
1843 | break; | 2287 | break; |
1844 | } | 2288 | } |
1845 | 2289 | mptsas_set_rphy(phy_info, rphy); | |
1846 | phy_info->rphy = rphy; | ||
1847 | break; | 2290 | break; |
1848 | case MPTSAS_ADD_RAID: | 2291 | case MPTSAS_ADD_RAID: |
1849 | sdev = scsi_device_lookup( | 2292 | sdev = scsi_device_lookup( |
@@ -1875,6 +2318,9 @@ mptsas_hotplug_work(void *arg) | |||
1875 | printk(MYIOC_s_INFO_FMT | 2318 | printk(MYIOC_s_INFO_FMT |
1876 | "removing raid volume, channel %d, id %d\n", | 2319 | "removing raid volume, channel %d, id %d\n", |
1877 | ioc->name, ioc->num_ports, ev->id); | 2320 | ioc->name, ioc->num_ports, ev->id); |
2321 | vdevice = sdev->hostdata; | ||
2322 | vdevice->vtarget->deleted = 1; | ||
2323 | mptsas_target_reset(ioc, vdevice->vtarget); | ||
1878 | scsi_remove_device(sdev); | 2324 | scsi_remove_device(sdev); |
1879 | scsi_device_put(sdev); | 2325 | scsi_device_put(sdev); |
1880 | mpt_findImVolumes(ioc); | 2326 | mpt_findImVolumes(ioc); |
@@ -1884,12 +2330,13 @@ mptsas_hotplug_work(void *arg) | |||
1884 | break; | 2330 | break; |
1885 | } | 2331 | } |
1886 | 2332 | ||
1887 | kfree(ev); | ||
1888 | mutex_unlock(&ioc->sas_discovery_mutex); | 2333 | mutex_unlock(&ioc->sas_discovery_mutex); |
2334 | kfree(ev); | ||
2335 | |||
1889 | } | 2336 | } |
1890 | 2337 | ||
1891 | static void | 2338 | static void |
1892 | mptscsih_send_sas_event(MPT_ADAPTER *ioc, | 2339 | mptsas_send_sas_event(MPT_ADAPTER *ioc, |
1893 | EVENT_DATA_SAS_DEVICE_STATUS_CHANGE *sas_event_data) | 2340 | EVENT_DATA_SAS_DEVICE_STATUS_CHANGE *sas_event_data) |
1894 | { | 2341 | { |
1895 | struct mptsas_hotplug_event *ev; | 2342 | struct mptsas_hotplug_event *ev; |
@@ -1905,7 +2352,7 @@ mptscsih_send_sas_event(MPT_ADAPTER *ioc, | |||
1905 | switch (sas_event_data->ReasonCode) { | 2352 | switch (sas_event_data->ReasonCode) { |
1906 | case MPI_EVENT_SAS_DEV_STAT_RC_ADDED: | 2353 | case MPI_EVENT_SAS_DEV_STAT_RC_ADDED: |
1907 | case MPI_EVENT_SAS_DEV_STAT_RC_NOT_RESPONDING: | 2354 | case MPI_EVENT_SAS_DEV_STAT_RC_NOT_RESPONDING: |
1908 | ev = kmalloc(sizeof(*ev), GFP_ATOMIC); | 2355 | ev = kzalloc(sizeof(*ev), GFP_ATOMIC); |
1909 | if (!ev) { | 2356 | if (!ev) { |
1910 | printk(KERN_WARNING "mptsas: lost hotplug event\n"); | 2357 | printk(KERN_WARNING "mptsas: lost hotplug event\n"); |
1911 | break; | 2358 | break; |
@@ -1935,10 +2382,9 @@ mptscsih_send_sas_event(MPT_ADAPTER *ioc, | |||
1935 | /* | 2382 | /* |
1936 | * Persistent table is full. | 2383 | * Persistent table is full. |
1937 | */ | 2384 | */ |
1938 | INIT_WORK(&ioc->mptscsih_persistTask, | 2385 | INIT_WORK(&ioc->sas_persist_task, |
1939 | mptscsih_sas_persist_clear_table, | 2386 | mptsas_persist_clear_table, (void *)ioc); |
1940 | (void *)ioc); | 2387 | schedule_work(&ioc->sas_persist_task); |
1941 | schedule_work(&ioc->mptscsih_persistTask); | ||
1942 | break; | 2388 | break; |
1943 | case MPI_EVENT_SAS_DEV_STAT_RC_SMART_DATA: | 2389 | case MPI_EVENT_SAS_DEV_STAT_RC_SMART_DATA: |
1944 | /* TODO */ | 2390 | /* TODO */ |
@@ -1950,7 +2396,7 @@ mptscsih_send_sas_event(MPT_ADAPTER *ioc, | |||
1950 | } | 2396 | } |
1951 | 2397 | ||
1952 | static void | 2398 | static void |
1953 | mptscsih_send_raid_event(MPT_ADAPTER *ioc, | 2399 | mptsas_send_raid_event(MPT_ADAPTER *ioc, |
1954 | EVENT_DATA_RAID *raid_event_data) | 2400 | EVENT_DATA_RAID *raid_event_data) |
1955 | { | 2401 | { |
1956 | struct mptsas_hotplug_event *ev; | 2402 | struct mptsas_hotplug_event *ev; |
@@ -1960,13 +2406,12 @@ mptscsih_send_raid_event(MPT_ADAPTER *ioc, | |||
1960 | if (ioc->bus_type != SAS) | 2406 | if (ioc->bus_type != SAS) |
1961 | return; | 2407 | return; |
1962 | 2408 | ||
1963 | ev = kmalloc(sizeof(*ev), GFP_ATOMIC); | 2409 | ev = kzalloc(sizeof(*ev), GFP_ATOMIC); |
1964 | if (!ev) { | 2410 | if (!ev) { |
1965 | printk(KERN_WARNING "mptsas: lost hotplug event\n"); | 2411 | printk(KERN_WARNING "mptsas: lost hotplug event\n"); |
1966 | return; | 2412 | return; |
1967 | } | 2413 | } |
1968 | 2414 | ||
1969 | memset(ev,0,sizeof(struct mptsas_hotplug_event)); | ||
1970 | INIT_WORK(&ev->work, mptsas_hotplug_work, ev); | 2415 | INIT_WORK(&ev->work, mptsas_hotplug_work, ev); |
1971 | ev->ioc = ioc; | 2416 | ev->ioc = ioc; |
1972 | ev->id = raid_event_data->VolumeID; | 2417 | ev->id = raid_event_data->VolumeID; |
@@ -2028,7 +2473,7 @@ mptscsih_send_raid_event(MPT_ADAPTER *ioc, | |||
2028 | } | 2473 | } |
2029 | 2474 | ||
2030 | static void | 2475 | static void |
2031 | mptscsih_send_discovery(MPT_ADAPTER *ioc, | 2476 | mptsas_send_discovery_event(MPT_ADAPTER *ioc, |
2032 | EVENT_DATA_SAS_DISCOVERY *discovery_data) | 2477 | EVENT_DATA_SAS_DISCOVERY *discovery_data) |
2033 | { | 2478 | { |
2034 | struct mptsas_discovery_event *ev; | 2479 | struct mptsas_discovery_event *ev; |
@@ -2043,11 +2488,10 @@ mptscsih_send_discovery(MPT_ADAPTER *ioc, | |||
2043 | if (discovery_data->DiscoveryStatus) | 2488 | if (discovery_data->DiscoveryStatus) |
2044 | return; | 2489 | return; |
2045 | 2490 | ||
2046 | ev = kmalloc(sizeof(*ev), GFP_ATOMIC); | 2491 | ev = kzalloc(sizeof(*ev), GFP_ATOMIC); |
2047 | if (!ev) | 2492 | if (!ev) |
2048 | return; | 2493 | return; |
2049 | memset(ev,0,sizeof(struct mptsas_discovery_event)); | 2494 | INIT_WORK(&ev->work, mptsas_discovery_work, ev); |
2050 | INIT_WORK(&ev->work, mptscsih_discovery_work, ev); | ||
2051 | ev->ioc = ioc; | 2495 | ev->ioc = ioc; |
2052 | schedule_work(&ev->work); | 2496 | schedule_work(&ev->work); |
2053 | }; | 2497 | }; |
@@ -2075,21 +2519,21 @@ mptsas_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *reply) | |||
2075 | 2519 | ||
2076 | switch (event) { | 2520 | switch (event) { |
2077 | case MPI_EVENT_SAS_DEVICE_STATUS_CHANGE: | 2521 | case MPI_EVENT_SAS_DEVICE_STATUS_CHANGE: |
2078 | mptscsih_send_sas_event(ioc, | 2522 | mptsas_send_sas_event(ioc, |
2079 | (EVENT_DATA_SAS_DEVICE_STATUS_CHANGE *)reply->Data); | 2523 | (EVENT_DATA_SAS_DEVICE_STATUS_CHANGE *)reply->Data); |
2080 | break; | 2524 | break; |
2081 | case MPI_EVENT_INTEGRATED_RAID: | 2525 | case MPI_EVENT_INTEGRATED_RAID: |
2082 | mptscsih_send_raid_event(ioc, | 2526 | mptsas_send_raid_event(ioc, |
2083 | (EVENT_DATA_RAID *)reply->Data); | 2527 | (EVENT_DATA_RAID *)reply->Data); |
2084 | break; | 2528 | break; |
2085 | case MPI_EVENT_PERSISTENT_TABLE_FULL: | 2529 | case MPI_EVENT_PERSISTENT_TABLE_FULL: |
2086 | INIT_WORK(&ioc->mptscsih_persistTask, | 2530 | INIT_WORK(&ioc->sas_persist_task, |
2087 | mptscsih_sas_persist_clear_table, | 2531 | mptsas_persist_clear_table, |
2088 | (void *)ioc); | 2532 | (void *)ioc); |
2089 | schedule_work(&ioc->mptscsih_persistTask); | 2533 | schedule_work(&ioc->sas_persist_task); |
2090 | break; | 2534 | break; |
2091 | case MPI_EVENT_SAS_DISCOVERY: | 2535 | case MPI_EVENT_SAS_DISCOVERY: |
2092 | mptscsih_send_discovery(ioc, | 2536 | mptsas_send_discovery_event(ioc, |
2093 | (EVENT_DATA_SAS_DISCOVERY *)reply->Data); | 2537 | (EVENT_DATA_SAS_DISCOVERY *)reply->Data); |
2094 | break; | 2538 | break; |
2095 | default: | 2539 | default: |
@@ -2308,7 +2752,7 @@ mptsas_probe(struct pci_dev *pdev, const struct pci_device_id *id) | |||
2308 | 2752 | ||
2309 | return 0; | 2753 | return 0; |
2310 | 2754 | ||
2311 | out_mptsas_probe: | 2755 | out_mptsas_probe: |
2312 | 2756 | ||
2313 | mptscsih_remove(pdev); | 2757 | mptscsih_remove(pdev); |
2314 | return error; | 2758 | return error; |
@@ -2318,6 +2762,7 @@ static void __devexit mptsas_remove(struct pci_dev *pdev) | |||
2318 | { | 2762 | { |
2319 | MPT_ADAPTER *ioc = pci_get_drvdata(pdev); | 2763 | MPT_ADAPTER *ioc = pci_get_drvdata(pdev); |
2320 | struct mptsas_portinfo *p, *n; | 2764 | struct mptsas_portinfo *p, *n; |
2765 | int i; | ||
2321 | 2766 | ||
2322 | ioc->sas_discovery_ignore_events=1; | 2767 | ioc->sas_discovery_ignore_events=1; |
2323 | sas_remove_host(ioc->sh); | 2768 | sas_remove_host(ioc->sh); |
@@ -2325,8 +2770,9 @@ static void __devexit mptsas_remove(struct pci_dev *pdev) | |||
2325 | mutex_lock(&ioc->sas_topology_mutex); | 2770 | mutex_lock(&ioc->sas_topology_mutex); |
2326 | list_for_each_entry_safe(p, n, &ioc->sas_topology, list) { | 2771 | list_for_each_entry_safe(p, n, &ioc->sas_topology, list) { |
2327 | list_del(&p->list); | 2772 | list_del(&p->list); |
2328 | if (p->phy_info) | 2773 | for (i = 0 ; i < p->num_phys ; i++) |
2329 | kfree(p->phy_info); | 2774 | mptsas_port_delete(p->phy_info[i].port_details); |
2775 | kfree(p->phy_info); | ||
2330 | kfree(p); | 2776 | kfree(p); |
2331 | } | 2777 | } |
2332 | mutex_unlock(&ioc->sas_topology_mutex); | 2778 | mutex_unlock(&ioc->sas_topology_mutex); |
@@ -2335,17 +2781,15 @@ static void __devexit mptsas_remove(struct pci_dev *pdev) | |||
2335 | } | 2781 | } |
2336 | 2782 | ||
2337 | static struct pci_device_id mptsas_pci_table[] = { | 2783 | static struct pci_device_id mptsas_pci_table[] = { |
2338 | { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1064, | 2784 | { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVID_SAS1064, |
2339 | PCI_ANY_ID, PCI_ANY_ID }, | ||
2340 | { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1066, | ||
2341 | PCI_ANY_ID, PCI_ANY_ID }, | 2785 | PCI_ANY_ID, PCI_ANY_ID }, |
2342 | { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1068, | 2786 | { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVID_SAS1068, |
2343 | PCI_ANY_ID, PCI_ANY_ID }, | 2787 | PCI_ANY_ID, PCI_ANY_ID }, |
2344 | { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1064E, | 2788 | { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVID_SAS1064E, |
2345 | PCI_ANY_ID, PCI_ANY_ID }, | 2789 | PCI_ANY_ID, PCI_ANY_ID }, |
2346 | { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1066E, | 2790 | { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVID_SAS1068E, |
2347 | PCI_ANY_ID, PCI_ANY_ID }, | 2791 | PCI_ANY_ID, PCI_ANY_ID }, |
2348 | { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1068E, | 2792 | { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVID_SAS1078, |
2349 | PCI_ANY_ID, PCI_ANY_ID }, | 2793 | PCI_ANY_ID, PCI_ANY_ID }, |
2350 | {0} /* Terminating entry */ | 2794 | {0} /* Terminating entry */ |
2351 | }; | 2795 | }; |
diff --git a/drivers/message/fusion/mptspi.c b/drivers/message/fusion/mptspi.c index 3201de053943..0a1ff762205f 100644 --- a/drivers/message/fusion/mptspi.c +++ b/drivers/message/fusion/mptspi.c | |||
@@ -775,9 +775,9 @@ static struct spi_function_template mptspi_transport_functions = { | |||
775 | */ | 775 | */ |
776 | 776 | ||
777 | static struct pci_device_id mptspi_pci_table[] = { | 777 | static struct pci_device_id mptspi_pci_table[] = { |
778 | { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_53C1030, | 778 | { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVID_53C1030, |
779 | PCI_ANY_ID, PCI_ANY_ID }, | 779 | PCI_ANY_ID, PCI_ANY_ID }, |
780 | { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_1030_53C1035, | 780 | { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVID_53C1035, |
781 | PCI_ANY_ID, PCI_ANY_ID }, | 781 | PCI_ANY_ID, PCI_ANY_ID }, |
782 | {0} /* Terminating entry */ | 782 | {0} /* Terminating entry */ |
783 | }; | 783 | }; |
diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c index 247ff2f23ac9..33525bdf2ab6 100644 --- a/drivers/mmc/mmc.c +++ b/drivers/mmc/mmc.c | |||
@@ -128,7 +128,7 @@ static void mmc_wait_done(struct mmc_request *mrq) | |||
128 | 128 | ||
129 | int mmc_wait_for_req(struct mmc_host *host, struct mmc_request *mrq) | 129 | int mmc_wait_for_req(struct mmc_host *host, struct mmc_request *mrq) |
130 | { | 130 | { |
131 | DECLARE_COMPLETION(complete); | 131 | DECLARE_COMPLETION_ONSTACK(complete); |
132 | 132 | ||
133 | mrq->done_data = &complete; | 133 | mrq->done_data = &complete; |
134 | mrq->done = mmc_wait_done; | 134 | mrq->done = mmc_wait_done; |
diff --git a/drivers/mtd/devices/doc2000.c b/drivers/mtd/devices/doc2000.c index c54e40464d82..603a7951ac9b 100644 --- a/drivers/mtd/devices/doc2000.c +++ b/drivers/mtd/devices/doc2000.c | |||
@@ -55,10 +55,6 @@ static int doc_read(struct mtd_info *mtd, loff_t from, size_t len, | |||
55 | size_t *retlen, u_char *buf); | 55 | size_t *retlen, u_char *buf); |
56 | static int doc_write(struct mtd_info *mtd, loff_t to, size_t len, | 56 | static int doc_write(struct mtd_info *mtd, loff_t to, size_t len, |
57 | size_t *retlen, const u_char *buf); | 57 | size_t *retlen, const u_char *buf); |
58 | static int doc_read_ecc(struct mtd_info *mtd, loff_t from, size_t len, | ||
59 | size_t *retlen, u_char *buf, u_char *eccbuf, struct nand_oobinfo *oobsel); | ||
60 | static int doc_write_ecc(struct mtd_info *mtd, loff_t to, size_t len, | ||
61 | size_t *retlen, const u_char *buf, u_char *eccbuf, struct nand_oobinfo *oobsel); | ||
62 | static int doc_read_oob(struct mtd_info *mtd, loff_t ofs, | 58 | static int doc_read_oob(struct mtd_info *mtd, loff_t ofs, |
63 | struct mtd_oob_ops *ops); | 59 | struct mtd_oob_ops *ops); |
64 | static int doc_write_oob(struct mtd_info *mtd, loff_t ofs, | 60 | static int doc_write_oob(struct mtd_info *mtd, loff_t ofs, |
@@ -615,17 +611,10 @@ EXPORT_SYMBOL_GPL(DoC2k_init); | |||
615 | static int doc_read(struct mtd_info *mtd, loff_t from, size_t len, | 611 | static int doc_read(struct mtd_info *mtd, loff_t from, size_t len, |
616 | size_t * retlen, u_char * buf) | 612 | size_t * retlen, u_char * buf) |
617 | { | 613 | { |
618 | /* Just a special case of doc_read_ecc */ | ||
619 | return doc_read_ecc(mtd, from, len, retlen, buf, NULL, NULL); | ||
620 | } | ||
621 | |||
622 | static int doc_read_ecc(struct mtd_info *mtd, loff_t from, size_t len, | ||
623 | size_t * retlen, u_char * buf, u_char * eccbuf, struct nand_oobinfo *oobsel) | ||
624 | { | ||
625 | struct DiskOnChip *this = mtd->priv; | 614 | struct DiskOnChip *this = mtd->priv; |
626 | void __iomem *docptr = this->virtadr; | 615 | void __iomem *docptr = this->virtadr; |
627 | struct Nand *mychip; | 616 | struct Nand *mychip; |
628 | unsigned char syndrome[6]; | 617 | unsigned char syndrome[6], eccbuf[6]; |
629 | volatile char dummy; | 618 | volatile char dummy; |
630 | int i, len256 = 0, ret=0; | 619 | int i, len256 = 0, ret=0; |
631 | size_t left = len; | 620 | size_t left = len; |
@@ -673,15 +662,9 @@ static int doc_read_ecc(struct mtd_info *mtd, loff_t from, size_t len, | |||
673 | DoC_Address(this, ADDR_COLUMN_PAGE, from, CDSN_CTRL_WP, | 662 | DoC_Address(this, ADDR_COLUMN_PAGE, from, CDSN_CTRL_WP, |
674 | CDSN_CTRL_ECC_IO); | 663 | CDSN_CTRL_ECC_IO); |
675 | 664 | ||
676 | if (eccbuf) { | 665 | /* Prime the ECC engine */ |
677 | /* Prime the ECC engine */ | 666 | WriteDOC(DOC_ECC_RESET, docptr, ECCConf); |
678 | WriteDOC(DOC_ECC_RESET, docptr, ECCConf); | 667 | WriteDOC(DOC_ECC_EN, docptr, ECCConf); |
679 | WriteDOC(DOC_ECC_EN, docptr, ECCConf); | ||
680 | } else { | ||
681 | /* disable the ECC engine */ | ||
682 | WriteDOC(DOC_ECC_RESET, docptr, ECCConf); | ||
683 | WriteDOC(DOC_ECC_DIS, docptr, ECCConf); | ||
684 | } | ||
685 | 668 | ||
686 | /* treat crossing 256-byte sector for 2M x 8bits devices */ | 669 | /* treat crossing 256-byte sector for 2M x 8bits devices */ |
687 | if (this->page256 && from + len > (from | 0xff) + 1) { | 670 | if (this->page256 && from + len > (from | 0xff) + 1) { |
@@ -698,58 +681,59 @@ static int doc_read_ecc(struct mtd_info *mtd, loff_t from, size_t len, | |||
698 | /* Let the caller know we completed it */ | 681 | /* Let the caller know we completed it */ |
699 | *retlen += len; | 682 | *retlen += len; |
700 | 683 | ||
701 | if (eccbuf) { | 684 | /* Read the ECC data through the DiskOnChip ECC logic */ |
702 | /* Read the ECC data through the DiskOnChip ECC logic */ | 685 | /* Note: this will work even with 2M x 8bit devices as */ |
703 | /* Note: this will work even with 2M x 8bit devices as */ | 686 | /* they have 8 bytes of OOB per 256 page. mf. */ |
704 | /* they have 8 bytes of OOB per 256 page. mf. */ | 687 | DoC_ReadBuf(this, eccbuf, 6); |
705 | DoC_ReadBuf(this, eccbuf, 6); | ||
706 | |||
707 | /* Flush the pipeline */ | ||
708 | if (DoC_is_Millennium(this)) { | ||
709 | dummy = ReadDOC(docptr, ECCConf); | ||
710 | dummy = ReadDOC(docptr, ECCConf); | ||
711 | i = ReadDOC(docptr, ECCConf); | ||
712 | } else { | ||
713 | dummy = ReadDOC(docptr, 2k_ECCStatus); | ||
714 | dummy = ReadDOC(docptr, 2k_ECCStatus); | ||
715 | i = ReadDOC(docptr, 2k_ECCStatus); | ||
716 | } | ||
717 | 688 | ||
718 | /* Check the ECC Status */ | 689 | /* Flush the pipeline */ |
719 | if (i & 0x80) { | 690 | if (DoC_is_Millennium(this)) { |
720 | int nb_errors; | 691 | dummy = ReadDOC(docptr, ECCConf); |
721 | /* There was an ECC error */ | 692 | dummy = ReadDOC(docptr, ECCConf); |
693 | i = ReadDOC(docptr, ECCConf); | ||
694 | } else { | ||
695 | dummy = ReadDOC(docptr, 2k_ECCStatus); | ||
696 | dummy = ReadDOC(docptr, 2k_ECCStatus); | ||
697 | i = ReadDOC(docptr, 2k_ECCStatus); | ||
698 | } | ||
699 | |||
700 | /* Check the ECC Status */ | ||
701 | if (i & 0x80) { | ||
702 | int nb_errors; | ||
703 | /* There was an ECC error */ | ||
722 | #ifdef ECC_DEBUG | 704 | #ifdef ECC_DEBUG |
723 | printk(KERN_ERR "DiskOnChip ECC Error: Read at %lx\n", (long)from); | 705 | printk(KERN_ERR "DiskOnChip ECC Error: Read at %lx\n", (long)from); |
724 | #endif | 706 | #endif |
725 | /* Read the ECC syndrom through the DiskOnChip ECC logic. | 707 | /* Read the ECC syndrom through the DiskOnChip ECC |
726 | These syndrome will be all ZERO when there is no error */ | 708 | logic. These syndrome will be all ZERO when there |
727 | for (i = 0; i < 6; i++) { | 709 | is no error */ |
728 | syndrome[i] = | 710 | for (i = 0; i < 6; i++) { |
729 | ReadDOC(docptr, ECCSyndrome0 + i); | 711 | syndrome[i] = |
730 | } | 712 | ReadDOC(docptr, ECCSyndrome0 + i); |
731 | nb_errors = doc_decode_ecc(buf, syndrome); | 713 | } |
714 | nb_errors = doc_decode_ecc(buf, syndrome); | ||
732 | 715 | ||
733 | #ifdef ECC_DEBUG | 716 | #ifdef ECC_DEBUG |
734 | printk(KERN_ERR "Errors corrected: %x\n", nb_errors); | 717 | printk(KERN_ERR "Errors corrected: %x\n", nb_errors); |
735 | #endif | 718 | #endif |
736 | if (nb_errors < 0) { | 719 | if (nb_errors < 0) { |
737 | /* We return error, but have actually done the read. Not that | 720 | /* We return error, but have actually done the |
738 | this can be told to user-space, via sys_read(), but at least | 721 | read. Not that this can be told to |
739 | MTD-aware stuff can know about it by checking *retlen */ | 722 | user-space, via sys_read(), but at least |
740 | ret = -EIO; | 723 | MTD-aware stuff can know about it by |
741 | } | 724 | checking *retlen */ |
725 | ret = -EIO; | ||
742 | } | 726 | } |
727 | } | ||
743 | 728 | ||
744 | #ifdef PSYCHO_DEBUG | 729 | #ifdef PSYCHO_DEBUG |
745 | printk(KERN_DEBUG "ECC DATA at %lxB: %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X\n", | 730 | printk(KERN_DEBUG "ECC DATA at %lxB: %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X\n", |
746 | (long)from, eccbuf[0], eccbuf[1], eccbuf[2], | 731 | (long)from, eccbuf[0], eccbuf[1], eccbuf[2], |
747 | eccbuf[3], eccbuf[4], eccbuf[5]); | 732 | eccbuf[3], eccbuf[4], eccbuf[5]); |
748 | #endif | 733 | #endif |
749 | 734 | ||
750 | /* disable the ECC engine */ | 735 | /* disable the ECC engine */ |
751 | WriteDOC(DOC_ECC_DIS, docptr , ECCConf); | 736 | WriteDOC(DOC_ECC_DIS, docptr , ECCConf); |
752 | } | ||
753 | 737 | ||
754 | /* according to 11.4.1, we need to wait for the busy line | 738 | /* according to 11.4.1, we need to wait for the busy line |
755 | * drop if we read to the end of the page. */ | 739 | * drop if we read to the end of the page. */ |
@@ -771,17 +755,10 @@ static int doc_read_ecc(struct mtd_info *mtd, loff_t from, size_t len, | |||
771 | static int doc_write(struct mtd_info *mtd, loff_t to, size_t len, | 755 | static int doc_write(struct mtd_info *mtd, loff_t to, size_t len, |
772 | size_t * retlen, const u_char * buf) | 756 | size_t * retlen, const u_char * buf) |
773 | { | 757 | { |
774 | char eccbuf[6]; | ||
775 | return doc_write_ecc(mtd, to, len, retlen, buf, eccbuf, NULL); | ||
776 | } | ||
777 | |||
778 | static int doc_write_ecc(struct mtd_info *mtd, loff_t to, size_t len, | ||
779 | size_t * retlen, const u_char * buf, | ||
780 | u_char * eccbuf, struct nand_oobinfo *oobsel) | ||
781 | { | ||
782 | struct DiskOnChip *this = mtd->priv; | 758 | struct DiskOnChip *this = mtd->priv; |
783 | int di; /* Yes, DI is a hangover from when I was disassembling the binary driver */ | 759 | int di; /* Yes, DI is a hangover from when I was disassembling the binary driver */ |
784 | void __iomem *docptr = this->virtadr; | 760 | void __iomem *docptr = this->virtadr; |
761 | unsigned char eccbuf[6]; | ||
785 | volatile char dummy; | 762 | volatile char dummy; |
786 | int len256 = 0; | 763 | int len256 = 0; |
787 | struct Nand *mychip; | 764 | struct Nand *mychip; |
@@ -835,15 +812,9 @@ static int doc_write_ecc(struct mtd_info *mtd, loff_t to, size_t len, | |||
835 | DoC_Command(this, NAND_CMD_SEQIN, 0); | 812 | DoC_Command(this, NAND_CMD_SEQIN, 0); |
836 | DoC_Address(this, ADDR_COLUMN_PAGE, to, 0, CDSN_CTRL_ECC_IO); | 813 | DoC_Address(this, ADDR_COLUMN_PAGE, to, 0, CDSN_CTRL_ECC_IO); |
837 | 814 | ||
838 | if (eccbuf) { | 815 | /* Prime the ECC engine */ |
839 | /* Prime the ECC engine */ | 816 | WriteDOC(DOC_ECC_RESET, docptr, ECCConf); |
840 | WriteDOC(DOC_ECC_RESET, docptr, ECCConf); | 817 | WriteDOC(DOC_ECC_EN | DOC_ECC_RW, docptr, ECCConf); |
841 | WriteDOC(DOC_ECC_EN | DOC_ECC_RW, docptr, ECCConf); | ||
842 | } else { | ||
843 | /* disable the ECC engine */ | ||
844 | WriteDOC(DOC_ECC_RESET, docptr, ECCConf); | ||
845 | WriteDOC(DOC_ECC_DIS, docptr, ECCConf); | ||
846 | } | ||
847 | 818 | ||
848 | /* treat crossing 256-byte sector for 2M x 8bits devices */ | 819 | /* treat crossing 256-byte sector for 2M x 8bits devices */ |
849 | if (this->page256 && to + len > (to | 0xff) + 1) { | 820 | if (this->page256 && to + len > (to | 0xff) + 1) { |
@@ -873,39 +844,35 @@ static int doc_write_ecc(struct mtd_info *mtd, loff_t to, size_t len, | |||
873 | 844 | ||
874 | DoC_WriteBuf(this, &buf[len256], len - len256); | 845 | DoC_WriteBuf(this, &buf[len256], len - len256); |
875 | 846 | ||
876 | if (eccbuf) { | 847 | WriteDOC(CDSN_CTRL_ECC_IO | CDSN_CTRL_CE, docptr, CDSNControl); |
877 | WriteDOC(CDSN_CTRL_ECC_IO | CDSN_CTRL_CE, docptr, | ||
878 | CDSNControl); | ||
879 | |||
880 | if (DoC_is_Millennium(this)) { | ||
881 | WriteDOC(0, docptr, NOP); | ||
882 | WriteDOC(0, docptr, NOP); | ||
883 | WriteDOC(0, docptr, NOP); | ||
884 | } else { | ||
885 | WriteDOC_(0, docptr, this->ioreg); | ||
886 | WriteDOC_(0, docptr, this->ioreg); | ||
887 | WriteDOC_(0, docptr, this->ioreg); | ||
888 | } | ||
889 | 848 | ||
890 | WriteDOC(CDSN_CTRL_ECC_IO | CDSN_CTRL_FLASH_IO | CDSN_CTRL_CE, docptr, | 849 | if (DoC_is_Millennium(this)) { |
891 | CDSNControl); | 850 | WriteDOC(0, docptr, NOP); |
851 | WriteDOC(0, docptr, NOP); | ||
852 | WriteDOC(0, docptr, NOP); | ||
853 | } else { | ||
854 | WriteDOC_(0, docptr, this->ioreg); | ||
855 | WriteDOC_(0, docptr, this->ioreg); | ||
856 | WriteDOC_(0, docptr, this->ioreg); | ||
857 | } | ||
892 | 858 | ||
893 | /* Read the ECC data through the DiskOnChip ECC logic */ | 859 | WriteDOC(CDSN_CTRL_ECC_IO | CDSN_CTRL_FLASH_IO | CDSN_CTRL_CE, docptr, |
894 | for (di = 0; di < 6; di++) { | 860 | CDSNControl); |
895 | eccbuf[di] = ReadDOC(docptr, ECCSyndrome0 + di); | ||
896 | } | ||
897 | 861 | ||
898 | /* Reset the ECC engine */ | 862 | /* Read the ECC data through the DiskOnChip ECC logic */ |
899 | WriteDOC(DOC_ECC_DIS, docptr, ECCConf); | 863 | for (di = 0; di < 6; di++) { |
864 | eccbuf[di] = ReadDOC(docptr, ECCSyndrome0 + di); | ||
865 | } | ||
866 | |||
867 | /* Reset the ECC engine */ | ||
868 | WriteDOC(DOC_ECC_DIS, docptr, ECCConf); | ||
900 | 869 | ||
901 | #ifdef PSYCHO_DEBUG | 870 | #ifdef PSYCHO_DEBUG |
902 | printk | 871 | printk |
903 | ("OOB data at %lx is %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X\n", | 872 | ("OOB data at %lx is %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X\n", |
904 | (long) to, eccbuf[0], eccbuf[1], eccbuf[2], eccbuf[3], | 873 | (long) to, eccbuf[0], eccbuf[1], eccbuf[2], eccbuf[3], |
905 | eccbuf[4], eccbuf[5]); | 874 | eccbuf[4], eccbuf[5]); |
906 | #endif | 875 | #endif |
907 | } | ||
908 | |||
909 | DoC_Command(this, NAND_CMD_PAGEPROG, 0); | 876 | DoC_Command(this, NAND_CMD_PAGEPROG, 0); |
910 | 877 | ||
911 | DoC_Command(this, NAND_CMD_STATUS, CDSN_CTRL_WP); | 878 | DoC_Command(this, NAND_CMD_STATUS, CDSN_CTRL_WP); |
diff --git a/drivers/mtd/devices/doc2001.c b/drivers/mtd/devices/doc2001.c index 0cf022a69e65..0e2a9326f717 100644 --- a/drivers/mtd/devices/doc2001.c +++ b/drivers/mtd/devices/doc2001.c | |||
@@ -37,12 +37,6 @@ static int doc_read(struct mtd_info *mtd, loff_t from, size_t len, | |||
37 | size_t *retlen, u_char *buf); | 37 | size_t *retlen, u_char *buf); |
38 | static int doc_write(struct mtd_info *mtd, loff_t to, size_t len, | 38 | static int doc_write(struct mtd_info *mtd, loff_t to, size_t len, |
39 | size_t *retlen, const u_char *buf); | 39 | size_t *retlen, const u_char *buf); |
40 | static int doc_read_ecc(struct mtd_info *mtd, loff_t from, size_t len, | ||
41 | size_t *retlen, u_char *buf, u_char *eccbuf, | ||
42 | struct nand_oobinfo *oobsel); | ||
43 | static int doc_write_ecc(struct mtd_info *mtd, loff_t to, size_t len, | ||
44 | size_t *retlen, const u_char *buf, u_char *eccbuf, | ||
45 | struct nand_oobinfo *oobsel); | ||
46 | static int doc_read_oob(struct mtd_info *mtd, loff_t ofs, | 40 | static int doc_read_oob(struct mtd_info *mtd, loff_t ofs, |
47 | struct mtd_oob_ops *ops); | 41 | struct mtd_oob_ops *ops); |
48 | static int doc_write_oob(struct mtd_info *mtd, loff_t ofs, | 42 | static int doc_write_oob(struct mtd_info *mtd, loff_t ofs, |
@@ -397,17 +391,9 @@ EXPORT_SYMBOL_GPL(DoCMil_init); | |||
397 | static int doc_read (struct mtd_info *mtd, loff_t from, size_t len, | 391 | static int doc_read (struct mtd_info *mtd, loff_t from, size_t len, |
398 | size_t *retlen, u_char *buf) | 392 | size_t *retlen, u_char *buf) |
399 | { | 393 | { |
400 | /* Just a special case of doc_read_ecc */ | ||
401 | return doc_read_ecc(mtd, from, len, retlen, buf, NULL, NULL); | ||
402 | } | ||
403 | |||
404 | static int doc_read_ecc (struct mtd_info *mtd, loff_t from, size_t len, | ||
405 | size_t *retlen, u_char *buf, u_char *eccbuf, | ||
406 | struct nand_oobinfo *oobsel) | ||
407 | { | ||
408 | int i, ret; | 394 | int i, ret; |
409 | volatile char dummy; | 395 | volatile char dummy; |
410 | unsigned char syndrome[6]; | 396 | unsigned char syndrome[6], eccbuf[6]; |
411 | struct DiskOnChip *this = mtd->priv; | 397 | struct DiskOnChip *this = mtd->priv; |
412 | void __iomem *docptr = this->virtadr; | 398 | void __iomem *docptr = this->virtadr; |
413 | struct Nand *mychip = &this->chips[from >> (this->chipshift)]; | 399 | struct Nand *mychip = &this->chips[from >> (this->chipshift)]; |
@@ -437,15 +423,9 @@ static int doc_read_ecc (struct mtd_info *mtd, loff_t from, size_t len, | |||
437 | DoC_Address(docptr, 3, from, CDSN_CTRL_WP, 0x00); | 423 | DoC_Address(docptr, 3, from, CDSN_CTRL_WP, 0x00); |
438 | DoC_WaitReady(docptr); | 424 | DoC_WaitReady(docptr); |
439 | 425 | ||
440 | if (eccbuf) { | 426 | /* init the ECC engine, see Reed-Solomon EDC/ECC 11.1 .*/ |
441 | /* init the ECC engine, see Reed-Solomon EDC/ECC 11.1 .*/ | 427 | WriteDOC (DOC_ECC_RESET, docptr, ECCConf); |
442 | WriteDOC (DOC_ECC_RESET, docptr, ECCConf); | 428 | WriteDOC (DOC_ECC_EN, docptr, ECCConf); |
443 | WriteDOC (DOC_ECC_EN, docptr, ECCConf); | ||
444 | } else { | ||
445 | /* disable the ECC engine */ | ||
446 | WriteDOC (DOC_ECC_RESET, docptr, ECCConf); | ||
447 | WriteDOC (DOC_ECC_DIS, docptr, ECCConf); | ||
448 | } | ||
449 | 429 | ||
450 | /* Read the data via the internal pipeline through CDSN IO register, | 430 | /* Read the data via the internal pipeline through CDSN IO register, |
451 | see Pipelined Read Operations 11.3 */ | 431 | see Pipelined Read Operations 11.3 */ |
@@ -465,58 +445,56 @@ static int doc_read_ecc (struct mtd_info *mtd, loff_t from, size_t len, | |||
465 | *retlen = len; | 445 | *retlen = len; |
466 | ret = 0; | 446 | ret = 0; |
467 | 447 | ||
468 | if (eccbuf) { | 448 | /* Read the ECC data from Spare Data Area, |
469 | /* Read the ECC data from Spare Data Area, | 449 | see Reed-Solomon EDC/ECC 11.1 */ |
470 | see Reed-Solomon EDC/ECC 11.1 */ | 450 | dummy = ReadDOC(docptr, ReadPipeInit); |
471 | dummy = ReadDOC(docptr, ReadPipeInit); | ||
472 | #ifndef USE_MEMCPY | 451 | #ifndef USE_MEMCPY |
473 | for (i = 0; i < 5; i++) { | 452 | for (i = 0; i < 5; i++) { |
474 | /* N.B. you have to increase the source address in this way or the | 453 | /* N.B. you have to increase the source address in this way or the |
475 | ECC logic will not work properly */ | 454 | ECC logic will not work properly */ |
476 | eccbuf[i] = ReadDOC(docptr, Mil_CDSN_IO + i); | 455 | eccbuf[i] = ReadDOC(docptr, Mil_CDSN_IO + i); |
477 | } | 456 | } |
478 | #else | 457 | #else |
479 | memcpy_fromio(eccbuf, docptr + DoC_Mil_CDSN_IO, 5); | 458 | memcpy_fromio(eccbuf, docptr + DoC_Mil_CDSN_IO, 5); |
480 | #endif | 459 | #endif |
481 | eccbuf[5] = ReadDOC(docptr, LastDataRead); | 460 | eccbuf[5] = ReadDOC(docptr, LastDataRead); |
482 | 461 | ||
483 | /* Flush the pipeline */ | 462 | /* Flush the pipeline */ |
484 | dummy = ReadDOC(docptr, ECCConf); | 463 | dummy = ReadDOC(docptr, ECCConf); |
485 | dummy = ReadDOC(docptr, ECCConf); | 464 | dummy = ReadDOC(docptr, ECCConf); |
486 | 465 | ||
487 | /* Check the ECC Status */ | 466 | /* Check the ECC Status */ |
488 | if (ReadDOC(docptr, ECCConf) & 0x80) { | 467 | if (ReadDOC(docptr, ECCConf) & 0x80) { |
489 | int nb_errors; | 468 | int nb_errors; |
490 | /* There was an ECC error */ | 469 | /* There was an ECC error */ |
491 | #ifdef ECC_DEBUG | 470 | #ifdef ECC_DEBUG |
492 | printk("DiskOnChip ECC Error: Read at %lx\n", (long)from); | 471 | printk("DiskOnChip ECC Error: Read at %lx\n", (long)from); |
493 | #endif | 472 | #endif |
494 | /* Read the ECC syndrom through the DiskOnChip ECC logic. | 473 | /* Read the ECC syndrom through the DiskOnChip ECC logic. |
495 | These syndrome will be all ZERO when there is no error */ | 474 | These syndrome will be all ZERO when there is no error */ |
496 | for (i = 0; i < 6; i++) { | 475 | for (i = 0; i < 6; i++) { |
497 | syndrome[i] = ReadDOC(docptr, ECCSyndrome0 + i); | 476 | syndrome[i] = ReadDOC(docptr, ECCSyndrome0 + i); |
498 | } | 477 | } |
499 | nb_errors = doc_decode_ecc(buf, syndrome); | 478 | nb_errors = doc_decode_ecc(buf, syndrome); |
500 | #ifdef ECC_DEBUG | 479 | #ifdef ECC_DEBUG |
501 | printk("ECC Errors corrected: %x\n", nb_errors); | 480 | printk("ECC Errors corrected: %x\n", nb_errors); |
502 | #endif | 481 | #endif |
503 | if (nb_errors < 0) { | 482 | if (nb_errors < 0) { |
504 | /* We return error, but have actually done the read. Not that | 483 | /* We return error, but have actually done the read. Not that |
505 | this can be told to user-space, via sys_read(), but at least | 484 | this can be told to user-space, via sys_read(), but at least |
506 | MTD-aware stuff can know about it by checking *retlen */ | 485 | MTD-aware stuff can know about it by checking *retlen */ |
507 | ret = -EIO; | 486 | ret = -EIO; |
508 | } | ||
509 | } | 487 | } |
488 | } | ||
510 | 489 | ||
511 | #ifdef PSYCHO_DEBUG | 490 | #ifdef PSYCHO_DEBUG |
512 | printk("ECC DATA at %lx: %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X\n", | 491 | printk("ECC DATA at %lx: %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X\n", |
513 | (long)from, eccbuf[0], eccbuf[1], eccbuf[2], eccbuf[3], | 492 | (long)from, eccbuf[0], eccbuf[1], eccbuf[2], eccbuf[3], |
514 | eccbuf[4], eccbuf[5]); | 493 | eccbuf[4], eccbuf[5]); |
515 | #endif | 494 | #endif |
516 | 495 | ||
517 | /* disable the ECC engine */ | 496 | /* disable the ECC engine */ |
518 | WriteDOC(DOC_ECC_DIS, docptr , ECCConf); | 497 | WriteDOC(DOC_ECC_DIS, docptr , ECCConf); |
519 | } | ||
520 | 498 | ||
521 | return ret; | 499 | return ret; |
522 | } | 500 | } |
@@ -524,15 +502,8 @@ static int doc_read_ecc (struct mtd_info *mtd, loff_t from, size_t len, | |||
524 | static int doc_write (struct mtd_info *mtd, loff_t to, size_t len, | 502 | static int doc_write (struct mtd_info *mtd, loff_t to, size_t len, |
525 | size_t *retlen, const u_char *buf) | 503 | size_t *retlen, const u_char *buf) |
526 | { | 504 | { |
527 | char eccbuf[6]; | ||
528 | return doc_write_ecc(mtd, to, len, retlen, buf, eccbuf, NULL); | ||
529 | } | ||
530 | |||
531 | static int doc_write_ecc (struct mtd_info *mtd, loff_t to, size_t len, | ||
532 | size_t *retlen, const u_char *buf, u_char *eccbuf, | ||
533 | struct nand_oobinfo *oobsel) | ||
534 | { | ||
535 | int i,ret = 0; | 505 | int i,ret = 0; |
506 | char eccbuf[6]; | ||
536 | volatile char dummy; | 507 | volatile char dummy; |
537 | struct DiskOnChip *this = mtd->priv; | 508 | struct DiskOnChip *this = mtd->priv; |
538 | void __iomem *docptr = this->virtadr; | 509 | void __iomem *docptr = this->virtadr; |
@@ -573,15 +544,9 @@ static int doc_write_ecc (struct mtd_info *mtd, loff_t to, size_t len, | |||
573 | DoC_Address(docptr, 3, to, 0x00, 0x00); | 544 | DoC_Address(docptr, 3, to, 0x00, 0x00); |
574 | DoC_WaitReady(docptr); | 545 | DoC_WaitReady(docptr); |
575 | 546 | ||
576 | if (eccbuf) { | 547 | /* init the ECC engine, see Reed-Solomon EDC/ECC 11.1 .*/ |
577 | /* init the ECC engine, see Reed-Solomon EDC/ECC 11.1 .*/ | 548 | WriteDOC (DOC_ECC_RESET, docptr, ECCConf); |
578 | WriteDOC (DOC_ECC_RESET, docptr, ECCConf); | 549 | WriteDOC (DOC_ECC_EN | DOC_ECC_RW, docptr, ECCConf); |
579 | WriteDOC (DOC_ECC_EN | DOC_ECC_RW, docptr, ECCConf); | ||
580 | } else { | ||
581 | /* disable the ECC engine */ | ||
582 | WriteDOC (DOC_ECC_RESET, docptr, ECCConf); | ||
583 | WriteDOC (DOC_ECC_DIS, docptr, ECCConf); | ||
584 | } | ||
585 | 550 | ||
586 | /* Write the data via the internal pipeline through CDSN IO register, | 551 | /* Write the data via the internal pipeline through CDSN IO register, |
587 | see Pipelined Write Operations 11.2 */ | 552 | see Pipelined Write Operations 11.2 */ |
@@ -596,46 +561,44 @@ static int doc_write_ecc (struct mtd_info *mtd, loff_t to, size_t len, | |||
596 | #endif | 561 | #endif |
597 | WriteDOC(0x00, docptr, WritePipeTerm); | 562 | WriteDOC(0x00, docptr, WritePipeTerm); |
598 | 563 | ||
599 | if (eccbuf) { | 564 | /* Write ECC data to flash, the ECC info is generated by the DiskOnChip ECC logic |
600 | /* Write ECC data to flash, the ECC info is generated by the DiskOnChip ECC logic | 565 | see Reed-Solomon EDC/ECC 11.1 */ |
601 | see Reed-Solomon EDC/ECC 11.1 */ | 566 | WriteDOC(0, docptr, NOP); |
602 | WriteDOC(0, docptr, NOP); | 567 | WriteDOC(0, docptr, NOP); |
603 | WriteDOC(0, docptr, NOP); | 568 | WriteDOC(0, docptr, NOP); |
604 | WriteDOC(0, docptr, NOP); | ||
605 | 569 | ||
606 | /* Read the ECC data through the DiskOnChip ECC logic */ | 570 | /* Read the ECC data through the DiskOnChip ECC logic */ |
607 | for (i = 0; i < 6; i++) { | 571 | for (i = 0; i < 6; i++) { |
608 | eccbuf[i] = ReadDOC(docptr, ECCSyndrome0 + i); | 572 | eccbuf[i] = ReadDOC(docptr, ECCSyndrome0 + i); |
609 | } | 573 | } |
610 | 574 | ||
611 | /* ignore the ECC engine */ | 575 | /* ignore the ECC engine */ |
612 | WriteDOC(DOC_ECC_DIS, docptr , ECCConf); | 576 | WriteDOC(DOC_ECC_DIS, docptr , ECCConf); |
613 | 577 | ||
614 | #ifndef USE_MEMCPY | 578 | #ifndef USE_MEMCPY |
615 | /* Write the ECC data to flash */ | 579 | /* Write the ECC data to flash */ |
616 | for (i = 0; i < 6; i++) { | 580 | for (i = 0; i < 6; i++) { |
617 | /* N.B. you have to increase the source address in this way or the | 581 | /* N.B. you have to increase the source address in this way or the |
618 | ECC logic will not work properly */ | 582 | ECC logic will not work properly */ |
619 | WriteDOC(eccbuf[i], docptr, Mil_CDSN_IO + i); | 583 | WriteDOC(eccbuf[i], docptr, Mil_CDSN_IO + i); |
620 | } | 584 | } |
621 | #else | 585 | #else |
622 | memcpy_toio(docptr + DoC_Mil_CDSN_IO, eccbuf, 6); | 586 | memcpy_toio(docptr + DoC_Mil_CDSN_IO, eccbuf, 6); |
623 | #endif | 587 | #endif |
624 | 588 | ||
625 | /* write the block status BLOCK_USED (0x5555) at the end of ECC data | 589 | /* write the block status BLOCK_USED (0x5555) at the end of ECC data |
626 | FIXME: this is only a hack for programming the IPL area for LinuxBIOS | 590 | FIXME: this is only a hack for programming the IPL area for LinuxBIOS |
627 | and should be replace with proper codes in user space utilities */ | 591 | and should be replace with proper codes in user space utilities */ |
628 | WriteDOC(0x55, docptr, Mil_CDSN_IO); | 592 | WriteDOC(0x55, docptr, Mil_CDSN_IO); |
629 | WriteDOC(0x55, docptr, Mil_CDSN_IO + 1); | 593 | WriteDOC(0x55, docptr, Mil_CDSN_IO + 1); |
630 | 594 | ||
631 | WriteDOC(0x00, docptr, WritePipeTerm); | 595 | WriteDOC(0x00, docptr, WritePipeTerm); |
632 | 596 | ||
633 | #ifdef PSYCHO_DEBUG | 597 | #ifdef PSYCHO_DEBUG |
634 | printk("OOB data at %lx is %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X\n", | 598 | printk("OOB data at %lx is %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X\n", |
635 | (long) to, eccbuf[0], eccbuf[1], eccbuf[2], eccbuf[3], | 599 | (long) to, eccbuf[0], eccbuf[1], eccbuf[2], eccbuf[3], |
636 | eccbuf[4], eccbuf[5]); | 600 | eccbuf[4], eccbuf[5]); |
637 | #endif | 601 | #endif |
638 | } | ||
639 | 602 | ||
640 | /* Commit the Page Program command and wait for ready | 603 | /* Commit the Page Program command and wait for ready |
641 | see Software Requirement 11.4 item 1.*/ | 604 | see Software Requirement 11.4 item 1.*/ |
diff --git a/drivers/mtd/devices/doc2001plus.c b/drivers/mtd/devices/doc2001plus.c index 66cb1e50469a..92dbb47f2ac3 100644 --- a/drivers/mtd/devices/doc2001plus.c +++ b/drivers/mtd/devices/doc2001plus.c | |||
@@ -41,12 +41,6 @@ static int doc_read(struct mtd_info *mtd, loff_t from, size_t len, | |||
41 | size_t *retlen, u_char *buf); | 41 | size_t *retlen, u_char *buf); |
42 | static int doc_write(struct mtd_info *mtd, loff_t to, size_t len, | 42 | static int doc_write(struct mtd_info *mtd, loff_t to, size_t len, |
43 | size_t *retlen, const u_char *buf); | 43 | size_t *retlen, const u_char *buf); |
44 | static int doc_read_ecc(struct mtd_info *mtd, loff_t from, size_t len, | ||
45 | size_t *retlen, u_char *buf, u_char *eccbuf, | ||
46 | struct nand_oobinfo *oobsel); | ||
47 | static int doc_write_ecc(struct mtd_info *mtd, loff_t to, size_t len, | ||
48 | size_t *retlen, const u_char *buf, u_char *eccbuf, | ||
49 | struct nand_oobinfo *oobsel); | ||
50 | static int doc_read_oob(struct mtd_info *mtd, loff_t ofs, | 44 | static int doc_read_oob(struct mtd_info *mtd, loff_t ofs, |
51 | struct mtd_oob_ops *ops); | 45 | struct mtd_oob_ops *ops); |
52 | static int doc_write_oob(struct mtd_info *mtd, loff_t ofs, | 46 | static int doc_write_oob(struct mtd_info *mtd, loff_t ofs, |
@@ -595,18 +589,10 @@ static int doc_dumpblk(struct mtd_info *mtd, loff_t from) | |||
595 | static int doc_read(struct mtd_info *mtd, loff_t from, size_t len, | 589 | static int doc_read(struct mtd_info *mtd, loff_t from, size_t len, |
596 | size_t *retlen, u_char *buf) | 590 | size_t *retlen, u_char *buf) |
597 | { | 591 | { |
598 | /* Just a special case of doc_read_ecc */ | ||
599 | return doc_read_ecc(mtd, from, len, retlen, buf, NULL, NULL); | ||
600 | } | ||
601 | |||
602 | static int doc_read_ecc(struct mtd_info *mtd, loff_t from, size_t len, | ||
603 | size_t *retlen, u_char *buf, u_char *eccbuf, | ||
604 | struct nand_oobinfo *oobsel) | ||
605 | { | ||
606 | int ret, i; | 592 | int ret, i; |
607 | volatile char dummy; | 593 | volatile char dummy; |
608 | loff_t fofs; | 594 | loff_t fofs; |
609 | unsigned char syndrome[6]; | 595 | unsigned char syndrome[6], eccbuf[6]; |
610 | struct DiskOnChip *this = mtd->priv; | 596 | struct DiskOnChip *this = mtd->priv; |
611 | void __iomem * docptr = this->virtadr; | 597 | void __iomem * docptr = this->virtadr; |
612 | struct Nand *mychip = &this->chips[from >> (this->chipshift)]; | 598 | struct Nand *mychip = &this->chips[from >> (this->chipshift)]; |
@@ -644,56 +630,51 @@ static int doc_read_ecc(struct mtd_info *mtd, loff_t from, size_t len, | |||
644 | WriteDOC(0, docptr, Mplus_FlashControl); | 630 | WriteDOC(0, docptr, Mplus_FlashControl); |
645 | DoC_WaitReady(docptr); | 631 | DoC_WaitReady(docptr); |
646 | 632 | ||
647 | if (eccbuf) { | 633 | /* init the ECC engine, see Reed-Solomon EDC/ECC 11.1 .*/ |
648 | /* init the ECC engine, see Reed-Solomon EDC/ECC 11.1 .*/ | 634 | WriteDOC(DOC_ECC_RESET, docptr, Mplus_ECCConf); |
649 | WriteDOC(DOC_ECC_RESET, docptr, Mplus_ECCConf); | 635 | WriteDOC(DOC_ECC_EN, docptr, Mplus_ECCConf); |
650 | WriteDOC(DOC_ECC_EN, docptr, Mplus_ECCConf); | ||
651 | } else { | ||
652 | /* disable the ECC engine */ | ||
653 | WriteDOC(DOC_ECC_RESET, docptr, Mplus_ECCConf); | ||
654 | } | ||
655 | 636 | ||
656 | /* Let the caller know we completed it */ | 637 | /* Let the caller know we completed it */ |
657 | *retlen = len; | 638 | *retlen = len; |
658 | ret = 0; | 639 | ret = 0; |
659 | 640 | ||
660 | ReadDOC(docptr, Mplus_ReadPipeInit); | 641 | ReadDOC(docptr, Mplus_ReadPipeInit); |
661 | ReadDOC(docptr, Mplus_ReadPipeInit); | 642 | ReadDOC(docptr, Mplus_ReadPipeInit); |
662 | 643 | ||
663 | if (eccbuf) { | 644 | /* Read the data via the internal pipeline through CDSN IO |
664 | /* Read the data via the internal pipeline through CDSN IO | 645 | register, see Pipelined Read Operations 11.3 */ |
665 | register, see Pipelined Read Operations 11.3 */ | 646 | MemReadDOC(docptr, buf, len); |
666 | MemReadDOC(docptr, buf, len); | ||
667 | 647 | ||
668 | /* Read the ECC data following raw data */ | 648 | /* Read the ECC data following raw data */ |
669 | MemReadDOC(docptr, eccbuf, 4); | 649 | MemReadDOC(docptr, eccbuf, 4); |
670 | eccbuf[4] = ReadDOC(docptr, Mplus_LastDataRead); | 650 | eccbuf[4] = ReadDOC(docptr, Mplus_LastDataRead); |
671 | eccbuf[5] = ReadDOC(docptr, Mplus_LastDataRead); | 651 | eccbuf[5] = ReadDOC(docptr, Mplus_LastDataRead); |
672 | 652 | ||
673 | /* Flush the pipeline */ | 653 | /* Flush the pipeline */ |
674 | dummy = ReadDOC(docptr, Mplus_ECCConf); | 654 | dummy = ReadDOC(docptr, Mplus_ECCConf); |
675 | dummy = ReadDOC(docptr, Mplus_ECCConf); | 655 | dummy = ReadDOC(docptr, Mplus_ECCConf); |
676 | 656 | ||
677 | /* Check the ECC Status */ | 657 | /* Check the ECC Status */ |
678 | if (ReadDOC(docptr, Mplus_ECCConf) & 0x80) { | 658 | if (ReadDOC(docptr, Mplus_ECCConf) & 0x80) { |
679 | int nb_errors; | 659 | int nb_errors; |
680 | /* There was an ECC error */ | 660 | /* There was an ECC error */ |
681 | #ifdef ECC_DEBUG | 661 | #ifdef ECC_DEBUG |
682 | printk("DiskOnChip ECC Error: Read at %lx\n", (long)from); | 662 | printk("DiskOnChip ECC Error: Read at %lx\n", (long)from); |
683 | #endif | 663 | #endif |
684 | /* Read the ECC syndrom through the DiskOnChip ECC logic. | 664 | /* Read the ECC syndrom through the DiskOnChip ECC logic. |
685 | These syndrome will be all ZERO when there is no error */ | 665 | These syndrome will be all ZERO when there is no error */ |
686 | for (i = 0; i < 6; i++) | 666 | for (i = 0; i < 6; i++) |
687 | syndrome[i] = ReadDOC(docptr, Mplus_ECCSyndrome0 + i); | 667 | syndrome[i] = ReadDOC(docptr, Mplus_ECCSyndrome0 + i); |
688 | 668 | ||
689 | nb_errors = doc_decode_ecc(buf, syndrome); | 669 | nb_errors = doc_decode_ecc(buf, syndrome); |
690 | #ifdef ECC_DEBUG | 670 | #ifdef ECC_DEBUG |
691 | printk("ECC Errors corrected: %x\n", nb_errors); | 671 | printk("ECC Errors corrected: %x\n", nb_errors); |
692 | #endif | 672 | #endif |
693 | if (nb_errors < 0) { | 673 | if (nb_errors < 0) { |
694 | /* We return error, but have actually done the read. Not that | 674 | /* We return error, but have actually done the |
695 | this can be told to user-space, via sys_read(), but at least | 675 | read. Not that this can be told to user-space, via |
696 | MTD-aware stuff can know about it by checking *retlen */ | 676 | sys_read(), but at least MTD-aware stuff can know |
677 | about it by checking *retlen */ | ||
697 | #ifdef ECC_DEBUG | 678 | #ifdef ECC_DEBUG |
698 | printk("%s(%d): Millennium Plus ECC error (from=0x%x:\n", | 679 | printk("%s(%d): Millennium Plus ECC error (from=0x%x:\n", |
699 | __FILE__, __LINE__, (int)from); | 680 | __FILE__, __LINE__, (int)from); |
@@ -707,24 +688,16 @@ static int doc_read_ecc(struct mtd_info *mtd, loff_t from, size_t len, | |||
707 | eccbuf[3], eccbuf[4], eccbuf[5]); | 688 | eccbuf[3], eccbuf[4], eccbuf[5]); |
708 | #endif | 689 | #endif |
709 | ret = -EIO; | 690 | ret = -EIO; |
710 | } | ||
711 | } | 691 | } |
692 | } | ||
712 | 693 | ||
713 | #ifdef PSYCHO_DEBUG | 694 | #ifdef PSYCHO_DEBUG |
714 | printk("ECC DATA at %lx: %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X\n", | 695 | printk("ECC DATA at %lx: %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X\n", |
715 | (long)from, eccbuf[0], eccbuf[1], eccbuf[2], eccbuf[3], | 696 | (long)from, eccbuf[0], eccbuf[1], eccbuf[2], eccbuf[3], |
716 | eccbuf[4], eccbuf[5]); | 697 | eccbuf[4], eccbuf[5]); |
717 | #endif | 698 | #endif |
718 | 699 | /* disable the ECC engine */ | |
719 | /* disable the ECC engine */ | 700 | WriteDOC(DOC_ECC_DIS, docptr , Mplus_ECCConf); |
720 | WriteDOC(DOC_ECC_DIS, docptr , Mplus_ECCConf); | ||
721 | } else { | ||
722 | /* Read the data via the internal pipeline through CDSN IO | ||
723 | register, see Pipelined Read Operations 11.3 */ | ||
724 | MemReadDOC(docptr, buf, len-2); | ||
725 | buf[len-2] = ReadDOC(docptr, Mplus_LastDataRead); | ||
726 | buf[len-1] = ReadDOC(docptr, Mplus_LastDataRead); | ||
727 | } | ||
728 | 701 | ||
729 | /* Disable flash internally */ | 702 | /* Disable flash internally */ |
730 | WriteDOC(0, docptr, Mplus_FlashSelect); | 703 | WriteDOC(0, docptr, Mplus_FlashSelect); |
@@ -735,17 +708,10 @@ static int doc_read_ecc(struct mtd_info *mtd, loff_t from, size_t len, | |||
735 | static int doc_write(struct mtd_info *mtd, loff_t to, size_t len, | 708 | static int doc_write(struct mtd_info *mtd, loff_t to, size_t len, |
736 | size_t *retlen, const u_char *buf) | 709 | size_t *retlen, const u_char *buf) |
737 | { | 710 | { |
738 | char eccbuf[6]; | ||
739 | return doc_write_ecc(mtd, to, len, retlen, buf, eccbuf, NULL); | ||
740 | } | ||
741 | |||
742 | static int doc_write_ecc(struct mtd_info *mtd, loff_t to, size_t len, | ||
743 | size_t *retlen, const u_char *buf, u_char *eccbuf, | ||
744 | struct nand_oobinfo *oobsel) | ||
745 | { | ||
746 | int i, before, ret = 0; | 711 | int i, before, ret = 0; |
747 | loff_t fto; | 712 | loff_t fto; |
748 | volatile char dummy; | 713 | volatile char dummy; |
714 | char eccbuf[6]; | ||
749 | struct DiskOnChip *this = mtd->priv; | 715 | struct DiskOnChip *this = mtd->priv; |
750 | void __iomem * docptr = this->virtadr; | 716 | void __iomem * docptr = this->virtadr; |
751 | struct Nand *mychip = &this->chips[to >> (this->chipshift)]; | 717 | struct Nand *mychip = &this->chips[to >> (this->chipshift)]; |
@@ -795,46 +761,42 @@ static int doc_write_ecc(struct mtd_info *mtd, loff_t to, size_t len, | |||
795 | /* Disable the ECC engine */ | 761 | /* Disable the ECC engine */ |
796 | WriteDOC(DOC_ECC_RESET, docptr, Mplus_ECCConf); | 762 | WriteDOC(DOC_ECC_RESET, docptr, Mplus_ECCConf); |
797 | 763 | ||
798 | if (eccbuf) { | 764 | if (before) { |
799 | if (before) { | 765 | /* Write the block status BLOCK_USED (0x5555) */ |
800 | /* Write the block status BLOCK_USED (0x5555) */ | 766 | WriteDOC(0x55, docptr, Mil_CDSN_IO); |
801 | WriteDOC(0x55, docptr, Mil_CDSN_IO); | 767 | WriteDOC(0x55, docptr, Mil_CDSN_IO); |
802 | WriteDOC(0x55, docptr, Mil_CDSN_IO); | ||
803 | } | ||
804 | |||
805 | /* init the ECC engine, see Reed-Solomon EDC/ECC 11.1 .*/ | ||
806 | WriteDOC(DOC_ECC_EN | DOC_ECC_RW, docptr, Mplus_ECCConf); | ||
807 | } | 768 | } |
808 | 769 | ||
770 | /* init the ECC engine, see Reed-Solomon EDC/ECC 11.1 .*/ | ||
771 | WriteDOC(DOC_ECC_EN | DOC_ECC_RW, docptr, Mplus_ECCConf); | ||
772 | |||
809 | MemWriteDOC(docptr, (unsigned char *) buf, len); | 773 | MemWriteDOC(docptr, (unsigned char *) buf, len); |
810 | 774 | ||
811 | if (eccbuf) { | 775 | /* Write ECC data to flash, the ECC info is generated by |
812 | /* Write ECC data to flash, the ECC info is generated by | 776 | the DiskOnChip ECC logic see Reed-Solomon EDC/ECC 11.1 */ |
813 | the DiskOnChip ECC logic see Reed-Solomon EDC/ECC 11.1 */ | 777 | DoC_Delay(docptr, 3); |
814 | DoC_Delay(docptr, 3); | ||
815 | 778 | ||
816 | /* Read the ECC data through the DiskOnChip ECC logic */ | 779 | /* Read the ECC data through the DiskOnChip ECC logic */ |
817 | for (i = 0; i < 6; i++) | 780 | for (i = 0; i < 6; i++) |
818 | eccbuf[i] = ReadDOC(docptr, Mplus_ECCSyndrome0 + i); | 781 | eccbuf[i] = ReadDOC(docptr, Mplus_ECCSyndrome0 + i); |
819 | 782 | ||
820 | /* disable the ECC engine */ | 783 | /* disable the ECC engine */ |
821 | WriteDOC(DOC_ECC_DIS, docptr, Mplus_ECCConf); | 784 | WriteDOC(DOC_ECC_DIS, docptr, Mplus_ECCConf); |
822 | 785 | ||
823 | /* Write the ECC data to flash */ | 786 | /* Write the ECC data to flash */ |
824 | MemWriteDOC(docptr, eccbuf, 6); | 787 | MemWriteDOC(docptr, eccbuf, 6); |
825 | 788 | ||
826 | if (!before) { | 789 | if (!before) { |
827 | /* Write the block status BLOCK_USED (0x5555) */ | 790 | /* Write the block status BLOCK_USED (0x5555) */ |
828 | WriteDOC(0x55, docptr, Mil_CDSN_IO+6); | 791 | WriteDOC(0x55, docptr, Mil_CDSN_IO+6); |
829 | WriteDOC(0x55, docptr, Mil_CDSN_IO+7); | 792 | WriteDOC(0x55, docptr, Mil_CDSN_IO+7); |
830 | } | 793 | } |
831 | 794 | ||
832 | #ifdef PSYCHO_DEBUG | 795 | #ifdef PSYCHO_DEBUG |
833 | printk("OOB data at %lx is %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X\n", | 796 | printk("OOB data at %lx is %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X\n", |
834 | (long) to, eccbuf[0], eccbuf[1], eccbuf[2], eccbuf[3], | 797 | (long) to, eccbuf[0], eccbuf[1], eccbuf[2], eccbuf[3], |
835 | eccbuf[4], eccbuf[5]); | 798 | eccbuf[4], eccbuf[5]); |
836 | #endif | 799 | #endif |
837 | } | ||
838 | 800 | ||
839 | WriteDOC(0x00, docptr, Mplus_WritePipeTerm); | 801 | WriteDOC(0x00, docptr, Mplus_WritePipeTerm); |
840 | WriteDOC(0x00, docptr, Mplus_WritePipeTerm); | 802 | WriteDOC(0x00, docptr, Mplus_WritePipeTerm); |
diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c index 80a76654d963..62b861304e03 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c | |||
@@ -155,7 +155,7 @@ static u16 nand_read_word(struct mtd_info *mtd) | |||
155 | /** | 155 | /** |
156 | * nand_select_chip - [DEFAULT] control CE line | 156 | * nand_select_chip - [DEFAULT] control CE line |
157 | * @mtd: MTD device structure | 157 | * @mtd: MTD device structure |
158 | * @chip: chipnumber to select, -1 for deselect | 158 | * @chipnr: chipnumber to select, -1 for deselect |
159 | * | 159 | * |
160 | * Default select function for 1 chip devices. | 160 | * Default select function for 1 chip devices. |
161 | */ | 161 | */ |
@@ -542,7 +542,6 @@ static void nand_command(struct mtd_info *mtd, unsigned int command, | |||
542 | * Send command to NAND device. This is the version for the new large page | 542 | * Send command to NAND device. This is the version for the new large page |
543 | * devices We dont have the separate regions as we have in the small page | 543 | * devices We dont have the separate regions as we have in the small page |
544 | * devices. We must emulate NAND_CMD_READOOB to keep the code compatible. | 544 | * devices. We must emulate NAND_CMD_READOOB to keep the code compatible. |
545 | * | ||
546 | */ | 545 | */ |
547 | static void nand_command_lp(struct mtd_info *mtd, unsigned int command, | 546 | static void nand_command_lp(struct mtd_info *mtd, unsigned int command, |
548 | int column, int page_addr) | 547 | int column, int page_addr) |
@@ -656,7 +655,7 @@ static void nand_command_lp(struct mtd_info *mtd, unsigned int command, | |||
656 | 655 | ||
657 | /** | 656 | /** |
658 | * nand_get_device - [GENERIC] Get chip for selected access | 657 | * nand_get_device - [GENERIC] Get chip for selected access |
659 | * @this: the nand chip descriptor | 658 | * @chip: the nand chip descriptor |
660 | * @mtd: MTD device structure | 659 | * @mtd: MTD device structure |
661 | * @new_state: the state which is requested | 660 | * @new_state: the state which is requested |
662 | * | 661 | * |
@@ -696,13 +695,12 @@ nand_get_device(struct nand_chip *chip, struct mtd_info *mtd, int new_state) | |||
696 | /** | 695 | /** |
697 | * nand_wait - [DEFAULT] wait until the command is done | 696 | * nand_wait - [DEFAULT] wait until the command is done |
698 | * @mtd: MTD device structure | 697 | * @mtd: MTD device structure |
699 | * @this: NAND chip structure | 698 | * @chip: NAND chip structure |
700 | * | 699 | * |
701 | * Wait for command done. This applies to erase and program only | 700 | * Wait for command done. This applies to erase and program only |
702 | * Erase can take up to 400ms and program up to 20ms according to | 701 | * Erase can take up to 400ms and program up to 20ms according to |
703 | * general NAND and SmartMedia specs | 702 | * general NAND and SmartMedia specs |
704 | * | 703 | */ |
705 | */ | ||
706 | static int nand_wait(struct mtd_info *mtd, struct nand_chip *chip) | 704 | static int nand_wait(struct mtd_info *mtd, struct nand_chip *chip) |
707 | { | 705 | { |
708 | 706 | ||
@@ -896,6 +894,7 @@ static int nand_read_page_syndrome(struct mtd_info *mtd, struct nand_chip *chip, | |||
896 | /** | 894 | /** |
897 | * nand_transfer_oob - [Internal] Transfer oob to client buffer | 895 | * nand_transfer_oob - [Internal] Transfer oob to client buffer |
898 | * @chip: nand chip structure | 896 | * @chip: nand chip structure |
897 | * @oob: oob destination address | ||
899 | * @ops: oob ops structure | 898 | * @ops: oob ops structure |
900 | */ | 899 | */ |
901 | static uint8_t *nand_transfer_oob(struct nand_chip *chip, uint8_t *oob, | 900 | static uint8_t *nand_transfer_oob(struct nand_chip *chip, uint8_t *oob, |
@@ -946,6 +945,7 @@ static uint8_t *nand_transfer_oob(struct nand_chip *chip, uint8_t *oob, | |||
946 | * | 945 | * |
947 | * @mtd: MTD device structure | 946 | * @mtd: MTD device structure |
948 | * @from: offset to read from | 947 | * @from: offset to read from |
948 | * @ops: oob ops structure | ||
949 | * | 949 | * |
950 | * Internal function. Called with chip held. | 950 | * Internal function. Called with chip held. |
951 | */ | 951 | */ |
@@ -1760,7 +1760,7 @@ static int nand_do_write_oob(struct mtd_info *mtd, loff_t to, | |||
1760 | /** | 1760 | /** |
1761 | * nand_write_oob - [MTD Interface] NAND write data and/or out-of-band | 1761 | * nand_write_oob - [MTD Interface] NAND write data and/or out-of-band |
1762 | * @mtd: MTD device structure | 1762 | * @mtd: MTD device structure |
1763 | * @from: offset to read from | 1763 | * @to: offset to write to |
1764 | * @ops: oob operation description structure | 1764 | * @ops: oob operation description structure |
1765 | */ | 1765 | */ |
1766 | static int nand_write_oob(struct mtd_info *mtd, loff_t to, | 1766 | static int nand_write_oob(struct mtd_info *mtd, loff_t to, |
@@ -2055,7 +2055,7 @@ static void nand_sync(struct mtd_info *mtd) | |||
2055 | /** | 2055 | /** |
2056 | * nand_block_isbad - [MTD Interface] Check if block at offset is bad | 2056 | * nand_block_isbad - [MTD Interface] Check if block at offset is bad |
2057 | * @mtd: MTD device structure | 2057 | * @mtd: MTD device structure |
2058 | * @ofs: offset relative to mtd start | 2058 | * @offs: offset relative to mtd start |
2059 | */ | 2059 | */ |
2060 | static int nand_block_isbad(struct mtd_info *mtd, loff_t offs) | 2060 | static int nand_block_isbad(struct mtd_info *mtd, loff_t offs) |
2061 | { | 2061 | { |
diff --git a/drivers/mtd/nand/nand_ecc.c b/drivers/mtd/nand/nand_ecc.c index 2a163e4084df..dd438ca47d9a 100644 --- a/drivers/mtd/nand/nand_ecc.c +++ b/drivers/mtd/nand/nand_ecc.c | |||
@@ -65,8 +65,7 @@ static const u_char nand_ecc_precalc_table[] = { | |||
65 | }; | 65 | }; |
66 | 66 | ||
67 | /** | 67 | /** |
68 | * nand_calculate_ecc - [NAND Interface] Calculate 3 byte ECC code | 68 | * nand_calculate_ecc - [NAND Interface] Calculate 3-byte ECC for 256-byte block |
69 | * for 256 byte block | ||
70 | * @mtd: MTD block structure | 69 | * @mtd: MTD block structure |
71 | * @dat: raw data | 70 | * @dat: raw data |
72 | * @ecc_code: buffer for ECC | 71 | * @ecc_code: buffer for ECC |
diff --git a/drivers/mtd/nand/sharpsl.c b/drivers/mtd/nand/sharpsl.c index 21743658d150..fbeedc3184e9 100644 --- a/drivers/mtd/nand/sharpsl.c +++ b/drivers/mtd/nand/sharpsl.c | |||
@@ -237,11 +237,6 @@ static int __init sharpsl_nand_init(void) | |||
237 | } | 237 | } |
238 | } | 238 | } |
239 | 239 | ||
240 | if (machine_is_husky() || machine_is_borzoi() || machine_is_akita()) { | ||
241 | /* Need to use small eraseblock size for backward compatibility */ | ||
242 | sharpsl_mtd->flags |= MTD_NO_VIRTBLOCKS; | ||
243 | } | ||
244 | |||
245 | add_mtd_partitions(sharpsl_mtd, sharpsl_partition_info, nr_partitions); | 240 | add_mtd_partitions(sharpsl_mtd, sharpsl_partition_info, nr_partitions); |
246 | 241 | ||
247 | /* Return happy */ | 242 | /* Return happy */ |
@@ -255,8 +250,6 @@ module_init(sharpsl_nand_init); | |||
255 | */ | 250 | */ |
256 | static void __exit sharpsl_nand_cleanup(void) | 251 | static void __exit sharpsl_nand_cleanup(void) |
257 | { | 252 | { |
258 | struct nand_chip *this = (struct nand_chip *)&sharpsl_mtd[1]; | ||
259 | |||
260 | /* Release resources, unregister device */ | 253 | /* Release resources, unregister device */ |
261 | nand_release(sharpsl_mtd); | 254 | nand_release(sharpsl_mtd); |
262 | 255 | ||
diff --git a/drivers/net/3c59x.c b/drivers/net/3c59x.c index 8ab03b4a885e..2819de79442c 100644 --- a/drivers/net/3c59x.c +++ b/drivers/net/3c59x.c | |||
@@ -1897,7 +1897,7 @@ vortex_timer(unsigned long data) | |||
1897 | printk(KERN_DEBUG "dev->watchdog_timeo=%d\n", dev->watchdog_timeo); | 1897 | printk(KERN_DEBUG "dev->watchdog_timeo=%d\n", dev->watchdog_timeo); |
1898 | } | 1898 | } |
1899 | 1899 | ||
1900 | disable_irq(dev->irq); | 1900 | disable_irq_lockdep(dev->irq); |
1901 | old_window = ioread16(ioaddr + EL3_CMD) >> 13; | 1901 | old_window = ioread16(ioaddr + EL3_CMD) >> 13; |
1902 | EL3WINDOW(4); | 1902 | EL3WINDOW(4); |
1903 | media_status = ioread16(ioaddr + Wn4_Media); | 1903 | media_status = ioread16(ioaddr + Wn4_Media); |
@@ -1978,7 +1978,7 @@ leave_media_alone: | |||
1978 | dev->name, media_tbl[dev->if_port].name); | 1978 | dev->name, media_tbl[dev->if_port].name); |
1979 | 1979 | ||
1980 | EL3WINDOW(old_window); | 1980 | EL3WINDOW(old_window); |
1981 | enable_irq(dev->irq); | 1981 | enable_irq_lockdep(dev->irq); |
1982 | mod_timer(&vp->timer, RUN_AT(next_tick)); | 1982 | mod_timer(&vp->timer, RUN_AT(next_tick)); |
1983 | if (vp->deferred) | 1983 | if (vp->deferred) |
1984 | iowrite16(FakeIntr, ioaddr + EL3_CMD); | 1984 | iowrite16(FakeIntr, ioaddr + EL3_CMD); |
diff --git a/drivers/net/8390.c b/drivers/net/8390.c index 86be96af9c8f..d2935ae39814 100644 --- a/drivers/net/8390.c +++ b/drivers/net/8390.c | |||
@@ -249,7 +249,7 @@ void ei_tx_timeout(struct net_device *dev) | |||
249 | 249 | ||
250 | /* Ugly but a reset can be slow, yet must be protected */ | 250 | /* Ugly but a reset can be slow, yet must be protected */ |
251 | 251 | ||
252 | disable_irq_nosync(dev->irq); | 252 | disable_irq_nosync_lockdep(dev->irq); |
253 | spin_lock(&ei_local->page_lock); | 253 | spin_lock(&ei_local->page_lock); |
254 | 254 | ||
255 | /* Try to restart the card. Perhaps the user has fixed something. */ | 255 | /* Try to restart the card. Perhaps the user has fixed something. */ |
@@ -257,7 +257,7 @@ void ei_tx_timeout(struct net_device *dev) | |||
257 | NS8390_init(dev, 1); | 257 | NS8390_init(dev, 1); |
258 | 258 | ||
259 | spin_unlock(&ei_local->page_lock); | 259 | spin_unlock(&ei_local->page_lock); |
260 | enable_irq(dev->irq); | 260 | enable_irq_lockdep(dev->irq); |
261 | netif_wake_queue(dev); | 261 | netif_wake_queue(dev); |
262 | } | 262 | } |
263 | 263 | ||
diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c index 3c90003f4230..037d870712ff 100644 --- a/drivers/net/forcedeth.c +++ b/drivers/net/forcedeth.c | |||
@@ -2735,21 +2735,21 @@ static void nv_do_nic_poll(unsigned long data) | |||
2735 | 2735 | ||
2736 | if (!using_multi_irqs(dev)) { | 2736 | if (!using_multi_irqs(dev)) { |
2737 | if (np->msi_flags & NV_MSI_X_ENABLED) | 2737 | if (np->msi_flags & NV_MSI_X_ENABLED) |
2738 | disable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_ALL].vector); | 2738 | disable_irq_lockdep(np->msi_x_entry[NV_MSI_X_VECTOR_ALL].vector); |
2739 | else | 2739 | else |
2740 | disable_irq(dev->irq); | 2740 | disable_irq_lockdep(dev->irq); |
2741 | mask = np->irqmask; | 2741 | mask = np->irqmask; |
2742 | } else { | 2742 | } else { |
2743 | if (np->nic_poll_irq & NVREG_IRQ_RX_ALL) { | 2743 | if (np->nic_poll_irq & NVREG_IRQ_RX_ALL) { |
2744 | disable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_RX].vector); | 2744 | disable_irq_lockdep(np->msi_x_entry[NV_MSI_X_VECTOR_RX].vector); |
2745 | mask |= NVREG_IRQ_RX_ALL; | 2745 | mask |= NVREG_IRQ_RX_ALL; |
2746 | } | 2746 | } |
2747 | if (np->nic_poll_irq & NVREG_IRQ_TX_ALL) { | 2747 | if (np->nic_poll_irq & NVREG_IRQ_TX_ALL) { |
2748 | disable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_TX].vector); | 2748 | disable_irq_lockdep(np->msi_x_entry[NV_MSI_X_VECTOR_TX].vector); |
2749 | mask |= NVREG_IRQ_TX_ALL; | 2749 | mask |= NVREG_IRQ_TX_ALL; |
2750 | } | 2750 | } |
2751 | if (np->nic_poll_irq & NVREG_IRQ_OTHER) { | 2751 | if (np->nic_poll_irq & NVREG_IRQ_OTHER) { |
2752 | disable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_OTHER].vector); | 2752 | disable_irq_lockdep(np->msi_x_entry[NV_MSI_X_VECTOR_OTHER].vector); |
2753 | mask |= NVREG_IRQ_OTHER; | 2753 | mask |= NVREG_IRQ_OTHER; |
2754 | } | 2754 | } |
2755 | } | 2755 | } |
@@ -2761,23 +2761,23 @@ static void nv_do_nic_poll(unsigned long data) | |||
2761 | pci_push(base); | 2761 | pci_push(base); |
2762 | 2762 | ||
2763 | if (!using_multi_irqs(dev)) { | 2763 | if (!using_multi_irqs(dev)) { |
2764 | nv_nic_irq((int) 0, (void *) data, (struct pt_regs *) NULL); | 2764 | nv_nic_irq(0, dev, NULL); |
2765 | if (np->msi_flags & NV_MSI_X_ENABLED) | 2765 | if (np->msi_flags & NV_MSI_X_ENABLED) |
2766 | enable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_ALL].vector); | 2766 | enable_irq_lockdep(np->msi_x_entry[NV_MSI_X_VECTOR_ALL].vector); |
2767 | else | 2767 | else |
2768 | enable_irq(dev->irq); | 2768 | enable_irq_lockdep(dev->irq); |
2769 | } else { | 2769 | } else { |
2770 | if (np->nic_poll_irq & NVREG_IRQ_RX_ALL) { | 2770 | if (np->nic_poll_irq & NVREG_IRQ_RX_ALL) { |
2771 | nv_nic_irq_rx((int) 0, (void *) data, (struct pt_regs *) NULL); | 2771 | nv_nic_irq_rx(0, dev, NULL); |
2772 | enable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_RX].vector); | 2772 | enable_irq_lockdep(np->msi_x_entry[NV_MSI_X_VECTOR_RX].vector); |
2773 | } | 2773 | } |
2774 | if (np->nic_poll_irq & NVREG_IRQ_TX_ALL) { | 2774 | if (np->nic_poll_irq & NVREG_IRQ_TX_ALL) { |
2775 | nv_nic_irq_tx((int) 0, (void *) data, (struct pt_regs *) NULL); | 2775 | nv_nic_irq_tx(0, dev, NULL); |
2776 | enable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_TX].vector); | 2776 | enable_irq_lockdep(np->msi_x_entry[NV_MSI_X_VECTOR_TX].vector); |
2777 | } | 2777 | } |
2778 | if (np->nic_poll_irq & NVREG_IRQ_OTHER) { | 2778 | if (np->nic_poll_irq & NVREG_IRQ_OTHER) { |
2779 | nv_nic_irq_other((int) 0, (void *) data, (struct pt_regs *) NULL); | 2779 | nv_nic_irq_other(0, dev, NULL); |
2780 | enable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_OTHER].vector); | 2780 | enable_irq_lockdep(np->msi_x_entry[NV_MSI_X_VECTOR_OTHER].vector); |
2781 | } | 2781 | } |
2782 | } | 2782 | } |
2783 | } | 2783 | } |
diff --git a/drivers/net/mace.c b/drivers/net/mace.c index f2c0bf89f0c7..29e4b5aa6ead 100644 --- a/drivers/net/mace.c +++ b/drivers/net/mace.c | |||
@@ -242,12 +242,12 @@ static int __devinit mace_probe(struct macio_dev *mdev, const struct of_device_i | |||
242 | } | 242 | } |
243 | rc = request_irq(mp->tx_dma_intr, mace_txdma_intr, 0, "MACE-txdma", dev); | 243 | rc = request_irq(mp->tx_dma_intr, mace_txdma_intr, 0, "MACE-txdma", dev); |
244 | if (rc) { | 244 | if (rc) { |
245 | printk(KERN_ERR "MACE: can't get irq %d\n", mace->intrs[1].line); | 245 | printk(KERN_ERR "MACE: can't get irq %d\n", mp->tx_dma_intr); |
246 | goto err_free_irq; | 246 | goto err_free_irq; |
247 | } | 247 | } |
248 | rc = request_irq(mp->rx_dma_intr, mace_rxdma_intr, 0, "MACE-rxdma", dev); | 248 | rc = request_irq(mp->rx_dma_intr, mace_rxdma_intr, 0, "MACE-rxdma", dev); |
249 | if (rc) { | 249 | if (rc) { |
250 | printk(KERN_ERR "MACE: can't get irq %d\n", mace->intrs[2].line); | 250 | printk(KERN_ERR "MACE: can't get irq %d\n", mp->rx_dma_intr); |
251 | goto err_free_tx_irq; | 251 | goto err_free_tx_irq; |
252 | } | 252 | } |
253 | 253 | ||
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index e5e1b2962936..f645921aff8b 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c | |||
@@ -68,8 +68,8 @@ | |||
68 | 68 | ||
69 | #define DRV_MODULE_NAME "tg3" | 69 | #define DRV_MODULE_NAME "tg3" |
70 | #define PFX DRV_MODULE_NAME ": " | 70 | #define PFX DRV_MODULE_NAME ": " |
71 | #define DRV_MODULE_VERSION "3.61" | 71 | #define DRV_MODULE_VERSION "3.62" |
72 | #define DRV_MODULE_RELDATE "June 29, 2006" | 72 | #define DRV_MODULE_RELDATE "June 30, 2006" |
73 | 73 | ||
74 | #define TG3_DEF_MAC_MODE 0 | 74 | #define TG3_DEF_MAC_MODE 0 |
75 | #define TG3_DEF_RX_MODE 0 | 75 | #define TG3_DEF_RX_MODE 0 |
@@ -3798,18 +3798,24 @@ static int tg3_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
3798 | goto out_unlock; | 3798 | goto out_unlock; |
3799 | } | 3799 | } |
3800 | 3800 | ||
3801 | tcp_opt_len = ((skb->h.th->doff - 5) * 4); | 3801 | if (skb_shinfo(skb)->gso_type & SKB_GSO_TCPV6) |
3802 | ip_tcp_len = (skb->nh.iph->ihl * 4) + sizeof(struct tcphdr); | 3802 | mss |= (skb_headlen(skb) - ETH_HLEN) << 9; |
3803 | else { | ||
3804 | tcp_opt_len = ((skb->h.th->doff - 5) * 4); | ||
3805 | ip_tcp_len = (skb->nh.iph->ihl * 4) + | ||
3806 | sizeof(struct tcphdr); | ||
3807 | |||
3808 | skb->nh.iph->check = 0; | ||
3809 | skb->nh.iph->tot_len = htons(mss + ip_tcp_len + | ||
3810 | tcp_opt_len); | ||
3811 | mss |= (ip_tcp_len + tcp_opt_len) << 9; | ||
3812 | } | ||
3803 | 3813 | ||
3804 | base_flags |= (TXD_FLAG_CPU_PRE_DMA | | 3814 | base_flags |= (TXD_FLAG_CPU_PRE_DMA | |
3805 | TXD_FLAG_CPU_POST_DMA); | 3815 | TXD_FLAG_CPU_POST_DMA); |
3806 | 3816 | ||
3807 | skb->nh.iph->check = 0; | ||
3808 | skb->nh.iph->tot_len = htons(mss + ip_tcp_len + tcp_opt_len); | ||
3809 | |||
3810 | skb->h.th->check = 0; | 3817 | skb->h.th->check = 0; |
3811 | 3818 | ||
3812 | mss |= (ip_tcp_len + tcp_opt_len) << 9; | ||
3813 | } | 3819 | } |
3814 | else if (skb->ip_summed == CHECKSUM_HW) | 3820 | else if (skb->ip_summed == CHECKSUM_HW) |
3815 | base_flags |= TXD_FLAG_TCPUDP_CSUM; | 3821 | base_flags |= TXD_FLAG_TCPUDP_CSUM; |
@@ -7887,6 +7893,12 @@ static int tg3_set_tso(struct net_device *dev, u32 value) | |||
7887 | return -EINVAL; | 7893 | return -EINVAL; |
7888 | return 0; | 7894 | return 0; |
7889 | } | 7895 | } |
7896 | if (tp->tg3_flags2 & TG3_FLG2_HW_TSO_2) { | ||
7897 | if (value) | ||
7898 | dev->features |= NETIF_F_TSO6; | ||
7899 | else | ||
7900 | dev->features &= ~NETIF_F_TSO6; | ||
7901 | } | ||
7890 | return ethtool_op_set_tso(dev, value); | 7902 | return ethtool_op_set_tso(dev, value); |
7891 | } | 7903 | } |
7892 | #endif | 7904 | #endif |
@@ -11507,8 +11519,11 @@ static int __devinit tg3_init_one(struct pci_dev *pdev, | |||
11507 | * Firmware TSO on older chips gives lower performance, so it | 11519 | * Firmware TSO on older chips gives lower performance, so it |
11508 | * is off by default, but can be enabled using ethtool. | 11520 | * is off by default, but can be enabled using ethtool. |
11509 | */ | 11521 | */ |
11510 | if (tp->tg3_flags2 & TG3_FLG2_HW_TSO) | 11522 | if (tp->tg3_flags2 & TG3_FLG2_HW_TSO) { |
11511 | dev->features |= NETIF_F_TSO; | 11523 | dev->features |= NETIF_F_TSO; |
11524 | if (tp->tg3_flags2 & TG3_FLG2_HW_TSO_2) | ||
11525 | dev->features |= NETIF_F_TSO6; | ||
11526 | } | ||
11512 | 11527 | ||
11513 | #endif | 11528 | #endif |
11514 | 11529 | ||
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_ethtool.c b/drivers/net/wireless/bcm43xx/bcm43xx_ethtool.c index b3ffcf501311..e386dcc32e8c 100644 --- a/drivers/net/wireless/bcm43xx/bcm43xx_ethtool.c +++ b/drivers/net/wireless/bcm43xx/bcm43xx_ethtool.c | |||
@@ -32,7 +32,7 @@ | |||
32 | #include <linux/netdevice.h> | 32 | #include <linux/netdevice.h> |
33 | #include <linux/pci.h> | 33 | #include <linux/pci.h> |
34 | #include <linux/string.h> | 34 | #include <linux/string.h> |
35 | #include <linux/version.h> | 35 | #include <linux/utsrelease.h> |
36 | 36 | ||
37 | 37 | ||
38 | static void bcm43xx_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) | 38 | static void bcm43xx_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) |
diff --git a/drivers/net/wireless/hostap/hostap_hw.c b/drivers/net/wireless/hostap/hostap_hw.c index b764cfda6e84..dafaa5ff5aa6 100644 --- a/drivers/net/wireless/hostap/hostap_hw.c +++ b/drivers/net/wireless/hostap/hostap_hw.c | |||
@@ -3095,6 +3095,14 @@ static void prism2_clear_set_tim_queue(local_info_t *local) | |||
3095 | } | 3095 | } |
3096 | 3096 | ||
3097 | 3097 | ||
3098 | /* | ||
3099 | * HostAP uses two layers of net devices, where the inner | ||
3100 | * layer gets called all the time from the outer layer. | ||
3101 | * This is a natural nesting, which needs a split lock type. | ||
3102 | */ | ||
3103 | static struct lock_class_key hostap_netdev_xmit_lock_key; | ||
3104 | |||
3105 | |||
3098 | static struct net_device * | 3106 | static struct net_device * |
3099 | prism2_init_local_data(struct prism2_helper_functions *funcs, int card_idx, | 3107 | prism2_init_local_data(struct prism2_helper_functions *funcs, int card_idx, |
3100 | struct device *sdev) | 3108 | struct device *sdev) |
@@ -3259,6 +3267,8 @@ while (0) | |||
3259 | SET_NETDEV_DEV(dev, sdev); | 3267 | SET_NETDEV_DEV(dev, sdev); |
3260 | if (ret >= 0) | 3268 | if (ret >= 0) |
3261 | ret = register_netdevice(dev); | 3269 | ret = register_netdevice(dev); |
3270 | |||
3271 | lockdep_set_class(&dev->_xmit_lock, &hostap_netdev_xmit_lock_key); | ||
3262 | rtnl_unlock(); | 3272 | rtnl_unlock(); |
3263 | if (ret < 0) { | 3273 | if (ret < 0) { |
3264 | printk(KERN_WARNING "%s: register netdevice failed!\n", | 3274 | printk(KERN_WARNING "%s: register netdevice failed!\n", |
diff --git a/drivers/pnp/pnpacpi/rsparser.c b/drivers/pnp/pnpacpi/rsparser.c index 3a4a644c2686..212268881857 100644 --- a/drivers/pnp/pnpacpi/rsparser.c +++ b/drivers/pnp/pnpacpi/rsparser.c | |||
@@ -74,7 +74,7 @@ static void decode_irq_flags(int flag, int *triggering, int *polarity) | |||
74 | 74 | ||
75 | static void | 75 | static void |
76 | pnpacpi_parse_allocated_irqresource(struct pnp_resource_table *res, u32 gsi, | 76 | pnpacpi_parse_allocated_irqresource(struct pnp_resource_table *res, u32 gsi, |
77 | int triggering, int polarity) | 77 | int triggering, int polarity, int shareable) |
78 | { | 78 | { |
79 | int i = 0; | 79 | int i = 0; |
80 | int irq; | 80 | int irq; |
@@ -95,6 +95,9 @@ pnpacpi_parse_allocated_irqresource(struct pnp_resource_table *res, u32 gsi, | |||
95 | return; | 95 | return; |
96 | } | 96 | } |
97 | 97 | ||
98 | if (shareable) | ||
99 | res->irq_resource[i].flags |= IORESOURCE_IRQ_SHAREABLE; | ||
100 | |||
98 | res->irq_resource[i].start = irq; | 101 | res->irq_resource[i].start = irq; |
99 | res->irq_resource[i].end = irq; | 102 | res->irq_resource[i].end = irq; |
100 | pcibios_penalize_isa_irq(irq, 1); | 103 | pcibios_penalize_isa_irq(irq, 1); |
@@ -194,7 +197,8 @@ static acpi_status pnpacpi_allocated_resource(struct acpi_resource *res, | |||
194 | pnpacpi_parse_allocated_irqresource(res_table, | 197 | pnpacpi_parse_allocated_irqresource(res_table, |
195 | res->data.irq.interrupts[i], | 198 | res->data.irq.interrupts[i], |
196 | res->data.irq.triggering, | 199 | res->data.irq.triggering, |
197 | res->data.irq.polarity); | 200 | res->data.irq.polarity, |
201 | res->data.irq.sharable); | ||
198 | } | 202 | } |
199 | break; | 203 | break; |
200 | 204 | ||
@@ -255,7 +259,8 @@ static acpi_status pnpacpi_allocated_resource(struct acpi_resource *res, | |||
255 | pnpacpi_parse_allocated_irqresource(res_table, | 259 | pnpacpi_parse_allocated_irqresource(res_table, |
256 | res->data.extended_irq.interrupts[i], | 260 | res->data.extended_irq.interrupts[i], |
257 | res->data.extended_irq.triggering, | 261 | res->data.extended_irq.triggering, |
258 | res->data.extended_irq.polarity); | 262 | res->data.extended_irq.polarity, |
263 | res->data.extended_irq.sharable); | ||
259 | } | 264 | } |
260 | break; | 265 | break; |
261 | 266 | ||
diff --git a/drivers/s390/char/sclp.c b/drivers/s390/char/sclp.c index 4138564402b8..985d1613baaa 100644 --- a/drivers/s390/char/sclp.c +++ b/drivers/s390/char/sclp.c | |||
@@ -383,6 +383,7 @@ void | |||
383 | sclp_sync_wait(void) | 383 | sclp_sync_wait(void) |
384 | { | 384 | { |
385 | unsigned long psw_mask; | 385 | unsigned long psw_mask; |
386 | unsigned long flags; | ||
386 | unsigned long cr0, cr0_sync; | 387 | unsigned long cr0, cr0_sync; |
387 | u64 timeout; | 388 | u64 timeout; |
388 | 389 | ||
@@ -395,9 +396,11 @@ sclp_sync_wait(void) | |||
395 | sclp_tod_from_jiffies(sclp_request_timer.expires - | 396 | sclp_tod_from_jiffies(sclp_request_timer.expires - |
396 | jiffies); | 397 | jiffies); |
397 | } | 398 | } |
399 | local_irq_save(flags); | ||
398 | /* Prevent bottom half from executing once we force interrupts open */ | 400 | /* Prevent bottom half from executing once we force interrupts open */ |
399 | local_bh_disable(); | 401 | local_bh_disable(); |
400 | /* Enable service-signal interruption, disable timer interrupts */ | 402 | /* Enable service-signal interruption, disable timer interrupts */ |
403 | trace_hardirqs_on(); | ||
401 | __ctl_store(cr0, 0, 0); | 404 | __ctl_store(cr0, 0, 0); |
402 | cr0_sync = cr0; | 405 | cr0_sync = cr0; |
403 | cr0_sync |= 0x00000200; | 406 | cr0_sync |= 0x00000200; |
@@ -415,11 +418,10 @@ sclp_sync_wait(void) | |||
415 | barrier(); | 418 | barrier(); |
416 | cpu_relax(); | 419 | cpu_relax(); |
417 | } | 420 | } |
418 | /* Restore interrupt settings */ | 421 | local_irq_disable(); |
419 | asm volatile ("SSM 0(%0)" | ||
420 | : : "a" (&psw_mask) : "memory"); | ||
421 | __ctl_load(cr0, 0, 0); | 422 | __ctl_load(cr0, 0, 0); |
422 | __local_bh_enable(); | 423 | _local_bh_enable(); |
424 | local_irq_restore(flags); | ||
423 | } | 425 | } |
424 | 426 | ||
425 | EXPORT_SYMBOL(sclp_sync_wait); | 427 | EXPORT_SYMBOL(sclp_sync_wait); |
diff --git a/drivers/s390/cio/cio.c b/drivers/s390/cio/cio.c index a3423267467f..6fec90eab00e 100644 --- a/drivers/s390/cio/cio.c +++ b/drivers/s390/cio/cio.c | |||
@@ -147,7 +147,7 @@ cio_tpi(void) | |||
147 | sch->driver->irq(&sch->dev); | 147 | sch->driver->irq(&sch->dev); |
148 | spin_unlock(&sch->lock); | 148 | spin_unlock(&sch->lock); |
149 | irq_exit (); | 149 | irq_exit (); |
150 | __local_bh_enable(); | 150 | _local_bh_enable(); |
151 | return 1; | 151 | return 1; |
152 | } | 152 | } |
153 | 153 | ||
diff --git a/drivers/s390/net/qeth_main.c b/drivers/s390/net/qeth_main.c index 36733b9823c6..8e8963f15731 100644 --- a/drivers/s390/net/qeth_main.c +++ b/drivers/s390/net/qeth_main.c | |||
@@ -84,6 +84,8 @@ static debug_info_t *qeth_dbf_qerr = NULL; | |||
84 | 84 | ||
85 | DEFINE_PER_CPU(char[256], qeth_dbf_txt_buf); | 85 | DEFINE_PER_CPU(char[256], qeth_dbf_txt_buf); |
86 | 86 | ||
87 | static struct lock_class_key qdio_out_skb_queue_key; | ||
88 | |||
87 | /** | 89 | /** |
88 | * some more definitions and declarations | 90 | * some more definitions and declarations |
89 | */ | 91 | */ |
@@ -3229,6 +3231,9 @@ qeth_alloc_qdio_buffers(struct qeth_card *card) | |||
3229 | &card->qdio.out_qs[i]->qdio_bufs[j]; | 3231 | &card->qdio.out_qs[i]->qdio_bufs[j]; |
3230 | skb_queue_head_init(&card->qdio.out_qs[i]->bufs[j]. | 3232 | skb_queue_head_init(&card->qdio.out_qs[i]->bufs[j]. |
3231 | skb_list); | 3233 | skb_list); |
3234 | lockdep_set_class( | ||
3235 | &card->qdio.out_qs[i]->bufs[j].skb_list.lock, | ||
3236 | &qdio_out_skb_queue_key); | ||
3232 | INIT_LIST_HEAD(&card->qdio.out_qs[i]->bufs[j].ctx_list); | 3237 | INIT_LIST_HEAD(&card->qdio.out_qs[i]->bufs[j].ctx_list); |
3233 | } | 3238 | } |
3234 | } | 3239 | } |
@@ -5272,6 +5277,7 @@ qeth_free_vlan_buffer(struct qeth_card *card, struct qeth_qdio_out_buffer *buf, | |||
5272 | struct sk_buff_head tmp_list; | 5277 | struct sk_buff_head tmp_list; |
5273 | 5278 | ||
5274 | skb_queue_head_init(&tmp_list); | 5279 | skb_queue_head_init(&tmp_list); |
5280 | lockdep_set_class(&tmp_list.lock, &qdio_out_skb_queue_key); | ||
5275 | for(i = 0; i < QETH_MAX_BUFFER_ELEMENTS(card); ++i){ | 5281 | for(i = 0; i < QETH_MAX_BUFFER_ELEMENTS(card); ++i){ |
5276 | while ((skb = skb_dequeue(&buf->skb_list))){ | 5282 | while ((skb = skb_dequeue(&buf->skb_list))){ |
5277 | if (vlan_tx_tag_present(skb) && | 5283 | if (vlan_tx_tag_present(skb) && |
diff --git a/drivers/s390/s390mach.c b/drivers/s390/s390mach.c index 432136f96e64..ffb3677e354f 100644 --- a/drivers/s390/s390mach.c +++ b/drivers/s390/s390mach.c | |||
@@ -378,6 +378,8 @@ s390_do_machine_check(struct pt_regs *regs) | |||
378 | struct mcck_struct *mcck; | 378 | struct mcck_struct *mcck; |
379 | int umode; | 379 | int umode; |
380 | 380 | ||
381 | lockdep_off(); | ||
382 | |||
381 | mci = (struct mci *) &S390_lowcore.mcck_interruption_code; | 383 | mci = (struct mci *) &S390_lowcore.mcck_interruption_code; |
382 | mcck = &__get_cpu_var(cpu_mcck); | 384 | mcck = &__get_cpu_var(cpu_mcck); |
383 | umode = user_mode(regs); | 385 | umode = user_mode(regs); |
@@ -482,6 +484,7 @@ s390_do_machine_check(struct pt_regs *regs) | |||
482 | mcck->warning = 1; | 484 | mcck->warning = 1; |
483 | set_thread_flag(TIF_MCCK_PENDING); | 485 | set_thread_flag(TIF_MCCK_PENDING); |
484 | } | 486 | } |
487 | lockdep_on(); | ||
485 | } | 488 | } |
486 | 489 | ||
487 | /* | 490 | /* |
diff --git a/drivers/s390/scsi/zfcp_erp.c b/drivers/s390/scsi/zfcp_erp.c index 909731b99d26..8ec8da0beaa8 100644 --- a/drivers/s390/scsi/zfcp_erp.c +++ b/drivers/s390/scsi/zfcp_erp.c | |||
@@ -2168,9 +2168,9 @@ zfcp_erp_adapter_strategy_open_fsf_xconfig(struct zfcp_erp_action *erp_action) | |||
2168 | atomic_clear_mask(ZFCP_STATUS_ADAPTER_HOST_CON_INIT, | 2168 | atomic_clear_mask(ZFCP_STATUS_ADAPTER_HOST_CON_INIT, |
2169 | &adapter->status); | 2169 | &adapter->status); |
2170 | ZFCP_LOG_DEBUG("Doing exchange config data\n"); | 2170 | ZFCP_LOG_DEBUG("Doing exchange config data\n"); |
2171 | write_lock(&adapter->erp_lock); | 2171 | write_lock_irq(&adapter->erp_lock); |
2172 | zfcp_erp_action_to_running(erp_action); | 2172 | zfcp_erp_action_to_running(erp_action); |
2173 | write_unlock(&adapter->erp_lock); | 2173 | write_unlock_irq(&adapter->erp_lock); |
2174 | zfcp_erp_timeout_init(erp_action); | 2174 | zfcp_erp_timeout_init(erp_action); |
2175 | if (zfcp_fsf_exchange_config_data(erp_action)) { | 2175 | if (zfcp_fsf_exchange_config_data(erp_action)) { |
2176 | retval = ZFCP_ERP_FAILED; | 2176 | retval = ZFCP_ERP_FAILED; |
@@ -2236,9 +2236,9 @@ zfcp_erp_adapter_strategy_open_fsf_xport(struct zfcp_erp_action *erp_action) | |||
2236 | adapter = erp_action->adapter; | 2236 | adapter = erp_action->adapter; |
2237 | atomic_clear_mask(ZFCP_STATUS_ADAPTER_XPORT_OK, &adapter->status); | 2237 | atomic_clear_mask(ZFCP_STATUS_ADAPTER_XPORT_OK, &adapter->status); |
2238 | 2238 | ||
2239 | write_lock(&adapter->erp_lock); | 2239 | write_lock_irq(&adapter->erp_lock); |
2240 | zfcp_erp_action_to_running(erp_action); | 2240 | zfcp_erp_action_to_running(erp_action); |
2241 | write_unlock(&adapter->erp_lock); | 2241 | write_unlock_irq(&adapter->erp_lock); |
2242 | 2242 | ||
2243 | zfcp_erp_timeout_init(erp_action); | 2243 | zfcp_erp_timeout_init(erp_action); |
2244 | ret = zfcp_fsf_exchange_port_data(erp_action, adapter, NULL); | 2244 | ret = zfcp_fsf_exchange_port_data(erp_action, adapter, NULL); |
diff --git a/drivers/s390/scsi/zfcp_qdio.c b/drivers/s390/scsi/zfcp_qdio.c index 345a191926a4..49ea5add4abc 100644 --- a/drivers/s390/scsi/zfcp_qdio.c +++ b/drivers/s390/scsi/zfcp_qdio.c | |||
@@ -427,6 +427,7 @@ int | |||
427 | zfcp_qdio_reqid_check(struct zfcp_adapter *adapter, void *sbale_addr) | 427 | zfcp_qdio_reqid_check(struct zfcp_adapter *adapter, void *sbale_addr) |
428 | { | 428 | { |
429 | struct zfcp_fsf_req *fsf_req; | 429 | struct zfcp_fsf_req *fsf_req; |
430 | unsigned long flags; | ||
430 | 431 | ||
431 | /* invalid (per convention used in this driver) */ | 432 | /* invalid (per convention used in this driver) */ |
432 | if (unlikely(!sbale_addr)) { | 433 | if (unlikely(!sbale_addr)) { |
@@ -438,15 +439,15 @@ zfcp_qdio_reqid_check(struct zfcp_adapter *adapter, void *sbale_addr) | |||
438 | fsf_req = (struct zfcp_fsf_req *) sbale_addr; | 439 | fsf_req = (struct zfcp_fsf_req *) sbale_addr; |
439 | 440 | ||
440 | /* serialize with zfcp_fsf_req_dismiss_all */ | 441 | /* serialize with zfcp_fsf_req_dismiss_all */ |
441 | spin_lock(&adapter->fsf_req_list_lock); | 442 | spin_lock_irqsave(&adapter->fsf_req_list_lock, flags); |
442 | if (list_empty(&adapter->fsf_req_list_head)) { | 443 | if (list_empty(&adapter->fsf_req_list_head)) { |
443 | spin_unlock(&adapter->fsf_req_list_lock); | 444 | spin_unlock_irqrestore(&adapter->fsf_req_list_lock, flags); |
444 | return 0; | 445 | return 0; |
445 | } | 446 | } |
446 | list_del(&fsf_req->list); | 447 | list_del(&fsf_req->list); |
447 | atomic_dec(&adapter->fsf_reqs_active); | 448 | atomic_dec(&adapter->fsf_reqs_active); |
448 | spin_unlock(&adapter->fsf_req_list_lock); | 449 | spin_unlock_irqrestore(&adapter->fsf_req_list_lock, flags); |
449 | 450 | ||
450 | if (unlikely(adapter != fsf_req->adapter)) { | 451 | if (unlikely(adapter != fsf_req->adapter)) { |
451 | ZFCP_LOG_NORMAL("bug: invalid reqid (fsf_req=%p, " | 452 | ZFCP_LOG_NORMAL("bug: invalid reqid (fsf_req=%p, " |
452 | "fsf_req->adapter=%p, adapter=%p)\n", | 453 | "fsf_req->adapter=%p, adapter=%p)\n", |
diff --git a/drivers/scsi/53c700.c b/drivers/scsi/53c700.c index eb7a6a4ded75..657a3ab75399 100644 --- a/drivers/scsi/53c700.c +++ b/drivers/scsi/53c700.c | |||
@@ -173,6 +173,7 @@ STATIC int NCR_700_bus_reset(struct scsi_cmnd * SCpnt); | |||
173 | STATIC int NCR_700_host_reset(struct scsi_cmnd * SCpnt); | 173 | STATIC int NCR_700_host_reset(struct scsi_cmnd * SCpnt); |
174 | STATIC void NCR_700_chip_setup(struct Scsi_Host *host); | 174 | STATIC void NCR_700_chip_setup(struct Scsi_Host *host); |
175 | STATIC void NCR_700_chip_reset(struct Scsi_Host *host); | 175 | STATIC void NCR_700_chip_reset(struct Scsi_Host *host); |
176 | STATIC int NCR_700_slave_alloc(struct scsi_device *SDpnt); | ||
176 | STATIC int NCR_700_slave_configure(struct scsi_device *SDpnt); | 177 | STATIC int NCR_700_slave_configure(struct scsi_device *SDpnt); |
177 | STATIC void NCR_700_slave_destroy(struct scsi_device *SDpnt); | 178 | STATIC void NCR_700_slave_destroy(struct scsi_device *SDpnt); |
178 | static int NCR_700_change_queue_depth(struct scsi_device *SDpnt, int depth); | 179 | static int NCR_700_change_queue_depth(struct scsi_device *SDpnt, int depth); |
@@ -182,10 +183,6 @@ STATIC struct device_attribute *NCR_700_dev_attrs[]; | |||
182 | 183 | ||
183 | STATIC struct scsi_transport_template *NCR_700_transport_template = NULL; | 184 | STATIC struct scsi_transport_template *NCR_700_transport_template = NULL; |
184 | 185 | ||
185 | struct NCR_700_sense { | ||
186 | unsigned char cmnd[MAX_COMMAND_SIZE]; | ||
187 | }; | ||
188 | |||
189 | static char *NCR_700_phase[] = { | 186 | static char *NCR_700_phase[] = { |
190 | "", | 187 | "", |
191 | "after selection", | 188 | "after selection", |
@@ -333,6 +330,7 @@ NCR_700_detect(struct scsi_host_template *tpnt, | |||
333 | tpnt->use_clustering = ENABLE_CLUSTERING; | 330 | tpnt->use_clustering = ENABLE_CLUSTERING; |
334 | tpnt->slave_configure = NCR_700_slave_configure; | 331 | tpnt->slave_configure = NCR_700_slave_configure; |
335 | tpnt->slave_destroy = NCR_700_slave_destroy; | 332 | tpnt->slave_destroy = NCR_700_slave_destroy; |
333 | tpnt->slave_alloc = NCR_700_slave_alloc; | ||
336 | tpnt->change_queue_depth = NCR_700_change_queue_depth; | 334 | tpnt->change_queue_depth = NCR_700_change_queue_depth; |
337 | tpnt->change_queue_type = NCR_700_change_queue_type; | 335 | tpnt->change_queue_type = NCR_700_change_queue_type; |
338 | 336 | ||
@@ -611,9 +609,10 @@ NCR_700_scsi_done(struct NCR_700_Host_Parameters *hostdata, | |||
611 | struct NCR_700_command_slot *slot = | 609 | struct NCR_700_command_slot *slot = |
612 | (struct NCR_700_command_slot *)SCp->host_scribble; | 610 | (struct NCR_700_command_slot *)SCp->host_scribble; |
613 | 611 | ||
614 | NCR_700_unmap(hostdata, SCp, slot); | 612 | dma_unmap_single(hostdata->dev, slot->pCmd, |
613 | sizeof(SCp->cmnd), DMA_TO_DEVICE); | ||
615 | if (slot->flags == NCR_700_FLAG_AUTOSENSE) { | 614 | if (slot->flags == NCR_700_FLAG_AUTOSENSE) { |
616 | struct NCR_700_sense *sense = SCp->device->hostdata; | 615 | char *cmnd = NCR_700_get_sense_cmnd(SCp->device); |
617 | #ifdef NCR_700_DEBUG | 616 | #ifdef NCR_700_DEBUG |
618 | printk(" ORIGINAL CMD %p RETURNED %d, new return is %d sense is\n", | 617 | printk(" ORIGINAL CMD %p RETURNED %d, new return is %d sense is\n", |
619 | SCp, SCp->cmnd[7], result); | 618 | SCp, SCp->cmnd[7], result); |
@@ -624,10 +623,9 @@ NCR_700_scsi_done(struct NCR_700_Host_Parameters *hostdata, | |||
624 | /* restore the old result if the request sense was | 623 | /* restore the old result if the request sense was |
625 | * successful */ | 624 | * successful */ |
626 | if(result == 0) | 625 | if(result == 0) |
627 | result = sense->cmnd[7]; | 626 | result = cmnd[7]; |
628 | } else | 627 | } else |
629 | dma_unmap_single(hostdata->dev, slot->pCmd, | 628 | NCR_700_unmap(hostdata, SCp, slot); |
630 | sizeof(SCp->cmnd), DMA_TO_DEVICE); | ||
631 | 629 | ||
632 | free_slot(slot, hostdata); | 630 | free_slot(slot, hostdata); |
633 | #ifdef NCR_700_DEBUG | 631 | #ifdef NCR_700_DEBUG |
@@ -969,14 +967,15 @@ process_script_interrupt(__u32 dsps, __u32 dsp, struct scsi_cmnd *SCp, | |||
969 | status_byte(hostdata->status[0]) == COMMAND_TERMINATED) { | 967 | status_byte(hostdata->status[0]) == COMMAND_TERMINATED) { |
970 | struct NCR_700_command_slot *slot = | 968 | struct NCR_700_command_slot *slot = |
971 | (struct NCR_700_command_slot *)SCp->host_scribble; | 969 | (struct NCR_700_command_slot *)SCp->host_scribble; |
972 | if(SCp->cmnd[0] == REQUEST_SENSE) { | 970 | if(slot->flags == NCR_700_FLAG_AUTOSENSE) { |
973 | /* OOPS: bad device, returning another | 971 | /* OOPS: bad device, returning another |
974 | * contingent allegiance condition */ | 972 | * contingent allegiance condition */ |
975 | scmd_printk(KERN_ERR, SCp, | 973 | scmd_printk(KERN_ERR, SCp, |
976 | "broken device is looping in contingent allegiance: ignoring\n"); | 974 | "broken device is looping in contingent allegiance: ignoring\n"); |
977 | NCR_700_scsi_done(hostdata, SCp, hostdata->status[0]); | 975 | NCR_700_scsi_done(hostdata, SCp, hostdata->status[0]); |
978 | } else { | 976 | } else { |
979 | struct NCR_700_sense *sense = SCp->device->hostdata; | 977 | char *cmnd = |
978 | NCR_700_get_sense_cmnd(SCp->device); | ||
980 | #ifdef NCR_DEBUG | 979 | #ifdef NCR_DEBUG |
981 | scsi_print_command(SCp); | 980 | scsi_print_command(SCp); |
982 | printk(" cmd %p has status %d, requesting sense\n", | 981 | printk(" cmd %p has status %d, requesting sense\n", |
@@ -994,21 +993,21 @@ process_script_interrupt(__u32 dsps, __u32 dsp, struct scsi_cmnd *SCp, | |||
994 | sizeof(SCp->cmnd), | 993 | sizeof(SCp->cmnd), |
995 | DMA_TO_DEVICE); | 994 | DMA_TO_DEVICE); |
996 | 995 | ||
997 | sense->cmnd[0] = REQUEST_SENSE; | 996 | cmnd[0] = REQUEST_SENSE; |
998 | sense->cmnd[1] = (SCp->device->lun & 0x7) << 5; | 997 | cmnd[1] = (SCp->device->lun & 0x7) << 5; |
999 | sense->cmnd[2] = 0; | 998 | cmnd[2] = 0; |
1000 | sense->cmnd[3] = 0; | 999 | cmnd[3] = 0; |
1001 | sense->cmnd[4] = sizeof(SCp->sense_buffer); | 1000 | cmnd[4] = sizeof(SCp->sense_buffer); |
1002 | sense->cmnd[5] = 0; | 1001 | cmnd[5] = 0; |
1003 | /* Here's a quiet hack: the | 1002 | /* Here's a quiet hack: the |
1004 | * REQUEST_SENSE command is six bytes, | 1003 | * REQUEST_SENSE command is six bytes, |
1005 | * so store a flag indicating that | 1004 | * so store a flag indicating that |
1006 | * this was an internal sense request | 1005 | * this was an internal sense request |
1007 | * and the original status at the end | 1006 | * and the original status at the end |
1008 | * of the command */ | 1007 | * of the command */ |
1009 | sense->cmnd[6] = NCR_700_INTERNAL_SENSE_MAGIC; | 1008 | cmnd[6] = NCR_700_INTERNAL_SENSE_MAGIC; |
1010 | sense->cmnd[7] = hostdata->status[0]; | 1009 | cmnd[7] = hostdata->status[0]; |
1011 | slot->pCmd = dma_map_single(hostdata->dev, sense->cmnd, sizeof(sense->cmnd), DMA_TO_DEVICE); | 1010 | slot->pCmd = dma_map_single(hostdata->dev, cmnd, MAX_COMMAND_SIZE, DMA_TO_DEVICE); |
1012 | slot->dma_handle = dma_map_single(hostdata->dev, SCp->sense_buffer, sizeof(SCp->sense_buffer), DMA_FROM_DEVICE); | 1011 | slot->dma_handle = dma_map_single(hostdata->dev, SCp->sense_buffer, sizeof(SCp->sense_buffer), DMA_FROM_DEVICE); |
1013 | slot->SG[0].ins = bS_to_host(SCRIPT_MOVE_DATA_IN | sizeof(SCp->sense_buffer)); | 1012 | slot->SG[0].ins = bS_to_host(SCRIPT_MOVE_DATA_IN | sizeof(SCp->sense_buffer)); |
1014 | slot->SG[0].pAddr = bS_to_host(slot->dma_handle); | 1013 | slot->SG[0].pAddr = bS_to_host(slot->dma_handle); |
@@ -1530,7 +1529,7 @@ NCR_700_intr(int irq, void *dev_id, struct pt_regs *regs) | |||
1530 | 1529 | ||
1531 | /* clear all the negotiated parameters */ | 1530 | /* clear all the negotiated parameters */ |
1532 | __shost_for_each_device(SDp, host) | 1531 | __shost_for_each_device(SDp, host) |
1533 | SDp->hostdata = NULL; | 1532 | NCR_700_clear_flag(SDp, ~0); |
1534 | 1533 | ||
1535 | /* clear all the slots and their pending commands */ | 1534 | /* clear all the slots and their pending commands */ |
1536 | for(i = 0; i < NCR_700_COMMAND_SLOTS_PER_HOST; i++) { | 1535 | for(i = 0; i < NCR_700_COMMAND_SLOTS_PER_HOST; i++) { |
@@ -2035,7 +2034,17 @@ NCR_700_set_offset(struct scsi_target *STp, int offset) | |||
2035 | spi_flags(STp) |= NCR_700_DEV_PRINT_SYNC_NEGOTIATION; | 2034 | spi_flags(STp) |= NCR_700_DEV_PRINT_SYNC_NEGOTIATION; |
2036 | } | 2035 | } |
2037 | 2036 | ||
2037 | STATIC int | ||
2038 | NCR_700_slave_alloc(struct scsi_device *SDp) | ||
2039 | { | ||
2040 | SDp->hostdata = kzalloc(sizeof(struct NCR_700_Device_Parameters), | ||
2041 | GFP_KERNEL); | ||
2038 | 2042 | ||
2043 | if (!SDp->hostdata) | ||
2044 | return -ENOMEM; | ||
2045 | |||
2046 | return 0; | ||
2047 | } | ||
2039 | 2048 | ||
2040 | STATIC int | 2049 | STATIC int |
2041 | NCR_700_slave_configure(struct scsi_device *SDp) | 2050 | NCR_700_slave_configure(struct scsi_device *SDp) |
@@ -2043,11 +2052,6 @@ NCR_700_slave_configure(struct scsi_device *SDp) | |||
2043 | struct NCR_700_Host_Parameters *hostdata = | 2052 | struct NCR_700_Host_Parameters *hostdata = |
2044 | (struct NCR_700_Host_Parameters *)SDp->host->hostdata[0]; | 2053 | (struct NCR_700_Host_Parameters *)SDp->host->hostdata[0]; |
2045 | 2054 | ||
2046 | SDp->hostdata = kmalloc(GFP_KERNEL, sizeof(struct NCR_700_sense)); | ||
2047 | |||
2048 | if (!SDp->hostdata) | ||
2049 | return -ENOMEM; | ||
2050 | |||
2051 | /* to do here: allocate memory; build a queue_full list */ | 2055 | /* to do here: allocate memory; build a queue_full list */ |
2052 | if(SDp->tagged_supported) { | 2056 | if(SDp->tagged_supported) { |
2053 | scsi_set_tag_type(SDp, MSG_ORDERED_TAG); | 2057 | scsi_set_tag_type(SDp, MSG_ORDERED_TAG); |
diff --git a/drivers/scsi/53c700.h b/drivers/scsi/53c700.h index 7f22a06fe5ec..97ebe71b701b 100644 --- a/drivers/scsi/53c700.h +++ b/drivers/scsi/53c700.h | |||
@@ -12,7 +12,7 @@ | |||
12 | #include <asm/io.h> | 12 | #include <asm/io.h> |
13 | 13 | ||
14 | #include <scsi/scsi_device.h> | 14 | #include <scsi/scsi_device.h> |
15 | 15 | #include <scsi/scsi_cmnd.h> | |
16 | 16 | ||
17 | /* Turn on for general debugging---too verbose for normal use */ | 17 | /* Turn on for general debugging---too verbose for normal use */ |
18 | #undef NCR_700_DEBUG | 18 | #undef NCR_700_DEBUG |
@@ -76,11 +76,16 @@ struct NCR_700_SG_List { | |||
76 | #define SCRIPT_RETURN 0x90080000 | 76 | #define SCRIPT_RETURN 0x90080000 |
77 | }; | 77 | }; |
78 | 78 | ||
79 | /* We use device->hostdata to store negotiated parameters. This is | 79 | struct NCR_700_Device_Parameters { |
80 | * supposed to be a pointer to a device private area, but we cannot | 80 | /* space for creating a request sense command. Really, except |
81 | * really use it as such since it will never be freed, so just use the | 81 | * for the annoying SCSI-2 requirement for LUN information in |
82 | * 32 bits to cram the information. The SYNC negotiation sequence looks | 82 | * cmnd[1], this could be in static storage */ |
83 | * like: | 83 | unsigned char cmnd[MAX_COMMAND_SIZE]; |
84 | __u8 depth; | ||
85 | }; | ||
86 | |||
87 | |||
88 | /* The SYNC negotiation sequence looks like: | ||
84 | * | 89 | * |
85 | * If DEV_NEGOTIATED_SYNC not set, tack and SDTR message on to the | 90 | * If DEV_NEGOTIATED_SYNC not set, tack and SDTR message on to the |
86 | * initial identify for the device and set DEV_BEGIN_SYNC_NEGOTATION | 91 | * initial identify for the device and set DEV_BEGIN_SYNC_NEGOTATION |
@@ -98,19 +103,26 @@ struct NCR_700_SG_List { | |||
98 | #define NCR_700_DEV_BEGIN_SYNC_NEGOTIATION (1<<17) | 103 | #define NCR_700_DEV_BEGIN_SYNC_NEGOTIATION (1<<17) |
99 | #define NCR_700_DEV_PRINT_SYNC_NEGOTIATION (1<<19) | 104 | #define NCR_700_DEV_PRINT_SYNC_NEGOTIATION (1<<19) |
100 | 105 | ||
106 | static inline char *NCR_700_get_sense_cmnd(struct scsi_device *SDp) | ||
107 | { | ||
108 | struct NCR_700_Device_Parameters *hostdata = SDp->hostdata; | ||
109 | |||
110 | return hostdata->cmnd; | ||
111 | } | ||
112 | |||
101 | static inline void | 113 | static inline void |
102 | NCR_700_set_depth(struct scsi_device *SDp, __u8 depth) | 114 | NCR_700_set_depth(struct scsi_device *SDp, __u8 depth) |
103 | { | 115 | { |
104 | long l = (long)SDp->hostdata; | 116 | struct NCR_700_Device_Parameters *hostdata = SDp->hostdata; |
105 | 117 | ||
106 | l &= 0xffff00ff; | 118 | hostdata->depth = depth; |
107 | l |= 0xff00 & (depth << 8); | ||
108 | SDp->hostdata = (void *)l; | ||
109 | } | 119 | } |
110 | static inline __u8 | 120 | static inline __u8 |
111 | NCR_700_get_depth(struct scsi_device *SDp) | 121 | NCR_700_get_depth(struct scsi_device *SDp) |
112 | { | 122 | { |
113 | return ((((unsigned long)SDp->hostdata) & 0xff00)>>8); | 123 | struct NCR_700_Device_Parameters *hostdata = SDp->hostdata; |
124 | |||
125 | return hostdata->depth; | ||
114 | } | 126 | } |
115 | static inline int | 127 | static inline int |
116 | NCR_700_is_flag_set(struct scsi_device *SDp, __u32 flag) | 128 | NCR_700_is_flag_set(struct scsi_device *SDp, __u32 flag) |
diff --git a/drivers/scsi/aacraid/comminit.c b/drivers/scsi/aacraid/comminit.c index 7cea514e810a..1cd3584ba7ff 100644 --- a/drivers/scsi/aacraid/comminit.c +++ b/drivers/scsi/aacraid/comminit.c | |||
@@ -92,31 +92,7 @@ static int aac_alloc_comm(struct aac_dev *dev, void **commaddr, unsigned long co | |||
92 | init->AdapterFibsPhysicalAddress = cpu_to_le32((u32)phys); | 92 | init->AdapterFibsPhysicalAddress = cpu_to_le32((u32)phys); |
93 | init->AdapterFibsSize = cpu_to_le32(fibsize); | 93 | init->AdapterFibsSize = cpu_to_le32(fibsize); |
94 | init->AdapterFibAlign = cpu_to_le32(sizeof(struct hw_fib)); | 94 | init->AdapterFibAlign = cpu_to_le32(sizeof(struct hw_fib)); |
95 | /* | 95 | init->HostPhysMemPages = cpu_to_le32(AAC_MAX_HOSTPHYSMEMPAGES); |
96 | * number of 4k pages of host physical memory. The aacraid fw needs | ||
97 | * this number to be less than 4gb worth of pages. num_physpages is in | ||
98 | * system page units. New firmware doesn't have any issues with the | ||
99 | * mapping system, but older Firmware did, and had *troubles* dealing | ||
100 | * with the math overloading past 32 bits, thus we must limit this | ||
101 | * field. | ||
102 | * | ||
103 | * This assumes the memory is mapped zero->n, which isnt | ||
104 | * always true on real computers. It also has some slight problems | ||
105 | * with the GART on x86-64. I've btw never tried DMA from PCI space | ||
106 | * on this platform but don't be surprised if its problematic. | ||
107 | * [AK: something is very very wrong when a driver tests this symbol. | ||
108 | * Someone should figure out what the comment writer really meant here and fix | ||
109 | * the code. Or just remove that bad code. ] | ||
110 | */ | ||
111 | #ifndef CONFIG_IOMMU | ||
112 | if ((num_physpages << (PAGE_SHIFT - 12)) <= AAC_MAX_HOSTPHYSMEMPAGES) { | ||
113 | init->HostPhysMemPages = | ||
114 | cpu_to_le32(num_physpages << (PAGE_SHIFT-12)); | ||
115 | } else | ||
116 | #endif | ||
117 | { | ||
118 | init->HostPhysMemPages = cpu_to_le32(AAC_MAX_HOSTPHYSMEMPAGES); | ||
119 | } | ||
120 | 96 | ||
121 | init->InitFlags = 0; | 97 | init->InitFlags = 0; |
122 | if (dev->new_comm_interface) { | 98 | if (dev->new_comm_interface) { |
diff --git a/drivers/scsi/aic7xxx/aic79xx.h b/drivers/scsi/aic7xxx/aic79xx.h index eb7745692682..df3346b5caf8 100644 --- a/drivers/scsi/aic7xxx/aic79xx.h +++ b/drivers/scsi/aic7xxx/aic79xx.h | |||
@@ -1487,6 +1487,7 @@ typedef enum { | |||
1487 | } ahd_queue_alg; | 1487 | } ahd_queue_alg; |
1488 | 1488 | ||
1489 | void ahd_set_tags(struct ahd_softc *ahd, | 1489 | void ahd_set_tags(struct ahd_softc *ahd, |
1490 | struct scsi_cmnd *cmd, | ||
1490 | struct ahd_devinfo *devinfo, | 1491 | struct ahd_devinfo *devinfo, |
1491 | ahd_queue_alg alg); | 1492 | ahd_queue_alg alg); |
1492 | 1493 | ||
diff --git a/drivers/scsi/aic7xxx/aic79xx_core.c b/drivers/scsi/aic7xxx/aic79xx_core.c index 801fc81d0b20..a1e8ca758594 100644 --- a/drivers/scsi/aic7xxx/aic79xx_core.c +++ b/drivers/scsi/aic7xxx/aic79xx_core.c | |||
@@ -1090,7 +1090,7 @@ ahd_handle_seqint(struct ahd_softc *ahd, u_int intstat) | |||
1090 | 1090 | ||
1091 | /* Notify XPT */ | 1091 | /* Notify XPT */ |
1092 | ahd_send_async(ahd, devinfo.channel, devinfo.target, | 1092 | ahd_send_async(ahd, devinfo.channel, devinfo.target, |
1093 | CAM_LUN_WILDCARD, AC_SENT_BDR, NULL); | 1093 | CAM_LUN_WILDCARD, AC_SENT_BDR); |
1094 | 1094 | ||
1095 | /* | 1095 | /* |
1096 | * Allow the sequencer to continue with | 1096 | * Allow the sequencer to continue with |
@@ -3062,7 +3062,7 @@ ahd_set_syncrate(struct ahd_softc *ahd, struct ahd_devinfo *devinfo, | |||
3062 | tinfo->curr.ppr_options = ppr_options; | 3062 | tinfo->curr.ppr_options = ppr_options; |
3063 | 3063 | ||
3064 | ahd_send_async(ahd, devinfo->channel, devinfo->target, | 3064 | ahd_send_async(ahd, devinfo->channel, devinfo->target, |
3065 | CAM_LUN_WILDCARD, AC_TRANSFER_NEG, NULL); | 3065 | CAM_LUN_WILDCARD, AC_TRANSFER_NEG); |
3066 | if (bootverbose) { | 3066 | if (bootverbose) { |
3067 | if (offset != 0) { | 3067 | if (offset != 0) { |
3068 | int options; | 3068 | int options; |
@@ -3184,7 +3184,7 @@ ahd_set_width(struct ahd_softc *ahd, struct ahd_devinfo *devinfo, | |||
3184 | 3184 | ||
3185 | tinfo->curr.width = width; | 3185 | tinfo->curr.width = width; |
3186 | ahd_send_async(ahd, devinfo->channel, devinfo->target, | 3186 | ahd_send_async(ahd, devinfo->channel, devinfo->target, |
3187 | CAM_LUN_WILDCARD, AC_TRANSFER_NEG, NULL); | 3187 | CAM_LUN_WILDCARD, AC_TRANSFER_NEG); |
3188 | if (bootverbose) { | 3188 | if (bootverbose) { |
3189 | printf("%s: target %d using %dbit transfers\n", | 3189 | printf("%s: target %d using %dbit transfers\n", |
3190 | ahd_name(ahd), devinfo->target, | 3190 | ahd_name(ahd), devinfo->target, |
@@ -3211,12 +3211,14 @@ ahd_set_width(struct ahd_softc *ahd, struct ahd_devinfo *devinfo, | |||
3211 | * Update the current state of tagged queuing for a given target. | 3211 | * Update the current state of tagged queuing for a given target. |
3212 | */ | 3212 | */ |
3213 | void | 3213 | void |
3214 | ahd_set_tags(struct ahd_softc *ahd, struct ahd_devinfo *devinfo, | 3214 | ahd_set_tags(struct ahd_softc *ahd, struct scsi_cmnd *cmd, |
3215 | ahd_queue_alg alg) | 3215 | struct ahd_devinfo *devinfo, ahd_queue_alg alg) |
3216 | { | 3216 | { |
3217 | ahd_platform_set_tags(ahd, devinfo, alg); | 3217 | struct scsi_device *sdev = cmd->device; |
3218 | |||
3219 | ahd_platform_set_tags(ahd, sdev, devinfo, alg); | ||
3218 | ahd_send_async(ahd, devinfo->channel, devinfo->target, | 3220 | ahd_send_async(ahd, devinfo->channel, devinfo->target, |
3219 | devinfo->lun, AC_TRANSFER_NEG, &alg); | 3221 | devinfo->lun, AC_TRANSFER_NEG); |
3220 | } | 3222 | } |
3221 | 3223 | ||
3222 | static void | 3224 | static void |
@@ -4746,7 +4748,7 @@ ahd_handle_msg_reject(struct ahd_softc *ahd, struct ahd_devinfo *devinfo) | |||
4746 | printf("(%s:%c:%d:%d): refuses tagged commands. " | 4748 | printf("(%s:%c:%d:%d): refuses tagged commands. " |
4747 | "Performing non-tagged I/O\n", ahd_name(ahd), | 4749 | "Performing non-tagged I/O\n", ahd_name(ahd), |
4748 | devinfo->channel, devinfo->target, devinfo->lun); | 4750 | devinfo->channel, devinfo->target, devinfo->lun); |
4749 | ahd_set_tags(ahd, devinfo, AHD_QUEUE_NONE); | 4751 | ahd_set_tags(ahd, scb->io_ctx, devinfo, AHD_QUEUE_NONE); |
4750 | mask = ~0x23; | 4752 | mask = ~0x23; |
4751 | } else { | 4753 | } else { |
4752 | printf("(%s:%c:%d:%d): refuses %s tagged commands. " | 4754 | printf("(%s:%c:%d:%d): refuses %s tagged commands. " |
@@ -4754,7 +4756,7 @@ ahd_handle_msg_reject(struct ahd_softc *ahd, struct ahd_devinfo *devinfo) | |||
4754 | ahd_name(ahd), devinfo->channel, devinfo->target, | 4756 | ahd_name(ahd), devinfo->channel, devinfo->target, |
4755 | devinfo->lun, tag_type == MSG_ORDERED_TASK | 4757 | devinfo->lun, tag_type == MSG_ORDERED_TASK |
4756 | ? "ordered" : "head of queue"); | 4758 | ? "ordered" : "head of queue"); |
4757 | ahd_set_tags(ahd, devinfo, AHD_QUEUE_BASIC); | 4759 | ahd_set_tags(ahd, scb->io_ctx, devinfo, AHD_QUEUE_BASIC); |
4758 | mask = ~0x03; | 4760 | mask = ~0x03; |
4759 | } | 4761 | } |
4760 | 4762 | ||
@@ -5098,7 +5100,7 @@ ahd_handle_devreset(struct ahd_softc *ahd, struct ahd_devinfo *devinfo, | |||
5098 | 5100 | ||
5099 | if (status != CAM_SEL_TIMEOUT) | 5101 | if (status != CAM_SEL_TIMEOUT) |
5100 | ahd_send_async(ahd, devinfo->channel, devinfo->target, | 5102 | ahd_send_async(ahd, devinfo->channel, devinfo->target, |
5101 | CAM_LUN_WILDCARD, AC_SENT_BDR, NULL); | 5103 | CAM_LUN_WILDCARD, AC_SENT_BDR); |
5102 | 5104 | ||
5103 | if (message != NULL && bootverbose) | 5105 | if (message != NULL && bootverbose) |
5104 | printf("%s: %s on %c:%d. %d SCBs aborted\n", ahd_name(ahd), | 5106 | printf("%s: %s on %c:%d. %d SCBs aborted\n", ahd_name(ahd), |
@@ -7952,7 +7954,7 @@ ahd_reset_channel(struct ahd_softc *ahd, char channel, int initiate_reset) | |||
7952 | #endif | 7954 | #endif |
7953 | /* Notify the XPT that a bus reset occurred */ | 7955 | /* Notify the XPT that a bus reset occurred */ |
7954 | ahd_send_async(ahd, devinfo.channel, CAM_TARGET_WILDCARD, | 7956 | ahd_send_async(ahd, devinfo.channel, CAM_TARGET_WILDCARD, |
7955 | CAM_LUN_WILDCARD, AC_BUS_RESET, NULL); | 7957 | CAM_LUN_WILDCARD, AC_BUS_RESET); |
7956 | 7958 | ||
7957 | /* | 7959 | /* |
7958 | * Revert to async/narrow transfers until we renegotiate. | 7960 | * Revert to async/narrow transfers until we renegotiate. |
diff --git a/drivers/scsi/aic7xxx/aic79xx_osm.c b/drivers/scsi/aic7xxx/aic79xx_osm.c index e0ccdf362200..b244c7124179 100644 --- a/drivers/scsi/aic7xxx/aic79xx_osm.c +++ b/drivers/scsi/aic7xxx/aic79xx_osm.c | |||
@@ -484,7 +484,6 @@ ahd_linux_target_alloc(struct scsi_target *starget) | |||
484 | struct seeprom_config *sc = ahd->seep_config; | 484 | struct seeprom_config *sc = ahd->seep_config; |
485 | unsigned long flags; | 485 | unsigned long flags; |
486 | struct scsi_target **ahd_targp = ahd_linux_target_in_softc(starget); | 486 | struct scsi_target **ahd_targp = ahd_linux_target_in_softc(starget); |
487 | struct ahd_linux_target *targ = scsi_transport_target_data(starget); | ||
488 | struct ahd_devinfo devinfo; | 487 | struct ahd_devinfo devinfo; |
489 | struct ahd_initiator_tinfo *tinfo; | 488 | struct ahd_initiator_tinfo *tinfo; |
490 | struct ahd_tmode_tstate *tstate; | 489 | struct ahd_tmode_tstate *tstate; |
@@ -495,7 +494,6 @@ ahd_linux_target_alloc(struct scsi_target *starget) | |||
495 | BUG_ON(*ahd_targp != NULL); | 494 | BUG_ON(*ahd_targp != NULL); |
496 | 495 | ||
497 | *ahd_targp = starget; | 496 | *ahd_targp = starget; |
498 | memset(targ, 0, sizeof(*targ)); | ||
499 | 497 | ||
500 | if (sc) { | 498 | if (sc) { |
501 | int flags = sc->device_flags[starget->id]; | 499 | int flags = sc->device_flags[starget->id]; |
@@ -551,15 +549,11 @@ ahd_linux_slave_alloc(struct scsi_device *sdev) | |||
551 | { | 549 | { |
552 | struct ahd_softc *ahd = | 550 | struct ahd_softc *ahd = |
553 | *((struct ahd_softc **)sdev->host->hostdata); | 551 | *((struct ahd_softc **)sdev->host->hostdata); |
554 | struct scsi_target *starget = sdev->sdev_target; | ||
555 | struct ahd_linux_target *targ = scsi_transport_target_data(starget); | ||
556 | struct ahd_linux_device *dev; | 552 | struct ahd_linux_device *dev; |
557 | 553 | ||
558 | if (bootverbose) | 554 | if (bootverbose) |
559 | printf("%s: Slave Alloc %d\n", ahd_name(ahd), sdev->id); | 555 | printf("%s: Slave Alloc %d\n", ahd_name(ahd), sdev->id); |
560 | 556 | ||
561 | BUG_ON(targ->sdev[sdev->lun] != NULL); | ||
562 | |||
563 | dev = scsi_transport_device_data(sdev); | 557 | dev = scsi_transport_device_data(sdev); |
564 | memset(dev, 0, sizeof(*dev)); | 558 | memset(dev, 0, sizeof(*dev)); |
565 | 559 | ||
@@ -576,8 +570,6 @@ ahd_linux_slave_alloc(struct scsi_device *sdev) | |||
576 | */ | 570 | */ |
577 | dev->maxtags = 0; | 571 | dev->maxtags = 0; |
578 | 572 | ||
579 | targ->sdev[sdev->lun] = sdev; | ||
580 | |||
581 | return (0); | 573 | return (0); |
582 | } | 574 | } |
583 | 575 | ||
@@ -599,23 +591,6 @@ ahd_linux_slave_configure(struct scsi_device *sdev) | |||
599 | return 0; | 591 | return 0; |
600 | } | 592 | } |
601 | 593 | ||
602 | static void | ||
603 | ahd_linux_slave_destroy(struct scsi_device *sdev) | ||
604 | { | ||
605 | struct ahd_softc *ahd; | ||
606 | struct ahd_linux_device *dev = scsi_transport_device_data(sdev); | ||
607 | struct ahd_linux_target *targ = scsi_transport_target_data(sdev->sdev_target); | ||
608 | |||
609 | ahd = *((struct ahd_softc **)sdev->host->hostdata); | ||
610 | if (bootverbose) | ||
611 | printf("%s: Slave Destroy %d\n", ahd_name(ahd), sdev->id); | ||
612 | |||
613 | BUG_ON(dev->active); | ||
614 | |||
615 | targ->sdev[sdev->lun] = NULL; | ||
616 | |||
617 | } | ||
618 | |||
619 | #if defined(__i386__) | 594 | #if defined(__i386__) |
620 | /* | 595 | /* |
621 | * Return the disk geometry for the given SCSI device. | 596 | * Return the disk geometry for the given SCSI device. |
@@ -822,7 +797,6 @@ struct scsi_host_template aic79xx_driver_template = { | |||
822 | .use_clustering = ENABLE_CLUSTERING, | 797 | .use_clustering = ENABLE_CLUSTERING, |
823 | .slave_alloc = ahd_linux_slave_alloc, | 798 | .slave_alloc = ahd_linux_slave_alloc, |
824 | .slave_configure = ahd_linux_slave_configure, | 799 | .slave_configure = ahd_linux_slave_configure, |
825 | .slave_destroy = ahd_linux_slave_destroy, | ||
826 | .target_alloc = ahd_linux_target_alloc, | 800 | .target_alloc = ahd_linux_target_alloc, |
827 | .target_destroy = ahd_linux_target_destroy, | 801 | .target_destroy = ahd_linux_target_destroy, |
828 | }; | 802 | }; |
@@ -1249,20 +1223,13 @@ void | |||
1249 | ahd_platform_free(struct ahd_softc *ahd) | 1223 | ahd_platform_free(struct ahd_softc *ahd) |
1250 | { | 1224 | { |
1251 | struct scsi_target *starget; | 1225 | struct scsi_target *starget; |
1252 | int i, j; | 1226 | int i; |
1253 | 1227 | ||
1254 | if (ahd->platform_data != NULL) { | 1228 | if (ahd->platform_data != NULL) { |
1255 | /* destroy all of the device and target objects */ | 1229 | /* destroy all of the device and target objects */ |
1256 | for (i = 0; i < AHD_NUM_TARGETS; i++) { | 1230 | for (i = 0; i < AHD_NUM_TARGETS; i++) { |
1257 | starget = ahd->platform_data->starget[i]; | 1231 | starget = ahd->platform_data->starget[i]; |
1258 | if (starget != NULL) { | 1232 | if (starget != NULL) { |
1259 | for (j = 0; j < AHD_NUM_LUNS; j++) { | ||
1260 | struct ahd_linux_target *targ = | ||
1261 | scsi_transport_target_data(starget); | ||
1262 | if (targ->sdev[j] == NULL) | ||
1263 | continue; | ||
1264 | targ->sdev[j] = NULL; | ||
1265 | } | ||
1266 | ahd->platform_data->starget[i] = NULL; | 1233 | ahd->platform_data->starget[i] = NULL; |
1267 | } | 1234 | } |
1268 | } | 1235 | } |
@@ -1318,20 +1285,13 @@ ahd_platform_freeze_devq(struct ahd_softc *ahd, struct scb *scb) | |||
1318 | } | 1285 | } |
1319 | 1286 | ||
1320 | void | 1287 | void |
1321 | ahd_platform_set_tags(struct ahd_softc *ahd, struct ahd_devinfo *devinfo, | 1288 | ahd_platform_set_tags(struct ahd_softc *ahd, struct scsi_device *sdev, |
1322 | ahd_queue_alg alg) | 1289 | struct ahd_devinfo *devinfo, ahd_queue_alg alg) |
1323 | { | 1290 | { |
1324 | struct scsi_target *starget; | ||
1325 | struct ahd_linux_target *targ; | ||
1326 | struct ahd_linux_device *dev; | 1291 | struct ahd_linux_device *dev; |
1327 | struct scsi_device *sdev; | ||
1328 | int was_queuing; | 1292 | int was_queuing; |
1329 | int now_queuing; | 1293 | int now_queuing; |
1330 | 1294 | ||
1331 | starget = ahd->platform_data->starget[devinfo->target]; | ||
1332 | targ = scsi_transport_target_data(starget); | ||
1333 | BUG_ON(targ == NULL); | ||
1334 | sdev = targ->sdev[devinfo->lun]; | ||
1335 | if (sdev == NULL) | 1295 | if (sdev == NULL) |
1336 | return; | 1296 | return; |
1337 | 1297 | ||
@@ -1467,11 +1427,15 @@ ahd_linux_device_queue_depth(struct scsi_device *sdev) | |||
1467 | tags = ahd_linux_user_tagdepth(ahd, &devinfo); | 1427 | tags = ahd_linux_user_tagdepth(ahd, &devinfo); |
1468 | if (tags != 0 && sdev->tagged_supported != 0) { | 1428 | if (tags != 0 && sdev->tagged_supported != 0) { |
1469 | 1429 | ||
1470 | ahd_set_tags(ahd, &devinfo, AHD_QUEUE_TAGGED); | 1430 | ahd_platform_set_tags(ahd, sdev, &devinfo, AHD_QUEUE_TAGGED); |
1431 | ahd_send_async(ahd, devinfo.channel, devinfo.target, | ||
1432 | devinfo.lun, AC_TRANSFER_NEG); | ||
1471 | ahd_print_devinfo(ahd, &devinfo); | 1433 | ahd_print_devinfo(ahd, &devinfo); |
1472 | printf("Tagged Queuing enabled. Depth %d\n", tags); | 1434 | printf("Tagged Queuing enabled. Depth %d\n", tags); |
1473 | } else { | 1435 | } else { |
1474 | ahd_set_tags(ahd, &devinfo, AHD_QUEUE_NONE); | 1436 | ahd_platform_set_tags(ahd, sdev, &devinfo, AHD_QUEUE_NONE); |
1437 | ahd_send_async(ahd, devinfo.channel, devinfo.target, | ||
1438 | devinfo.lun, AC_TRANSFER_NEG); | ||
1475 | } | 1439 | } |
1476 | } | 1440 | } |
1477 | 1441 | ||
@@ -1629,7 +1593,7 @@ ahd_linux_isr(int irq, void *dev_id, struct pt_regs * regs) | |||
1629 | 1593 | ||
1630 | void | 1594 | void |
1631 | ahd_send_async(struct ahd_softc *ahd, char channel, | 1595 | ahd_send_async(struct ahd_softc *ahd, char channel, |
1632 | u_int target, u_int lun, ac_code code, void *arg) | 1596 | u_int target, u_int lun, ac_code code) |
1633 | { | 1597 | { |
1634 | switch (code) { | 1598 | switch (code) { |
1635 | case AC_TRANSFER_NEG: | 1599 | case AC_TRANSFER_NEG: |
@@ -1956,7 +1920,7 @@ ahd_linux_handle_scsi_status(struct ahd_softc *ahd, | |||
1956 | } | 1920 | } |
1957 | ahd_set_transaction_status(scb, CAM_REQUEUE_REQ); | 1921 | ahd_set_transaction_status(scb, CAM_REQUEUE_REQ); |
1958 | ahd_set_scsi_status(scb, SCSI_STATUS_OK); | 1922 | ahd_set_scsi_status(scb, SCSI_STATUS_OK); |
1959 | ahd_platform_set_tags(ahd, &devinfo, | 1923 | ahd_platform_set_tags(ahd, sdev, &devinfo, |
1960 | (dev->flags & AHD_DEV_Q_BASIC) | 1924 | (dev->flags & AHD_DEV_Q_BASIC) |
1961 | ? AHD_QUEUE_BASIC : AHD_QUEUE_TAGGED); | 1925 | ? AHD_QUEUE_BASIC : AHD_QUEUE_TAGGED); |
1962 | break; | 1926 | break; |
@@ -1966,7 +1930,7 @@ ahd_linux_handle_scsi_status(struct ahd_softc *ahd, | |||
1966 | * as if the target returned BUSY SCSI status. | 1930 | * as if the target returned BUSY SCSI status. |
1967 | */ | 1931 | */ |
1968 | dev->openings = 1; | 1932 | dev->openings = 1; |
1969 | ahd_platform_set_tags(ahd, &devinfo, | 1933 | ahd_platform_set_tags(ahd, sdev, &devinfo, |
1970 | (dev->flags & AHD_DEV_Q_BASIC) | 1934 | (dev->flags & AHD_DEV_Q_BASIC) |
1971 | ? AHD_QUEUE_BASIC : AHD_QUEUE_TAGGED); | 1935 | ? AHD_QUEUE_BASIC : AHD_QUEUE_TAGGED); |
1972 | ahd_set_scsi_status(scb, SCSI_STATUS_BUSY); | 1936 | ahd_set_scsi_status(scb, SCSI_STATUS_BUSY); |
@@ -2778,8 +2742,6 @@ ahd_linux_init(void) | |||
2778 | if (!ahd_linux_transport_template) | 2742 | if (!ahd_linux_transport_template) |
2779 | return -ENODEV; | 2743 | return -ENODEV; |
2780 | 2744 | ||
2781 | scsi_transport_reserve_target(ahd_linux_transport_template, | ||
2782 | sizeof(struct ahd_linux_target)); | ||
2783 | scsi_transport_reserve_device(ahd_linux_transport_template, | 2745 | scsi_transport_reserve_device(ahd_linux_transport_template, |
2784 | sizeof(struct ahd_linux_device)); | 2746 | sizeof(struct ahd_linux_device)); |
2785 | 2747 | ||
diff --git a/drivers/scsi/aic7xxx/aic79xx_osm.h b/drivers/scsi/aic7xxx/aic79xx_osm.h index 92c6154575e7..9e871de23835 100644 --- a/drivers/scsi/aic7xxx/aic79xx_osm.h +++ b/drivers/scsi/aic7xxx/aic79xx_osm.h | |||
@@ -262,7 +262,6 @@ typedef enum { | |||
262 | AHD_DEV_PERIODIC_OTAG = 0x40, /* Send OTAG to prevent starvation */ | 262 | AHD_DEV_PERIODIC_OTAG = 0x40, /* Send OTAG to prevent starvation */ |
263 | } ahd_linux_dev_flags; | 263 | } ahd_linux_dev_flags; |
264 | 264 | ||
265 | struct ahd_linux_target; | ||
266 | struct ahd_linux_device { | 265 | struct ahd_linux_device { |
267 | TAILQ_ENTRY(ahd_linux_device) links; | 266 | TAILQ_ENTRY(ahd_linux_device) links; |
268 | 267 | ||
@@ -342,12 +341,6 @@ struct ahd_linux_device { | |||
342 | #define AHD_OTAG_THRESH 500 | 341 | #define AHD_OTAG_THRESH 500 |
343 | }; | 342 | }; |
344 | 343 | ||
345 | struct ahd_linux_target { | ||
346 | struct scsi_device *sdev[AHD_NUM_LUNS]; | ||
347 | struct ahd_transinfo last_tinfo; | ||
348 | struct ahd_softc *ahd; | ||
349 | }; | ||
350 | |||
351 | /********************* Definitions Required by the Core ***********************/ | 344 | /********************* Definitions Required by the Core ***********************/ |
352 | /* | 345 | /* |
353 | * Number of SG segments we require. So long as the S/G segments for | 346 | * Number of SG segments we require. So long as the S/G segments for |
@@ -864,7 +857,7 @@ ahd_freeze_scb(struct scb *scb) | |||
864 | } | 857 | } |
865 | } | 858 | } |
866 | 859 | ||
867 | void ahd_platform_set_tags(struct ahd_softc *ahd, | 860 | void ahd_platform_set_tags(struct ahd_softc *ahd, struct scsi_device *sdev, |
868 | struct ahd_devinfo *devinfo, ahd_queue_alg); | 861 | struct ahd_devinfo *devinfo, ahd_queue_alg); |
869 | int ahd_platform_abort_scbs(struct ahd_softc *ahd, int target, | 862 | int ahd_platform_abort_scbs(struct ahd_softc *ahd, int target, |
870 | char channel, int lun, u_int tag, | 863 | char channel, int lun, u_int tag, |
@@ -873,7 +866,7 @@ irqreturn_t | |||
873 | ahd_linux_isr(int irq, void *dev_id, struct pt_regs * regs); | 866 | ahd_linux_isr(int irq, void *dev_id, struct pt_regs * regs); |
874 | void ahd_done(struct ahd_softc*, struct scb*); | 867 | void ahd_done(struct ahd_softc*, struct scb*); |
875 | void ahd_send_async(struct ahd_softc *, char channel, | 868 | void ahd_send_async(struct ahd_softc *, char channel, |
876 | u_int target, u_int lun, ac_code, void *); | 869 | u_int target, u_int lun, ac_code); |
877 | void ahd_print_path(struct ahd_softc *, struct scb *); | 870 | void ahd_print_path(struct ahd_softc *, struct scb *); |
878 | 871 | ||
879 | #ifdef CONFIG_PCI | 872 | #ifdef CONFIG_PCI |
diff --git a/drivers/scsi/aic7xxx/aic79xx_proc.c b/drivers/scsi/aic7xxx/aic79xx_proc.c index 24fd59a230bf..c5f0ee591509 100644 --- a/drivers/scsi/aic7xxx/aic79xx_proc.c +++ b/drivers/scsi/aic7xxx/aic79xx_proc.c | |||
@@ -47,7 +47,7 @@ static int copy_info(struct info_str *info, char *fmt, ...); | |||
47 | static void ahd_dump_target_state(struct ahd_softc *ahd, | 47 | static void ahd_dump_target_state(struct ahd_softc *ahd, |
48 | struct info_str *info, | 48 | struct info_str *info, |
49 | u_int our_id, char channel, | 49 | u_int our_id, char channel, |
50 | u_int target_id, u_int target_offset); | 50 | u_int target_id); |
51 | static void ahd_dump_device_state(struct info_str *info, | 51 | static void ahd_dump_device_state(struct info_str *info, |
52 | struct scsi_device *sdev); | 52 | struct scsi_device *sdev); |
53 | static int ahd_proc_write_seeprom(struct ahd_softc *ahd, | 53 | static int ahd_proc_write_seeprom(struct ahd_softc *ahd, |
@@ -204,10 +204,8 @@ ahd_format_transinfo(struct info_str *info, struct ahd_transinfo *tinfo) | |||
204 | 204 | ||
205 | static void | 205 | static void |
206 | ahd_dump_target_state(struct ahd_softc *ahd, struct info_str *info, | 206 | ahd_dump_target_state(struct ahd_softc *ahd, struct info_str *info, |
207 | u_int our_id, char channel, u_int target_id, | 207 | u_int our_id, char channel, u_int target_id) |
208 | u_int target_offset) | ||
209 | { | 208 | { |
210 | struct ahd_linux_target *targ; | ||
211 | struct scsi_target *starget; | 209 | struct scsi_target *starget; |
212 | struct ahd_initiator_tinfo *tinfo; | 210 | struct ahd_initiator_tinfo *tinfo; |
213 | struct ahd_tmode_tstate *tstate; | 211 | struct ahd_tmode_tstate *tstate; |
@@ -218,10 +216,9 @@ ahd_dump_target_state(struct ahd_softc *ahd, struct info_str *info, | |||
218 | copy_info(info, "Target %d Negotiation Settings\n", target_id); | 216 | copy_info(info, "Target %d Negotiation Settings\n", target_id); |
219 | copy_info(info, "\tUser: "); | 217 | copy_info(info, "\tUser: "); |
220 | ahd_format_transinfo(info, &tinfo->user); | 218 | ahd_format_transinfo(info, &tinfo->user); |
221 | starget = ahd->platform_data->starget[target_offset]; | 219 | starget = ahd->platform_data->starget[target_id]; |
222 | if (starget == NULL) | 220 | if (starget == NULL) |
223 | return; | 221 | return; |
224 | targ = scsi_transport_target_data(starget); | ||
225 | 222 | ||
226 | copy_info(info, "\tGoal: "); | 223 | copy_info(info, "\tGoal: "); |
227 | ahd_format_transinfo(info, &tinfo->goal); | 224 | ahd_format_transinfo(info, &tinfo->goal); |
@@ -231,7 +228,7 @@ ahd_dump_target_state(struct ahd_softc *ahd, struct info_str *info, | |||
231 | for (lun = 0; lun < AHD_NUM_LUNS; lun++) { | 228 | for (lun = 0; lun < AHD_NUM_LUNS; lun++) { |
232 | struct scsi_device *dev; | 229 | struct scsi_device *dev; |
233 | 230 | ||
234 | dev = targ->sdev[lun]; | 231 | dev = scsi_device_lookup_by_target(starget, lun); |
235 | 232 | ||
236 | if (dev == NULL) | 233 | if (dev == NULL) |
237 | continue; | 234 | continue; |
@@ -355,7 +352,7 @@ ahd_linux_proc_info(struct Scsi_Host *shost, char *buffer, char **start, | |||
355 | copy_info(&info, "Allocated SCBs: %d, SG List Length: %d\n\n", | 352 | copy_info(&info, "Allocated SCBs: %d, SG List Length: %d\n\n", |
356 | ahd->scb_data.numscbs, AHD_NSEG); | 353 | ahd->scb_data.numscbs, AHD_NSEG); |
357 | 354 | ||
358 | max_targ = 15; | 355 | max_targ = 16; |
359 | 356 | ||
360 | if (ahd->seep_config == NULL) | 357 | if (ahd->seep_config == NULL) |
361 | copy_info(&info, "No Serial EEPROM\n"); | 358 | copy_info(&info, "No Serial EEPROM\n"); |
@@ -373,12 +370,12 @@ ahd_linux_proc_info(struct Scsi_Host *shost, char *buffer, char **start, | |||
373 | copy_info(&info, "\n"); | 370 | copy_info(&info, "\n"); |
374 | 371 | ||
375 | if ((ahd->features & AHD_WIDE) == 0) | 372 | if ((ahd->features & AHD_WIDE) == 0) |
376 | max_targ = 7; | 373 | max_targ = 8; |
377 | 374 | ||
378 | for (i = 0; i <= max_targ; i++) { | 375 | for (i = 0; i < max_targ; i++) { |
379 | 376 | ||
380 | ahd_dump_target_state(ahd, &info, ahd->our_id, 'A', | 377 | ahd_dump_target_state(ahd, &info, ahd->our_id, 'A', |
381 | /*target_id*/i, /*target_offset*/i); | 378 | /*target_id*/i); |
382 | } | 379 | } |
383 | retval = info.pos > info.offset ? info.pos - info.offset : 0; | 380 | retval = info.pos > info.offset ? info.pos - info.offset : 0; |
384 | done: | 381 | done: |
diff --git a/drivers/scsi/atp870u.c b/drivers/scsi/atp870u.c index 412f8301b757..0ec41f34f462 100644 --- a/drivers/scsi/atp870u.c +++ b/drivers/scsi/atp870u.c | |||
@@ -2625,29 +2625,32 @@ static int atp870u_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
2625 | unsigned int base_io, tmport, error,n; | 2625 | unsigned int base_io, tmport, error,n; |
2626 | unsigned char host_id; | 2626 | unsigned char host_id; |
2627 | struct Scsi_Host *shpnt = NULL; | 2627 | struct Scsi_Host *shpnt = NULL; |
2628 | struct atp_unit atp_dev, *p; | 2628 | struct atp_unit *atpdev, *p; |
2629 | unsigned char setupdata[2][16]; | 2629 | unsigned char setupdata[2][16]; |
2630 | int count = 0; | 2630 | int count = 0; |
2631 | 2631 | ||
2632 | atpdev = kzalloc(sizeof(*atpdev), GFP_KERNEL); | ||
2633 | if (!atpdev) | ||
2634 | return -ENOMEM; | ||
2635 | |||
2632 | if (pci_enable_device(pdev)) | 2636 | if (pci_enable_device(pdev)) |
2633 | return -EIO; | 2637 | goto err_eio; |
2634 | 2638 | ||
2635 | if (!pci_set_dma_mask(pdev, DMA_32BIT_MASK)) { | 2639 | if (!pci_set_dma_mask(pdev, DMA_32BIT_MASK)) { |
2636 | printk(KERN_INFO "atp870u: use 32bit DMA mask.\n"); | 2640 | printk(KERN_INFO "atp870u: use 32bit DMA mask.\n"); |
2637 | } else { | 2641 | } else { |
2638 | printk(KERN_ERR "atp870u: DMA mask required but not available.\n"); | 2642 | printk(KERN_ERR "atp870u: DMA mask required but not available.\n"); |
2639 | return -EIO; | 2643 | goto err_eio; |
2640 | } | 2644 | } |
2641 | 2645 | ||
2642 | memset(&atp_dev, 0, sizeof atp_dev); | ||
2643 | /* | 2646 | /* |
2644 | * It's probably easier to weed out some revisions like | 2647 | * It's probably easier to weed out some revisions like |
2645 | * this than via the PCI device table | 2648 | * this than via the PCI device table |
2646 | */ | 2649 | */ |
2647 | if (ent->device == PCI_DEVICE_ID_ARTOP_AEC7610) { | 2650 | if (ent->device == PCI_DEVICE_ID_ARTOP_AEC7610) { |
2648 | error = pci_read_config_byte(pdev, PCI_CLASS_REVISION, &atp_dev.chip_ver); | 2651 | error = pci_read_config_byte(pdev, PCI_CLASS_REVISION, &atpdev->chip_ver); |
2649 | if (atp_dev.chip_ver < 2) | 2652 | if (atpdev->chip_ver < 2) |
2650 | return -EIO; | 2653 | goto err_eio; |
2651 | } | 2654 | } |
2652 | 2655 | ||
2653 | switch (ent->device) { | 2656 | switch (ent->device) { |
@@ -2656,15 +2659,15 @@ static int atp870u_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
2656 | case ATP880_DEVID1: | 2659 | case ATP880_DEVID1: |
2657 | case ATP880_DEVID2: | 2660 | case ATP880_DEVID2: |
2658 | case ATP885_DEVID: | 2661 | case ATP885_DEVID: |
2659 | atp_dev.chip_ver = 0x04; | 2662 | atpdev->chip_ver = 0x04; |
2660 | default: | 2663 | default: |
2661 | break; | 2664 | break; |
2662 | } | 2665 | } |
2663 | base_io = pci_resource_start(pdev, 0); | 2666 | base_io = pci_resource_start(pdev, 0); |
2664 | base_io &= 0xfffffff8; | 2667 | base_io &= 0xfffffff8; |
2665 | 2668 | ||
2666 | if ((ent->device == ATP880_DEVID1)||(ent->device == ATP880_DEVID2)) { | 2669 | if ((ent->device == ATP880_DEVID1)||(ent->device == ATP880_DEVID2)) { |
2667 | error = pci_read_config_byte(pdev, PCI_CLASS_REVISION, &atp_dev.chip_ver); | 2670 | error = pci_read_config_byte(pdev, PCI_CLASS_REVISION, &atpdev->chip_ver); |
2668 | pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0x80);//JCC082803 | 2671 | pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0x80);//JCC082803 |
2669 | 2672 | ||
2670 | host_id = inb(base_io + 0x39); | 2673 | host_id = inb(base_io + 0x39); |
@@ -2672,17 +2675,17 @@ static int atp870u_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
2672 | 2675 | ||
2673 | printk(KERN_INFO " ACARD AEC-67160 PCI Ultra3 LVD Host Adapter: %d" | 2676 | printk(KERN_INFO " ACARD AEC-67160 PCI Ultra3 LVD Host Adapter: %d" |
2674 | " IO:%x, IRQ:%d.\n", count, base_io, pdev->irq); | 2677 | " IO:%x, IRQ:%d.\n", count, base_io, pdev->irq); |
2675 | atp_dev.ioport[0] = base_io + 0x40; | 2678 | atpdev->ioport[0] = base_io + 0x40; |
2676 | atp_dev.pciport[0] = base_io + 0x28; | 2679 | atpdev->pciport[0] = base_io + 0x28; |
2677 | atp_dev.dev_id = ent->device; | 2680 | atpdev->dev_id = ent->device; |
2678 | atp_dev.host_id[0] = host_id; | 2681 | atpdev->host_id[0] = host_id; |
2679 | 2682 | ||
2680 | tmport = base_io + 0x22; | 2683 | tmport = base_io + 0x22; |
2681 | atp_dev.scam_on = inb(tmport); | 2684 | atpdev->scam_on = inb(tmport); |
2682 | tmport += 0x13; | 2685 | tmport += 0x13; |
2683 | atp_dev.global_map[0] = inb(tmport); | 2686 | atpdev->global_map[0] = inb(tmport); |
2684 | tmport += 0x07; | 2687 | tmport += 0x07; |
2685 | atp_dev.ultra_map[0] = inw(tmport); | 2688 | atpdev->ultra_map[0] = inw(tmport); |
2686 | 2689 | ||
2687 | n = 0x3f09; | 2690 | n = 0x3f09; |
2688 | next_fblk_880: | 2691 | next_fblk_880: |
@@ -2695,57 +2698,57 @@ next_fblk_880: | |||
2695 | if (inb(base_io + 0x30) == 0xff) | 2698 | if (inb(base_io + 0x30) == 0xff) |
2696 | goto flash_ok_880; | 2699 | goto flash_ok_880; |
2697 | 2700 | ||
2698 | atp_dev.sp[0][m++] = inb(base_io + 0x30); | 2701 | atpdev->sp[0][m++] = inb(base_io + 0x30); |
2699 | atp_dev.sp[0][m++] = inb(base_io + 0x31); | 2702 | atpdev->sp[0][m++] = inb(base_io + 0x31); |
2700 | atp_dev.sp[0][m++] = inb(base_io + 0x32); | 2703 | atpdev->sp[0][m++] = inb(base_io + 0x32); |
2701 | atp_dev.sp[0][m++] = inb(base_io + 0x33); | 2704 | atpdev->sp[0][m++] = inb(base_io + 0x33); |
2702 | outw(n, base_io + 0x34); | 2705 | outw(n, base_io + 0x34); |
2703 | n += 0x0002; | 2706 | n += 0x0002; |
2704 | atp_dev.sp[0][m++] = inb(base_io + 0x30); | 2707 | atpdev->sp[0][m++] = inb(base_io + 0x30); |
2705 | atp_dev.sp[0][m++] = inb(base_io + 0x31); | 2708 | atpdev->sp[0][m++] = inb(base_io + 0x31); |
2706 | atp_dev.sp[0][m++] = inb(base_io + 0x32); | 2709 | atpdev->sp[0][m++] = inb(base_io + 0x32); |
2707 | atp_dev.sp[0][m++] = inb(base_io + 0x33); | 2710 | atpdev->sp[0][m++] = inb(base_io + 0x33); |
2708 | outw(n, base_io + 0x34); | 2711 | outw(n, base_io + 0x34); |
2709 | n += 0x0002; | 2712 | n += 0x0002; |
2710 | atp_dev.sp[0][m++] = inb(base_io + 0x30); | 2713 | atpdev->sp[0][m++] = inb(base_io + 0x30); |
2711 | atp_dev.sp[0][m++] = inb(base_io + 0x31); | 2714 | atpdev->sp[0][m++] = inb(base_io + 0x31); |
2712 | atp_dev.sp[0][m++] = inb(base_io + 0x32); | 2715 | atpdev->sp[0][m++] = inb(base_io + 0x32); |
2713 | atp_dev.sp[0][m++] = inb(base_io + 0x33); | 2716 | atpdev->sp[0][m++] = inb(base_io + 0x33); |
2714 | outw(n, base_io + 0x34); | 2717 | outw(n, base_io + 0x34); |
2715 | n += 0x0002; | 2718 | n += 0x0002; |
2716 | atp_dev.sp[0][m++] = inb(base_io + 0x30); | 2719 | atpdev->sp[0][m++] = inb(base_io + 0x30); |
2717 | atp_dev.sp[0][m++] = inb(base_io + 0x31); | 2720 | atpdev->sp[0][m++] = inb(base_io + 0x31); |
2718 | atp_dev.sp[0][m++] = inb(base_io + 0x32); | 2721 | atpdev->sp[0][m++] = inb(base_io + 0x32); |
2719 | atp_dev.sp[0][m++] = inb(base_io + 0x33); | 2722 | atpdev->sp[0][m++] = inb(base_io + 0x33); |
2720 | n += 0x0018; | 2723 | n += 0x0018; |
2721 | goto next_fblk_880; | 2724 | goto next_fblk_880; |
2722 | flash_ok_880: | 2725 | flash_ok_880: |
2723 | outw(0, base_io + 0x34); | 2726 | outw(0, base_io + 0x34); |
2724 | atp_dev.ultra_map[0] = 0; | 2727 | atpdev->ultra_map[0] = 0; |
2725 | atp_dev.async[0] = 0; | 2728 | atpdev->async[0] = 0; |
2726 | for (k = 0; k < 16; k++) { | 2729 | for (k = 0; k < 16; k++) { |
2727 | n = 1; | 2730 | n = 1; |
2728 | n = n << k; | 2731 | n = n << k; |
2729 | if (atp_dev.sp[0][k] > 1) { | 2732 | if (atpdev->sp[0][k] > 1) { |
2730 | atp_dev.ultra_map[0] |= n; | 2733 | atpdev->ultra_map[0] |= n; |
2731 | } else { | 2734 | } else { |
2732 | if (atp_dev.sp[0][k] == 0) | 2735 | if (atpdev->sp[0][k] == 0) |
2733 | atp_dev.async[0] |= n; | 2736 | atpdev->async[0] |= n; |
2734 | } | 2737 | } |
2735 | } | 2738 | } |
2736 | atp_dev.async[0] = ~(atp_dev.async[0]); | 2739 | atpdev->async[0] = ~(atpdev->async[0]); |
2737 | outb(atp_dev.global_map[0], base_io + 0x35); | 2740 | outb(atpdev->global_map[0], base_io + 0x35); |
2738 | 2741 | ||
2739 | shpnt = scsi_host_alloc(&atp870u_template, sizeof(struct atp_unit)); | 2742 | shpnt = scsi_host_alloc(&atp870u_template, sizeof(struct atp_unit)); |
2740 | if (!shpnt) | 2743 | if (!shpnt) |
2741 | return -ENOMEM; | 2744 | goto err_nomem; |
2742 | 2745 | ||
2743 | p = (struct atp_unit *)&shpnt->hostdata; | 2746 | p = (struct atp_unit *)&shpnt->hostdata; |
2744 | 2747 | ||
2745 | atp_dev.host = shpnt; | 2748 | atpdev->host = shpnt; |
2746 | atp_dev.pdev = pdev; | 2749 | atpdev->pdev = pdev; |
2747 | pci_set_drvdata(pdev, p); | 2750 | pci_set_drvdata(pdev, p); |
2748 | memcpy(p, &atp_dev, sizeof atp_dev); | 2751 | memcpy(p, atpdev, sizeof(*atpdev)); |
2749 | if (atp870u_init_tables(shpnt) < 0) { | 2752 | if (atp870u_init_tables(shpnt) < 0) { |
2750 | printk(KERN_ERR "Unable to allocate tables for Acard controller\n"); | 2753 | printk(KERN_ERR "Unable to allocate tables for Acard controller\n"); |
2751 | goto unregister; | 2754 | goto unregister; |
@@ -2798,24 +2801,24 @@ flash_ok_880: | |||
2798 | printk(KERN_INFO " ACARD AEC-67162 PCI Ultra3 LVD Host Adapter: IO:%x, IRQ:%d.\n" | 2801 | printk(KERN_INFO " ACARD AEC-67162 PCI Ultra3 LVD Host Adapter: IO:%x, IRQ:%d.\n" |
2799 | , base_io, pdev->irq); | 2802 | , base_io, pdev->irq); |
2800 | 2803 | ||
2801 | atp_dev.pdev = pdev; | 2804 | atpdev->pdev = pdev; |
2802 | atp_dev.dev_id = ent->device; | 2805 | atpdev->dev_id = ent->device; |
2803 | atp_dev.baseport = base_io; | 2806 | atpdev->baseport = base_io; |
2804 | atp_dev.ioport[0] = base_io + 0x80; | 2807 | atpdev->ioport[0] = base_io + 0x80; |
2805 | atp_dev.ioport[1] = base_io + 0xc0; | 2808 | atpdev->ioport[1] = base_io + 0xc0; |
2806 | atp_dev.pciport[0] = base_io + 0x40; | 2809 | atpdev->pciport[0] = base_io + 0x40; |
2807 | atp_dev.pciport[1] = base_io + 0x50; | 2810 | atpdev->pciport[1] = base_io + 0x50; |
2808 | 2811 | ||
2809 | shpnt = scsi_host_alloc(&atp870u_template, sizeof(struct atp_unit)); | 2812 | shpnt = scsi_host_alloc(&atp870u_template, sizeof(struct atp_unit)); |
2810 | if (!shpnt) | 2813 | if (!shpnt) |
2811 | return -ENOMEM; | 2814 | goto err_nomem; |
2812 | 2815 | ||
2813 | p = (struct atp_unit *)&shpnt->hostdata; | 2816 | p = (struct atp_unit *)&shpnt->hostdata; |
2814 | 2817 | ||
2815 | atp_dev.host = shpnt; | 2818 | atpdev->host = shpnt; |
2816 | atp_dev.pdev = pdev; | 2819 | atpdev->pdev = pdev; |
2817 | pci_set_drvdata(pdev, p); | 2820 | pci_set_drvdata(pdev, p); |
2818 | memcpy(p, &atp_dev, sizeof(struct atp_unit)); | 2821 | memcpy(p, atpdev, sizeof(struct atp_unit)); |
2819 | if (atp870u_init_tables(shpnt) < 0) | 2822 | if (atp870u_init_tables(shpnt) < 0) |
2820 | goto unregister; | 2823 | goto unregister; |
2821 | 2824 | ||
@@ -2974,33 +2977,33 @@ flash_ok_885: | |||
2974 | printk(KERN_INFO " ACARD AEC-671X PCI Ultra/W SCSI-2/3 Host Adapter: %d " | 2977 | printk(KERN_INFO " ACARD AEC-671X PCI Ultra/W SCSI-2/3 Host Adapter: %d " |
2975 | "IO:%x, IRQ:%d.\n", count, base_io, pdev->irq); | 2978 | "IO:%x, IRQ:%d.\n", count, base_io, pdev->irq); |
2976 | 2979 | ||
2977 | atp_dev.ioport[0] = base_io; | 2980 | atpdev->ioport[0] = base_io; |
2978 | atp_dev.pciport[0] = base_io + 0x20; | 2981 | atpdev->pciport[0] = base_io + 0x20; |
2979 | atp_dev.dev_id = ent->device; | 2982 | atpdev->dev_id = ent->device; |
2980 | host_id &= 0x07; | 2983 | host_id &= 0x07; |
2981 | atp_dev.host_id[0] = host_id; | 2984 | atpdev->host_id[0] = host_id; |
2982 | tmport = base_io + 0x22; | 2985 | tmport = base_io + 0x22; |
2983 | atp_dev.scam_on = inb(tmport); | 2986 | atpdev->scam_on = inb(tmport); |
2984 | tmport += 0x0b; | 2987 | tmport += 0x0b; |
2985 | atp_dev.global_map[0] = inb(tmport++); | 2988 | atpdev->global_map[0] = inb(tmport++); |
2986 | atp_dev.ultra_map[0] = inw(tmport); | 2989 | atpdev->ultra_map[0] = inw(tmport); |
2987 | 2990 | ||
2988 | if (atp_dev.ultra_map[0] == 0) { | 2991 | if (atpdev->ultra_map[0] == 0) { |
2989 | atp_dev.scam_on = 0x00; | 2992 | atpdev->scam_on = 0x00; |
2990 | atp_dev.global_map[0] = 0x20; | 2993 | atpdev->global_map[0] = 0x20; |
2991 | atp_dev.ultra_map[0] = 0xffff; | 2994 | atpdev->ultra_map[0] = 0xffff; |
2992 | } | 2995 | } |
2993 | 2996 | ||
2994 | shpnt = scsi_host_alloc(&atp870u_template, sizeof(struct atp_unit)); | 2997 | shpnt = scsi_host_alloc(&atp870u_template, sizeof(struct atp_unit)); |
2995 | if (!shpnt) | 2998 | if (!shpnt) |
2996 | return -ENOMEM; | 2999 | goto err_nomem; |
2997 | 3000 | ||
2998 | p = (struct atp_unit *)&shpnt->hostdata; | 3001 | p = (struct atp_unit *)&shpnt->hostdata; |
2999 | 3002 | ||
3000 | atp_dev.host = shpnt; | 3003 | atpdev->host = shpnt; |
3001 | atp_dev.pdev = pdev; | 3004 | atpdev->pdev = pdev; |
3002 | pci_set_drvdata(pdev, p); | 3005 | pci_set_drvdata(pdev, p); |
3003 | memcpy(p, &atp_dev, sizeof atp_dev); | 3006 | memcpy(p, atpdev, sizeof(*atpdev)); |
3004 | if (atp870u_init_tables(shpnt) < 0) | 3007 | if (atp870u_init_tables(shpnt) < 0) |
3005 | goto unregister; | 3008 | goto unregister; |
3006 | 3009 | ||
@@ -3010,7 +3013,7 @@ flash_ok_885: | |||
3010 | } | 3013 | } |
3011 | 3014 | ||
3012 | spin_lock_irqsave(shpnt->host_lock, flags); | 3015 | spin_lock_irqsave(shpnt->host_lock, flags); |
3013 | if (atp_dev.chip_ver > 0x07) { /* check if atp876 chip then enable terminator */ | 3016 | if (atpdev->chip_ver > 0x07) { /* check if atp876 chip then enable terminator */ |
3014 | tmport = base_io + 0x3e; | 3017 | tmport = base_io + 0x3e; |
3015 | outb(0x00, tmport); | 3018 | outb(0x00, tmport); |
3016 | } | 3019 | } |
@@ -3044,7 +3047,7 @@ flash_ok_885: | |||
3044 | outb((inb(tmport) & 0xef), tmport); | 3047 | outb((inb(tmport) & 0xef), tmport); |
3045 | tmport++; | 3048 | tmport++; |
3046 | outb((inb(tmport) | 0x20), tmport); | 3049 | outb((inb(tmport) | 0x20), tmport); |
3047 | if (atp_dev.chip_ver == 4) | 3050 | if (atpdev->chip_ver == 4) |
3048 | shpnt->max_id = 16; | 3051 | shpnt->max_id = 16; |
3049 | else | 3052 | else |
3050 | shpnt->max_id = 8; | 3053 | shpnt->max_id = 8; |
@@ -3093,6 +3096,12 @@ unregister: | |||
3093 | printk("atp870u_prob:unregister\n"); | 3096 | printk("atp870u_prob:unregister\n"); |
3094 | scsi_host_put(shpnt); | 3097 | scsi_host_put(shpnt); |
3095 | return -1; | 3098 | return -1; |
3099 | err_eio: | ||
3100 | kfree(atpdev); | ||
3101 | return -EIO; | ||
3102 | err_nomem: | ||
3103 | kfree(atpdev); | ||
3104 | return -ENOMEM; | ||
3096 | } | 3105 | } |
3097 | 3106 | ||
3098 | /* The abort command does not leave the device in a clean state where | 3107 | /* The abort command does not leave the device in a clean state where |
diff --git a/drivers/scsi/ibmvscsi/ibmvscsi.c b/drivers/scsi/ibmvscsi/ibmvscsi.c index 944fc1203ebd..669ea4fff166 100644 --- a/drivers/scsi/ibmvscsi/ibmvscsi.c +++ b/drivers/scsi/ibmvscsi/ibmvscsi.c | |||
@@ -535,6 +535,7 @@ static int ibmvscsi_send_srp_event(struct srp_event_struct *evt_struct, | |||
535 | struct ibmvscsi_host_data *hostdata) | 535 | struct ibmvscsi_host_data *hostdata) |
536 | { | 536 | { |
537 | u64 *crq_as_u64 = (u64 *) &evt_struct->crq; | 537 | u64 *crq_as_u64 = (u64 *) &evt_struct->crq; |
538 | int request_status; | ||
538 | int rc; | 539 | int rc; |
539 | 540 | ||
540 | /* If we have exhausted our request limit, just fail this request. | 541 | /* If we have exhausted our request limit, just fail this request. |
@@ -542,9 +543,18 @@ static int ibmvscsi_send_srp_event(struct srp_event_struct *evt_struct, | |||
542 | * (such as task management requests) that the mid layer may think we | 543 | * (such as task management requests) that the mid layer may think we |
543 | * can handle more requests (can_queue) when we actually can't | 544 | * can handle more requests (can_queue) when we actually can't |
544 | */ | 545 | */ |
545 | if ((evt_struct->crq.format == VIOSRP_SRP_FORMAT) && | 546 | if (evt_struct->crq.format == VIOSRP_SRP_FORMAT) { |
546 | (atomic_dec_if_positive(&hostdata->request_limit) < 0)) | 547 | request_status = |
547 | goto send_error; | 548 | atomic_dec_if_positive(&hostdata->request_limit); |
549 | /* If request limit was -1 when we started, it is now even | ||
550 | * less than that | ||
551 | */ | ||
552 | if (request_status < -1) | ||
553 | goto send_error; | ||
554 | /* Otherwise, if we have run out of requests */ | ||
555 | else if (request_status < 0) | ||
556 | goto send_busy; | ||
557 | } | ||
548 | 558 | ||
549 | /* Copy the IU into the transfer area */ | 559 | /* Copy the IU into the transfer area */ |
550 | *evt_struct->xfer_iu = evt_struct->iu; | 560 | *evt_struct->xfer_iu = evt_struct->iu; |
@@ -567,11 +577,23 @@ static int ibmvscsi_send_srp_event(struct srp_event_struct *evt_struct, | |||
567 | 577 | ||
568 | return 0; | 578 | return 0; |
569 | 579 | ||
570 | send_error: | 580 | send_busy: |
571 | unmap_cmd_data(&evt_struct->iu.srp.cmd, evt_struct, hostdata->dev); | 581 | unmap_cmd_data(&evt_struct->iu.srp.cmd, evt_struct, hostdata->dev); |
572 | 582 | ||
573 | free_event_struct(&hostdata->pool, evt_struct); | 583 | free_event_struct(&hostdata->pool, evt_struct); |
574 | return SCSI_MLQUEUE_HOST_BUSY; | 584 | return SCSI_MLQUEUE_HOST_BUSY; |
585 | |||
586 | send_error: | ||
587 | unmap_cmd_data(&evt_struct->iu.srp.cmd, evt_struct, hostdata->dev); | ||
588 | |||
589 | if (evt_struct->cmnd != NULL) { | ||
590 | evt_struct->cmnd->result = DID_ERROR << 16; | ||
591 | evt_struct->cmnd_done(evt_struct->cmnd); | ||
592 | } else if (evt_struct->done) | ||
593 | evt_struct->done(evt_struct); | ||
594 | |||
595 | free_event_struct(&hostdata->pool, evt_struct); | ||
596 | return 0; | ||
575 | } | 597 | } |
576 | 598 | ||
577 | /** | 599 | /** |
@@ -1184,27 +1206,37 @@ void ibmvscsi_handle_crq(struct viosrp_crq *crq, | |||
1184 | return; | 1206 | return; |
1185 | case 0xFF: /* Hypervisor telling us the connection is closed */ | 1207 | case 0xFF: /* Hypervisor telling us the connection is closed */ |
1186 | scsi_block_requests(hostdata->host); | 1208 | scsi_block_requests(hostdata->host); |
1209 | atomic_set(&hostdata->request_limit, 0); | ||
1187 | if (crq->format == 0x06) { | 1210 | if (crq->format == 0x06) { |
1188 | /* We need to re-setup the interpartition connection */ | 1211 | /* We need to re-setup the interpartition connection */ |
1189 | printk(KERN_INFO | 1212 | printk(KERN_INFO |
1190 | "ibmvscsi: Re-enabling adapter!\n"); | 1213 | "ibmvscsi: Re-enabling adapter!\n"); |
1191 | atomic_set(&hostdata->request_limit, -1); | ||
1192 | purge_requests(hostdata, DID_REQUEUE); | 1214 | purge_requests(hostdata, DID_REQUEUE); |
1193 | if (ibmvscsi_reenable_crq_queue(&hostdata->queue, | 1215 | if ((ibmvscsi_reenable_crq_queue(&hostdata->queue, |
1194 | hostdata) == 0) | 1216 | hostdata) == 0) || |
1195 | if (ibmvscsi_send_crq(hostdata, | 1217 | (ibmvscsi_send_crq(hostdata, |
1196 | 0xC001000000000000LL, 0)) | 1218 | 0xC001000000000000LL, 0))) { |
1219 | atomic_set(&hostdata->request_limit, | ||
1220 | -1); | ||
1197 | printk(KERN_ERR | 1221 | printk(KERN_ERR |
1198 | "ibmvscsi: transmit error after" | 1222 | "ibmvscsi: error after" |
1199 | " enable\n"); | 1223 | " enable\n"); |
1224 | } | ||
1200 | } else { | 1225 | } else { |
1201 | printk(KERN_INFO | 1226 | printk(KERN_INFO |
1202 | "ibmvscsi: Virtual adapter failed rc %d!\n", | 1227 | "ibmvscsi: Virtual adapter failed rc %d!\n", |
1203 | crq->format); | 1228 | crq->format); |
1204 | 1229 | ||
1205 | atomic_set(&hostdata->request_limit, -1); | ||
1206 | purge_requests(hostdata, DID_ERROR); | 1230 | purge_requests(hostdata, DID_ERROR); |
1207 | ibmvscsi_reset_crq_queue(&hostdata->queue, hostdata); | 1231 | if ((ibmvscsi_reset_crq_queue(&hostdata->queue, |
1232 | hostdata)) || | ||
1233 | (ibmvscsi_send_crq(hostdata, | ||
1234 | 0xC001000000000000LL, 0))) { | ||
1235 | atomic_set(&hostdata->request_limit, | ||
1236 | -1); | ||
1237 | printk(KERN_ERR | ||
1238 | "ibmvscsi: error after reset\n"); | ||
1239 | } | ||
1208 | } | 1240 | } |
1209 | scsi_unblock_requests(hostdata->host); | 1241 | scsi_unblock_requests(hostdata->host); |
1210 | return; | 1242 | return; |
@@ -1467,6 +1499,7 @@ static int ibmvscsi_probe(struct vio_dev *vdev, const struct vio_device_id *id) | |||
1467 | struct Scsi_Host *host; | 1499 | struct Scsi_Host *host; |
1468 | struct device *dev = &vdev->dev; | 1500 | struct device *dev = &vdev->dev; |
1469 | unsigned long wait_switch = 0; | 1501 | unsigned long wait_switch = 0; |
1502 | int rc; | ||
1470 | 1503 | ||
1471 | vdev->dev.driver_data = NULL; | 1504 | vdev->dev.driver_data = NULL; |
1472 | 1505 | ||
@@ -1484,8 +1517,8 @@ static int ibmvscsi_probe(struct vio_dev *vdev, const struct vio_device_id *id) | |||
1484 | atomic_set(&hostdata->request_limit, -1); | 1517 | atomic_set(&hostdata->request_limit, -1); |
1485 | hostdata->host->max_sectors = 32 * 8; /* default max I/O 32 pages */ | 1518 | hostdata->host->max_sectors = 32 * 8; /* default max I/O 32 pages */ |
1486 | 1519 | ||
1487 | if (ibmvscsi_init_crq_queue(&hostdata->queue, hostdata, | 1520 | rc = ibmvscsi_init_crq_queue(&hostdata->queue, hostdata, max_requests); |
1488 | max_requests) != 0) { | 1521 | if (rc != 0 && rc != H_RESOURCE) { |
1489 | printk(KERN_ERR "ibmvscsi: couldn't initialize crq\n"); | 1522 | printk(KERN_ERR "ibmvscsi: couldn't initialize crq\n"); |
1490 | goto init_crq_failed; | 1523 | goto init_crq_failed; |
1491 | } | 1524 | } |
@@ -1505,7 +1538,8 @@ static int ibmvscsi_probe(struct vio_dev *vdev, const struct vio_device_id *id) | |||
1505 | * to fail if the other end is not acive. In that case we don't | 1538 | * to fail if the other end is not acive. In that case we don't |
1506 | * want to scan | 1539 | * want to scan |
1507 | */ | 1540 | */ |
1508 | if (ibmvscsi_send_crq(hostdata, 0xC001000000000000LL, 0) == 0) { | 1541 | if (ibmvscsi_send_crq(hostdata, 0xC001000000000000LL, 0) == 0 |
1542 | || rc == H_RESOURCE) { | ||
1509 | /* | 1543 | /* |
1510 | * Wait around max init_timeout secs for the adapter to finish | 1544 | * Wait around max init_timeout secs for the adapter to finish |
1511 | * initializing. When we are done initializing, we will have a | 1545 | * initializing. When we are done initializing, we will have a |
diff --git a/drivers/scsi/ibmvscsi/rpa_vscsi.c b/drivers/scsi/ibmvscsi/rpa_vscsi.c index 1a9992bdfef8..242b8873b333 100644 --- a/drivers/scsi/ibmvscsi/rpa_vscsi.c +++ b/drivers/scsi/ibmvscsi/rpa_vscsi.c | |||
@@ -208,6 +208,7 @@ int ibmvscsi_init_crq_queue(struct crq_queue *queue, | |||
208 | int max_requests) | 208 | int max_requests) |
209 | { | 209 | { |
210 | int rc; | 210 | int rc; |
211 | int retrc; | ||
211 | struct vio_dev *vdev = to_vio_dev(hostdata->dev); | 212 | struct vio_dev *vdev = to_vio_dev(hostdata->dev); |
212 | 213 | ||
213 | queue->msgs = (struct viosrp_crq *)get_zeroed_page(GFP_KERNEL); | 214 | queue->msgs = (struct viosrp_crq *)get_zeroed_page(GFP_KERNEL); |
@@ -226,7 +227,7 @@ int ibmvscsi_init_crq_queue(struct crq_queue *queue, | |||
226 | gather_partition_info(); | 227 | gather_partition_info(); |
227 | set_adapter_info(hostdata); | 228 | set_adapter_info(hostdata); |
228 | 229 | ||
229 | rc = plpar_hcall_norets(H_REG_CRQ, | 230 | retrc = rc = plpar_hcall_norets(H_REG_CRQ, |
230 | vdev->unit_address, | 231 | vdev->unit_address, |
231 | queue->msg_token, PAGE_SIZE); | 232 | queue->msg_token, PAGE_SIZE); |
232 | if (rc == H_RESOURCE) | 233 | if (rc == H_RESOURCE) |
@@ -263,7 +264,7 @@ int ibmvscsi_init_crq_queue(struct crq_queue *queue, | |||
263 | tasklet_init(&hostdata->srp_task, (void *)ibmvscsi_task, | 264 | tasklet_init(&hostdata->srp_task, (void *)ibmvscsi_task, |
264 | (unsigned long)hostdata); | 265 | (unsigned long)hostdata); |
265 | 266 | ||
266 | return 0; | 267 | return retrc; |
267 | 268 | ||
268 | req_irq_failed: | 269 | req_irq_failed: |
269 | do { | 270 | do { |
diff --git a/drivers/scsi/iscsi_tcp.c b/drivers/scsi/iscsi_tcp.c index b4743a9ecc80..848fb2aa4ca3 100644 --- a/drivers/scsi/iscsi_tcp.c +++ b/drivers/scsi/iscsi_tcp.c | |||
@@ -2130,19 +2130,21 @@ iscsi_r2tpool_free(struct iscsi_session *session) | |||
2130 | 2130 | ||
2131 | static int | 2131 | static int |
2132 | iscsi_conn_set_param(struct iscsi_cls_conn *cls_conn, enum iscsi_param param, | 2132 | iscsi_conn_set_param(struct iscsi_cls_conn *cls_conn, enum iscsi_param param, |
2133 | uint32_t value) | 2133 | char *buf, int buflen) |
2134 | { | 2134 | { |
2135 | struct iscsi_conn *conn = cls_conn->dd_data; | 2135 | struct iscsi_conn *conn = cls_conn->dd_data; |
2136 | struct iscsi_session *session = conn->session; | 2136 | struct iscsi_session *session = conn->session; |
2137 | struct iscsi_tcp_conn *tcp_conn = conn->dd_data; | 2137 | struct iscsi_tcp_conn *tcp_conn = conn->dd_data; |
2138 | int value; | ||
2138 | 2139 | ||
2139 | switch(param) { | 2140 | switch(param) { |
2140 | case ISCSI_PARAM_MAX_RECV_DLENGTH: { | 2141 | case ISCSI_PARAM_MAX_RECV_DLENGTH: { |
2141 | char *saveptr = tcp_conn->data; | 2142 | char *saveptr = tcp_conn->data; |
2142 | gfp_t flags = GFP_KERNEL; | 2143 | gfp_t flags = GFP_KERNEL; |
2143 | 2144 | ||
2145 | sscanf(buf, "%d", &value); | ||
2144 | if (tcp_conn->data_size >= value) { | 2146 | if (tcp_conn->data_size >= value) { |
2145 | conn->max_recv_dlength = value; | 2147 | iscsi_set_param(cls_conn, param, buf, buflen); |
2146 | break; | 2148 | break; |
2147 | } | 2149 | } |
2148 | 2150 | ||
@@ -2165,15 +2167,12 @@ iscsi_conn_set_param(struct iscsi_cls_conn *cls_conn, enum iscsi_param param, | |||
2165 | else | 2167 | else |
2166 | free_pages((unsigned long)saveptr, | 2168 | free_pages((unsigned long)saveptr, |
2167 | get_order(tcp_conn->data_size)); | 2169 | get_order(tcp_conn->data_size)); |
2168 | conn->max_recv_dlength = value; | 2170 | iscsi_set_param(cls_conn, param, buf, buflen); |
2169 | tcp_conn->data_size = value; | 2171 | tcp_conn->data_size = value; |
2170 | } | ||
2171 | break; | ||
2172 | case ISCSI_PARAM_MAX_XMIT_DLENGTH: | ||
2173 | conn->max_xmit_dlength = value; | ||
2174 | break; | 2172 | break; |
2173 | } | ||
2175 | case ISCSI_PARAM_HDRDGST_EN: | 2174 | case ISCSI_PARAM_HDRDGST_EN: |
2176 | conn->hdrdgst_en = value; | 2175 | iscsi_set_param(cls_conn, param, buf, buflen); |
2177 | tcp_conn->hdr_size = sizeof(struct iscsi_hdr); | 2176 | tcp_conn->hdr_size = sizeof(struct iscsi_hdr); |
2178 | if (conn->hdrdgst_en) { | 2177 | if (conn->hdrdgst_en) { |
2179 | tcp_conn->hdr_size += sizeof(__u32); | 2178 | tcp_conn->hdr_size += sizeof(__u32); |
@@ -2197,7 +2196,7 @@ iscsi_conn_set_param(struct iscsi_cls_conn *cls_conn, enum iscsi_param param, | |||
2197 | } | 2196 | } |
2198 | break; | 2197 | break; |
2199 | case ISCSI_PARAM_DATADGST_EN: | 2198 | case ISCSI_PARAM_DATADGST_EN: |
2200 | conn->datadgst_en = value; | 2199 | iscsi_set_param(cls_conn, param, buf, buflen); |
2201 | if (conn->datadgst_en) { | 2200 | if (conn->datadgst_en) { |
2202 | if (!tcp_conn->data_tx_tfm) | 2201 | if (!tcp_conn->data_tx_tfm) |
2203 | tcp_conn->data_tx_tfm = | 2202 | tcp_conn->data_tx_tfm = |
@@ -2220,121 +2219,36 @@ iscsi_conn_set_param(struct iscsi_cls_conn *cls_conn, enum iscsi_param param, | |||
2220 | tcp_conn->sendpage = conn->datadgst_en ? | 2219 | tcp_conn->sendpage = conn->datadgst_en ? |
2221 | sock_no_sendpage : tcp_conn->sock->ops->sendpage; | 2220 | sock_no_sendpage : tcp_conn->sock->ops->sendpage; |
2222 | break; | 2221 | break; |
2223 | case ISCSI_PARAM_INITIAL_R2T_EN: | ||
2224 | session->initial_r2t_en = value; | ||
2225 | break; | ||
2226 | case ISCSI_PARAM_MAX_R2T: | 2222 | case ISCSI_PARAM_MAX_R2T: |
2223 | sscanf(buf, "%d", &value); | ||
2227 | if (session->max_r2t == roundup_pow_of_two(value)) | 2224 | if (session->max_r2t == roundup_pow_of_two(value)) |
2228 | break; | 2225 | break; |
2229 | iscsi_r2tpool_free(session); | 2226 | iscsi_r2tpool_free(session); |
2230 | session->max_r2t = value; | 2227 | iscsi_set_param(cls_conn, param, buf, buflen); |
2231 | if (session->max_r2t & (session->max_r2t - 1)) | 2228 | if (session->max_r2t & (session->max_r2t - 1)) |
2232 | session->max_r2t = roundup_pow_of_two(session->max_r2t); | 2229 | session->max_r2t = roundup_pow_of_two(session->max_r2t); |
2233 | if (iscsi_r2tpool_alloc(session)) | 2230 | if (iscsi_r2tpool_alloc(session)) |
2234 | return -ENOMEM; | 2231 | return -ENOMEM; |
2235 | break; | 2232 | break; |
2236 | case ISCSI_PARAM_IMM_DATA_EN: | ||
2237 | session->imm_data_en = value; | ||
2238 | break; | ||
2239 | case ISCSI_PARAM_FIRST_BURST: | ||
2240 | session->first_burst = value; | ||
2241 | break; | ||
2242 | case ISCSI_PARAM_MAX_BURST: | ||
2243 | session->max_burst = value; | ||
2244 | break; | ||
2245 | case ISCSI_PARAM_PDU_INORDER_EN: | ||
2246 | session->pdu_inorder_en = value; | ||
2247 | break; | ||
2248 | case ISCSI_PARAM_DATASEQ_INORDER_EN: | ||
2249 | session->dataseq_inorder_en = value; | ||
2250 | break; | ||
2251 | case ISCSI_PARAM_ERL: | ||
2252 | session->erl = value; | ||
2253 | break; | ||
2254 | case ISCSI_PARAM_IFMARKER_EN: | ||
2255 | BUG_ON(value); | ||
2256 | session->ifmarker_en = value; | ||
2257 | break; | ||
2258 | case ISCSI_PARAM_OFMARKER_EN: | ||
2259 | BUG_ON(value); | ||
2260 | session->ofmarker_en = value; | ||
2261 | break; | ||
2262 | case ISCSI_PARAM_EXP_STATSN: | ||
2263 | conn->exp_statsn = value; | ||
2264 | break; | ||
2265 | default: | ||
2266 | break; | ||
2267 | } | ||
2268 | |||
2269 | return 0; | ||
2270 | } | ||
2271 | |||
2272 | static int | ||
2273 | iscsi_session_get_param(struct iscsi_cls_session *cls_session, | ||
2274 | enum iscsi_param param, uint32_t *value) | ||
2275 | { | ||
2276 | struct Scsi_Host *shost = iscsi_session_to_shost(cls_session); | ||
2277 | struct iscsi_session *session = iscsi_hostdata(shost->hostdata); | ||
2278 | |||
2279 | switch(param) { | ||
2280 | case ISCSI_PARAM_INITIAL_R2T_EN: | ||
2281 | *value = session->initial_r2t_en; | ||
2282 | break; | ||
2283 | case ISCSI_PARAM_MAX_R2T: | ||
2284 | *value = session->max_r2t; | ||
2285 | break; | ||
2286 | case ISCSI_PARAM_IMM_DATA_EN: | ||
2287 | *value = session->imm_data_en; | ||
2288 | break; | ||
2289 | case ISCSI_PARAM_FIRST_BURST: | ||
2290 | *value = session->first_burst; | ||
2291 | break; | ||
2292 | case ISCSI_PARAM_MAX_BURST: | ||
2293 | *value = session->max_burst; | ||
2294 | break; | ||
2295 | case ISCSI_PARAM_PDU_INORDER_EN: | ||
2296 | *value = session->pdu_inorder_en; | ||
2297 | break; | ||
2298 | case ISCSI_PARAM_DATASEQ_INORDER_EN: | ||
2299 | *value = session->dataseq_inorder_en; | ||
2300 | break; | ||
2301 | case ISCSI_PARAM_ERL: | ||
2302 | *value = session->erl; | ||
2303 | break; | ||
2304 | case ISCSI_PARAM_IFMARKER_EN: | ||
2305 | *value = session->ifmarker_en; | ||
2306 | break; | ||
2307 | case ISCSI_PARAM_OFMARKER_EN: | ||
2308 | *value = session->ofmarker_en; | ||
2309 | break; | ||
2310 | default: | 2233 | default: |
2311 | return -EINVAL; | 2234 | return iscsi_set_param(cls_conn, param, buf, buflen); |
2312 | } | 2235 | } |
2313 | 2236 | ||
2314 | return 0; | 2237 | return 0; |
2315 | } | 2238 | } |
2316 | 2239 | ||
2317 | static int | 2240 | static int |
2318 | iscsi_conn_get_param(struct iscsi_cls_conn *cls_conn, | 2241 | iscsi_tcp_conn_get_param(struct iscsi_cls_conn *cls_conn, |
2319 | enum iscsi_param param, uint32_t *value) | 2242 | enum iscsi_param param, char *buf) |
2320 | { | 2243 | { |
2321 | struct iscsi_conn *conn = cls_conn->dd_data; | 2244 | struct iscsi_conn *conn = cls_conn->dd_data; |
2322 | struct iscsi_tcp_conn *tcp_conn = conn->dd_data; | 2245 | struct iscsi_tcp_conn *tcp_conn = conn->dd_data; |
2323 | struct inet_sock *inet; | 2246 | struct inet_sock *inet; |
2247 | struct ipv6_pinfo *np; | ||
2248 | struct sock *sk; | ||
2249 | int len; | ||
2324 | 2250 | ||
2325 | switch(param) { | 2251 | switch(param) { |
2326 | case ISCSI_PARAM_MAX_RECV_DLENGTH: | ||
2327 | *value = conn->max_recv_dlength; | ||
2328 | break; | ||
2329 | case ISCSI_PARAM_MAX_XMIT_DLENGTH: | ||
2330 | *value = conn->max_xmit_dlength; | ||
2331 | break; | ||
2332 | case ISCSI_PARAM_HDRDGST_EN: | ||
2333 | *value = conn->hdrdgst_en; | ||
2334 | break; | ||
2335 | case ISCSI_PARAM_DATADGST_EN: | ||
2336 | *value = conn->datadgst_en; | ||
2337 | break; | ||
2338 | case ISCSI_PARAM_CONN_PORT: | 2252 | case ISCSI_PARAM_CONN_PORT: |
2339 | mutex_lock(&conn->xmitmutex); | 2253 | mutex_lock(&conn->xmitmutex); |
2340 | if (!tcp_conn->sock) { | 2254 | if (!tcp_conn->sock) { |
@@ -2343,30 +2257,9 @@ iscsi_conn_get_param(struct iscsi_cls_conn *cls_conn, | |||
2343 | } | 2257 | } |
2344 | 2258 | ||
2345 | inet = inet_sk(tcp_conn->sock->sk); | 2259 | inet = inet_sk(tcp_conn->sock->sk); |
2346 | *value = be16_to_cpu(inet->dport); | 2260 | len = sprintf(buf, "%hu\n", be16_to_cpu(inet->dport)); |
2347 | mutex_unlock(&conn->xmitmutex); | 2261 | mutex_unlock(&conn->xmitmutex); |
2348 | case ISCSI_PARAM_EXP_STATSN: | ||
2349 | *value = conn->exp_statsn; | ||
2350 | break; | 2262 | break; |
2351 | default: | ||
2352 | return -EINVAL; | ||
2353 | } | ||
2354 | |||
2355 | return 0; | ||
2356 | } | ||
2357 | |||
2358 | static int | ||
2359 | iscsi_conn_get_str_param(struct iscsi_cls_conn *cls_conn, | ||
2360 | enum iscsi_param param, char *buf) | ||
2361 | { | ||
2362 | struct iscsi_conn *conn = cls_conn->dd_data; | ||
2363 | struct iscsi_tcp_conn *tcp_conn = conn->dd_data; | ||
2364 | struct sock *sk; | ||
2365 | struct inet_sock *inet; | ||
2366 | struct ipv6_pinfo *np; | ||
2367 | int len = 0; | ||
2368 | |||
2369 | switch (param) { | ||
2370 | case ISCSI_PARAM_CONN_ADDRESS: | 2263 | case ISCSI_PARAM_CONN_ADDRESS: |
2371 | mutex_lock(&conn->xmitmutex); | 2264 | mutex_lock(&conn->xmitmutex); |
2372 | if (!tcp_conn->sock) { | 2265 | if (!tcp_conn->sock) { |
@@ -2388,7 +2281,7 @@ iscsi_conn_get_str_param(struct iscsi_cls_conn *cls_conn, | |||
2388 | mutex_unlock(&conn->xmitmutex); | 2281 | mutex_unlock(&conn->xmitmutex); |
2389 | break; | 2282 | break; |
2390 | default: | 2283 | default: |
2391 | return -EINVAL; | 2284 | return iscsi_conn_get_param(cls_conn, param, buf); |
2392 | } | 2285 | } |
2393 | 2286 | ||
2394 | return len; | 2287 | return len; |
@@ -2501,7 +2394,11 @@ static struct iscsi_transport iscsi_tcp_transport = { | |||
2501 | ISCSI_ERL | | 2394 | ISCSI_ERL | |
2502 | ISCSI_CONN_PORT | | 2395 | ISCSI_CONN_PORT | |
2503 | ISCSI_CONN_ADDRESS | | 2396 | ISCSI_CONN_ADDRESS | |
2504 | ISCSI_EXP_STATSN, | 2397 | ISCSI_EXP_STATSN | |
2398 | ISCSI_PERSISTENT_PORT | | ||
2399 | ISCSI_PERSISTENT_ADDRESS | | ||
2400 | ISCSI_TARGET_NAME | | ||
2401 | ISCSI_TPGT, | ||
2505 | .host_template = &iscsi_sht, | 2402 | .host_template = &iscsi_sht, |
2506 | .conndata_size = sizeof(struct iscsi_conn), | 2403 | .conndata_size = sizeof(struct iscsi_conn), |
2507 | .max_conn = 1, | 2404 | .max_conn = 1, |
@@ -2514,8 +2411,7 @@ static struct iscsi_transport iscsi_tcp_transport = { | |||
2514 | .bind_conn = iscsi_tcp_conn_bind, | 2411 | .bind_conn = iscsi_tcp_conn_bind, |
2515 | .destroy_conn = iscsi_tcp_conn_destroy, | 2412 | .destroy_conn = iscsi_tcp_conn_destroy, |
2516 | .set_param = iscsi_conn_set_param, | 2413 | .set_param = iscsi_conn_set_param, |
2517 | .get_conn_param = iscsi_conn_get_param, | 2414 | .get_conn_param = iscsi_tcp_conn_get_param, |
2518 | .get_conn_str_param = iscsi_conn_get_str_param, | ||
2519 | .get_session_param = iscsi_session_get_param, | 2415 | .get_session_param = iscsi_session_get_param, |
2520 | .start_conn = iscsi_conn_start, | 2416 | .start_conn = iscsi_conn_start, |
2521 | .stop_conn = iscsi_conn_stop, | 2417 | .stop_conn = iscsi_conn_stop, |
diff --git a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c index 82caba464291..1c960ac1617f 100644 --- a/drivers/scsi/libata-core.c +++ b/drivers/scsi/libata-core.c | |||
@@ -1001,7 +1001,7 @@ unsigned ata_exec_internal(struct ata_device *dev, | |||
1001 | struct ata_queued_cmd *qc; | 1001 | struct ata_queued_cmd *qc; |
1002 | unsigned int tag, preempted_tag; | 1002 | unsigned int tag, preempted_tag; |
1003 | u32 preempted_sactive, preempted_qc_active; | 1003 | u32 preempted_sactive, preempted_qc_active; |
1004 | DECLARE_COMPLETION(wait); | 1004 | DECLARE_COMPLETION_ONSTACK(wait); |
1005 | unsigned long flags; | 1005 | unsigned long flags; |
1006 | unsigned int err_mask; | 1006 | unsigned int err_mask; |
1007 | int rc; | 1007 | int rc; |
diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c index 2673a11a9495..7e6e031cc41b 100644 --- a/drivers/scsi/libiscsi.c +++ b/drivers/scsi/libiscsi.c | |||
@@ -1287,13 +1287,18 @@ iscsi_session_setup(struct iscsi_transport *iscsit, | |||
1287 | if (scsi_add_host(shost, NULL)) | 1287 | if (scsi_add_host(shost, NULL)) |
1288 | goto add_host_fail; | 1288 | goto add_host_fail; |
1289 | 1289 | ||
1290 | if (!try_module_get(iscsit->owner)) | ||
1291 | goto cls_session_fail; | ||
1292 | |||
1290 | cls_session = iscsi_create_session(shost, iscsit, 0); | 1293 | cls_session = iscsi_create_session(shost, iscsit, 0); |
1291 | if (!cls_session) | 1294 | if (!cls_session) |
1292 | goto cls_session_fail; | 1295 | goto module_put; |
1293 | *(unsigned long*)shost->hostdata = (unsigned long)cls_session; | 1296 | *(unsigned long*)shost->hostdata = (unsigned long)cls_session; |
1294 | 1297 | ||
1295 | return cls_session; | 1298 | return cls_session; |
1296 | 1299 | ||
1300 | module_put: | ||
1301 | module_put(iscsit->owner); | ||
1297 | cls_session_fail: | 1302 | cls_session_fail: |
1298 | scsi_remove_host(shost); | 1303 | scsi_remove_host(shost); |
1299 | add_host_fail: | 1304 | add_host_fail: |
@@ -1325,6 +1330,7 @@ void iscsi_session_teardown(struct iscsi_cls_session *cls_session) | |||
1325 | 1330 | ||
1326 | iscsi_destroy_session(cls_session); | 1331 | iscsi_destroy_session(cls_session); |
1327 | scsi_host_put(shost); | 1332 | scsi_host_put(shost); |
1333 | module_put(cls_session->transport->owner); | ||
1328 | } | 1334 | } |
1329 | EXPORT_SYMBOL_GPL(iscsi_session_teardown); | 1335 | EXPORT_SYMBOL_GPL(iscsi_session_teardown); |
1330 | 1336 | ||
@@ -1697,6 +1703,185 @@ int iscsi_conn_bind(struct iscsi_cls_session *cls_session, | |||
1697 | } | 1703 | } |
1698 | EXPORT_SYMBOL_GPL(iscsi_conn_bind); | 1704 | EXPORT_SYMBOL_GPL(iscsi_conn_bind); |
1699 | 1705 | ||
1706 | |||
1707 | int iscsi_set_param(struct iscsi_cls_conn *cls_conn, | ||
1708 | enum iscsi_param param, char *buf, int buflen) | ||
1709 | { | ||
1710 | struct iscsi_conn *conn = cls_conn->dd_data; | ||
1711 | struct iscsi_session *session = conn->session; | ||
1712 | uint32_t value; | ||
1713 | |||
1714 | switch(param) { | ||
1715 | case ISCSI_PARAM_MAX_RECV_DLENGTH: | ||
1716 | sscanf(buf, "%d", &conn->max_recv_dlength); | ||
1717 | break; | ||
1718 | case ISCSI_PARAM_MAX_XMIT_DLENGTH: | ||
1719 | sscanf(buf, "%d", &conn->max_xmit_dlength); | ||
1720 | break; | ||
1721 | case ISCSI_PARAM_HDRDGST_EN: | ||
1722 | sscanf(buf, "%d", &conn->hdrdgst_en); | ||
1723 | break; | ||
1724 | case ISCSI_PARAM_DATADGST_EN: | ||
1725 | sscanf(buf, "%d", &conn->datadgst_en); | ||
1726 | break; | ||
1727 | case ISCSI_PARAM_INITIAL_R2T_EN: | ||
1728 | sscanf(buf, "%d", &session->initial_r2t_en); | ||
1729 | break; | ||
1730 | case ISCSI_PARAM_MAX_R2T: | ||
1731 | sscanf(buf, "%d", &session->max_r2t); | ||
1732 | break; | ||
1733 | case ISCSI_PARAM_IMM_DATA_EN: | ||
1734 | sscanf(buf, "%d", &session->imm_data_en); | ||
1735 | break; | ||
1736 | case ISCSI_PARAM_FIRST_BURST: | ||
1737 | sscanf(buf, "%d", &session->first_burst); | ||
1738 | break; | ||
1739 | case ISCSI_PARAM_MAX_BURST: | ||
1740 | sscanf(buf, "%d", &session->max_burst); | ||
1741 | break; | ||
1742 | case ISCSI_PARAM_PDU_INORDER_EN: | ||
1743 | sscanf(buf, "%d", &session->pdu_inorder_en); | ||
1744 | break; | ||
1745 | case ISCSI_PARAM_DATASEQ_INORDER_EN: | ||
1746 | sscanf(buf, "%d", &session->dataseq_inorder_en); | ||
1747 | break; | ||
1748 | case ISCSI_PARAM_ERL: | ||
1749 | sscanf(buf, "%d", &session->erl); | ||
1750 | break; | ||
1751 | case ISCSI_PARAM_IFMARKER_EN: | ||
1752 | sscanf(buf, "%d", &value); | ||
1753 | BUG_ON(value); | ||
1754 | break; | ||
1755 | case ISCSI_PARAM_OFMARKER_EN: | ||
1756 | sscanf(buf, "%d", &value); | ||
1757 | BUG_ON(value); | ||
1758 | break; | ||
1759 | case ISCSI_PARAM_EXP_STATSN: | ||
1760 | sscanf(buf, "%u", &conn->exp_statsn); | ||
1761 | break; | ||
1762 | case ISCSI_PARAM_TARGET_NAME: | ||
1763 | /* this should not change between logins */ | ||
1764 | if (session->targetname) | ||
1765 | break; | ||
1766 | |||
1767 | session->targetname = kstrdup(buf, GFP_KERNEL); | ||
1768 | if (!session->targetname) | ||
1769 | return -ENOMEM; | ||
1770 | break; | ||
1771 | case ISCSI_PARAM_TPGT: | ||
1772 | sscanf(buf, "%d", &session->tpgt); | ||
1773 | break; | ||
1774 | case ISCSI_PARAM_PERSISTENT_PORT: | ||
1775 | sscanf(buf, "%d", &conn->persistent_port); | ||
1776 | break; | ||
1777 | case ISCSI_PARAM_PERSISTENT_ADDRESS: | ||
1778 | /* | ||
1779 | * this is the address returned in discovery so it should | ||
1780 | * not change between logins. | ||
1781 | */ | ||
1782 | if (conn->persistent_address) | ||
1783 | break; | ||
1784 | |||
1785 | conn->persistent_address = kstrdup(buf, GFP_KERNEL); | ||
1786 | if (!conn->persistent_address) | ||
1787 | return -ENOMEM; | ||
1788 | break; | ||
1789 | default: | ||
1790 | return -ENOSYS; | ||
1791 | } | ||
1792 | |||
1793 | return 0; | ||
1794 | } | ||
1795 | EXPORT_SYMBOL_GPL(iscsi_set_param); | ||
1796 | |||
1797 | int iscsi_session_get_param(struct iscsi_cls_session *cls_session, | ||
1798 | enum iscsi_param param, char *buf) | ||
1799 | { | ||
1800 | struct Scsi_Host *shost = iscsi_session_to_shost(cls_session); | ||
1801 | struct iscsi_session *session = iscsi_hostdata(shost->hostdata); | ||
1802 | int len; | ||
1803 | |||
1804 | switch(param) { | ||
1805 | case ISCSI_PARAM_INITIAL_R2T_EN: | ||
1806 | len = sprintf(buf, "%d\n", session->initial_r2t_en); | ||
1807 | break; | ||
1808 | case ISCSI_PARAM_MAX_R2T: | ||
1809 | len = sprintf(buf, "%hu\n", session->max_r2t); | ||
1810 | break; | ||
1811 | case ISCSI_PARAM_IMM_DATA_EN: | ||
1812 | len = sprintf(buf, "%d\n", session->imm_data_en); | ||
1813 | break; | ||
1814 | case ISCSI_PARAM_FIRST_BURST: | ||
1815 | len = sprintf(buf, "%u\n", session->first_burst); | ||
1816 | break; | ||
1817 | case ISCSI_PARAM_MAX_BURST: | ||
1818 | len = sprintf(buf, "%u\n", session->max_burst); | ||
1819 | break; | ||
1820 | case ISCSI_PARAM_PDU_INORDER_EN: | ||
1821 | len = sprintf(buf, "%d\n", session->pdu_inorder_en); | ||
1822 | break; | ||
1823 | case ISCSI_PARAM_DATASEQ_INORDER_EN: | ||
1824 | len = sprintf(buf, "%d\n", session->dataseq_inorder_en); | ||
1825 | break; | ||
1826 | case ISCSI_PARAM_ERL: | ||
1827 | len = sprintf(buf, "%d\n", session->erl); | ||
1828 | break; | ||
1829 | case ISCSI_PARAM_TARGET_NAME: | ||
1830 | len = sprintf(buf, "%s\n", session->targetname); | ||
1831 | break; | ||
1832 | case ISCSI_PARAM_TPGT: | ||
1833 | len = sprintf(buf, "%d\n", session->tpgt); | ||
1834 | break; | ||
1835 | default: | ||
1836 | return -ENOSYS; | ||
1837 | } | ||
1838 | |||
1839 | return len; | ||
1840 | } | ||
1841 | EXPORT_SYMBOL_GPL(iscsi_session_get_param); | ||
1842 | |||
1843 | int iscsi_conn_get_param(struct iscsi_cls_conn *cls_conn, | ||
1844 | enum iscsi_param param, char *buf) | ||
1845 | { | ||
1846 | struct iscsi_conn *conn = cls_conn->dd_data; | ||
1847 | int len; | ||
1848 | |||
1849 | switch(param) { | ||
1850 | case ISCSI_PARAM_MAX_RECV_DLENGTH: | ||
1851 | len = sprintf(buf, "%u\n", conn->max_recv_dlength); | ||
1852 | break; | ||
1853 | case ISCSI_PARAM_MAX_XMIT_DLENGTH: | ||
1854 | len = sprintf(buf, "%u\n", conn->max_xmit_dlength); | ||
1855 | break; | ||
1856 | case ISCSI_PARAM_HDRDGST_EN: | ||
1857 | len = sprintf(buf, "%d\n", conn->hdrdgst_en); | ||
1858 | break; | ||
1859 | case ISCSI_PARAM_DATADGST_EN: | ||
1860 | len = sprintf(buf, "%d\n", conn->datadgst_en); | ||
1861 | break; | ||
1862 | case ISCSI_PARAM_IFMARKER_EN: | ||
1863 | len = sprintf(buf, "%d\n", conn->ifmarker_en); | ||
1864 | break; | ||
1865 | case ISCSI_PARAM_OFMARKER_EN: | ||
1866 | len = sprintf(buf, "%d\n", conn->ofmarker_en); | ||
1867 | break; | ||
1868 | case ISCSI_PARAM_EXP_STATSN: | ||
1869 | len = sprintf(buf, "%u\n", conn->exp_statsn); | ||
1870 | break; | ||
1871 | case ISCSI_PARAM_PERSISTENT_PORT: | ||
1872 | len = sprintf(buf, "%d\n", conn->persistent_port); | ||
1873 | break; | ||
1874 | case ISCSI_PARAM_PERSISTENT_ADDRESS: | ||
1875 | len = sprintf(buf, "%s\n", conn->persistent_address); | ||
1876 | break; | ||
1877 | default: | ||
1878 | return -ENOSYS; | ||
1879 | } | ||
1880 | |||
1881 | return len; | ||
1882 | } | ||
1883 | EXPORT_SYMBOL_GPL(iscsi_conn_get_param); | ||
1884 | |||
1700 | MODULE_AUTHOR("Mike Christie"); | 1885 | MODULE_AUTHOR("Mike Christie"); |
1701 | MODULE_DESCRIPTION("iSCSI library functions"); | 1886 | MODULE_DESCRIPTION("iSCSI library functions"); |
1702 | MODULE_LICENSE("GPL"); | 1887 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/scsi/lpfc/lpfc.h b/drivers/scsi/lpfc/lpfc.h index 087c44539a16..f81691fcf177 100644 --- a/drivers/scsi/lpfc/lpfc.h +++ b/drivers/scsi/lpfc/lpfc.h | |||
@@ -174,7 +174,6 @@ struct lpfc_hba { | |||
174 | dma_addr_t slim2p_mapping; | 174 | dma_addr_t slim2p_mapping; |
175 | uint16_t pci_cfg_value; | 175 | uint16_t pci_cfg_value; |
176 | 176 | ||
177 | struct semaphore hba_can_block; | ||
178 | int32_t hba_state; | 177 | int32_t hba_state; |
179 | 178 | ||
180 | #define LPFC_STATE_UNKNOWN 0 /* HBA state is unknown */ | 179 | #define LPFC_STATE_UNKNOWN 0 /* HBA state is unknown */ |
diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c index 283b7d824c34..4126fd87956f 100644 --- a/drivers/scsi/lpfc/lpfc_els.c +++ b/drivers/scsi/lpfc/lpfc_els.c | |||
@@ -821,7 +821,7 @@ lpfc_issue_els_plogi(struct lpfc_hba * phba, uint32_t did, uint8_t retry) | |||
821 | pring = &psli->ring[LPFC_ELS_RING]; /* ELS ring */ | 821 | pring = &psli->ring[LPFC_ELS_RING]; /* ELS ring */ |
822 | 822 | ||
823 | cmdsize = (sizeof (uint32_t) + sizeof (struct serv_parm)); | 823 | cmdsize = (sizeof (uint32_t) + sizeof (struct serv_parm)); |
824 | elsiocb = lpfc_prep_els_iocb(phba, 1, cmdsize, retry, 0, did, | 824 | elsiocb = lpfc_prep_els_iocb(phba, 1, cmdsize, retry, NULL, did, |
825 | ELS_CMD_PLOGI); | 825 | ELS_CMD_PLOGI); |
826 | if (!elsiocb) | 826 | if (!elsiocb) |
827 | return 1; | 827 | return 1; |
@@ -2791,8 +2791,8 @@ lpfc_els_rsp_rps_acc(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) | |||
2791 | 2791 | ||
2792 | ndlp = (struct lpfc_nodelist *) pmb->context2; | 2792 | ndlp = (struct lpfc_nodelist *) pmb->context2; |
2793 | xri = (uint16_t) ((unsigned long)(pmb->context1)); | 2793 | xri = (uint16_t) ((unsigned long)(pmb->context1)); |
2794 | pmb->context1 = 0; | 2794 | pmb->context1 = NULL; |
2795 | pmb->context2 = 0; | 2795 | pmb->context2 = NULL; |
2796 | 2796 | ||
2797 | if (mb->mbxStatus) { | 2797 | if (mb->mbxStatus) { |
2798 | mempool_free( pmb, phba->mbox_mem_pool); | 2798 | mempool_free( pmb, phba->mbox_mem_pool); |
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index 5a28d9bf8e4d..81755a3f7c68 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c | |||
@@ -939,12 +939,12 @@ lpfc_get_hba_model_desc(struct lpfc_hba * phba, uint8_t * mdp, uint8_t * descp) | |||
939 | "10-port ", "PCIe"}; | 939 | "10-port ", "PCIe"}; |
940 | break; | 940 | break; |
941 | default: | 941 | default: |
942 | m = (typeof(m)){ 0 }; | 942 | m = (typeof(m)){ NULL }; |
943 | break; | 943 | break; |
944 | } | 944 | } |
945 | break; | 945 | break; |
946 | default: | 946 | default: |
947 | m = (typeof(m)){ 0 }; | 947 | m = (typeof(m)){ NULL }; |
948 | break; | 948 | break; |
949 | } | 949 | } |
950 | 950 | ||
@@ -1451,7 +1451,6 @@ lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid) | |||
1451 | goto out_put_host; | 1451 | goto out_put_host; |
1452 | 1452 | ||
1453 | host->unique_id = phba->brd_no; | 1453 | host->unique_id = phba->brd_no; |
1454 | init_MUTEX(&phba->hba_can_block); | ||
1455 | INIT_LIST_HEAD(&phba->ctrspbuflist); | 1454 | INIT_LIST_HEAD(&phba->ctrspbuflist); |
1456 | INIT_LIST_HEAD(&phba->rnidrspbuflist); | 1455 | INIT_LIST_HEAD(&phba->rnidrspbuflist); |
1457 | INIT_LIST_HEAD(&phba->freebufList); | 1456 | INIT_LIST_HEAD(&phba->freebufList); |
diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c index 7dc4c2e6bed2..aea1ee472f3d 100644 --- a/drivers/scsi/lpfc/lpfc_scsi.c +++ b/drivers/scsi/lpfc/lpfc_scsi.c | |||
@@ -41,20 +41,6 @@ | |||
41 | #define LPFC_ABORT_WAIT 2 | 41 | #define LPFC_ABORT_WAIT 2 |
42 | 42 | ||
43 | 43 | ||
44 | static inline void | ||
45 | lpfc_block_requests(struct lpfc_hba * phba) | ||
46 | { | ||
47 | down(&phba->hba_can_block); | ||
48 | scsi_block_requests(phba->host); | ||
49 | } | ||
50 | |||
51 | static inline void | ||
52 | lpfc_unblock_requests(struct lpfc_hba * phba) | ||
53 | { | ||
54 | scsi_unblock_requests(phba->host); | ||
55 | up(&phba->hba_can_block); | ||
56 | } | ||
57 | |||
58 | /* | 44 | /* |
59 | * This routine allocates a scsi buffer, which contains all the necessary | 45 | * This routine allocates a scsi buffer, which contains all the necessary |
60 | * information needed to initiate a SCSI I/O. The non-DMAable buffer region | 46 | * information needed to initiate a SCSI I/O. The non-DMAable buffer region |
@@ -859,7 +845,6 @@ lpfc_abort_handler(struct scsi_cmnd *cmnd) | |||
859 | unsigned int loop_count = 0; | 845 | unsigned int loop_count = 0; |
860 | int ret = SUCCESS; | 846 | int ret = SUCCESS; |
861 | 847 | ||
862 | lpfc_block_requests(phba); | ||
863 | spin_lock_irq(shost->host_lock); | 848 | spin_lock_irq(shost->host_lock); |
864 | 849 | ||
865 | lpfc_cmd = (struct lpfc_scsi_buf *)cmnd->host_scribble; | 850 | lpfc_cmd = (struct lpfc_scsi_buf *)cmnd->host_scribble; |
@@ -945,7 +930,6 @@ lpfc_abort_handler(struct scsi_cmnd *cmnd) | |||
945 | cmnd->device->lun, cmnd->serial_number); | 930 | cmnd->device->lun, cmnd->serial_number); |
946 | 931 | ||
947 | spin_unlock_irq(shost->host_lock); | 932 | spin_unlock_irq(shost->host_lock); |
948 | lpfc_unblock_requests(phba); | ||
949 | 933 | ||
950 | return ret; | 934 | return ret; |
951 | } | 935 | } |
@@ -963,7 +947,6 @@ lpfc_reset_lun_handler(struct scsi_cmnd *cmnd) | |||
963 | int ret = FAILED; | 947 | int ret = FAILED; |
964 | int cnt, loopcnt; | 948 | int cnt, loopcnt; |
965 | 949 | ||
966 | lpfc_block_requests(phba); | ||
967 | spin_lock_irq(shost->host_lock); | 950 | spin_lock_irq(shost->host_lock); |
968 | /* | 951 | /* |
969 | * If target is not in a MAPPED state, delay the reset until | 952 | * If target is not in a MAPPED state, delay the reset until |
@@ -1065,7 +1048,6 @@ out_free_scsi_buf: | |||
1065 | 1048 | ||
1066 | out: | 1049 | out: |
1067 | spin_unlock_irq(shost->host_lock); | 1050 | spin_unlock_irq(shost->host_lock); |
1068 | lpfc_unblock_requests(phba); | ||
1069 | return ret; | 1051 | return ret; |
1070 | } | 1052 | } |
1071 | 1053 | ||
@@ -1080,7 +1062,6 @@ lpfc_reset_bus_handler(struct scsi_cmnd *cmnd) | |||
1080 | int cnt, loopcnt; | 1062 | int cnt, loopcnt; |
1081 | struct lpfc_scsi_buf * lpfc_cmd; | 1063 | struct lpfc_scsi_buf * lpfc_cmd; |
1082 | 1064 | ||
1083 | lpfc_block_requests(phba); | ||
1084 | spin_lock_irq(shost->host_lock); | 1065 | spin_lock_irq(shost->host_lock); |
1085 | 1066 | ||
1086 | lpfc_cmd = lpfc_get_scsi_buf(phba); | 1067 | lpfc_cmd = lpfc_get_scsi_buf(phba); |
@@ -1163,7 +1144,6 @@ lpfc_reset_bus_handler(struct scsi_cmnd *cmnd) | |||
1163 | phba->brd_no, ret); | 1144 | phba->brd_no, ret); |
1164 | out: | 1145 | out: |
1165 | spin_unlock_irq(shost->host_lock); | 1146 | spin_unlock_irq(shost->host_lock); |
1166 | lpfc_unblock_requests(phba); | ||
1167 | return ret; | 1147 | return ret; |
1168 | } | 1148 | } |
1169 | 1149 | ||
diff --git a/drivers/scsi/megaraid/megaraid_sas.c b/drivers/scsi/megaraid/megaraid_sas.c index e5c017ccda59..a8c9627a15c4 100644 --- a/drivers/scsi/megaraid/megaraid_sas.c +++ b/drivers/scsi/megaraid/megaraid_sas.c | |||
@@ -10,7 +10,7 @@ | |||
10 | * 2 of the License, or (at your option) any later version. | 10 | * 2 of the License, or (at your option) any later version. |
11 | * | 11 | * |
12 | * FILE : megaraid_sas.c | 12 | * FILE : megaraid_sas.c |
13 | * Version : v00.00.02.04 | 13 | * Version : v00.00.03.01 |
14 | * | 14 | * |
15 | * Authors: | 15 | * Authors: |
16 | * Sreenivas Bagalkote <Sreenivas.Bagalkote@lsil.com> | 16 | * Sreenivas Bagalkote <Sreenivas.Bagalkote@lsil.com> |
@@ -55,19 +55,25 @@ static struct pci_device_id megasas_pci_table[] = { | |||
55 | 55 | ||
56 | { | 56 | { |
57 | PCI_VENDOR_ID_LSI_LOGIC, | 57 | PCI_VENDOR_ID_LSI_LOGIC, |
58 | PCI_DEVICE_ID_LSI_SAS1064R, // xscale IOP | 58 | PCI_DEVICE_ID_LSI_SAS1064R, /* xscale IOP */ |
59 | PCI_ANY_ID, | 59 | PCI_ANY_ID, |
60 | PCI_ANY_ID, | 60 | PCI_ANY_ID, |
61 | }, | 61 | }, |
62 | { | 62 | { |
63 | PCI_VENDOR_ID_LSI_LOGIC, | 63 | PCI_VENDOR_ID_LSI_LOGIC, |
64 | PCI_DEVICE_ID_LSI_SAS1078R, // ppc IOP | 64 | PCI_DEVICE_ID_LSI_SAS1078R, /* ppc IOP */ |
65 | PCI_ANY_ID, | 65 | PCI_ANY_ID, |
66 | PCI_ANY_ID, | 66 | PCI_ANY_ID, |
67 | }, | 67 | }, |
68 | { | 68 | { |
69 | PCI_VENDOR_ID_LSI_LOGIC, | ||
70 | PCI_DEVICE_ID_LSI_VERDE_ZCR, /* xscale IOP, vega */ | ||
71 | PCI_ANY_ID, | ||
72 | PCI_ANY_ID, | ||
73 | }, | ||
74 | { | ||
69 | PCI_VENDOR_ID_DELL, | 75 | PCI_VENDOR_ID_DELL, |
70 | PCI_DEVICE_ID_DELL_PERC5, // xscale IOP | 76 | PCI_DEVICE_ID_DELL_PERC5, /* xscale IOP */ |
71 | PCI_ANY_ID, | 77 | PCI_ANY_ID, |
72 | PCI_ANY_ID, | 78 | PCI_ANY_ID, |
73 | }, | 79 | }, |
@@ -289,9 +295,14 @@ static struct megasas_instance_template megasas_instance_template_ppc = { | |||
289 | * @regs: MFI register set | 295 | * @regs: MFI register set |
290 | */ | 296 | */ |
291 | static inline void | 297 | static inline void |
292 | megasas_disable_intr(struct megasas_register_set __iomem * regs) | 298 | megasas_disable_intr(struct megasas_instance *instance) |
293 | { | 299 | { |
294 | u32 mask = 0x1f; | 300 | u32 mask = 0x1f; |
301 | struct megasas_register_set __iomem *regs = instance->reg_set; | ||
302 | |||
303 | if(instance->pdev->device == PCI_DEVICE_ID_LSI_SAS1078R) | ||
304 | mask = 0xffffffff; | ||
305 | |||
295 | writel(mask, ®s->outbound_intr_mask); | 306 | writel(mask, ®s->outbound_intr_mask); |
296 | 307 | ||
297 | /* Dummy readl to force pci flush */ | 308 | /* Dummy readl to force pci flush */ |
@@ -1260,7 +1271,7 @@ megasas_transition_to_ready(struct megasas_instance* instance) | |||
1260 | /* | 1271 | /* |
1261 | * Bring it to READY state; assuming max wait 2 secs | 1272 | * Bring it to READY state; assuming max wait 2 secs |
1262 | */ | 1273 | */ |
1263 | megasas_disable_intr(instance->reg_set); | 1274 | megasas_disable_intr(instance); |
1264 | writel(MFI_INIT_READY, &instance->reg_set->inbound_doorbell); | 1275 | writel(MFI_INIT_READY, &instance->reg_set->inbound_doorbell); |
1265 | 1276 | ||
1266 | max_wait = 10; | 1277 | max_wait = 10; |
@@ -1757,6 +1768,11 @@ static int megasas_init_mfi(struct megasas_instance *instance) | |||
1757 | init_frame->data_xfer_len = sizeof(struct megasas_init_queue_info); | 1768 | init_frame->data_xfer_len = sizeof(struct megasas_init_queue_info); |
1758 | 1769 | ||
1759 | /* | 1770 | /* |
1771 | * disable the intr before firing the init frame to FW | ||
1772 | */ | ||
1773 | megasas_disable_intr(instance); | ||
1774 | |||
1775 | /* | ||
1760 | * Issue the init frame in polled mode | 1776 | * Issue the init frame in polled mode |
1761 | */ | 1777 | */ |
1762 | if (megasas_issue_polled(instance, cmd)) { | 1778 | if (megasas_issue_polled(instance, cmd)) { |
@@ -2234,7 +2250,7 @@ megasas_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) | |||
2234 | megasas_mgmt_info.max_index--; | 2250 | megasas_mgmt_info.max_index--; |
2235 | 2251 | ||
2236 | pci_set_drvdata(pdev, NULL); | 2252 | pci_set_drvdata(pdev, NULL); |
2237 | megasas_disable_intr(instance->reg_set); | 2253 | megasas_disable_intr(instance); |
2238 | free_irq(instance->pdev->irq, instance); | 2254 | free_irq(instance->pdev->irq, instance); |
2239 | 2255 | ||
2240 | megasas_release_mfi(instance); | 2256 | megasas_release_mfi(instance); |
@@ -2364,7 +2380,7 @@ static void megasas_detach_one(struct pci_dev *pdev) | |||
2364 | 2380 | ||
2365 | pci_set_drvdata(instance->pdev, NULL); | 2381 | pci_set_drvdata(instance->pdev, NULL); |
2366 | 2382 | ||
2367 | megasas_disable_intr(instance->reg_set); | 2383 | megasas_disable_intr(instance); |
2368 | 2384 | ||
2369 | free_irq(instance->pdev->irq, instance); | 2385 | free_irq(instance->pdev->irq, instance); |
2370 | 2386 | ||
diff --git a/drivers/scsi/megaraid/megaraid_sas.h b/drivers/scsi/megaraid/megaraid_sas.h index 927d6ffef05f..3531a14222a7 100644 --- a/drivers/scsi/megaraid/megaraid_sas.h +++ b/drivers/scsi/megaraid/megaraid_sas.h | |||
@@ -18,9 +18,16 @@ | |||
18 | /** | 18 | /** |
19 | * MegaRAID SAS Driver meta data | 19 | * MegaRAID SAS Driver meta data |
20 | */ | 20 | */ |
21 | #define MEGASAS_VERSION "00.00.02.04" | 21 | #define MEGASAS_VERSION "00.00.03.01" |
22 | #define MEGASAS_RELDATE "Feb 03, 2006" | 22 | #define MEGASAS_RELDATE "May 14, 2006" |
23 | #define MEGASAS_EXT_VERSION "Fri Feb 03 14:31:44 PST 2006" | 23 | #define MEGASAS_EXT_VERSION "Sun May 14 22:49:52 PDT 2006" |
24 | |||
25 | /* | ||
26 | * Device IDs | ||
27 | */ | ||
28 | #define PCI_DEVICE_ID_LSI_SAS1078R 0x0060 | ||
29 | #define PCI_DEVICE_ID_LSI_VERDE_ZCR 0x0413 | ||
30 | |||
24 | /* | 31 | /* |
25 | * ===================================== | 32 | * ===================================== |
26 | * MegaRAID SAS MFI firmware definitions | 33 | * MegaRAID SAS MFI firmware definitions |
@@ -554,7 +561,11 @@ struct megasas_ctrl_info { | |||
554 | #define MFI_POLL_TIMEOUT_SECS 10 | 561 | #define MFI_POLL_TIMEOUT_SECS 10 |
555 | 562 | ||
556 | #define MFI_REPLY_1078_MESSAGE_INTERRUPT 0x80000000 | 563 | #define MFI_REPLY_1078_MESSAGE_INTERRUPT 0x80000000 |
557 | #define PCI_DEVICE_ID_LSI_SAS1078R 0x00000060 | 564 | |
565 | /* | ||
566 | * register set for both 1068 and 1078 controllers | ||
567 | * structure extended for 1078 registers | ||
568 | */ | ||
558 | 569 | ||
559 | struct megasas_register_set { | 570 | struct megasas_register_set { |
560 | u32 reserved_0[4]; /*0000h*/ | 571 | u32 reserved_0[4]; /*0000h*/ |
@@ -1150,10 +1161,10 @@ struct compat_megasas_iocpacket { | |||
1150 | struct compat_iovec sgl[MAX_IOCTL_SGE]; | 1161 | struct compat_iovec sgl[MAX_IOCTL_SGE]; |
1151 | } __attribute__ ((packed)); | 1162 | } __attribute__ ((packed)); |
1152 | 1163 | ||
1164 | #define MEGASAS_IOC_FIRMWARE32 _IOWR('M', 1, struct compat_megasas_iocpacket) | ||
1153 | #endif | 1165 | #endif |
1154 | 1166 | ||
1155 | #define MEGASAS_IOC_FIRMWARE _IOWR('M', 1, struct megasas_iocpacket) | 1167 | #define MEGASAS_IOC_FIRMWARE _IOWR('M', 1, struct megasas_iocpacket) |
1156 | #define MEGASAS_IOC_FIRMWARE32 _IOWR('M', 1, struct compat_megasas_iocpacket) | ||
1157 | #define MEGASAS_IOC_GET_AEN _IOW('M', 3, struct megasas_aen) | 1168 | #define MEGASAS_IOC_GET_AEN _IOW('M', 3, struct megasas_aen) |
1158 | 1169 | ||
1159 | struct megasas_mgmt_info { | 1170 | struct megasas_mgmt_info { |
diff --git a/drivers/scsi/nsp32.c b/drivers/scsi/nsp32.c index bd337a914298..bfb4f49e125d 100644 --- a/drivers/scsi/nsp32.c +++ b/drivers/scsi/nsp32.c | |||
@@ -2866,8 +2866,7 @@ static int nsp32_detect(struct scsi_host_template *sht) | |||
2866 | */ | 2866 | */ |
2867 | nsp32_do_bus_reset(data); | 2867 | nsp32_do_bus_reset(data); |
2868 | 2868 | ||
2869 | ret = request_irq(host->irq, do_nsp32_isr, | 2869 | ret = request_irq(host->irq, do_nsp32_isr, IRQF_SHARED, "nsp32", data); |
2870 | IRQF_SHARED | IRQF_SAMPLE_RANDOM, "nsp32", data); | ||
2871 | if (ret < 0) { | 2870 | if (ret < 0) { |
2872 | nsp32_msg(KERN_ERR, "Unable to allocate IRQ for NinjaSCSI32 " | 2871 | nsp32_msg(KERN_ERR, "Unable to allocate IRQ for NinjaSCSI32 " |
2873 | "SCSI PCI controller. Interrupt: %d", host->irq); | 2872 | "SCSI PCI controller. Interrupt: %d", host->irq); |
@@ -2886,12 +2885,19 @@ static int nsp32_detect(struct scsi_host_template *sht) | |||
2886 | } | 2885 | } |
2887 | 2886 | ||
2888 | #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,73)) | 2887 | #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,73)) |
2889 | scsi_add_host (host, &PCIDEV->dev); | 2888 | ret = scsi_add_host(host, &PCIDEV->dev); |
2889 | if (ret) { | ||
2890 | nsp32_msg(KERN_ERR, "failed to add scsi host"); | ||
2891 | goto free_region; | ||
2892 | } | ||
2890 | scsi_scan_host(host); | 2893 | scsi_scan_host(host); |
2891 | #endif | 2894 | #endif |
2892 | pci_set_drvdata(PCIDEV, host); | 2895 | pci_set_drvdata(PCIDEV, host); |
2893 | return DETECT_OK; | 2896 | return DETECT_OK; |
2894 | 2897 | ||
2898 | free_region: | ||
2899 | release_region(host->io_port, host->n_io_port); | ||
2900 | |||
2895 | free_irq: | 2901 | free_irq: |
2896 | free_irq(host->irq, data); | 2902 | free_irq(host->irq, data); |
2897 | 2903 | ||
diff --git a/drivers/scsi/pcmcia/nsp_cs.c b/drivers/scsi/pcmcia/nsp_cs.c index 7ff5851c040b..0d4c04e1f3de 100644 --- a/drivers/scsi/pcmcia/nsp_cs.c +++ b/drivers/scsi/pcmcia/nsp_cs.c | |||
@@ -1623,7 +1623,7 @@ static int nsp_cs_probe(struct pcmcia_device *link) | |||
1623 | /* Interrupt handler */ | 1623 | /* Interrupt handler */ |
1624 | link->irq.Handler = &nspintr; | 1624 | link->irq.Handler = &nspintr; |
1625 | link->irq.Instance = info; | 1625 | link->irq.Instance = info; |
1626 | link->irq.Attributes |= (IRQF_SHARED | IRQF_SAMPLE_RANDOM); | 1626 | link->irq.Attributes |= IRQF_SHARED; |
1627 | 1627 | ||
1628 | /* General socket configuration */ | 1628 | /* General socket configuration */ |
1629 | link->conf.Attributes = CONF_ENABLE_IRQ; | 1629 | link->conf.Attributes = CONF_ENABLE_IRQ; |
diff --git a/drivers/scsi/qla1280.c b/drivers/scsi/qla1280.c index b818b9bfe678..8953991462d7 100644 --- a/drivers/scsi/qla1280.c +++ b/drivers/scsi/qla1280.c | |||
@@ -4209,7 +4209,7 @@ qla1280_setup(char *s) | |||
4209 | } | 4209 | } |
4210 | 4210 | ||
4211 | 4211 | ||
4212 | static int | 4212 | static int __init |
4213 | qla1280_get_token(char *str) | 4213 | qla1280_get_token(char *str) |
4214 | { | 4214 | { |
4215 | char *sep; | 4215 | char *sep; |
diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c index e96d58ded57c..87f90c4f08e9 100644 --- a/drivers/scsi/qla2xxx/qla_attr.c +++ b/drivers/scsi/qla2xxx/qla_attr.c | |||
@@ -16,15 +16,16 @@ qla2x00_sysfs_read_fw_dump(struct kobject *kobj, char *buf, loff_t off, | |||
16 | { | 16 | { |
17 | struct scsi_qla_host *ha = to_qla_host(dev_to_shost(container_of(kobj, | 17 | struct scsi_qla_host *ha = to_qla_host(dev_to_shost(container_of(kobj, |
18 | struct device, kobj))); | 18 | struct device, kobj))); |
19 | char *rbuf = (char *)ha->fw_dump; | ||
19 | 20 | ||
20 | if (ha->fw_dump_reading == 0) | 21 | if (ha->fw_dump_reading == 0) |
21 | return 0; | 22 | return 0; |
22 | if (off > ha->fw_dump_buffer_len) | 23 | if (off > ha->fw_dump_len) |
23 | return 0; | 24 | return 0; |
24 | if (off + count > ha->fw_dump_buffer_len) | 25 | if (off + count > ha->fw_dump_len) |
25 | count = ha->fw_dump_buffer_len - off; | 26 | count = ha->fw_dump_len - off; |
26 | 27 | ||
27 | memcpy(buf, &ha->fw_dump_buffer[off], count); | 28 | memcpy(buf, &rbuf[off], count); |
28 | 29 | ||
29 | return (count); | 30 | return (count); |
30 | } | 31 | } |
@@ -36,7 +37,6 @@ qla2x00_sysfs_write_fw_dump(struct kobject *kobj, char *buf, loff_t off, | |||
36 | struct scsi_qla_host *ha = to_qla_host(dev_to_shost(container_of(kobj, | 37 | struct scsi_qla_host *ha = to_qla_host(dev_to_shost(container_of(kobj, |
37 | struct device, kobj))); | 38 | struct device, kobj))); |
38 | int reading; | 39 | int reading; |
39 | uint32_t dump_size; | ||
40 | 40 | ||
41 | if (off != 0) | 41 | if (off != 0) |
42 | return (0); | 42 | return (0); |
@@ -44,46 +44,27 @@ qla2x00_sysfs_write_fw_dump(struct kobject *kobj, char *buf, loff_t off, | |||
44 | reading = simple_strtol(buf, NULL, 10); | 44 | reading = simple_strtol(buf, NULL, 10); |
45 | switch (reading) { | 45 | switch (reading) { |
46 | case 0: | 46 | case 0: |
47 | if (ha->fw_dump_reading == 1) { | 47 | if (!ha->fw_dump_reading) |
48 | qla_printk(KERN_INFO, ha, | 48 | break; |
49 | "Firmware dump cleared on (%ld).\n", ha->host_no); | ||
50 | 49 | ||
51 | vfree(ha->fw_dump_buffer); | 50 | qla_printk(KERN_INFO, ha, |
52 | ha->fw_dump_buffer = NULL; | 51 | "Firmware dump cleared on (%ld).\n", ha->host_no); |
53 | ha->fw_dump_reading = 0; | 52 | |
54 | ha->fw_dumped = 0; | 53 | ha->fw_dump_reading = 0; |
55 | } | 54 | ha->fw_dumped = 0; |
56 | break; | 55 | break; |
57 | case 1: | 56 | case 1: |
58 | if (ha->fw_dumped && !ha->fw_dump_reading) { | 57 | if (ha->fw_dumped && !ha->fw_dump_reading) { |
59 | ha->fw_dump_reading = 1; | 58 | ha->fw_dump_reading = 1; |
60 | 59 | ||
61 | if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) | ||
62 | dump_size = FW_DUMP_SIZE_24XX; | ||
63 | else { | ||
64 | dump_size = FW_DUMP_SIZE_1M; | ||
65 | if (ha->fw_memory_size < 0x20000) | ||
66 | dump_size = FW_DUMP_SIZE_128K; | ||
67 | else if (ha->fw_memory_size < 0x80000) | ||
68 | dump_size = FW_DUMP_SIZE_512K; | ||
69 | } | ||
70 | ha->fw_dump_buffer = (char *)vmalloc(dump_size); | ||
71 | if (ha->fw_dump_buffer == NULL) { | ||
72 | qla_printk(KERN_WARNING, ha, | ||
73 | "Unable to allocate memory for firmware " | ||
74 | "dump buffer (%d).\n", dump_size); | ||
75 | |||
76 | ha->fw_dump_reading = 0; | ||
77 | return (count); | ||
78 | } | ||
79 | qla_printk(KERN_INFO, ha, | 60 | qla_printk(KERN_INFO, ha, |
80 | "Firmware dump ready for read on (%ld).\n", | 61 | "Raw firmware dump ready for read on (%ld).\n", |
81 | ha->host_no); | 62 | ha->host_no); |
82 | memset(ha->fw_dump_buffer, 0, dump_size); | ||
83 | ha->isp_ops.ascii_fw_dump(ha); | ||
84 | ha->fw_dump_buffer_len = strlen(ha->fw_dump_buffer); | ||
85 | } | 63 | } |
86 | break; | 64 | break; |
65 | case 2: | ||
66 | qla2x00_alloc_fw_dump(ha); | ||
67 | break; | ||
87 | } | 68 | } |
88 | return (count); | 69 | return (count); |
89 | } | 70 | } |
@@ -313,9 +294,6 @@ qla2x00_sysfs_read_vpd(struct kobject *kobj, char *buf, loff_t off, | |||
313 | if (!capable(CAP_SYS_ADMIN) || off != 0) | 294 | if (!capable(CAP_SYS_ADMIN) || off != 0) |
314 | return 0; | 295 | return 0; |
315 | 296 | ||
316 | if (!IS_QLA24XX(ha) && !IS_QLA54XX(ha)) | ||
317 | return -ENOTSUPP; | ||
318 | |||
319 | /* Read NVRAM. */ | 297 | /* Read NVRAM. */ |
320 | spin_lock_irqsave(&ha->hardware_lock, flags); | 298 | spin_lock_irqsave(&ha->hardware_lock, flags); |
321 | ha->isp_ops.read_nvram(ha, (uint8_t *)buf, ha->vpd_base, ha->vpd_size); | 299 | ha->isp_ops.read_nvram(ha, (uint8_t *)buf, ha->vpd_base, ha->vpd_size); |
@@ -335,9 +313,6 @@ qla2x00_sysfs_write_vpd(struct kobject *kobj, char *buf, loff_t off, | |||
335 | if (!capable(CAP_SYS_ADMIN) || off != 0 || count != ha->vpd_size) | 313 | if (!capable(CAP_SYS_ADMIN) || off != 0 || count != ha->vpd_size) |
336 | return 0; | 314 | return 0; |
337 | 315 | ||
338 | if (!IS_QLA24XX(ha) && !IS_QLA54XX(ha)) | ||
339 | return -ENOTSUPP; | ||
340 | |||
341 | /* Write NVRAM. */ | 316 | /* Write NVRAM. */ |
342 | spin_lock_irqsave(&ha->hardware_lock, flags); | 317 | spin_lock_irqsave(&ha->hardware_lock, flags); |
343 | ha->isp_ops.write_nvram(ha, (uint8_t *)buf, ha->vpd_base, count); | 318 | ha->isp_ops.write_nvram(ha, (uint8_t *)buf, ha->vpd_base, count); |
@@ -357,6 +332,53 @@ static struct bin_attribute sysfs_vpd_attr = { | |||
357 | .write = qla2x00_sysfs_write_vpd, | 332 | .write = qla2x00_sysfs_write_vpd, |
358 | }; | 333 | }; |
359 | 334 | ||
335 | static ssize_t | ||
336 | qla2x00_sysfs_read_sfp(struct kobject *kobj, char *buf, loff_t off, | ||
337 | size_t count) | ||
338 | { | ||
339 | struct scsi_qla_host *ha = to_qla_host(dev_to_shost(container_of(kobj, | ||
340 | struct device, kobj))); | ||
341 | uint16_t iter, addr, offset; | ||
342 | int rval; | ||
343 | |||
344 | if (!capable(CAP_SYS_ADMIN) || off != 0 || count != SFP_DEV_SIZE * 2) | ||
345 | return 0; | ||
346 | |||
347 | addr = 0xa0; | ||
348 | for (iter = 0, offset = 0; iter < (SFP_DEV_SIZE * 2) / SFP_BLOCK_SIZE; | ||
349 | iter++, offset += SFP_BLOCK_SIZE) { | ||
350 | if (iter == 4) { | ||
351 | /* Skip to next device address. */ | ||
352 | addr = 0xa2; | ||
353 | offset = 0; | ||
354 | } | ||
355 | |||
356 | rval = qla2x00_read_sfp(ha, ha->sfp_data_dma, addr, offset, | ||
357 | SFP_BLOCK_SIZE); | ||
358 | if (rval != QLA_SUCCESS) { | ||
359 | qla_printk(KERN_WARNING, ha, | ||
360 | "Unable to read SFP data (%x/%x/%x).\n", rval, | ||
361 | addr, offset); | ||
362 | count = 0; | ||
363 | break; | ||
364 | } | ||
365 | memcpy(buf, ha->sfp_data, SFP_BLOCK_SIZE); | ||
366 | buf += SFP_BLOCK_SIZE; | ||
367 | } | ||
368 | |||
369 | return count; | ||
370 | } | ||
371 | |||
372 | static struct bin_attribute sysfs_sfp_attr = { | ||
373 | .attr = { | ||
374 | .name = "sfp", | ||
375 | .mode = S_IRUSR | S_IWUSR, | ||
376 | .owner = THIS_MODULE, | ||
377 | }, | ||
378 | .size = SFP_DEV_SIZE * 2, | ||
379 | .read = qla2x00_sysfs_read_sfp, | ||
380 | }; | ||
381 | |||
360 | void | 382 | void |
361 | qla2x00_alloc_sysfs_attr(scsi_qla_host_t *ha) | 383 | qla2x00_alloc_sysfs_attr(scsi_qla_host_t *ha) |
362 | { | 384 | { |
@@ -367,7 +389,12 @@ qla2x00_alloc_sysfs_attr(scsi_qla_host_t *ha) | |||
367 | sysfs_create_bin_file(&host->shost_gendev.kobj, &sysfs_optrom_attr); | 389 | sysfs_create_bin_file(&host->shost_gendev.kobj, &sysfs_optrom_attr); |
368 | sysfs_create_bin_file(&host->shost_gendev.kobj, | 390 | sysfs_create_bin_file(&host->shost_gendev.kobj, |
369 | &sysfs_optrom_ctl_attr); | 391 | &sysfs_optrom_ctl_attr); |
370 | sysfs_create_bin_file(&host->shost_gendev.kobj, &sysfs_vpd_attr); | 392 | if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) { |
393 | sysfs_create_bin_file(&host->shost_gendev.kobj, | ||
394 | &sysfs_vpd_attr); | ||
395 | sysfs_create_bin_file(&host->shost_gendev.kobj, | ||
396 | &sysfs_sfp_attr); | ||
397 | } | ||
371 | } | 398 | } |
372 | 399 | ||
373 | void | 400 | void |
@@ -380,7 +407,12 @@ qla2x00_free_sysfs_attr(scsi_qla_host_t *ha) | |||
380 | sysfs_remove_bin_file(&host->shost_gendev.kobj, &sysfs_optrom_attr); | 407 | sysfs_remove_bin_file(&host->shost_gendev.kobj, &sysfs_optrom_attr); |
381 | sysfs_remove_bin_file(&host->shost_gendev.kobj, | 408 | sysfs_remove_bin_file(&host->shost_gendev.kobj, |
382 | &sysfs_optrom_ctl_attr); | 409 | &sysfs_optrom_ctl_attr); |
383 | sysfs_remove_bin_file(&host->shost_gendev.kobj, &sysfs_vpd_attr); | 410 | if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) { |
411 | sysfs_remove_bin_file(&host->shost_gendev.kobj, | ||
412 | &sysfs_vpd_attr); | ||
413 | sysfs_remove_bin_file(&host->shost_gendev.kobj, | ||
414 | &sysfs_sfp_attr); | ||
415 | } | ||
384 | 416 | ||
385 | if (ha->beacon_blink_led == 1) | 417 | if (ha->beacon_blink_led == 1) |
386 | ha->isp_ops.beacon_off(ha); | 418 | ha->isp_ops.beacon_off(ha); |
diff --git a/drivers/scsi/qla2xxx/qla_dbg.c b/drivers/scsi/qla2xxx/qla_dbg.c index 74e54713aa7c..f6ed6962bc2b 100644 --- a/drivers/scsi/qla2xxx/qla_dbg.c +++ b/drivers/scsi/qla2xxx/qla_dbg.c | |||
@@ -8,7 +8,34 @@ | |||
8 | 8 | ||
9 | #include <linux/delay.h> | 9 | #include <linux/delay.h> |
10 | 10 | ||
11 | static int qla_uprintf(char **, char *, ...); | 11 | static inline void |
12 | qla2xxx_prep_dump(scsi_qla_host_t *ha, struct qla2xxx_fw_dump *fw_dump) | ||
13 | { | ||
14 | fw_dump->fw_major_version = htonl(ha->fw_major_version); | ||
15 | fw_dump->fw_minor_version = htonl(ha->fw_minor_version); | ||
16 | fw_dump->fw_subminor_version = htonl(ha->fw_subminor_version); | ||
17 | fw_dump->fw_attributes = htonl(ha->fw_attributes); | ||
18 | |||
19 | fw_dump->vendor = htonl(ha->pdev->vendor); | ||
20 | fw_dump->device = htonl(ha->pdev->device); | ||
21 | fw_dump->subsystem_vendor = htonl(ha->pdev->subsystem_vendor); | ||
22 | fw_dump->subsystem_device = htonl(ha->pdev->subsystem_device); | ||
23 | } | ||
24 | |||
25 | static inline void * | ||
26 | qla2xxx_copy_queues(scsi_qla_host_t *ha, void *ptr) | ||
27 | { | ||
28 | /* Request queue. */ | ||
29 | memcpy(ptr, ha->request_ring, ha->request_q_length * | ||
30 | sizeof(request_t)); | ||
31 | |||
32 | /* Response queue. */ | ||
33 | ptr += ha->request_q_length * sizeof(request_t); | ||
34 | memcpy(ptr, ha->response_ring, ha->response_q_length * | ||
35 | sizeof(response_t)); | ||
36 | |||
37 | return ptr + (ha->response_q_length * sizeof(response_t)); | ||
38 | } | ||
12 | 39 | ||
13 | /** | 40 | /** |
14 | * qla2300_fw_dump() - Dumps binary data from the 2300 firmware. | 41 | * qla2300_fw_dump() - Dumps binary data from the 2300 firmware. |
@@ -49,10 +76,11 @@ qla2300_fw_dump(scsi_qla_host_t *ha, int hardware_locked) | |||
49 | "request...\n", ha->fw_dump); | 76 | "request...\n", ha->fw_dump); |
50 | goto qla2300_fw_dump_failed; | 77 | goto qla2300_fw_dump_failed; |
51 | } | 78 | } |
52 | fw = ha->fw_dump; | 79 | fw = &ha->fw_dump->isp.isp23; |
80 | qla2xxx_prep_dump(ha, ha->fw_dump); | ||
53 | 81 | ||
54 | rval = QLA_SUCCESS; | 82 | rval = QLA_SUCCESS; |
55 | fw->hccr = RD_REG_WORD(®->hccr); | 83 | fw->hccr = htons(RD_REG_WORD(®->hccr)); |
56 | 84 | ||
57 | /* Pause RISC. */ | 85 | /* Pause RISC. */ |
58 | WRT_REG_WORD(®->hccr, HCCR_PAUSE_RISC); | 86 | WRT_REG_WORD(®->hccr, HCCR_PAUSE_RISC); |
@@ -73,85 +101,86 @@ qla2300_fw_dump(scsi_qla_host_t *ha, int hardware_locked) | |||
73 | if (rval == QLA_SUCCESS) { | 101 | if (rval == QLA_SUCCESS) { |
74 | dmp_reg = (uint16_t __iomem *)(reg + 0); | 102 | dmp_reg = (uint16_t __iomem *)(reg + 0); |
75 | for (cnt = 0; cnt < sizeof(fw->pbiu_reg) / 2; cnt++) | 103 | for (cnt = 0; cnt < sizeof(fw->pbiu_reg) / 2; cnt++) |
76 | fw->pbiu_reg[cnt] = RD_REG_WORD(dmp_reg++); | 104 | fw->pbiu_reg[cnt] = htons(RD_REG_WORD(dmp_reg++)); |
77 | 105 | ||
78 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x10); | 106 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x10); |
79 | for (cnt = 0; cnt < sizeof(fw->risc_host_reg) / 2; cnt++) | 107 | for (cnt = 0; cnt < sizeof(fw->risc_host_reg) / 2; cnt++) |
80 | fw->risc_host_reg[cnt] = RD_REG_WORD(dmp_reg++); | 108 | fw->risc_host_reg[cnt] = htons(RD_REG_WORD(dmp_reg++)); |
81 | 109 | ||
82 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x40); | 110 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x40); |
83 | for (cnt = 0; cnt < sizeof(fw->mailbox_reg) / 2; cnt++) | 111 | for (cnt = 0; cnt < sizeof(fw->mailbox_reg) / 2; cnt++) |
84 | fw->mailbox_reg[cnt] = RD_REG_WORD(dmp_reg++); | 112 | fw->mailbox_reg[cnt] = htons(RD_REG_WORD(dmp_reg++)); |
85 | 113 | ||
86 | WRT_REG_WORD(®->ctrl_status, 0x40); | 114 | WRT_REG_WORD(®->ctrl_status, 0x40); |
87 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); | 115 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); |
88 | for (cnt = 0; cnt < sizeof(fw->resp_dma_reg) / 2; cnt++) | 116 | for (cnt = 0; cnt < sizeof(fw->resp_dma_reg) / 2; cnt++) |
89 | fw->resp_dma_reg[cnt] = RD_REG_WORD(dmp_reg++); | 117 | fw->resp_dma_reg[cnt] = htons(RD_REG_WORD(dmp_reg++)); |
90 | 118 | ||
91 | WRT_REG_WORD(®->ctrl_status, 0x50); | 119 | WRT_REG_WORD(®->ctrl_status, 0x50); |
92 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); | 120 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); |
93 | for (cnt = 0; cnt < sizeof(fw->dma_reg) / 2; cnt++) | 121 | for (cnt = 0; cnt < sizeof(fw->dma_reg) / 2; cnt++) |
94 | fw->dma_reg[cnt] = RD_REG_WORD(dmp_reg++); | 122 | fw->dma_reg[cnt] = htons(RD_REG_WORD(dmp_reg++)); |
95 | 123 | ||
96 | WRT_REG_WORD(®->ctrl_status, 0x00); | 124 | WRT_REG_WORD(®->ctrl_status, 0x00); |
97 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0xA0); | 125 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0xA0); |
98 | for (cnt = 0; cnt < sizeof(fw->risc_hdw_reg) / 2; cnt++) | 126 | for (cnt = 0; cnt < sizeof(fw->risc_hdw_reg) / 2; cnt++) |
99 | fw->risc_hdw_reg[cnt] = RD_REG_WORD(dmp_reg++); | 127 | fw->risc_hdw_reg[cnt] = htons(RD_REG_WORD(dmp_reg++)); |
100 | 128 | ||
101 | WRT_REG_WORD(®->pcr, 0x2000); | 129 | WRT_REG_WORD(®->pcr, 0x2000); |
102 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); | 130 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); |
103 | for (cnt = 0; cnt < sizeof(fw->risc_gp0_reg) / 2; cnt++) | 131 | for (cnt = 0; cnt < sizeof(fw->risc_gp0_reg) / 2; cnt++) |
104 | fw->risc_gp0_reg[cnt] = RD_REG_WORD(dmp_reg++); | 132 | fw->risc_gp0_reg[cnt] = htons(RD_REG_WORD(dmp_reg++)); |
105 | 133 | ||
106 | WRT_REG_WORD(®->pcr, 0x2200); | 134 | WRT_REG_WORD(®->pcr, 0x2200); |
107 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); | 135 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); |
108 | for (cnt = 0; cnt < sizeof(fw->risc_gp1_reg) / 2; cnt++) | 136 | for (cnt = 0; cnt < sizeof(fw->risc_gp1_reg) / 2; cnt++) |
109 | fw->risc_gp1_reg[cnt] = RD_REG_WORD(dmp_reg++); | 137 | fw->risc_gp1_reg[cnt] = htons(RD_REG_WORD(dmp_reg++)); |
110 | 138 | ||
111 | WRT_REG_WORD(®->pcr, 0x2400); | 139 | WRT_REG_WORD(®->pcr, 0x2400); |
112 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); | 140 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); |
113 | for (cnt = 0; cnt < sizeof(fw->risc_gp2_reg) / 2; cnt++) | 141 | for (cnt = 0; cnt < sizeof(fw->risc_gp2_reg) / 2; cnt++) |
114 | fw->risc_gp2_reg[cnt] = RD_REG_WORD(dmp_reg++); | 142 | fw->risc_gp2_reg[cnt] = htons(RD_REG_WORD(dmp_reg++)); |
115 | 143 | ||
116 | WRT_REG_WORD(®->pcr, 0x2600); | 144 | WRT_REG_WORD(®->pcr, 0x2600); |
117 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); | 145 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); |
118 | for (cnt = 0; cnt < sizeof(fw->risc_gp3_reg) / 2; cnt++) | 146 | for (cnt = 0; cnt < sizeof(fw->risc_gp3_reg) / 2; cnt++) |
119 | fw->risc_gp3_reg[cnt] = RD_REG_WORD(dmp_reg++); | 147 | fw->risc_gp3_reg[cnt] = htons(RD_REG_WORD(dmp_reg++)); |
120 | 148 | ||
121 | WRT_REG_WORD(®->pcr, 0x2800); | 149 | WRT_REG_WORD(®->pcr, 0x2800); |
122 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); | 150 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); |
123 | for (cnt = 0; cnt < sizeof(fw->risc_gp4_reg) / 2; cnt++) | 151 | for (cnt = 0; cnt < sizeof(fw->risc_gp4_reg) / 2; cnt++) |
124 | fw->risc_gp4_reg[cnt] = RD_REG_WORD(dmp_reg++); | 152 | fw->risc_gp4_reg[cnt] = htons(RD_REG_WORD(dmp_reg++)); |
125 | 153 | ||
126 | WRT_REG_WORD(®->pcr, 0x2A00); | 154 | WRT_REG_WORD(®->pcr, 0x2A00); |
127 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); | 155 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); |
128 | for (cnt = 0; cnt < sizeof(fw->risc_gp5_reg) / 2; cnt++) | 156 | for (cnt = 0; cnt < sizeof(fw->risc_gp5_reg) / 2; cnt++) |
129 | fw->risc_gp5_reg[cnt] = RD_REG_WORD(dmp_reg++); | 157 | fw->risc_gp5_reg[cnt] = htons(RD_REG_WORD(dmp_reg++)); |
130 | 158 | ||
131 | WRT_REG_WORD(®->pcr, 0x2C00); | 159 | WRT_REG_WORD(®->pcr, 0x2C00); |
132 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); | 160 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); |
133 | for (cnt = 0; cnt < sizeof(fw->risc_gp6_reg) / 2; cnt++) | 161 | for (cnt = 0; cnt < sizeof(fw->risc_gp6_reg) / 2; cnt++) |
134 | fw->risc_gp6_reg[cnt] = RD_REG_WORD(dmp_reg++); | 162 | fw->risc_gp6_reg[cnt] = htons(RD_REG_WORD(dmp_reg++)); |
135 | 163 | ||
136 | WRT_REG_WORD(®->pcr, 0x2E00); | 164 | WRT_REG_WORD(®->pcr, 0x2E00); |
137 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); | 165 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); |
138 | for (cnt = 0; cnt < sizeof(fw->risc_gp7_reg) / 2; cnt++) | 166 | for (cnt = 0; cnt < sizeof(fw->risc_gp7_reg) / 2; cnt++) |
139 | fw->risc_gp7_reg[cnt] = RD_REG_WORD(dmp_reg++); | 167 | fw->risc_gp7_reg[cnt] = htons(RD_REG_WORD(dmp_reg++)); |
140 | 168 | ||
141 | WRT_REG_WORD(®->ctrl_status, 0x10); | 169 | WRT_REG_WORD(®->ctrl_status, 0x10); |
142 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); | 170 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); |
143 | for (cnt = 0; cnt < sizeof(fw->frame_buf_hdw_reg) / 2; cnt++) | 171 | for (cnt = 0; cnt < sizeof(fw->frame_buf_hdw_reg) / 2; cnt++) |
144 | fw->frame_buf_hdw_reg[cnt] = RD_REG_WORD(dmp_reg++); | 172 | fw->frame_buf_hdw_reg[cnt] = |
173 | htons(RD_REG_WORD(dmp_reg++)); | ||
145 | 174 | ||
146 | WRT_REG_WORD(®->ctrl_status, 0x20); | 175 | WRT_REG_WORD(®->ctrl_status, 0x20); |
147 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); | 176 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); |
148 | for (cnt = 0; cnt < sizeof(fw->fpm_b0_reg) / 2; cnt++) | 177 | for (cnt = 0; cnt < sizeof(fw->fpm_b0_reg) / 2; cnt++) |
149 | fw->fpm_b0_reg[cnt] = RD_REG_WORD(dmp_reg++); | 178 | fw->fpm_b0_reg[cnt] = htons(RD_REG_WORD(dmp_reg++)); |
150 | 179 | ||
151 | WRT_REG_WORD(®->ctrl_status, 0x30); | 180 | WRT_REG_WORD(®->ctrl_status, 0x30); |
152 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); | 181 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); |
153 | for (cnt = 0; cnt < sizeof(fw->fpm_b1_reg) / 2; cnt++) | 182 | for (cnt = 0; cnt < sizeof(fw->fpm_b1_reg) / 2; cnt++) |
154 | fw->fpm_b1_reg[cnt] = RD_REG_WORD(dmp_reg++); | 183 | fw->fpm_b1_reg[cnt] = htons(RD_REG_WORD(dmp_reg++)); |
155 | 184 | ||
156 | /* Reset RISC. */ | 185 | /* Reset RISC. */ |
157 | WRT_REG_WORD(®->ctrl_status, CSR_ISP_SOFT_RESET); | 186 | WRT_REG_WORD(®->ctrl_status, CSR_ISP_SOFT_RESET); |
@@ -226,7 +255,7 @@ qla2300_fw_dump(scsi_qla_host_t *ha, int hardware_locked) | |||
226 | 255 | ||
227 | if (test_and_clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags)) { | 256 | if (test_and_clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags)) { |
228 | rval = mb0 & MBS_MASK; | 257 | rval = mb0 & MBS_MASK; |
229 | fw->risc_ram[cnt] = mb2; | 258 | fw->risc_ram[cnt] = htons(mb2); |
230 | } else { | 259 | } else { |
231 | rval = QLA_FUNCTION_FAILED; | 260 | rval = QLA_FUNCTION_FAILED; |
232 | } | 261 | } |
@@ -285,7 +314,7 @@ qla2300_fw_dump(scsi_qla_host_t *ha, int hardware_locked) | |||
285 | 314 | ||
286 | if (test_and_clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags)) { | 315 | if (test_and_clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags)) { |
287 | rval = mb0 & MBS_MASK; | 316 | rval = mb0 & MBS_MASK; |
288 | fw->stack_ram[cnt] = mb2; | 317 | fw->stack_ram[cnt] = htons(mb2); |
289 | } else { | 318 | } else { |
290 | rval = QLA_FUNCTION_FAILED; | 319 | rval = QLA_FUNCTION_FAILED; |
291 | } | 320 | } |
@@ -345,12 +374,15 @@ qla2300_fw_dump(scsi_qla_host_t *ha, int hardware_locked) | |||
345 | 374 | ||
346 | if (test_and_clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags)) { | 375 | if (test_and_clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags)) { |
347 | rval = mb0 & MBS_MASK; | 376 | rval = mb0 & MBS_MASK; |
348 | fw->data_ram[cnt] = mb2; | 377 | fw->data_ram[cnt] = htons(mb2); |
349 | } else { | 378 | } else { |
350 | rval = QLA_FUNCTION_FAILED; | 379 | rval = QLA_FUNCTION_FAILED; |
351 | } | 380 | } |
352 | } | 381 | } |
353 | 382 | ||
383 | if (rval == QLA_SUCCESS) | ||
384 | qla2xxx_copy_queues(ha, &fw->data_ram[cnt]); | ||
385 | |||
354 | if (rval != QLA_SUCCESS) { | 386 | if (rval != QLA_SUCCESS) { |
355 | qla_printk(KERN_WARNING, ha, | 387 | qla_printk(KERN_WARNING, ha, |
356 | "Failed to dump firmware (%x)!!!\n", rval); | 388 | "Failed to dump firmware (%x)!!!\n", rval); |
@@ -369,193 +401,6 @@ qla2300_fw_dump_failed: | |||
369 | } | 401 | } |
370 | 402 | ||
371 | /** | 403 | /** |
372 | * qla2300_ascii_fw_dump() - Converts a binary firmware dump to ASCII. | ||
373 | * @ha: HA context | ||
374 | */ | ||
375 | void | ||
376 | qla2300_ascii_fw_dump(scsi_qla_host_t *ha) | ||
377 | { | ||
378 | uint32_t cnt; | ||
379 | char *uiter; | ||
380 | char fw_info[30]; | ||
381 | struct qla2300_fw_dump *fw; | ||
382 | uint32_t data_ram_cnt; | ||
383 | |||
384 | uiter = ha->fw_dump_buffer; | ||
385 | fw = ha->fw_dump; | ||
386 | |||
387 | qla_uprintf(&uiter, "%s Firmware Version %s\n", ha->model_number, | ||
388 | ha->isp_ops.fw_version_str(ha, fw_info)); | ||
389 | |||
390 | qla_uprintf(&uiter, "\n[==>BEG]\n"); | ||
391 | |||
392 | qla_uprintf(&uiter, "HCCR Register:\n%04x\n\n", fw->hccr); | ||
393 | |||
394 | qla_uprintf(&uiter, "PBIU Registers:"); | ||
395 | for (cnt = 0; cnt < sizeof (fw->pbiu_reg) / 2; cnt++) { | ||
396 | if (cnt % 8 == 0) { | ||
397 | qla_uprintf(&uiter, "\n"); | ||
398 | } | ||
399 | qla_uprintf(&uiter, "%04x ", fw->pbiu_reg[cnt]); | ||
400 | } | ||
401 | |||
402 | qla_uprintf(&uiter, "\n\nReqQ-RspQ-Risc2Host Status registers:"); | ||
403 | for (cnt = 0; cnt < sizeof (fw->risc_host_reg) / 2; cnt++) { | ||
404 | if (cnt % 8 == 0) { | ||
405 | qla_uprintf(&uiter, "\n"); | ||
406 | } | ||
407 | qla_uprintf(&uiter, "%04x ", fw->risc_host_reg[cnt]); | ||
408 | } | ||
409 | |||
410 | qla_uprintf(&uiter, "\n\nMailbox Registers:"); | ||
411 | for (cnt = 0; cnt < sizeof (fw->mailbox_reg) / 2; cnt++) { | ||
412 | if (cnt % 8 == 0) { | ||
413 | qla_uprintf(&uiter, "\n"); | ||
414 | } | ||
415 | qla_uprintf(&uiter, "%04x ", fw->mailbox_reg[cnt]); | ||
416 | } | ||
417 | |||
418 | qla_uprintf(&uiter, "\n\nAuto Request Response DMA Registers:"); | ||
419 | for (cnt = 0; cnt < sizeof (fw->resp_dma_reg) / 2; cnt++) { | ||
420 | if (cnt % 8 == 0) { | ||
421 | qla_uprintf(&uiter, "\n"); | ||
422 | } | ||
423 | qla_uprintf(&uiter, "%04x ", fw->resp_dma_reg[cnt]); | ||
424 | } | ||
425 | |||
426 | qla_uprintf(&uiter, "\n\nDMA Registers:"); | ||
427 | for (cnt = 0; cnt < sizeof (fw->dma_reg) / 2; cnt++) { | ||
428 | if (cnt % 8 == 0) { | ||
429 | qla_uprintf(&uiter, "\n"); | ||
430 | } | ||
431 | qla_uprintf(&uiter, "%04x ", fw->dma_reg[cnt]); | ||
432 | } | ||
433 | |||
434 | qla_uprintf(&uiter, "\n\nRISC Hardware Registers:"); | ||
435 | for (cnt = 0; cnt < sizeof (fw->risc_hdw_reg) / 2; cnt++) { | ||
436 | if (cnt % 8 == 0) { | ||
437 | qla_uprintf(&uiter, "\n"); | ||
438 | } | ||
439 | qla_uprintf(&uiter, "%04x ", fw->risc_hdw_reg[cnt]); | ||
440 | } | ||
441 | |||
442 | qla_uprintf(&uiter, "\n\nRISC GP0 Registers:"); | ||
443 | for (cnt = 0; cnt < sizeof (fw->risc_gp0_reg) / 2; cnt++) { | ||
444 | if (cnt % 8 == 0) { | ||
445 | qla_uprintf(&uiter, "\n"); | ||
446 | } | ||
447 | qla_uprintf(&uiter, "%04x ", fw->risc_gp0_reg[cnt]); | ||
448 | } | ||
449 | |||
450 | qla_uprintf(&uiter, "\n\nRISC GP1 Registers:"); | ||
451 | for (cnt = 0; cnt < sizeof (fw->risc_gp1_reg) / 2; cnt++) { | ||
452 | if (cnt % 8 == 0) { | ||
453 | qla_uprintf(&uiter, "\n"); | ||
454 | } | ||
455 | qla_uprintf(&uiter, "%04x ", fw->risc_gp1_reg[cnt]); | ||
456 | } | ||
457 | |||
458 | qla_uprintf(&uiter, "\n\nRISC GP2 Registers:"); | ||
459 | for (cnt = 0; cnt < sizeof (fw->risc_gp2_reg) / 2; cnt++) { | ||
460 | if (cnt % 8 == 0) { | ||
461 | qla_uprintf(&uiter, "\n"); | ||
462 | } | ||
463 | qla_uprintf(&uiter, "%04x ", fw->risc_gp2_reg[cnt]); | ||
464 | } | ||
465 | |||
466 | qla_uprintf(&uiter, "\n\nRISC GP3 Registers:"); | ||
467 | for (cnt = 0; cnt < sizeof (fw->risc_gp3_reg) / 2; cnt++) { | ||
468 | if (cnt % 8 == 0) { | ||
469 | qla_uprintf(&uiter, "\n"); | ||
470 | } | ||
471 | qla_uprintf(&uiter, "%04x ", fw->risc_gp3_reg[cnt]); | ||
472 | } | ||
473 | |||
474 | qla_uprintf(&uiter, "\n\nRISC GP4 Registers:"); | ||
475 | for (cnt = 0; cnt < sizeof (fw->risc_gp4_reg) / 2; cnt++) { | ||
476 | if (cnt % 8 == 0) { | ||
477 | qla_uprintf(&uiter, "\n"); | ||
478 | } | ||
479 | qla_uprintf(&uiter, "%04x ", fw->risc_gp4_reg[cnt]); | ||
480 | } | ||
481 | |||
482 | qla_uprintf(&uiter, "\n\nRISC GP5 Registers:"); | ||
483 | for (cnt = 0; cnt < sizeof (fw->risc_gp5_reg) / 2; cnt++) { | ||
484 | if (cnt % 8 == 0) { | ||
485 | qla_uprintf(&uiter, "\n"); | ||
486 | } | ||
487 | qla_uprintf(&uiter, "%04x ", fw->risc_gp5_reg[cnt]); | ||
488 | } | ||
489 | |||
490 | qla_uprintf(&uiter, "\n\nRISC GP6 Registers:"); | ||
491 | for (cnt = 0; cnt < sizeof (fw->risc_gp6_reg) / 2; cnt++) { | ||
492 | if (cnt % 8 == 0) { | ||
493 | qla_uprintf(&uiter, "\n"); | ||
494 | } | ||
495 | qla_uprintf(&uiter, "%04x ", fw->risc_gp6_reg[cnt]); | ||
496 | } | ||
497 | |||
498 | qla_uprintf(&uiter, "\n\nRISC GP7 Registers:"); | ||
499 | for (cnt = 0; cnt < sizeof (fw->risc_gp7_reg) / 2; cnt++) { | ||
500 | if (cnt % 8 == 0) { | ||
501 | qla_uprintf(&uiter, "\n"); | ||
502 | } | ||
503 | qla_uprintf(&uiter, "%04x ", fw->risc_gp7_reg[cnt]); | ||
504 | } | ||
505 | |||
506 | qla_uprintf(&uiter, "\n\nFrame Buffer Hardware Registers:"); | ||
507 | for (cnt = 0; cnt < sizeof (fw->frame_buf_hdw_reg) / 2; cnt++) { | ||
508 | if (cnt % 8 == 0) { | ||
509 | qla_uprintf(&uiter, "\n"); | ||
510 | } | ||
511 | qla_uprintf(&uiter, "%04x ", fw->frame_buf_hdw_reg[cnt]); | ||
512 | } | ||
513 | |||
514 | qla_uprintf(&uiter, "\n\nFPM B0 Registers:"); | ||
515 | for (cnt = 0; cnt < sizeof (fw->fpm_b0_reg) / 2; cnt++) { | ||
516 | if (cnt % 8 == 0) { | ||
517 | qla_uprintf(&uiter, "\n"); | ||
518 | } | ||
519 | qla_uprintf(&uiter, "%04x ", fw->fpm_b0_reg[cnt]); | ||
520 | } | ||
521 | |||
522 | qla_uprintf(&uiter, "\n\nFPM B1 Registers:"); | ||
523 | for (cnt = 0; cnt < sizeof (fw->fpm_b1_reg) / 2; cnt++) { | ||
524 | if (cnt % 8 == 0) { | ||
525 | qla_uprintf(&uiter, "\n"); | ||
526 | } | ||
527 | qla_uprintf(&uiter, "%04x ", fw->fpm_b1_reg[cnt]); | ||
528 | } | ||
529 | |||
530 | qla_uprintf(&uiter, "\n\nCode RAM Dump:"); | ||
531 | for (cnt = 0; cnt < sizeof (fw->risc_ram) / 2; cnt++) { | ||
532 | if (cnt % 8 == 0) { | ||
533 | qla_uprintf(&uiter, "\n%04x: ", cnt + 0x0800); | ||
534 | } | ||
535 | qla_uprintf(&uiter, "%04x ", fw->risc_ram[cnt]); | ||
536 | } | ||
537 | |||
538 | qla_uprintf(&uiter, "\n\nStack RAM Dump:"); | ||
539 | for (cnt = 0; cnt < sizeof (fw->stack_ram) / 2; cnt++) { | ||
540 | if (cnt % 8 == 0) { | ||
541 | qla_uprintf(&uiter, "\n%05x: ", cnt + 0x10000); | ||
542 | } | ||
543 | qla_uprintf(&uiter, "%04x ", fw->stack_ram[cnt]); | ||
544 | } | ||
545 | |||
546 | qla_uprintf(&uiter, "\n\nData RAM Dump:"); | ||
547 | data_ram_cnt = ha->fw_memory_size - 0x11000 + 1; | ||
548 | for (cnt = 0; cnt < data_ram_cnt; cnt++) { | ||
549 | if (cnt % 8 == 0) { | ||
550 | qla_uprintf(&uiter, "\n%05x: ", cnt + 0x11000); | ||
551 | } | ||
552 | qla_uprintf(&uiter, "%04x ", fw->data_ram[cnt]); | ||
553 | } | ||
554 | |||
555 | qla_uprintf(&uiter, "\n\n[<==END] ISP Debug Dump."); | ||
556 | } | ||
557 | |||
558 | /** | ||
559 | * qla2100_fw_dump() - Dumps binary data from the 2100/2200 firmware. | 404 | * qla2100_fw_dump() - Dumps binary data from the 2100/2200 firmware. |
560 | * @ha: HA context | 405 | * @ha: HA context |
561 | * @hardware_locked: Called with the hardware_lock | 406 | * @hardware_locked: Called with the hardware_lock |
@@ -591,10 +436,11 @@ qla2100_fw_dump(scsi_qla_host_t *ha, int hardware_locked) | |||
591 | "request...\n", ha->fw_dump); | 436 | "request...\n", ha->fw_dump); |
592 | goto qla2100_fw_dump_failed; | 437 | goto qla2100_fw_dump_failed; |
593 | } | 438 | } |
594 | fw = ha->fw_dump; | 439 | fw = &ha->fw_dump->isp.isp21; |
440 | qla2xxx_prep_dump(ha, ha->fw_dump); | ||
595 | 441 | ||
596 | rval = QLA_SUCCESS; | 442 | rval = QLA_SUCCESS; |
597 | fw->hccr = RD_REG_WORD(®->hccr); | 443 | fw->hccr = htons(RD_REG_WORD(®->hccr)); |
598 | 444 | ||
599 | /* Pause RISC. */ | 445 | /* Pause RISC. */ |
600 | WRT_REG_WORD(®->hccr, HCCR_PAUSE_RISC); | 446 | WRT_REG_WORD(®->hccr, HCCR_PAUSE_RISC); |
@@ -608,79 +454,81 @@ qla2100_fw_dump(scsi_qla_host_t *ha, int hardware_locked) | |||
608 | if (rval == QLA_SUCCESS) { | 454 | if (rval == QLA_SUCCESS) { |
609 | dmp_reg = (uint16_t __iomem *)(reg + 0); | 455 | dmp_reg = (uint16_t __iomem *)(reg + 0); |
610 | for (cnt = 0; cnt < sizeof(fw->pbiu_reg) / 2; cnt++) | 456 | for (cnt = 0; cnt < sizeof(fw->pbiu_reg) / 2; cnt++) |
611 | fw->pbiu_reg[cnt] = RD_REG_WORD(dmp_reg++); | 457 | fw->pbiu_reg[cnt] = htons(RD_REG_WORD(dmp_reg++)); |
612 | 458 | ||
613 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x10); | 459 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x10); |
614 | for (cnt = 0; cnt < ha->mbx_count; cnt++) { | 460 | for (cnt = 0; cnt < ha->mbx_count; cnt++) { |
615 | if (cnt == 8) { | 461 | if (cnt == 8) { |
616 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0xe0); | 462 | dmp_reg = (uint16_t __iomem *) |
463 | ((uint8_t __iomem *)reg + 0xe0); | ||
617 | } | 464 | } |
618 | fw->mailbox_reg[cnt] = RD_REG_WORD(dmp_reg++); | 465 | fw->mailbox_reg[cnt] = htons(RD_REG_WORD(dmp_reg++)); |
619 | } | 466 | } |
620 | 467 | ||
621 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x20); | 468 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x20); |
622 | for (cnt = 0; cnt < sizeof(fw->dma_reg) / 2; cnt++) | 469 | for (cnt = 0; cnt < sizeof(fw->dma_reg) / 2; cnt++) |
623 | fw->dma_reg[cnt] = RD_REG_WORD(dmp_reg++); | 470 | fw->dma_reg[cnt] = htons(RD_REG_WORD(dmp_reg++)); |
624 | 471 | ||
625 | WRT_REG_WORD(®->ctrl_status, 0x00); | 472 | WRT_REG_WORD(®->ctrl_status, 0x00); |
626 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0xA0); | 473 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0xA0); |
627 | for (cnt = 0; cnt < sizeof(fw->risc_hdw_reg) / 2; cnt++) | 474 | for (cnt = 0; cnt < sizeof(fw->risc_hdw_reg) / 2; cnt++) |
628 | fw->risc_hdw_reg[cnt] = RD_REG_WORD(dmp_reg++); | 475 | fw->risc_hdw_reg[cnt] = htons(RD_REG_WORD(dmp_reg++)); |
629 | 476 | ||
630 | WRT_REG_WORD(®->pcr, 0x2000); | 477 | WRT_REG_WORD(®->pcr, 0x2000); |
631 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); | 478 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); |
632 | for (cnt = 0; cnt < sizeof(fw->risc_gp0_reg) / 2; cnt++) | 479 | for (cnt = 0; cnt < sizeof(fw->risc_gp0_reg) / 2; cnt++) |
633 | fw->risc_gp0_reg[cnt] = RD_REG_WORD(dmp_reg++); | 480 | fw->risc_gp0_reg[cnt] = htons(RD_REG_WORD(dmp_reg++)); |
634 | 481 | ||
635 | WRT_REG_WORD(®->pcr, 0x2100); | 482 | WRT_REG_WORD(®->pcr, 0x2100); |
636 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); | 483 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); |
637 | for (cnt = 0; cnt < sizeof(fw->risc_gp1_reg) / 2; cnt++) | 484 | for (cnt = 0; cnt < sizeof(fw->risc_gp1_reg) / 2; cnt++) |
638 | fw->risc_gp1_reg[cnt] = RD_REG_WORD(dmp_reg++); | 485 | fw->risc_gp1_reg[cnt] = htons(RD_REG_WORD(dmp_reg++)); |
639 | 486 | ||
640 | WRT_REG_WORD(®->pcr, 0x2200); | 487 | WRT_REG_WORD(®->pcr, 0x2200); |
641 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); | 488 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); |
642 | for (cnt = 0; cnt < sizeof(fw->risc_gp2_reg) / 2; cnt++) | 489 | for (cnt = 0; cnt < sizeof(fw->risc_gp2_reg) / 2; cnt++) |
643 | fw->risc_gp2_reg[cnt] = RD_REG_WORD(dmp_reg++); | 490 | fw->risc_gp2_reg[cnt] = htons(RD_REG_WORD(dmp_reg++)); |
644 | 491 | ||
645 | WRT_REG_WORD(®->pcr, 0x2300); | 492 | WRT_REG_WORD(®->pcr, 0x2300); |
646 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); | 493 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); |
647 | for (cnt = 0; cnt < sizeof(fw->risc_gp3_reg) / 2; cnt++) | 494 | for (cnt = 0; cnt < sizeof(fw->risc_gp3_reg) / 2; cnt++) |
648 | fw->risc_gp3_reg[cnt] = RD_REG_WORD(dmp_reg++); | 495 | fw->risc_gp3_reg[cnt] = htons(RD_REG_WORD(dmp_reg++)); |
649 | 496 | ||
650 | WRT_REG_WORD(®->pcr, 0x2400); | 497 | WRT_REG_WORD(®->pcr, 0x2400); |
651 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); | 498 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); |
652 | for (cnt = 0; cnt < sizeof(fw->risc_gp4_reg) / 2; cnt++) | 499 | for (cnt = 0; cnt < sizeof(fw->risc_gp4_reg) / 2; cnt++) |
653 | fw->risc_gp4_reg[cnt] = RD_REG_WORD(dmp_reg++); | 500 | fw->risc_gp4_reg[cnt] = htons(RD_REG_WORD(dmp_reg++)); |
654 | 501 | ||
655 | WRT_REG_WORD(®->pcr, 0x2500); | 502 | WRT_REG_WORD(®->pcr, 0x2500); |
656 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); | 503 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); |
657 | for (cnt = 0; cnt < sizeof(fw->risc_gp5_reg) / 2; cnt++) | 504 | for (cnt = 0; cnt < sizeof(fw->risc_gp5_reg) / 2; cnt++) |
658 | fw->risc_gp5_reg[cnt] = RD_REG_WORD(dmp_reg++); | 505 | fw->risc_gp5_reg[cnt] = htons(RD_REG_WORD(dmp_reg++)); |
659 | 506 | ||
660 | WRT_REG_WORD(®->pcr, 0x2600); | 507 | WRT_REG_WORD(®->pcr, 0x2600); |
661 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); | 508 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); |
662 | for (cnt = 0; cnt < sizeof(fw->risc_gp6_reg) / 2; cnt++) | 509 | for (cnt = 0; cnt < sizeof(fw->risc_gp6_reg) / 2; cnt++) |
663 | fw->risc_gp6_reg[cnt] = RD_REG_WORD(dmp_reg++); | 510 | fw->risc_gp6_reg[cnt] = htons(RD_REG_WORD(dmp_reg++)); |
664 | 511 | ||
665 | WRT_REG_WORD(®->pcr, 0x2700); | 512 | WRT_REG_WORD(®->pcr, 0x2700); |
666 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); | 513 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); |
667 | for (cnt = 0; cnt < sizeof(fw->risc_gp7_reg) / 2; cnt++) | 514 | for (cnt = 0; cnt < sizeof(fw->risc_gp7_reg) / 2; cnt++) |
668 | fw->risc_gp7_reg[cnt] = RD_REG_WORD(dmp_reg++); | 515 | fw->risc_gp7_reg[cnt] = htons(RD_REG_WORD(dmp_reg++)); |
669 | 516 | ||
670 | WRT_REG_WORD(®->ctrl_status, 0x10); | 517 | WRT_REG_WORD(®->ctrl_status, 0x10); |
671 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); | 518 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); |
672 | for (cnt = 0; cnt < sizeof(fw->frame_buf_hdw_reg) / 2; cnt++) | 519 | for (cnt = 0; cnt < sizeof(fw->frame_buf_hdw_reg) / 2; cnt++) |
673 | fw->frame_buf_hdw_reg[cnt] = RD_REG_WORD(dmp_reg++); | 520 | fw->frame_buf_hdw_reg[cnt] = |
521 | htons(RD_REG_WORD(dmp_reg++)); | ||
674 | 522 | ||
675 | WRT_REG_WORD(®->ctrl_status, 0x20); | 523 | WRT_REG_WORD(®->ctrl_status, 0x20); |
676 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); | 524 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); |
677 | for (cnt = 0; cnt < sizeof(fw->fpm_b0_reg) / 2; cnt++) | 525 | for (cnt = 0; cnt < sizeof(fw->fpm_b0_reg) / 2; cnt++) |
678 | fw->fpm_b0_reg[cnt] = RD_REG_WORD(dmp_reg++); | 526 | fw->fpm_b0_reg[cnt] = htons(RD_REG_WORD(dmp_reg++)); |
679 | 527 | ||
680 | WRT_REG_WORD(®->ctrl_status, 0x30); | 528 | WRT_REG_WORD(®->ctrl_status, 0x30); |
681 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); | 529 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); |
682 | for (cnt = 0; cnt < sizeof(fw->fpm_b1_reg) / 2; cnt++) | 530 | for (cnt = 0; cnt < sizeof(fw->fpm_b1_reg) / 2; cnt++) |
683 | fw->fpm_b1_reg[cnt] = RD_REG_WORD(dmp_reg++); | 531 | fw->fpm_b1_reg[cnt] = htons(RD_REG_WORD(dmp_reg++)); |
684 | 532 | ||
685 | /* Reset the ISP. */ | 533 | /* Reset the ISP. */ |
686 | WRT_REG_WORD(®->ctrl_status, CSR_ISP_SOFT_RESET); | 534 | WRT_REG_WORD(®->ctrl_status, CSR_ISP_SOFT_RESET); |
@@ -755,12 +603,15 @@ qla2100_fw_dump(scsi_qla_host_t *ha, int hardware_locked) | |||
755 | 603 | ||
756 | if (test_and_clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags)) { | 604 | if (test_and_clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags)) { |
757 | rval = mb0 & MBS_MASK; | 605 | rval = mb0 & MBS_MASK; |
758 | fw->risc_ram[cnt] = mb2; | 606 | fw->risc_ram[cnt] = htons(mb2); |
759 | } else { | 607 | } else { |
760 | rval = QLA_FUNCTION_FAILED; | 608 | rval = QLA_FUNCTION_FAILED; |
761 | } | 609 | } |
762 | } | 610 | } |
763 | 611 | ||
612 | if (rval == QLA_SUCCESS) | ||
613 | qla2xxx_copy_queues(ha, &fw->risc_ram[cnt]); | ||
614 | |||
764 | if (rval != QLA_SUCCESS) { | 615 | if (rval != QLA_SUCCESS) { |
765 | qla_printk(KERN_WARNING, ha, | 616 | qla_printk(KERN_WARNING, ha, |
766 | "Failed to dump firmware (%x)!!!\n", rval); | 617 | "Failed to dump firmware (%x)!!!\n", rval); |
@@ -778,179 +629,6 @@ qla2100_fw_dump_failed: | |||
778 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | 629 | spin_unlock_irqrestore(&ha->hardware_lock, flags); |
779 | } | 630 | } |
780 | 631 | ||
781 | /** | ||
782 | * qla2100_ascii_fw_dump() - Converts a binary firmware dump to ASCII. | ||
783 | * @ha: HA context | ||
784 | */ | ||
785 | void | ||
786 | qla2100_ascii_fw_dump(scsi_qla_host_t *ha) | ||
787 | { | ||
788 | uint32_t cnt; | ||
789 | char *uiter; | ||
790 | char fw_info[30]; | ||
791 | struct qla2100_fw_dump *fw; | ||
792 | |||
793 | uiter = ha->fw_dump_buffer; | ||
794 | fw = ha->fw_dump; | ||
795 | |||
796 | qla_uprintf(&uiter, "%s Firmware Version %s\n", ha->model_number, | ||
797 | ha->isp_ops.fw_version_str(ha, fw_info)); | ||
798 | |||
799 | qla_uprintf(&uiter, "\n[==>BEG]\n"); | ||
800 | |||
801 | qla_uprintf(&uiter, "HCCR Register:\n%04x\n\n", fw->hccr); | ||
802 | |||
803 | qla_uprintf(&uiter, "PBIU Registers:"); | ||
804 | for (cnt = 0; cnt < sizeof (fw->pbiu_reg) / 2; cnt++) { | ||
805 | if (cnt % 8 == 0) { | ||
806 | qla_uprintf(&uiter, "\n"); | ||
807 | } | ||
808 | qla_uprintf(&uiter, "%04x ", fw->pbiu_reg[cnt]); | ||
809 | } | ||
810 | |||
811 | qla_uprintf(&uiter, "\n\nMailbox Registers:"); | ||
812 | for (cnt = 0; cnt < sizeof (fw->mailbox_reg) / 2; cnt++) { | ||
813 | if (cnt % 8 == 0) { | ||
814 | qla_uprintf(&uiter, "\n"); | ||
815 | } | ||
816 | qla_uprintf(&uiter, "%04x ", fw->mailbox_reg[cnt]); | ||
817 | } | ||
818 | |||
819 | qla_uprintf(&uiter, "\n\nDMA Registers:"); | ||
820 | for (cnt = 0; cnt < sizeof (fw->dma_reg) / 2; cnt++) { | ||
821 | if (cnt % 8 == 0) { | ||
822 | qla_uprintf(&uiter, "\n"); | ||
823 | } | ||
824 | qla_uprintf(&uiter, "%04x ", fw->dma_reg[cnt]); | ||
825 | } | ||
826 | |||
827 | qla_uprintf(&uiter, "\n\nRISC Hardware Registers:"); | ||
828 | for (cnt = 0; cnt < sizeof (fw->risc_hdw_reg) / 2; cnt++) { | ||
829 | if (cnt % 8 == 0) { | ||
830 | qla_uprintf(&uiter, "\n"); | ||
831 | } | ||
832 | qla_uprintf(&uiter, "%04x ", fw->risc_hdw_reg[cnt]); | ||
833 | } | ||
834 | |||
835 | qla_uprintf(&uiter, "\n\nRISC GP0 Registers:"); | ||
836 | for (cnt = 0; cnt < sizeof (fw->risc_gp0_reg) / 2; cnt++) { | ||
837 | if (cnt % 8 == 0) { | ||
838 | qla_uprintf(&uiter, "\n"); | ||
839 | } | ||
840 | qla_uprintf(&uiter, "%04x ", fw->risc_gp0_reg[cnt]); | ||
841 | } | ||
842 | |||
843 | qla_uprintf(&uiter, "\n\nRISC GP1 Registers:"); | ||
844 | for (cnt = 0; cnt < sizeof (fw->risc_gp1_reg) / 2; cnt++) { | ||
845 | if (cnt % 8 == 0) { | ||
846 | qla_uprintf(&uiter, "\n"); | ||
847 | } | ||
848 | qla_uprintf(&uiter, "%04x ", fw->risc_gp1_reg[cnt]); | ||
849 | } | ||
850 | |||
851 | qla_uprintf(&uiter, "\n\nRISC GP2 Registers:"); | ||
852 | for (cnt = 0; cnt < sizeof (fw->risc_gp2_reg) / 2; cnt++) { | ||
853 | if (cnt % 8 == 0) { | ||
854 | qla_uprintf(&uiter, "\n"); | ||
855 | } | ||
856 | qla_uprintf(&uiter, "%04x ", fw->risc_gp2_reg[cnt]); | ||
857 | } | ||
858 | |||
859 | qla_uprintf(&uiter, "\n\nRISC GP3 Registers:"); | ||
860 | for (cnt = 0; cnt < sizeof (fw->risc_gp3_reg) / 2; cnt++) { | ||
861 | if (cnt % 8 == 0) { | ||
862 | qla_uprintf(&uiter, "\n"); | ||
863 | } | ||
864 | qla_uprintf(&uiter, "%04x ", fw->risc_gp3_reg[cnt]); | ||
865 | } | ||
866 | |||
867 | qla_uprintf(&uiter, "\n\nRISC GP4 Registers:"); | ||
868 | for (cnt = 0; cnt < sizeof (fw->risc_gp4_reg) / 2; cnt++) { | ||
869 | if (cnt % 8 == 0) { | ||
870 | qla_uprintf(&uiter, "\n"); | ||
871 | } | ||
872 | qla_uprintf(&uiter, "%04x ", fw->risc_gp4_reg[cnt]); | ||
873 | } | ||
874 | |||
875 | qla_uprintf(&uiter, "\n\nRISC GP5 Registers:"); | ||
876 | for (cnt = 0; cnt < sizeof (fw->risc_gp5_reg) / 2; cnt++) { | ||
877 | if (cnt % 8 == 0) { | ||
878 | qla_uprintf(&uiter, "\n"); | ||
879 | } | ||
880 | qla_uprintf(&uiter, "%04x ", fw->risc_gp5_reg[cnt]); | ||
881 | } | ||
882 | |||
883 | qla_uprintf(&uiter, "\n\nRISC GP6 Registers:"); | ||
884 | for (cnt = 0; cnt < sizeof (fw->risc_gp6_reg) / 2; cnt++) { | ||
885 | if (cnt % 8 == 0) { | ||
886 | qla_uprintf(&uiter, "\n"); | ||
887 | } | ||
888 | qla_uprintf(&uiter, "%04x ", fw->risc_gp6_reg[cnt]); | ||
889 | } | ||
890 | |||
891 | qla_uprintf(&uiter, "\n\nRISC GP7 Registers:"); | ||
892 | for (cnt = 0; cnt < sizeof (fw->risc_gp7_reg) / 2; cnt++) { | ||
893 | if (cnt % 8 == 0) { | ||
894 | qla_uprintf(&uiter, "\n"); | ||
895 | } | ||
896 | qla_uprintf(&uiter, "%04x ", fw->risc_gp7_reg[cnt]); | ||
897 | } | ||
898 | |||
899 | qla_uprintf(&uiter, "\n\nFrame Buffer Hardware Registers:"); | ||
900 | for (cnt = 0; cnt < sizeof (fw->frame_buf_hdw_reg) / 2; cnt++) { | ||
901 | if (cnt % 8 == 0) { | ||
902 | qla_uprintf(&uiter, "\n"); | ||
903 | } | ||
904 | qla_uprintf(&uiter, "%04x ", fw->frame_buf_hdw_reg[cnt]); | ||
905 | } | ||
906 | |||
907 | qla_uprintf(&uiter, "\n\nFPM B0 Registers:"); | ||
908 | for (cnt = 0; cnt < sizeof (fw->fpm_b0_reg) / 2; cnt++) { | ||
909 | if (cnt % 8 == 0) { | ||
910 | qla_uprintf(&uiter, "\n"); | ||
911 | } | ||
912 | qla_uprintf(&uiter, "%04x ", fw->fpm_b0_reg[cnt]); | ||
913 | } | ||
914 | |||
915 | qla_uprintf(&uiter, "\n\nFPM B1 Registers:"); | ||
916 | for (cnt = 0; cnt < sizeof (fw->fpm_b1_reg) / 2; cnt++) { | ||
917 | if (cnt % 8 == 0) { | ||
918 | qla_uprintf(&uiter, "\n"); | ||
919 | } | ||
920 | qla_uprintf(&uiter, "%04x ", fw->fpm_b1_reg[cnt]); | ||
921 | } | ||
922 | |||
923 | qla_uprintf(&uiter, "\n\nRISC SRAM:"); | ||
924 | for (cnt = 0; cnt < sizeof (fw->risc_ram) / 2; cnt++) { | ||
925 | if (cnt % 8 == 0) { | ||
926 | qla_uprintf(&uiter, "\n%04x: ", cnt + 0x1000); | ||
927 | } | ||
928 | qla_uprintf(&uiter, "%04x ", fw->risc_ram[cnt]); | ||
929 | } | ||
930 | |||
931 | qla_uprintf(&uiter, "\n\n[<==END] ISP Debug Dump."); | ||
932 | |||
933 | return; | ||
934 | } | ||
935 | |||
936 | static int | ||
937 | qla_uprintf(char **uiter, char *fmt, ...) | ||
938 | { | ||
939 | int iter, len; | ||
940 | char buf[128]; | ||
941 | va_list args; | ||
942 | |||
943 | va_start(args, fmt); | ||
944 | len = vsprintf(buf, fmt, args); | ||
945 | va_end(args); | ||
946 | |||
947 | for (iter = 0; iter < len; iter++, *uiter += 1) | ||
948 | *uiter[0] = buf[iter]; | ||
949 | |||
950 | return (len); | ||
951 | } | ||
952 | |||
953 | |||
954 | void | 632 | void |
955 | qla24xx_fw_dump(scsi_qla_host_t *ha, int hardware_locked) | 633 | qla24xx_fw_dump(scsi_qla_host_t *ha, int hardware_locked) |
956 | { | 634 | { |
@@ -967,6 +645,7 @@ qla24xx_fw_dump(scsi_qla_host_t *ha, int hardware_locked) | |||
967 | unsigned long flags; | 645 | unsigned long flags; |
968 | struct qla24xx_fw_dump *fw; | 646 | struct qla24xx_fw_dump *fw; |
969 | uint32_t ext_mem_cnt; | 647 | uint32_t ext_mem_cnt; |
648 | void *eft; | ||
970 | 649 | ||
971 | risc_address = ext_mem_cnt = 0; | 650 | risc_address = ext_mem_cnt = 0; |
972 | memset(mb, 0, sizeof(mb)); | 651 | memset(mb, 0, sizeof(mb)); |
@@ -987,10 +666,11 @@ qla24xx_fw_dump(scsi_qla_host_t *ha, int hardware_locked) | |||
987 | "request...\n", ha->fw_dump); | 666 | "request...\n", ha->fw_dump); |
988 | goto qla24xx_fw_dump_failed; | 667 | goto qla24xx_fw_dump_failed; |
989 | } | 668 | } |
990 | fw = ha->fw_dump; | 669 | fw = &ha->fw_dump->isp.isp24; |
670 | qla2xxx_prep_dump(ha, ha->fw_dump); | ||
991 | 671 | ||
992 | rval = QLA_SUCCESS; | 672 | rval = QLA_SUCCESS; |
993 | fw->host_status = RD_REG_DWORD(®->host_status); | 673 | fw->host_status = htonl(RD_REG_DWORD(®->host_status)); |
994 | 674 | ||
995 | /* Pause RISC. */ | 675 | /* Pause RISC. */ |
996 | if ((RD_REG_DWORD(®->hccr) & HCCRX_RISC_PAUSE) == 0) { | 676 | if ((RD_REG_DWORD(®->hccr) & HCCRX_RISC_PAUSE) == 0) { |
@@ -1012,7 +692,7 @@ qla24xx_fw_dump(scsi_qla_host_t *ha, int hardware_locked) | |||
1012 | /* Host interface registers. */ | 692 | /* Host interface registers. */ |
1013 | dmp_reg = (uint32_t __iomem *)(reg + 0); | 693 | dmp_reg = (uint32_t __iomem *)(reg + 0); |
1014 | for (cnt = 0; cnt < sizeof(fw->host_reg) / 4; cnt++) | 694 | for (cnt = 0; cnt < sizeof(fw->host_reg) / 4; cnt++) |
1015 | fw->host_reg[cnt] = RD_REG_DWORD(dmp_reg++); | 695 | fw->host_reg[cnt] = htonl(RD_REG_DWORD(dmp_reg++)); |
1016 | 696 | ||
1017 | /* Disable interrupts. */ | 697 | /* Disable interrupts. */ |
1018 | WRT_REG_DWORD(®->ictrl, 0); | 698 | WRT_REG_DWORD(®->ictrl, 0); |
@@ -1024,470 +704,471 @@ qla24xx_fw_dump(scsi_qla_host_t *ha, int hardware_locked) | |||
1024 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xF0); | 704 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xF0); |
1025 | WRT_REG_DWORD(dmp_reg, 0xB0000000); | 705 | WRT_REG_DWORD(dmp_reg, 0xB0000000); |
1026 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xFC); | 706 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xFC); |
1027 | fw->shadow_reg[0] = RD_REG_DWORD(dmp_reg); | 707 | fw->shadow_reg[0] = htonl(RD_REG_DWORD(dmp_reg)); |
1028 | 708 | ||
1029 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xF0); | 709 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xF0); |
1030 | WRT_REG_DWORD(dmp_reg, 0xB0100000); | 710 | WRT_REG_DWORD(dmp_reg, 0xB0100000); |
1031 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xFC); | 711 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xFC); |
1032 | fw->shadow_reg[1] = RD_REG_DWORD(dmp_reg); | 712 | fw->shadow_reg[1] = htonl(RD_REG_DWORD(dmp_reg)); |
1033 | 713 | ||
1034 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xF0); | 714 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xF0); |
1035 | WRT_REG_DWORD(dmp_reg, 0xB0200000); | 715 | WRT_REG_DWORD(dmp_reg, 0xB0200000); |
1036 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xFC); | 716 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xFC); |
1037 | fw->shadow_reg[2] = RD_REG_DWORD(dmp_reg); | 717 | fw->shadow_reg[2] = htonl(RD_REG_DWORD(dmp_reg)); |
1038 | 718 | ||
1039 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xF0); | 719 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xF0); |
1040 | WRT_REG_DWORD(dmp_reg, 0xB0300000); | 720 | WRT_REG_DWORD(dmp_reg, 0xB0300000); |
1041 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xFC); | 721 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xFC); |
1042 | fw->shadow_reg[3] = RD_REG_DWORD(dmp_reg); | 722 | fw->shadow_reg[3] = htonl(RD_REG_DWORD(dmp_reg)); |
1043 | 723 | ||
1044 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xF0); | 724 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xF0); |
1045 | WRT_REG_DWORD(dmp_reg, 0xB0400000); | 725 | WRT_REG_DWORD(dmp_reg, 0xB0400000); |
1046 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xFC); | 726 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xFC); |
1047 | fw->shadow_reg[4] = RD_REG_DWORD(dmp_reg); | 727 | fw->shadow_reg[4] = htonl(RD_REG_DWORD(dmp_reg)); |
1048 | 728 | ||
1049 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xF0); | 729 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xF0); |
1050 | WRT_REG_DWORD(dmp_reg, 0xB0500000); | 730 | WRT_REG_DWORD(dmp_reg, 0xB0500000); |
1051 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xFC); | 731 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xFC); |
1052 | fw->shadow_reg[5] = RD_REG_DWORD(dmp_reg); | 732 | fw->shadow_reg[5] = htonl(RD_REG_DWORD(dmp_reg)); |
1053 | 733 | ||
1054 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xF0); | 734 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xF0); |
1055 | WRT_REG_DWORD(dmp_reg, 0xB0600000); | 735 | WRT_REG_DWORD(dmp_reg, 0xB0600000); |
1056 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xFC); | 736 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xFC); |
1057 | fw->shadow_reg[6] = RD_REG_DWORD(dmp_reg); | 737 | fw->shadow_reg[6] = htonl(RD_REG_DWORD(dmp_reg)); |
1058 | 738 | ||
1059 | /* Mailbox registers. */ | 739 | /* Mailbox registers. */ |
1060 | mbx_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); | 740 | mbx_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); |
1061 | for (cnt = 0; cnt < sizeof(fw->mailbox_reg) / 2; cnt++) | 741 | for (cnt = 0; cnt < sizeof(fw->mailbox_reg) / 2; cnt++) |
1062 | fw->mailbox_reg[cnt] = RD_REG_WORD(mbx_reg++); | 742 | fw->mailbox_reg[cnt] = htons(RD_REG_WORD(mbx_reg++)); |
1063 | 743 | ||
1064 | /* Transfer sequence registers. */ | 744 | /* Transfer sequence registers. */ |
1065 | iter_reg = fw->xseq_gp_reg; | 745 | iter_reg = fw->xseq_gp_reg; |
1066 | WRT_REG_DWORD(®->iobase_addr, 0xBF00); | 746 | WRT_REG_DWORD(®->iobase_addr, 0xBF00); |
1067 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 747 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1068 | for (cnt = 0; cnt < 16; cnt++) | 748 | for (cnt = 0; cnt < 16; cnt++) |
1069 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 749 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1070 | 750 | ||
1071 | WRT_REG_DWORD(®->iobase_addr, 0xBF10); | 751 | WRT_REG_DWORD(®->iobase_addr, 0xBF10); |
1072 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 752 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1073 | for (cnt = 0; cnt < 16; cnt++) | 753 | for (cnt = 0; cnt < 16; cnt++) |
1074 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 754 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1075 | 755 | ||
1076 | WRT_REG_DWORD(®->iobase_addr, 0xBF20); | 756 | WRT_REG_DWORD(®->iobase_addr, 0xBF20); |
1077 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 757 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1078 | for (cnt = 0; cnt < 16; cnt++) | 758 | for (cnt = 0; cnt < 16; cnt++) |
1079 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 759 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1080 | 760 | ||
1081 | WRT_REG_DWORD(®->iobase_addr, 0xBF30); | 761 | WRT_REG_DWORD(®->iobase_addr, 0xBF30); |
1082 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 762 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1083 | for (cnt = 0; cnt < 16; cnt++) | 763 | for (cnt = 0; cnt < 16; cnt++) |
1084 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 764 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1085 | 765 | ||
1086 | WRT_REG_DWORD(®->iobase_addr, 0xBF40); | 766 | WRT_REG_DWORD(®->iobase_addr, 0xBF40); |
1087 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 767 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1088 | for (cnt = 0; cnt < 16; cnt++) | 768 | for (cnt = 0; cnt < 16; cnt++) |
1089 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 769 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1090 | 770 | ||
1091 | WRT_REG_DWORD(®->iobase_addr, 0xBF50); | 771 | WRT_REG_DWORD(®->iobase_addr, 0xBF50); |
1092 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 772 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1093 | for (cnt = 0; cnt < 16; cnt++) | 773 | for (cnt = 0; cnt < 16; cnt++) |
1094 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 774 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1095 | 775 | ||
1096 | WRT_REG_DWORD(®->iobase_addr, 0xBF60); | 776 | WRT_REG_DWORD(®->iobase_addr, 0xBF60); |
1097 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 777 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1098 | for (cnt = 0; cnt < 16; cnt++) | 778 | for (cnt = 0; cnt < 16; cnt++) |
1099 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 779 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1100 | 780 | ||
1101 | WRT_REG_DWORD(®->iobase_addr, 0xBF70); | 781 | WRT_REG_DWORD(®->iobase_addr, 0xBF70); |
1102 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 782 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1103 | for (cnt = 0; cnt < 16; cnt++) | 783 | for (cnt = 0; cnt < 16; cnt++) |
1104 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 784 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1105 | 785 | ||
1106 | WRT_REG_DWORD(®->iobase_addr, 0xBFE0); | 786 | WRT_REG_DWORD(®->iobase_addr, 0xBFE0); |
1107 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 787 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1108 | for (cnt = 0; cnt < sizeof(fw->xseq_0_reg) / 4; cnt++) | 788 | for (cnt = 0; cnt < sizeof(fw->xseq_0_reg) / 4; cnt++) |
1109 | fw->xseq_0_reg[cnt] = RD_REG_DWORD(dmp_reg++); | 789 | fw->xseq_0_reg[cnt] = htonl(RD_REG_DWORD(dmp_reg++)); |
1110 | 790 | ||
1111 | WRT_REG_DWORD(®->iobase_addr, 0xBFF0); | 791 | WRT_REG_DWORD(®->iobase_addr, 0xBFF0); |
1112 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 792 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1113 | for (cnt = 0; cnt < sizeof(fw->xseq_1_reg) / 4; cnt++) | 793 | for (cnt = 0; cnt < sizeof(fw->xseq_1_reg) / 4; cnt++) |
1114 | fw->xseq_1_reg[cnt] = RD_REG_DWORD(dmp_reg++); | 794 | fw->xseq_1_reg[cnt] = htonl(RD_REG_DWORD(dmp_reg++)); |
1115 | 795 | ||
1116 | /* Receive sequence registers. */ | 796 | /* Receive sequence registers. */ |
1117 | iter_reg = fw->rseq_gp_reg; | 797 | iter_reg = fw->rseq_gp_reg; |
1118 | WRT_REG_DWORD(®->iobase_addr, 0xFF00); | 798 | WRT_REG_DWORD(®->iobase_addr, 0xFF00); |
1119 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 799 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1120 | for (cnt = 0; cnt < 16; cnt++) | 800 | for (cnt = 0; cnt < 16; cnt++) |
1121 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 801 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1122 | 802 | ||
1123 | WRT_REG_DWORD(®->iobase_addr, 0xFF10); | 803 | WRT_REG_DWORD(®->iobase_addr, 0xFF10); |
1124 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 804 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1125 | for (cnt = 0; cnt < 16; cnt++) | 805 | for (cnt = 0; cnt < 16; cnt++) |
1126 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 806 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1127 | 807 | ||
1128 | WRT_REG_DWORD(®->iobase_addr, 0xFF20); | 808 | WRT_REG_DWORD(®->iobase_addr, 0xFF20); |
1129 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 809 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1130 | for (cnt = 0; cnt < 16; cnt++) | 810 | for (cnt = 0; cnt < 16; cnt++) |
1131 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 811 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1132 | 812 | ||
1133 | WRT_REG_DWORD(®->iobase_addr, 0xFF30); | 813 | WRT_REG_DWORD(®->iobase_addr, 0xFF30); |
1134 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 814 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1135 | for (cnt = 0; cnt < 16; cnt++) | 815 | for (cnt = 0; cnt < 16; cnt++) |
1136 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 816 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1137 | 817 | ||
1138 | WRT_REG_DWORD(®->iobase_addr, 0xFF40); | 818 | WRT_REG_DWORD(®->iobase_addr, 0xFF40); |
1139 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 819 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1140 | for (cnt = 0; cnt < 16; cnt++) | 820 | for (cnt = 0; cnt < 16; cnt++) |
1141 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 821 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1142 | 822 | ||
1143 | WRT_REG_DWORD(®->iobase_addr, 0xFF50); | 823 | WRT_REG_DWORD(®->iobase_addr, 0xFF50); |
1144 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 824 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1145 | for (cnt = 0; cnt < 16; cnt++) | 825 | for (cnt = 0; cnt < 16; cnt++) |
1146 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 826 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1147 | 827 | ||
1148 | WRT_REG_DWORD(®->iobase_addr, 0xFF60); | 828 | WRT_REG_DWORD(®->iobase_addr, 0xFF60); |
1149 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 829 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1150 | for (cnt = 0; cnt < 16; cnt++) | 830 | for (cnt = 0; cnt < 16; cnt++) |
1151 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 831 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1152 | 832 | ||
1153 | WRT_REG_DWORD(®->iobase_addr, 0xFF70); | 833 | WRT_REG_DWORD(®->iobase_addr, 0xFF70); |
1154 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 834 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1155 | for (cnt = 0; cnt < 16; cnt++) | 835 | for (cnt = 0; cnt < 16; cnt++) |
1156 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 836 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1157 | 837 | ||
1158 | WRT_REG_DWORD(®->iobase_addr, 0xFFD0); | 838 | WRT_REG_DWORD(®->iobase_addr, 0xFFD0); |
1159 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 839 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1160 | for (cnt = 0; cnt < sizeof(fw->rseq_0_reg) / 4; cnt++) | 840 | for (cnt = 0; cnt < sizeof(fw->rseq_0_reg) / 4; cnt++) |
1161 | fw->rseq_0_reg[cnt] = RD_REG_DWORD(dmp_reg++); | 841 | fw->rseq_0_reg[cnt] = htonl(RD_REG_DWORD(dmp_reg++)); |
1162 | 842 | ||
1163 | WRT_REG_DWORD(®->iobase_addr, 0xFFE0); | 843 | WRT_REG_DWORD(®->iobase_addr, 0xFFE0); |
1164 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 844 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1165 | for (cnt = 0; cnt < sizeof(fw->rseq_1_reg) / 4; cnt++) | 845 | for (cnt = 0; cnt < sizeof(fw->rseq_1_reg) / 4; cnt++) |
1166 | fw->rseq_1_reg[cnt] = RD_REG_DWORD(dmp_reg++); | 846 | fw->rseq_1_reg[cnt] = htonl(RD_REG_DWORD(dmp_reg++)); |
1167 | 847 | ||
1168 | WRT_REG_DWORD(®->iobase_addr, 0xFFF0); | 848 | WRT_REG_DWORD(®->iobase_addr, 0xFFF0); |
1169 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 849 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1170 | for (cnt = 0; cnt < sizeof(fw->rseq_2_reg) / 4; cnt++) | 850 | for (cnt = 0; cnt < sizeof(fw->rseq_2_reg) / 4; cnt++) |
1171 | fw->rseq_2_reg[cnt] = RD_REG_DWORD(dmp_reg++); | 851 | fw->rseq_2_reg[cnt] = htonl(RD_REG_DWORD(dmp_reg++)); |
1172 | 852 | ||
1173 | /* Command DMA registers. */ | 853 | /* Command DMA registers. */ |
1174 | WRT_REG_DWORD(®->iobase_addr, 0x7100); | 854 | WRT_REG_DWORD(®->iobase_addr, 0x7100); |
1175 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 855 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1176 | for (cnt = 0; cnt < sizeof(fw->cmd_dma_reg) / 4; cnt++) | 856 | for (cnt = 0; cnt < sizeof(fw->cmd_dma_reg) / 4; cnt++) |
1177 | fw->cmd_dma_reg[cnt] = RD_REG_DWORD(dmp_reg++); | 857 | fw->cmd_dma_reg[cnt] = htonl(RD_REG_DWORD(dmp_reg++)); |
1178 | 858 | ||
1179 | /* Queues. */ | 859 | /* Queues. */ |
1180 | iter_reg = fw->req0_dma_reg; | 860 | iter_reg = fw->req0_dma_reg; |
1181 | WRT_REG_DWORD(®->iobase_addr, 0x7200); | 861 | WRT_REG_DWORD(®->iobase_addr, 0x7200); |
1182 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 862 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1183 | for (cnt = 0; cnt < 8; cnt++) | 863 | for (cnt = 0; cnt < 8; cnt++) |
1184 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 864 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1185 | 865 | ||
1186 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xE4); | 866 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xE4); |
1187 | for (cnt = 0; cnt < 7; cnt++) | 867 | for (cnt = 0; cnt < 7; cnt++) |
1188 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 868 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1189 | 869 | ||
1190 | iter_reg = fw->resp0_dma_reg; | 870 | iter_reg = fw->resp0_dma_reg; |
1191 | WRT_REG_DWORD(®->iobase_addr, 0x7300); | 871 | WRT_REG_DWORD(®->iobase_addr, 0x7300); |
1192 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 872 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1193 | for (cnt = 0; cnt < 8; cnt++) | 873 | for (cnt = 0; cnt < 8; cnt++) |
1194 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 874 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1195 | 875 | ||
1196 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xE4); | 876 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xE4); |
1197 | for (cnt = 0; cnt < 7; cnt++) | 877 | for (cnt = 0; cnt < 7; cnt++) |
1198 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 878 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1199 | 879 | ||
1200 | iter_reg = fw->req1_dma_reg; | 880 | iter_reg = fw->req1_dma_reg; |
1201 | WRT_REG_DWORD(®->iobase_addr, 0x7400); | 881 | WRT_REG_DWORD(®->iobase_addr, 0x7400); |
1202 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 882 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1203 | for (cnt = 0; cnt < 8; cnt++) | 883 | for (cnt = 0; cnt < 8; cnt++) |
1204 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 884 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1205 | 885 | ||
1206 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xE4); | 886 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xE4); |
1207 | for (cnt = 0; cnt < 7; cnt++) | 887 | for (cnt = 0; cnt < 7; cnt++) |
1208 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 888 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1209 | 889 | ||
1210 | /* Transmit DMA registers. */ | 890 | /* Transmit DMA registers. */ |
1211 | iter_reg = fw->xmt0_dma_reg; | 891 | iter_reg = fw->xmt0_dma_reg; |
1212 | WRT_REG_DWORD(®->iobase_addr, 0x7600); | 892 | WRT_REG_DWORD(®->iobase_addr, 0x7600); |
1213 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 893 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1214 | for (cnt = 0; cnt < 16; cnt++) | 894 | for (cnt = 0; cnt < 16; cnt++) |
1215 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 895 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1216 | 896 | ||
1217 | WRT_REG_DWORD(®->iobase_addr, 0x7610); | 897 | WRT_REG_DWORD(®->iobase_addr, 0x7610); |
1218 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 898 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1219 | for (cnt = 0; cnt < 16; cnt++) | 899 | for (cnt = 0; cnt < 16; cnt++) |
1220 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 900 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1221 | 901 | ||
1222 | iter_reg = fw->xmt1_dma_reg; | 902 | iter_reg = fw->xmt1_dma_reg; |
1223 | WRT_REG_DWORD(®->iobase_addr, 0x7620); | 903 | WRT_REG_DWORD(®->iobase_addr, 0x7620); |
1224 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 904 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1225 | for (cnt = 0; cnt < 16; cnt++) | 905 | for (cnt = 0; cnt < 16; cnt++) |
1226 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 906 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1227 | 907 | ||
1228 | WRT_REG_DWORD(®->iobase_addr, 0x7630); | 908 | WRT_REG_DWORD(®->iobase_addr, 0x7630); |
1229 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 909 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1230 | for (cnt = 0; cnt < 16; cnt++) | 910 | for (cnt = 0; cnt < 16; cnt++) |
1231 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 911 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1232 | 912 | ||
1233 | iter_reg = fw->xmt2_dma_reg; | 913 | iter_reg = fw->xmt2_dma_reg; |
1234 | WRT_REG_DWORD(®->iobase_addr, 0x7640); | 914 | WRT_REG_DWORD(®->iobase_addr, 0x7640); |
1235 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 915 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1236 | for (cnt = 0; cnt < 16; cnt++) | 916 | for (cnt = 0; cnt < 16; cnt++) |
1237 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 917 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1238 | 918 | ||
1239 | WRT_REG_DWORD(®->iobase_addr, 0x7650); | 919 | WRT_REG_DWORD(®->iobase_addr, 0x7650); |
1240 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 920 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1241 | for (cnt = 0; cnt < 16; cnt++) | 921 | for (cnt = 0; cnt < 16; cnt++) |
1242 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 922 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1243 | 923 | ||
1244 | iter_reg = fw->xmt3_dma_reg; | 924 | iter_reg = fw->xmt3_dma_reg; |
1245 | WRT_REG_DWORD(®->iobase_addr, 0x7660); | 925 | WRT_REG_DWORD(®->iobase_addr, 0x7660); |
1246 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 926 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1247 | for (cnt = 0; cnt < 16; cnt++) | 927 | for (cnt = 0; cnt < 16; cnt++) |
1248 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 928 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1249 | 929 | ||
1250 | WRT_REG_DWORD(®->iobase_addr, 0x7670); | 930 | WRT_REG_DWORD(®->iobase_addr, 0x7670); |
1251 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 931 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1252 | for (cnt = 0; cnt < 16; cnt++) | 932 | for (cnt = 0; cnt < 16; cnt++) |
1253 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 933 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1254 | 934 | ||
1255 | iter_reg = fw->xmt4_dma_reg; | 935 | iter_reg = fw->xmt4_dma_reg; |
1256 | WRT_REG_DWORD(®->iobase_addr, 0x7680); | 936 | WRT_REG_DWORD(®->iobase_addr, 0x7680); |
1257 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 937 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1258 | for (cnt = 0; cnt < 16; cnt++) | 938 | for (cnt = 0; cnt < 16; cnt++) |
1259 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 939 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1260 | 940 | ||
1261 | WRT_REG_DWORD(®->iobase_addr, 0x7690); | 941 | WRT_REG_DWORD(®->iobase_addr, 0x7690); |
1262 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 942 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1263 | for (cnt = 0; cnt < 16; cnt++) | 943 | for (cnt = 0; cnt < 16; cnt++) |
1264 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 944 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1265 | 945 | ||
1266 | WRT_REG_DWORD(®->iobase_addr, 0x76A0); | 946 | WRT_REG_DWORD(®->iobase_addr, 0x76A0); |
1267 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 947 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1268 | for (cnt = 0; cnt < sizeof(fw->xmt_data_dma_reg) / 4; cnt++) | 948 | for (cnt = 0; cnt < sizeof(fw->xmt_data_dma_reg) / 4; cnt++) |
1269 | fw->xmt_data_dma_reg[cnt] = RD_REG_DWORD(dmp_reg++); | 949 | fw->xmt_data_dma_reg[cnt] = |
950 | htonl(RD_REG_DWORD(dmp_reg++)); | ||
1270 | 951 | ||
1271 | /* Receive DMA registers. */ | 952 | /* Receive DMA registers. */ |
1272 | iter_reg = fw->rcvt0_data_dma_reg; | 953 | iter_reg = fw->rcvt0_data_dma_reg; |
1273 | WRT_REG_DWORD(®->iobase_addr, 0x7700); | 954 | WRT_REG_DWORD(®->iobase_addr, 0x7700); |
1274 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 955 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1275 | for (cnt = 0; cnt < 16; cnt++) | 956 | for (cnt = 0; cnt < 16; cnt++) |
1276 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 957 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1277 | 958 | ||
1278 | WRT_REG_DWORD(®->iobase_addr, 0x7710); | 959 | WRT_REG_DWORD(®->iobase_addr, 0x7710); |
1279 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 960 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1280 | for (cnt = 0; cnt < 16; cnt++) | 961 | for (cnt = 0; cnt < 16; cnt++) |
1281 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 962 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1282 | 963 | ||
1283 | iter_reg = fw->rcvt1_data_dma_reg; | 964 | iter_reg = fw->rcvt1_data_dma_reg; |
1284 | WRT_REG_DWORD(®->iobase_addr, 0x7720); | 965 | WRT_REG_DWORD(®->iobase_addr, 0x7720); |
1285 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 966 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1286 | for (cnt = 0; cnt < 16; cnt++) | 967 | for (cnt = 0; cnt < 16; cnt++) |
1287 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 968 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1288 | 969 | ||
1289 | WRT_REG_DWORD(®->iobase_addr, 0x7730); | 970 | WRT_REG_DWORD(®->iobase_addr, 0x7730); |
1290 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 971 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1291 | for (cnt = 0; cnt < 16; cnt++) | 972 | for (cnt = 0; cnt < 16; cnt++) |
1292 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 973 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1293 | 974 | ||
1294 | /* RISC registers. */ | 975 | /* RISC registers. */ |
1295 | iter_reg = fw->risc_gp_reg; | 976 | iter_reg = fw->risc_gp_reg; |
1296 | WRT_REG_DWORD(®->iobase_addr, 0x0F00); | 977 | WRT_REG_DWORD(®->iobase_addr, 0x0F00); |
1297 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 978 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1298 | for (cnt = 0; cnt < 16; cnt++) | 979 | for (cnt = 0; cnt < 16; cnt++) |
1299 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 980 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1300 | 981 | ||
1301 | WRT_REG_DWORD(®->iobase_addr, 0x0F10); | 982 | WRT_REG_DWORD(®->iobase_addr, 0x0F10); |
1302 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 983 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1303 | for (cnt = 0; cnt < 16; cnt++) | 984 | for (cnt = 0; cnt < 16; cnt++) |
1304 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 985 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1305 | 986 | ||
1306 | WRT_REG_DWORD(®->iobase_addr, 0x0F20); | 987 | WRT_REG_DWORD(®->iobase_addr, 0x0F20); |
1307 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 988 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1308 | for (cnt = 0; cnt < 16; cnt++) | 989 | for (cnt = 0; cnt < 16; cnt++) |
1309 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 990 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1310 | 991 | ||
1311 | WRT_REG_DWORD(®->iobase_addr, 0x0F30); | 992 | WRT_REG_DWORD(®->iobase_addr, 0x0F30); |
1312 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 993 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1313 | for (cnt = 0; cnt < 16; cnt++) | 994 | for (cnt = 0; cnt < 16; cnt++) |
1314 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 995 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1315 | 996 | ||
1316 | WRT_REG_DWORD(®->iobase_addr, 0x0F40); | 997 | WRT_REG_DWORD(®->iobase_addr, 0x0F40); |
1317 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 998 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1318 | for (cnt = 0; cnt < 16; cnt++) | 999 | for (cnt = 0; cnt < 16; cnt++) |
1319 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 1000 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1320 | 1001 | ||
1321 | WRT_REG_DWORD(®->iobase_addr, 0x0F50); | 1002 | WRT_REG_DWORD(®->iobase_addr, 0x0F50); |
1322 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 1003 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1323 | for (cnt = 0; cnt < 16; cnt++) | 1004 | for (cnt = 0; cnt < 16; cnt++) |
1324 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 1005 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1325 | 1006 | ||
1326 | WRT_REG_DWORD(®->iobase_addr, 0x0F60); | 1007 | WRT_REG_DWORD(®->iobase_addr, 0x0F60); |
1327 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 1008 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1328 | for (cnt = 0; cnt < 16; cnt++) | 1009 | for (cnt = 0; cnt < 16; cnt++) |
1329 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 1010 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1330 | 1011 | ||
1331 | WRT_REG_DWORD(®->iobase_addr, 0x0F70); | 1012 | WRT_REG_DWORD(®->iobase_addr, 0x0F70); |
1332 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 1013 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1333 | for (cnt = 0; cnt < 16; cnt++) | 1014 | for (cnt = 0; cnt < 16; cnt++) |
1334 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 1015 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1335 | 1016 | ||
1336 | /* Local memory controller registers. */ | 1017 | /* Local memory controller registers. */ |
1337 | iter_reg = fw->lmc_reg; | 1018 | iter_reg = fw->lmc_reg; |
1338 | WRT_REG_DWORD(®->iobase_addr, 0x3000); | 1019 | WRT_REG_DWORD(®->iobase_addr, 0x3000); |
1339 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 1020 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1340 | for (cnt = 0; cnt < 16; cnt++) | 1021 | for (cnt = 0; cnt < 16; cnt++) |
1341 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 1022 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1342 | 1023 | ||
1343 | WRT_REG_DWORD(®->iobase_addr, 0x3010); | 1024 | WRT_REG_DWORD(®->iobase_addr, 0x3010); |
1344 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 1025 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1345 | for (cnt = 0; cnt < 16; cnt++) | 1026 | for (cnt = 0; cnt < 16; cnt++) |
1346 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 1027 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1347 | 1028 | ||
1348 | WRT_REG_DWORD(®->iobase_addr, 0x3020); | 1029 | WRT_REG_DWORD(®->iobase_addr, 0x3020); |
1349 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 1030 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1350 | for (cnt = 0; cnt < 16; cnt++) | 1031 | for (cnt = 0; cnt < 16; cnt++) |
1351 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 1032 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1352 | 1033 | ||
1353 | WRT_REG_DWORD(®->iobase_addr, 0x3030); | 1034 | WRT_REG_DWORD(®->iobase_addr, 0x3030); |
1354 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 1035 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1355 | for (cnt = 0; cnt < 16; cnt++) | 1036 | for (cnt = 0; cnt < 16; cnt++) |
1356 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 1037 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1357 | 1038 | ||
1358 | WRT_REG_DWORD(®->iobase_addr, 0x3040); | 1039 | WRT_REG_DWORD(®->iobase_addr, 0x3040); |
1359 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 1040 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1360 | for (cnt = 0; cnt < 16; cnt++) | 1041 | for (cnt = 0; cnt < 16; cnt++) |
1361 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 1042 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1362 | 1043 | ||
1363 | WRT_REG_DWORD(®->iobase_addr, 0x3050); | 1044 | WRT_REG_DWORD(®->iobase_addr, 0x3050); |
1364 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 1045 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1365 | for (cnt = 0; cnt < 16; cnt++) | 1046 | for (cnt = 0; cnt < 16; cnt++) |
1366 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 1047 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1367 | 1048 | ||
1368 | WRT_REG_DWORD(®->iobase_addr, 0x3060); | 1049 | WRT_REG_DWORD(®->iobase_addr, 0x3060); |
1369 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 1050 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1370 | for (cnt = 0; cnt < 16; cnt++) | 1051 | for (cnt = 0; cnt < 16; cnt++) |
1371 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 1052 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1372 | 1053 | ||
1373 | /* Fibre Protocol Module registers. */ | 1054 | /* Fibre Protocol Module registers. */ |
1374 | iter_reg = fw->fpm_hdw_reg; | 1055 | iter_reg = fw->fpm_hdw_reg; |
1375 | WRT_REG_DWORD(®->iobase_addr, 0x4000); | 1056 | WRT_REG_DWORD(®->iobase_addr, 0x4000); |
1376 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 1057 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1377 | for (cnt = 0; cnt < 16; cnt++) | 1058 | for (cnt = 0; cnt < 16; cnt++) |
1378 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 1059 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1379 | 1060 | ||
1380 | WRT_REG_DWORD(®->iobase_addr, 0x4010); | 1061 | WRT_REG_DWORD(®->iobase_addr, 0x4010); |
1381 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 1062 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1382 | for (cnt = 0; cnt < 16; cnt++) | 1063 | for (cnt = 0; cnt < 16; cnt++) |
1383 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 1064 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1384 | 1065 | ||
1385 | WRT_REG_DWORD(®->iobase_addr, 0x4020); | 1066 | WRT_REG_DWORD(®->iobase_addr, 0x4020); |
1386 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 1067 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1387 | for (cnt = 0; cnt < 16; cnt++) | 1068 | for (cnt = 0; cnt < 16; cnt++) |
1388 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 1069 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1389 | 1070 | ||
1390 | WRT_REG_DWORD(®->iobase_addr, 0x4030); | 1071 | WRT_REG_DWORD(®->iobase_addr, 0x4030); |
1391 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 1072 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1392 | for (cnt = 0; cnt < 16; cnt++) | 1073 | for (cnt = 0; cnt < 16; cnt++) |
1393 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 1074 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1394 | 1075 | ||
1395 | WRT_REG_DWORD(®->iobase_addr, 0x4040); | 1076 | WRT_REG_DWORD(®->iobase_addr, 0x4040); |
1396 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 1077 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1397 | for (cnt = 0; cnt < 16; cnt++) | 1078 | for (cnt = 0; cnt < 16; cnt++) |
1398 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 1079 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1399 | 1080 | ||
1400 | WRT_REG_DWORD(®->iobase_addr, 0x4050); | 1081 | WRT_REG_DWORD(®->iobase_addr, 0x4050); |
1401 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 1082 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1402 | for (cnt = 0; cnt < 16; cnt++) | 1083 | for (cnt = 0; cnt < 16; cnt++) |
1403 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 1084 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1404 | 1085 | ||
1405 | WRT_REG_DWORD(®->iobase_addr, 0x4060); | 1086 | WRT_REG_DWORD(®->iobase_addr, 0x4060); |
1406 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 1087 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1407 | for (cnt = 0; cnt < 16; cnt++) | 1088 | for (cnt = 0; cnt < 16; cnt++) |
1408 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 1089 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1409 | 1090 | ||
1410 | WRT_REG_DWORD(®->iobase_addr, 0x4070); | 1091 | WRT_REG_DWORD(®->iobase_addr, 0x4070); |
1411 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 1092 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1412 | for (cnt = 0; cnt < 16; cnt++) | 1093 | for (cnt = 0; cnt < 16; cnt++) |
1413 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 1094 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1414 | 1095 | ||
1415 | WRT_REG_DWORD(®->iobase_addr, 0x4080); | 1096 | WRT_REG_DWORD(®->iobase_addr, 0x4080); |
1416 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 1097 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1417 | for (cnt = 0; cnt < 16; cnt++) | 1098 | for (cnt = 0; cnt < 16; cnt++) |
1418 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 1099 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1419 | 1100 | ||
1420 | WRT_REG_DWORD(®->iobase_addr, 0x4090); | 1101 | WRT_REG_DWORD(®->iobase_addr, 0x4090); |
1421 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 1102 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1422 | for (cnt = 0; cnt < 16; cnt++) | 1103 | for (cnt = 0; cnt < 16; cnt++) |
1423 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 1104 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1424 | 1105 | ||
1425 | WRT_REG_DWORD(®->iobase_addr, 0x40A0); | 1106 | WRT_REG_DWORD(®->iobase_addr, 0x40A0); |
1426 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 1107 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1427 | for (cnt = 0; cnt < 16; cnt++) | 1108 | for (cnt = 0; cnt < 16; cnt++) |
1428 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 1109 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1429 | 1110 | ||
1430 | WRT_REG_DWORD(®->iobase_addr, 0x40B0); | 1111 | WRT_REG_DWORD(®->iobase_addr, 0x40B0); |
1431 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 1112 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1432 | for (cnt = 0; cnt < 16; cnt++) | 1113 | for (cnt = 0; cnt < 16; cnt++) |
1433 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 1114 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1434 | 1115 | ||
1435 | /* Frame Buffer registers. */ | 1116 | /* Frame Buffer registers. */ |
1436 | iter_reg = fw->fb_hdw_reg; | 1117 | iter_reg = fw->fb_hdw_reg; |
1437 | WRT_REG_DWORD(®->iobase_addr, 0x6000); | 1118 | WRT_REG_DWORD(®->iobase_addr, 0x6000); |
1438 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 1119 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1439 | for (cnt = 0; cnt < 16; cnt++) | 1120 | for (cnt = 0; cnt < 16; cnt++) |
1440 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 1121 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1441 | 1122 | ||
1442 | WRT_REG_DWORD(®->iobase_addr, 0x6010); | 1123 | WRT_REG_DWORD(®->iobase_addr, 0x6010); |
1443 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 1124 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1444 | for (cnt = 0; cnt < 16; cnt++) | 1125 | for (cnt = 0; cnt < 16; cnt++) |
1445 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 1126 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1446 | 1127 | ||
1447 | WRT_REG_DWORD(®->iobase_addr, 0x6020); | 1128 | WRT_REG_DWORD(®->iobase_addr, 0x6020); |
1448 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 1129 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1449 | for (cnt = 0; cnt < 16; cnt++) | 1130 | for (cnt = 0; cnt < 16; cnt++) |
1450 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 1131 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1451 | 1132 | ||
1452 | WRT_REG_DWORD(®->iobase_addr, 0x6030); | 1133 | WRT_REG_DWORD(®->iobase_addr, 0x6030); |
1453 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 1134 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1454 | for (cnt = 0; cnt < 16; cnt++) | 1135 | for (cnt = 0; cnt < 16; cnt++) |
1455 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 1136 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1456 | 1137 | ||
1457 | WRT_REG_DWORD(®->iobase_addr, 0x6040); | 1138 | WRT_REG_DWORD(®->iobase_addr, 0x6040); |
1458 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 1139 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1459 | for (cnt = 0; cnt < 16; cnt++) | 1140 | for (cnt = 0; cnt < 16; cnt++) |
1460 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 1141 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1461 | 1142 | ||
1462 | WRT_REG_DWORD(®->iobase_addr, 0x6100); | 1143 | WRT_REG_DWORD(®->iobase_addr, 0x6100); |
1463 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 1144 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1464 | for (cnt = 0; cnt < 16; cnt++) | 1145 | for (cnt = 0; cnt < 16; cnt++) |
1465 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 1146 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1466 | 1147 | ||
1467 | WRT_REG_DWORD(®->iobase_addr, 0x6130); | 1148 | WRT_REG_DWORD(®->iobase_addr, 0x6130); |
1468 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 1149 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1469 | for (cnt = 0; cnt < 16; cnt++) | 1150 | for (cnt = 0; cnt < 16; cnt++) |
1470 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 1151 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1471 | 1152 | ||
1472 | WRT_REG_DWORD(®->iobase_addr, 0x6150); | 1153 | WRT_REG_DWORD(®->iobase_addr, 0x6150); |
1473 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 1154 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1474 | for (cnt = 0; cnt < 16; cnt++) | 1155 | for (cnt = 0; cnt < 16; cnt++) |
1475 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 1156 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1476 | 1157 | ||
1477 | WRT_REG_DWORD(®->iobase_addr, 0x6170); | 1158 | WRT_REG_DWORD(®->iobase_addr, 0x6170); |
1478 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 1159 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1479 | for (cnt = 0; cnt < 16; cnt++) | 1160 | for (cnt = 0; cnt < 16; cnt++) |
1480 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 1161 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1481 | 1162 | ||
1482 | WRT_REG_DWORD(®->iobase_addr, 0x6190); | 1163 | WRT_REG_DWORD(®->iobase_addr, 0x6190); |
1483 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 1164 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1484 | for (cnt = 0; cnt < 16; cnt++) | 1165 | for (cnt = 0; cnt < 16; cnt++) |
1485 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 1166 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1486 | 1167 | ||
1487 | WRT_REG_DWORD(®->iobase_addr, 0x61B0); | 1168 | WRT_REG_DWORD(®->iobase_addr, 0x61B0); |
1488 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 1169 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1489 | for (cnt = 0; cnt < 16; cnt++) | 1170 | for (cnt = 0; cnt < 16; cnt++) |
1490 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 1171 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1491 | 1172 | ||
1492 | /* Reset RISC. */ | 1173 | /* Reset RISC. */ |
1493 | WRT_REG_DWORD(®->ctrl_status, | 1174 | WRT_REG_DWORD(®->ctrl_status, |
@@ -1577,7 +1258,7 @@ qla24xx_fw_dump(scsi_qla_host_t *ha, int hardware_locked) | |||
1577 | 1258 | ||
1578 | if (test_and_clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags)) { | 1259 | if (test_and_clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags)) { |
1579 | rval = mb[0] & MBS_MASK; | 1260 | rval = mb[0] & MBS_MASK; |
1580 | fw->code_ram[cnt] = (mb[3] << 16) | mb[2]; | 1261 | fw->code_ram[cnt] = htonl((mb[3] << 16) | mb[2]); |
1581 | } else { | 1262 | } else { |
1582 | rval = QLA_FUNCTION_FAILED; | 1263 | rval = QLA_FUNCTION_FAILED; |
1583 | } | 1264 | } |
@@ -1627,12 +1308,18 @@ qla24xx_fw_dump(scsi_qla_host_t *ha, int hardware_locked) | |||
1627 | 1308 | ||
1628 | if (test_and_clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags)) { | 1309 | if (test_and_clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags)) { |
1629 | rval = mb[0] & MBS_MASK; | 1310 | rval = mb[0] & MBS_MASK; |
1630 | fw->ext_mem[cnt] = (mb[3] << 16) | mb[2]; | 1311 | fw->ext_mem[cnt] = htonl((mb[3] << 16) | mb[2]); |
1631 | } else { | 1312 | } else { |
1632 | rval = QLA_FUNCTION_FAILED; | 1313 | rval = QLA_FUNCTION_FAILED; |
1633 | } | 1314 | } |
1634 | } | 1315 | } |
1635 | 1316 | ||
1317 | if (rval == QLA_SUCCESS) { | ||
1318 | eft = qla2xxx_copy_queues(ha, &fw->ext_mem[cnt]); | ||
1319 | if (ha->eft) | ||
1320 | memcpy(eft, ha->eft, ntohl(ha->fw_dump->eft_size)); | ||
1321 | } | ||
1322 | |||
1636 | if (rval != QLA_SUCCESS) { | 1323 | if (rval != QLA_SUCCESS) { |
1637 | qla_printk(KERN_WARNING, ha, | 1324 | qla_printk(KERN_WARNING, ha, |
1638 | "Failed to dump firmware (%x)!!!\n", rval); | 1325 | "Failed to dump firmware (%x)!!!\n", rval); |
@@ -1650,252 +1337,6 @@ qla24xx_fw_dump_failed: | |||
1650 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | 1337 | spin_unlock_irqrestore(&ha->hardware_lock, flags); |
1651 | } | 1338 | } |
1652 | 1339 | ||
1653 | void | ||
1654 | qla24xx_ascii_fw_dump(scsi_qla_host_t *ha) | ||
1655 | { | ||
1656 | uint32_t cnt; | ||
1657 | char *uiter; | ||
1658 | struct qla24xx_fw_dump *fw; | ||
1659 | uint32_t ext_mem_cnt; | ||
1660 | |||
1661 | uiter = ha->fw_dump_buffer; | ||
1662 | fw = ha->fw_dump; | ||
1663 | |||
1664 | qla_uprintf(&uiter, "ISP FW Version %d.%02d.%02d Attributes %04x\n", | ||
1665 | ha->fw_major_version, ha->fw_minor_version, | ||
1666 | ha->fw_subminor_version, ha->fw_attributes); | ||
1667 | |||
1668 | qla_uprintf(&uiter, "\nR2H Status Register\n%04x\n", fw->host_status); | ||
1669 | |||
1670 | qla_uprintf(&uiter, "\nHost Interface Registers"); | ||
1671 | for (cnt = 0; cnt < sizeof(fw->host_reg) / 4; cnt++) { | ||
1672 | if (cnt % 8 == 0) | ||
1673 | qla_uprintf(&uiter, "\n"); | ||
1674 | |||
1675 | qla_uprintf(&uiter, "%08x ", fw->host_reg[cnt]); | ||
1676 | } | ||
1677 | |||
1678 | qla_uprintf(&uiter, "\n\nShadow Registers"); | ||
1679 | for (cnt = 0; cnt < sizeof(fw->shadow_reg) / 4; cnt++) { | ||
1680 | if (cnt % 8 == 0) | ||
1681 | qla_uprintf(&uiter, "\n"); | ||
1682 | |||
1683 | qla_uprintf(&uiter, "%08x ", fw->shadow_reg[cnt]); | ||
1684 | } | ||
1685 | |||
1686 | qla_uprintf(&uiter, "\n\nMailbox Registers"); | ||
1687 | for (cnt = 0; cnt < sizeof(fw->mailbox_reg) / 2; cnt++) { | ||
1688 | if (cnt % 8 == 0) | ||
1689 | qla_uprintf(&uiter, "\n"); | ||
1690 | |||
1691 | qla_uprintf(&uiter, "%08x ", fw->mailbox_reg[cnt]); | ||
1692 | } | ||
1693 | |||
1694 | qla_uprintf(&uiter, "\n\nXSEQ GP Registers"); | ||
1695 | for (cnt = 0; cnt < sizeof(fw->xseq_gp_reg) / 4; cnt++) { | ||
1696 | if (cnt % 8 == 0) | ||
1697 | qla_uprintf(&uiter, "\n"); | ||
1698 | |||
1699 | qla_uprintf(&uiter, "%08x ", fw->xseq_gp_reg[cnt]); | ||
1700 | } | ||
1701 | |||
1702 | qla_uprintf(&uiter, "\n\nXSEQ-0 Registers"); | ||
1703 | for (cnt = 0; cnt < sizeof(fw->xseq_0_reg) / 4; cnt++) { | ||
1704 | if (cnt % 8 == 0) | ||
1705 | qla_uprintf(&uiter, "\n"); | ||
1706 | |||
1707 | qla_uprintf(&uiter, "%08x ", fw->xseq_0_reg[cnt]); | ||
1708 | } | ||
1709 | |||
1710 | qla_uprintf(&uiter, "\n\nXSEQ-1 Registers"); | ||
1711 | for (cnt = 0; cnt < sizeof(fw->xseq_1_reg) / 4; cnt++) { | ||
1712 | if (cnt % 8 == 0) | ||
1713 | qla_uprintf(&uiter, "\n"); | ||
1714 | |||
1715 | qla_uprintf(&uiter, "%08x ", fw->xseq_1_reg[cnt]); | ||
1716 | } | ||
1717 | |||
1718 | qla_uprintf(&uiter, "\n\nRSEQ GP Registers"); | ||
1719 | for (cnt = 0; cnt < sizeof(fw->rseq_gp_reg) / 4; cnt++) { | ||
1720 | if (cnt % 8 == 0) | ||
1721 | qla_uprintf(&uiter, "\n"); | ||
1722 | |||
1723 | qla_uprintf(&uiter, "%08x ", fw->rseq_gp_reg[cnt]); | ||
1724 | } | ||
1725 | |||
1726 | qla_uprintf(&uiter, "\n\nRSEQ-0 Registers"); | ||
1727 | for (cnt = 0; cnt < sizeof(fw->rseq_0_reg) / 4; cnt++) { | ||
1728 | if (cnt % 8 == 0) | ||
1729 | qla_uprintf(&uiter, "\n"); | ||
1730 | |||
1731 | qla_uprintf(&uiter, "%08x ", fw->rseq_0_reg[cnt]); | ||
1732 | } | ||
1733 | |||
1734 | qla_uprintf(&uiter, "\n\nRSEQ-1 Registers"); | ||
1735 | for (cnt = 0; cnt < sizeof(fw->rseq_1_reg) / 4; cnt++) { | ||
1736 | if (cnt % 8 == 0) | ||
1737 | qla_uprintf(&uiter, "\n"); | ||
1738 | |||
1739 | qla_uprintf(&uiter, "%08x ", fw->rseq_1_reg[cnt]); | ||
1740 | } | ||
1741 | |||
1742 | qla_uprintf(&uiter, "\n\nRSEQ-2 Registers"); | ||
1743 | for (cnt = 0; cnt < sizeof(fw->rseq_2_reg) / 4; cnt++) { | ||
1744 | if (cnt % 8 == 0) | ||
1745 | qla_uprintf(&uiter, "\n"); | ||
1746 | |||
1747 | qla_uprintf(&uiter, "%08x ", fw->rseq_2_reg[cnt]); | ||
1748 | } | ||
1749 | |||
1750 | qla_uprintf(&uiter, "\n\nCommand DMA Registers"); | ||
1751 | for (cnt = 0; cnt < sizeof(fw->cmd_dma_reg) / 4; cnt++) { | ||
1752 | if (cnt % 8 == 0) | ||
1753 | qla_uprintf(&uiter, "\n"); | ||
1754 | |||
1755 | qla_uprintf(&uiter, "%08x ", fw->cmd_dma_reg[cnt]); | ||
1756 | } | ||
1757 | |||
1758 | qla_uprintf(&uiter, "\n\nRequest0 Queue DMA Channel Registers"); | ||
1759 | for (cnt = 0; cnt < sizeof(fw->req0_dma_reg) / 4; cnt++) { | ||
1760 | if (cnt % 8 == 0) | ||
1761 | qla_uprintf(&uiter, "\n"); | ||
1762 | |||
1763 | qla_uprintf(&uiter, "%08x ", fw->req0_dma_reg[cnt]); | ||
1764 | } | ||
1765 | |||
1766 | qla_uprintf(&uiter, "\n\nResponse0 Queue DMA Channel Registers"); | ||
1767 | for (cnt = 0; cnt < sizeof(fw->resp0_dma_reg) / 4; cnt++) { | ||
1768 | if (cnt % 8 == 0) | ||
1769 | qla_uprintf(&uiter, "\n"); | ||
1770 | |||
1771 | qla_uprintf(&uiter, "%08x ", fw->resp0_dma_reg[cnt]); | ||
1772 | } | ||
1773 | |||
1774 | qla_uprintf(&uiter, "\n\nRequest1 Queue DMA Channel Registers"); | ||
1775 | for (cnt = 0; cnt < sizeof(fw->req1_dma_reg) / 4; cnt++) { | ||
1776 | if (cnt % 8 == 0) | ||
1777 | qla_uprintf(&uiter, "\n"); | ||
1778 | |||
1779 | qla_uprintf(&uiter, "%08x ", fw->req1_dma_reg[cnt]); | ||
1780 | } | ||
1781 | |||
1782 | qla_uprintf(&uiter, "\n\nXMT0 Data DMA Registers"); | ||
1783 | for (cnt = 0; cnt < sizeof(fw->xmt0_dma_reg) / 4; cnt++) { | ||
1784 | if (cnt % 8 == 0) | ||
1785 | qla_uprintf(&uiter, "\n"); | ||
1786 | |||
1787 | qla_uprintf(&uiter, "%08x ", fw->xmt0_dma_reg[cnt]); | ||
1788 | } | ||
1789 | |||
1790 | qla_uprintf(&uiter, "\n\nXMT1 Data DMA Registers"); | ||
1791 | for (cnt = 0; cnt < sizeof(fw->xmt1_dma_reg) / 4; cnt++) { | ||
1792 | if (cnt % 8 == 0) | ||
1793 | qla_uprintf(&uiter, "\n"); | ||
1794 | |||
1795 | qla_uprintf(&uiter, "%08x ", fw->xmt1_dma_reg[cnt]); | ||
1796 | } | ||
1797 | |||
1798 | qla_uprintf(&uiter, "\n\nXMT2 Data DMA Registers"); | ||
1799 | for (cnt = 0; cnt < sizeof(fw->xmt2_dma_reg) / 4; cnt++) { | ||
1800 | if (cnt % 8 == 0) | ||
1801 | qla_uprintf(&uiter, "\n"); | ||
1802 | |||
1803 | qla_uprintf(&uiter, "%08x ", fw->xmt2_dma_reg[cnt]); | ||
1804 | } | ||
1805 | |||
1806 | qla_uprintf(&uiter, "\n\nXMT3 Data DMA Registers"); | ||
1807 | for (cnt = 0; cnt < sizeof(fw->xmt3_dma_reg) / 4; cnt++) { | ||
1808 | if (cnt % 8 == 0) | ||
1809 | qla_uprintf(&uiter, "\n"); | ||
1810 | |||
1811 | qla_uprintf(&uiter, "%08x ", fw->xmt3_dma_reg[cnt]); | ||
1812 | } | ||
1813 | |||
1814 | qla_uprintf(&uiter, "\n\nXMT4 Data DMA Registers"); | ||
1815 | for (cnt = 0; cnt < sizeof(fw->xmt4_dma_reg) / 4; cnt++) { | ||
1816 | if (cnt % 8 == 0) | ||
1817 | qla_uprintf(&uiter, "\n"); | ||
1818 | |||
1819 | qla_uprintf(&uiter, "%08x ", fw->xmt4_dma_reg[cnt]); | ||
1820 | } | ||
1821 | |||
1822 | qla_uprintf(&uiter, "\n\nXMT Data DMA Common Registers"); | ||
1823 | for (cnt = 0; cnt < sizeof(fw->xmt_data_dma_reg) / 4; cnt++) { | ||
1824 | if (cnt % 8 == 0) | ||
1825 | qla_uprintf(&uiter, "\n"); | ||
1826 | |||
1827 | qla_uprintf(&uiter, "%08x ", fw->xmt_data_dma_reg[cnt]); | ||
1828 | } | ||
1829 | |||
1830 | qla_uprintf(&uiter, "\n\nRCV Thread 0 Data DMA Registers"); | ||
1831 | for (cnt = 0; cnt < sizeof(fw->rcvt0_data_dma_reg) / 4; cnt++) { | ||
1832 | if (cnt % 8 == 0) | ||
1833 | qla_uprintf(&uiter, "\n"); | ||
1834 | |||
1835 | qla_uprintf(&uiter, "%08x ", fw->rcvt0_data_dma_reg[cnt]); | ||
1836 | } | ||
1837 | |||
1838 | qla_uprintf(&uiter, "\n\nRCV Thread 1 Data DMA Registers"); | ||
1839 | for (cnt = 0; cnt < sizeof(fw->rcvt1_data_dma_reg) / 4; cnt++) { | ||
1840 | if (cnt % 8 == 0) | ||
1841 | qla_uprintf(&uiter, "\n"); | ||
1842 | |||
1843 | qla_uprintf(&uiter, "%08x ", fw->rcvt1_data_dma_reg[cnt]); | ||
1844 | } | ||
1845 | |||
1846 | qla_uprintf(&uiter, "\n\nRISC GP Registers"); | ||
1847 | for (cnt = 0; cnt < sizeof(fw->risc_gp_reg) / 4; cnt++) { | ||
1848 | if (cnt % 8 == 0) | ||
1849 | qla_uprintf(&uiter, "\n"); | ||
1850 | |||
1851 | qla_uprintf(&uiter, "%08x ", fw->risc_gp_reg[cnt]); | ||
1852 | } | ||
1853 | |||
1854 | qla_uprintf(&uiter, "\n\nLMC Registers"); | ||
1855 | for (cnt = 0; cnt < sizeof(fw->lmc_reg) / 4; cnt++) { | ||
1856 | if (cnt % 8 == 0) | ||
1857 | qla_uprintf(&uiter, "\n"); | ||
1858 | |||
1859 | qla_uprintf(&uiter, "%08x ", fw->lmc_reg[cnt]); | ||
1860 | } | ||
1861 | |||
1862 | qla_uprintf(&uiter, "\n\nFPM Hardware Registers"); | ||
1863 | for (cnt = 0; cnt < sizeof(fw->fpm_hdw_reg) / 4; cnt++) { | ||
1864 | if (cnt % 8 == 0) | ||
1865 | qla_uprintf(&uiter, "\n"); | ||
1866 | |||
1867 | qla_uprintf(&uiter, "%08x ", fw->fpm_hdw_reg[cnt]); | ||
1868 | } | ||
1869 | |||
1870 | qla_uprintf(&uiter, "\n\nFB Hardware Registers"); | ||
1871 | for (cnt = 0; cnt < sizeof(fw->fb_hdw_reg) / 4; cnt++) { | ||
1872 | if (cnt % 8 == 0) | ||
1873 | qla_uprintf(&uiter, "\n"); | ||
1874 | |||
1875 | qla_uprintf(&uiter, "%08x ", fw->fb_hdw_reg[cnt]); | ||
1876 | } | ||
1877 | |||
1878 | qla_uprintf(&uiter, "\n\nCode RAM"); | ||
1879 | for (cnt = 0; cnt < sizeof (fw->code_ram) / 4; cnt++) { | ||
1880 | if (cnt % 8 == 0) { | ||
1881 | qla_uprintf(&uiter, "\n%08x: ", cnt + 0x20000); | ||
1882 | } | ||
1883 | qla_uprintf(&uiter, "%08x ", fw->code_ram[cnt]); | ||
1884 | } | ||
1885 | |||
1886 | qla_uprintf(&uiter, "\n\nExternal Memory"); | ||
1887 | ext_mem_cnt = ha->fw_memory_size - 0x100000 + 1; | ||
1888 | for (cnt = 0; cnt < ext_mem_cnt; cnt++) { | ||
1889 | if (cnt % 8 == 0) { | ||
1890 | qla_uprintf(&uiter, "\n%08x: ", cnt + 0x100000); | ||
1891 | } | ||
1892 | qla_uprintf(&uiter, "%08x ", fw->ext_mem[cnt]); | ||
1893 | } | ||
1894 | |||
1895 | qla_uprintf(&uiter, "\n[<==END] ISP Debug Dump"); | ||
1896 | } | ||
1897 | |||
1898 | |||
1899 | /****************************************************************************/ | 1340 | /****************************************************************************/ |
1900 | /* Driver Debug Functions. */ | 1341 | /* Driver Debug Functions. */ |
1901 | /****************************************************************************/ | 1342 | /****************************************************************************/ |
diff --git a/drivers/scsi/qla2xxx/qla_dbg.h b/drivers/scsi/qla2xxx/qla_dbg.h index ab6afeaa2f2c..533425338e05 100644 --- a/drivers/scsi/qla2xxx/qla_dbg.h +++ b/drivers/scsi/qla2xxx/qla_dbg.h | |||
@@ -37,134 +37,86 @@ | |||
37 | /* | 37 | /* |
38 | * Macros use for debugging the driver. | 38 | * Macros use for debugging the driver. |
39 | */ | 39 | */ |
40 | #undef ENTER_TRACE | ||
41 | #if defined(ENTER_TRACE) | ||
42 | #define ENTER(x) do { printk("qla2100 : Entering %s()\n", x); } while (0) | ||
43 | #define LEAVE(x) do { printk("qla2100 : Leaving %s()\n", x); } while (0) | ||
44 | #define ENTER_INTR(x) do { printk("qla2100 : Entering %s()\n", x); } while (0) | ||
45 | #define LEAVE_INTR(x) do { printk("qla2100 : Leaving %s()\n", x); } while (0) | ||
46 | #else | ||
47 | #define ENTER(x) do {} while (0) | ||
48 | #define LEAVE(x) do {} while (0) | ||
49 | #define ENTER_INTR(x) do {} while (0) | ||
50 | #define LEAVE_INTR(x) do {} while (0) | ||
51 | #endif | ||
52 | 40 | ||
53 | #if DEBUG_QLA2100 | 41 | #define DEBUG(x) do { if (extended_error_logging) { x; } } while (0) |
54 | #define DEBUG(x) do {x;} while (0); | ||
55 | #else | ||
56 | #define DEBUG(x) do {} while (0); | ||
57 | #endif | ||
58 | 42 | ||
59 | #if defined(QL_DEBUG_LEVEL_1) | 43 | #if defined(QL_DEBUG_LEVEL_1) |
60 | #define DEBUG1(x) do {x;} while (0); | 44 | #define DEBUG1(x) do {x;} while (0) |
61 | #else | 45 | #else |
62 | #define DEBUG1(x) do {} while (0); | 46 | #define DEBUG1(x) do {} while (0) |
63 | #endif | 47 | #endif |
64 | 48 | ||
65 | #if defined(QL_DEBUG_LEVEL_2) | 49 | #define DEBUG2(x) do { if (extended_error_logging) { x; } } while (0) |
66 | #define DEBUG2(x) do {x;} while (0); | 50 | #define DEBUG2_3(x) do { if (extended_error_logging) { x; } } while (0) |
67 | #define DEBUG2_3(x) do {x;} while (0); | 51 | #define DEBUG2_3_11(x) do { if (extended_error_logging) { x; } } while (0) |
68 | #define DEBUG2_3_11(x) do {x;} while (0); | 52 | #define DEBUG2_9_10(x) do { if (extended_error_logging) { x; } } while (0) |
69 | #define DEBUG2_9_10(x) do {x;} while (0); | 53 | #define DEBUG2_11(x) do { if (extended_error_logging) { x; } } while (0) |
70 | #define DEBUG2_11(x) do {x;} while (0); | 54 | #define DEBUG2_13(x) do { if (extended_error_logging) { x; } } while (0) |
71 | #define DEBUG2_13(x) do {x;} while (0); | ||
72 | #else | ||
73 | #define DEBUG2(x) do {} while (0); | ||
74 | #endif | ||
75 | 55 | ||
76 | #if defined(QL_DEBUG_LEVEL_3) | 56 | #if defined(QL_DEBUG_LEVEL_3) |
77 | #define DEBUG3(x) do {x;} while (0); | 57 | #define DEBUG3(x) do {x;} while (0) |
78 | #define DEBUG2_3(x) do {x;} while (0); | 58 | #define DEBUG3_11(x) do {x;} while (0) |
79 | #define DEBUG2_3_11(x) do {x;} while (0); | ||
80 | #define DEBUG3_11(x) do {x;} while (0); | ||
81 | #else | 59 | #else |
82 | #define DEBUG3(x) do {} while (0); | 60 | #define DEBUG3(x) do {} while (0) |
83 | #if !defined(QL_DEBUG_LEVEL_2) | ||
84 | #define DEBUG2_3(x) do {} while (0); | ||
85 | #endif | ||
86 | #endif | 61 | #endif |
87 | 62 | ||
88 | #if defined(QL_DEBUG_LEVEL_4) | 63 | #if defined(QL_DEBUG_LEVEL_4) |
89 | #define DEBUG4(x) do {x;} while (0); | 64 | #define DEBUG4(x) do {x;} while (0) |
90 | #else | 65 | #else |
91 | #define DEBUG4(x) do {} while (0); | 66 | #define DEBUG4(x) do {} while (0) |
92 | #endif | 67 | #endif |
93 | 68 | ||
94 | #if defined(QL_DEBUG_LEVEL_5) | 69 | #if defined(QL_DEBUG_LEVEL_5) |
95 | #define DEBUG5(x) do {x;} while (0); | 70 | #define DEBUG5(x) do {x;} while (0) |
96 | #else | 71 | #else |
97 | #define DEBUG5(x) do {} while (0); | 72 | #define DEBUG5(x) do {} while (0) |
98 | #endif | 73 | #endif |
99 | 74 | ||
100 | #if defined(QL_DEBUG_LEVEL_7) | 75 | #if defined(QL_DEBUG_LEVEL_7) |
101 | #define DEBUG7(x) do {x;} while (0); | 76 | #define DEBUG7(x) do {x;} while (0) |
102 | #else | 77 | #else |
103 | #define DEBUG7(x) do {} while (0); | 78 | #define DEBUG7(x) do {} while (0) |
104 | #endif | 79 | #endif |
105 | 80 | ||
106 | #if defined(QL_DEBUG_LEVEL_9) | 81 | #if defined(QL_DEBUG_LEVEL_9) |
107 | #define DEBUG9(x) do {x;} while (0); | 82 | #define DEBUG9(x) do {x;} while (0) |
108 | #define DEBUG9_10(x) do {x;} while (0); | 83 | #define DEBUG9_10(x) do {x;} while (0) |
109 | #define DEBUG2_9_10(x) do {x;} while (0); | ||
110 | #else | 84 | #else |
111 | #define DEBUG9(x) do {} while (0); | 85 | #define DEBUG9(x) do {} while (0) |
112 | #endif | 86 | #endif |
113 | 87 | ||
114 | #if defined(QL_DEBUG_LEVEL_10) | 88 | #if defined(QL_DEBUG_LEVEL_10) |
115 | #define DEBUG10(x) do {x;} while (0); | 89 | #define DEBUG10(x) do {x;} while (0) |
116 | #define DEBUG2_9_10(x) do {x;} while (0); | 90 | #define DEBUG9_10(x) do {x;} while (0) |
117 | #define DEBUG9_10(x) do {x;} while (0); | ||
118 | #else | 91 | #else |
119 | #define DEBUG10(x) do {} while (0); | 92 | #define DEBUG10(x) do {} while (0) |
120 | #if !defined(DEBUG2_9_10) | ||
121 | #define DEBUG2_9_10(x) do {} while (0); | ||
122 | #endif | ||
123 | #if !defined(DEBUG9_10) | 93 | #if !defined(DEBUG9_10) |
124 | #define DEBUG9_10(x) do {} while (0); | 94 | #define DEBUG9_10(x) do {} while (0) |
125 | #endif | 95 | #endif |
126 | #endif | 96 | #endif |
127 | 97 | ||
128 | #if defined(QL_DEBUG_LEVEL_11) | 98 | #if defined(QL_DEBUG_LEVEL_11) |
129 | #define DEBUG11(x) do{x;} while(0); | 99 | #define DEBUG11(x) do{x;} while(0) |
130 | #if !defined(DEBUG2_11) | ||
131 | #define DEBUG2_11(x) do{x;} while(0); | ||
132 | #endif | ||
133 | #if !defined(DEBUG2_3_11) | ||
134 | #define DEBUG2_3_11(x) do{x;} while(0); | ||
135 | #endif | ||
136 | #if !defined(DEBUG3_11) | 100 | #if !defined(DEBUG3_11) |
137 | #define DEBUG3_11(x) do{x;} while(0); | 101 | #define DEBUG3_11(x) do{x;} while(0) |
138 | #endif | 102 | #endif |
139 | #else | 103 | #else |
140 | #define DEBUG11(x) do{} while(0); | 104 | #define DEBUG11(x) do{} while(0) |
141 | #if !defined(QL_DEBUG_LEVEL_2) | ||
142 | #define DEBUG2_11(x) do{} while(0); | ||
143 | #if !defined(QL_DEBUG_LEVEL_3) | ||
144 | #define DEBUG2_3_11(x) do{} while(0); | ||
145 | #endif | ||
146 | #endif | ||
147 | #if !defined(QL_DEBUG_LEVEL_3) | 105 | #if !defined(QL_DEBUG_LEVEL_3) |
148 | #define DEBUG3_11(x) do{} while(0); | 106 | #define DEBUG3_11(x) do{} while(0) |
149 | #endif | 107 | #endif |
150 | #endif | 108 | #endif |
151 | 109 | ||
152 | #if defined(QL_DEBUG_LEVEL_12) | 110 | #if defined(QL_DEBUG_LEVEL_12) |
153 | #define DEBUG12(x) do {x;} while (0); | 111 | #define DEBUG12(x) do {x;} while (0) |
154 | #else | 112 | #else |
155 | #define DEBUG12(x) do {} while (0); | 113 | #define DEBUG12(x) do {} while (0) |
156 | #endif | 114 | #endif |
157 | 115 | ||
158 | #if defined(QL_DEBUG_LEVEL_13) | 116 | #if defined(QL_DEBUG_LEVEL_13) |
159 | #define DEBUG13(x) do {x;} while (0) | 117 | #define DEBUG13(x) do {x;} while (0) |
160 | #if !defined(DEBUG2_13) | ||
161 | #define DEBUG2_13(x) do {x;} while(0) | ||
162 | #endif | ||
163 | #else | 118 | #else |
164 | #define DEBUG13(x) do {} while (0) | 119 | #define DEBUG13(x) do {} while (0) |
165 | #if !defined(QL_DEBUG_LEVEL_2) | ||
166 | #define DEBUG2_13(x) do {} while(0) | ||
167 | #endif | ||
168 | #endif | 120 | #endif |
169 | 121 | ||
170 | #if defined(QL_DEBUG_LEVEL_14) | 122 | #if defined(QL_DEBUG_LEVEL_14) |
@@ -176,9 +128,6 @@ | |||
176 | /* | 128 | /* |
177 | * Firmware Dump structure definition | 129 | * Firmware Dump structure definition |
178 | */ | 130 | */ |
179 | #define FW_DUMP_SIZE_128K 0xBC000 | ||
180 | #define FW_DUMP_SIZE_512K 0x2FC000 | ||
181 | #define FW_DUMP_SIZE_1M 0x5FC000 | ||
182 | 131 | ||
183 | struct qla2300_fw_dump { | 132 | struct qla2300_fw_dump { |
184 | uint16_t hccr; | 133 | uint16_t hccr; |
@@ -224,8 +173,6 @@ struct qla2100_fw_dump { | |||
224 | uint16_t risc_ram[0xf000]; | 173 | uint16_t risc_ram[0xf000]; |
225 | }; | 174 | }; |
226 | 175 | ||
227 | #define FW_DUMP_SIZE_24XX 0x2B0000 | ||
228 | |||
229 | struct qla24xx_fw_dump { | 176 | struct qla24xx_fw_dump { |
230 | uint32_t host_status; | 177 | uint32_t host_status; |
231 | uint32_t host_reg[32]; | 178 | uint32_t host_reg[32]; |
@@ -257,3 +204,39 @@ struct qla24xx_fw_dump { | |||
257 | uint32_t code_ram[0x2000]; | 204 | uint32_t code_ram[0x2000]; |
258 | uint32_t ext_mem[1]; | 205 | uint32_t ext_mem[1]; |
259 | }; | 206 | }; |
207 | |||
208 | #define EFT_NUM_BUFFERS 4 | ||
209 | #define EFT_BYTES_PER_BUFFER 0x4000 | ||
210 | #define EFT_SIZE ((EFT_BYTES_PER_BUFFER) * (EFT_NUM_BUFFERS)) | ||
211 | |||
212 | struct qla2xxx_fw_dump { | ||
213 | uint8_t signature[4]; | ||
214 | uint32_t version; | ||
215 | |||
216 | uint32_t fw_major_version; | ||
217 | uint32_t fw_minor_version; | ||
218 | uint32_t fw_subminor_version; | ||
219 | uint32_t fw_attributes; | ||
220 | |||
221 | uint32_t vendor; | ||
222 | uint32_t device; | ||
223 | uint32_t subsystem_vendor; | ||
224 | uint32_t subsystem_device; | ||
225 | |||
226 | uint32_t fixed_size; | ||
227 | uint32_t mem_size; | ||
228 | uint32_t req_q_size; | ||
229 | uint32_t rsp_q_size; | ||
230 | |||
231 | uint32_t eft_size; | ||
232 | uint32_t eft_addr_l; | ||
233 | uint32_t eft_addr_h; | ||
234 | |||
235 | uint32_t header_size; | ||
236 | |||
237 | union { | ||
238 | struct qla2100_fw_dump isp21; | ||
239 | struct qla2300_fw_dump isp23; | ||
240 | struct qla24xx_fw_dump isp24; | ||
241 | } isp; | ||
242 | }; | ||
diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h index 6734453ea28a..139ea0e27fd7 100644 --- a/drivers/scsi/qla2xxx/qla_def.h +++ b/drivers/scsi/qla2xxx/qla_def.h | |||
@@ -608,7 +608,9 @@ typedef struct { | |||
608 | #define MBC_SERDES_PARAMS 0x10 /* Serdes Tx Parameters. */ | 608 | #define MBC_SERDES_PARAMS 0x10 /* Serdes Tx Parameters. */ |
609 | #define MBC_GET_IOCB_STATUS 0x12 /* Get IOCB status command. */ | 609 | #define MBC_GET_IOCB_STATUS 0x12 /* Get IOCB status command. */ |
610 | #define MBC_GET_TIMEOUT_PARAMS 0x22 /* Get FW timeouts. */ | 610 | #define MBC_GET_TIMEOUT_PARAMS 0x22 /* Get FW timeouts. */ |
611 | #define MBC_TRACE_CONTROL 0x27 /* Trace control command. */ | ||
611 | #define MBC_GEN_SYSTEM_ERROR 0x2a /* Generate System Error. */ | 612 | #define MBC_GEN_SYSTEM_ERROR 0x2a /* Generate System Error. */ |
613 | #define MBC_READ_SFP 0x31 /* Read SFP Data. */ | ||
612 | #define MBC_SET_TIMEOUT_PARAMS 0x32 /* Set FW timeouts. */ | 614 | #define MBC_SET_TIMEOUT_PARAMS 0x32 /* Set FW timeouts. */ |
613 | #define MBC_MID_INITIALIZE_FIRMWARE 0x48 /* MID Initialize firmware. */ | 615 | #define MBC_MID_INITIALIZE_FIRMWARE 0x48 /* MID Initialize firmware. */ |
614 | #define MBC_MID_GET_VP_DATABASE 0x49 /* MID Get VP Database. */ | 616 | #define MBC_MID_GET_VP_DATABASE 0x49 /* MID Get VP Database. */ |
@@ -618,6 +620,9 @@ typedef struct { | |||
618 | #define MBC_GET_LINK_PRIV_STATS 0x6d /* Get link & private data. */ | 620 | #define MBC_GET_LINK_PRIV_STATS 0x6d /* Get link & private data. */ |
619 | #define MBC_SET_VENDOR_ID 0x76 /* Set Vendor ID. */ | 621 | #define MBC_SET_VENDOR_ID 0x76 /* Set Vendor ID. */ |
620 | 622 | ||
623 | #define TC_ENABLE 4 | ||
624 | #define TC_DISABLE 5 | ||
625 | |||
621 | /* Firmware return data sizes */ | 626 | /* Firmware return data sizes */ |
622 | #define FCAL_MAP_SIZE 128 | 627 | #define FCAL_MAP_SIZE 128 |
623 | 628 | ||
@@ -1997,7 +2002,6 @@ struct isp_operations { | |||
1997 | uint32_t); | 2002 | uint32_t); |
1998 | 2003 | ||
1999 | void (*fw_dump) (struct scsi_qla_host *, int); | 2004 | void (*fw_dump) (struct scsi_qla_host *, int); |
2000 | void (*ascii_fw_dump) (struct scsi_qla_host *); | ||
2001 | 2005 | ||
2002 | int (*beacon_on) (struct scsi_qla_host *); | 2006 | int (*beacon_on) (struct scsi_qla_host *); |
2003 | int (*beacon_off) (struct scsi_qla_host *); | 2007 | int (*beacon_off) (struct scsi_qla_host *); |
@@ -2041,6 +2045,7 @@ typedef struct scsi_qla_host { | |||
2041 | uint32_t enable_led_scheme :1; | 2045 | uint32_t enable_led_scheme :1; |
2042 | uint32_t msi_enabled :1; | 2046 | uint32_t msi_enabled :1; |
2043 | uint32_t msix_enabled :1; | 2047 | uint32_t msix_enabled :1; |
2048 | uint32_t disable_serdes :1; | ||
2044 | } flags; | 2049 | } flags; |
2045 | 2050 | ||
2046 | atomic_t loop_state; | 2051 | atomic_t loop_state; |
@@ -2238,6 +2243,11 @@ typedef struct scsi_qla_host { | |||
2238 | struct sns_cmd_pkt *sns_cmd; | 2243 | struct sns_cmd_pkt *sns_cmd; |
2239 | dma_addr_t sns_cmd_dma; | 2244 | dma_addr_t sns_cmd_dma; |
2240 | 2245 | ||
2246 | #define SFP_DEV_SIZE 256 | ||
2247 | #define SFP_BLOCK_SIZE 64 | ||
2248 | void *sfp_data; | ||
2249 | dma_addr_t sfp_data_dma; | ||
2250 | |||
2241 | struct task_struct *dpc_thread; | 2251 | struct task_struct *dpc_thread; |
2242 | uint8_t dpc_active; /* DPC routine is active */ | 2252 | uint8_t dpc_active; /* DPC routine is active */ |
2243 | 2253 | ||
@@ -2303,11 +2313,12 @@ typedef struct scsi_qla_host { | |||
2303 | uint16_t fw_seriallink_options24[4]; | 2313 | uint16_t fw_seriallink_options24[4]; |
2304 | 2314 | ||
2305 | /* Firmware dump information. */ | 2315 | /* Firmware dump information. */ |
2306 | void *fw_dump; | 2316 | struct qla2xxx_fw_dump *fw_dump; |
2317 | uint32_t fw_dump_len; | ||
2307 | int fw_dumped; | 2318 | int fw_dumped; |
2308 | int fw_dump_reading; | 2319 | int fw_dump_reading; |
2309 | char *fw_dump_buffer; | 2320 | dma_addr_t eft_dma; |
2310 | int fw_dump_buffer_len; | 2321 | void *eft; |
2311 | 2322 | ||
2312 | uint8_t host_str[16]; | 2323 | uint8_t host_str[16]; |
2313 | uint32_t pci_attr; | 2324 | uint32_t pci_attr; |
diff --git a/drivers/scsi/qla2xxx/qla_devtbl.h b/drivers/scsi/qla2xxx/qla_devtbl.h index a8fc0ffc7fc5..dd435410dfa2 100644 --- a/drivers/scsi/qla2xxx/qla_devtbl.h +++ b/drivers/scsi/qla2xxx/qla_devtbl.h | |||
@@ -1,4 +1,4 @@ | |||
1 | #define QLA_MODEL_NAMES 0x4A | 1 | #define QLA_MODEL_NAMES 0x57 |
2 | 2 | ||
3 | /* | 3 | /* |
4 | * Adapter model names and descriptions. | 4 | * Adapter model names and descriptions. |
@@ -76,6 +76,19 @@ static char *qla2x00_model_name[QLA_MODEL_NAMES*2] = { | |||
76 | "QLE2440", "PCI-Express to 4Gb FC, Single Channel", /* 0x145 */ | 76 | "QLE2440", "PCI-Express to 4Gb FC, Single Channel", /* 0x145 */ |
77 | "QLE2464", "PCI-Express to 4Gb FC, Quad Channel", /* 0x146 */ | 77 | "QLE2464", "PCI-Express to 4Gb FC, Quad Channel", /* 0x146 */ |
78 | "QLA2440", "PCI-X 2.0 to 4Gb FC, Single Channel", /* 0x147 */ | 78 | "QLA2440", "PCI-X 2.0 to 4Gb FC, Single Channel", /* 0x147 */ |
79 | " ", " ", /* 0x148 */ | 79 | "HP AE369A", "PCI-X 2.0 to 4Gb FC, Dual Channel", /* 0x148 */ |
80 | "QLA2340", "Sun 133MHz PCI-X to 2Gb FC, Single Channel", /* 0x149 */ | 80 | "QLA2340", "Sun 133MHz PCI-X to 2Gb FC, Single Channel", /* 0x149 */ |
81 | " ", " ", /* 0x14a */ | ||
82 | " ", " ", /* 0x14b */ | ||
83 | "QMC2432M", "IBM eServer BC 4Gb FC Expansion Card CFFE", /* 0x14c */ | ||
84 | "QMC2422M", "IBM eServer BC 4Gb FC Expansion Card CFFX", /* 0x14d */ | ||
85 | "QLE220", "Sun PCI-Express to 4Gb FC, Single Channel", /* 0x14e */ | ||
86 | " ", " ", /* 0x14f */ | ||
87 | " ", " ", /* 0x150 */ | ||
88 | " ", " ", /* 0x151 */ | ||
89 | "QME2462", "PCI-Express to 4Gb FC, Dual Channel Mezz HBA", /* 0x152 */ | ||
90 | "QMH2462", "PCI-Express to 4Gb FC, Dual Channel Mezz HBA", /* 0x153 */ | ||
91 | " ", " ", /* 0x154 */ | ||
92 | "QLE220", "PCI-Express to 4Gb FC, Single Channel", /* 0x155 */ | ||
93 | "QLE220", "PCI-Express to 4Gb FC, Single Channel", /* 0x156 */ | ||
81 | }; | 94 | }; |
diff --git a/drivers/scsi/qla2xxx/qla_fw.h b/drivers/scsi/qla2xxx/qla_fw.h index 3af478663be7..a0a722cf4237 100644 --- a/drivers/scsi/qla2xxx/qla_fw.h +++ b/drivers/scsi/qla2xxx/qla_fw.h | |||
@@ -141,7 +141,7 @@ struct nvram_24xx { | |||
141 | * BIT 2 = Enable Memory Map BIOS | 141 | * BIT 2 = Enable Memory Map BIOS |
142 | * BIT 3 = Enable Selectable Boot | 142 | * BIT 3 = Enable Selectable Boot |
143 | * BIT 4 = Disable RISC code load | 143 | * BIT 4 = Disable RISC code load |
144 | * BIT 5 = | 144 | * BIT 5 = Disable Serdes |
145 | * BIT 6 = | 145 | * BIT 6 = |
146 | * BIT 7 = | 146 | * BIT 7 = |
147 | * | 147 | * |
@@ -278,7 +278,7 @@ struct init_cb_24xx { | |||
278 | uint16_t response_q_length; | 278 | uint16_t response_q_length; |
279 | uint16_t request_q_length; | 279 | uint16_t request_q_length; |
280 | 280 | ||
281 | uint16_t link_down_timeout; /* Milliseconds. */ | 281 | uint16_t link_down_on_nos; /* Milliseconds. */ |
282 | 282 | ||
283 | uint16_t prio_request_q_length; | 283 | uint16_t prio_request_q_length; |
284 | 284 | ||
diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h index 164d53ccbfd0..8311ac2b93a8 100644 --- a/drivers/scsi/qla2xxx/qla_gbl.h +++ b/drivers/scsi/qla2xxx/qla_gbl.h | |||
@@ -31,13 +31,9 @@ extern void qla2x00_update_fw_options(struct scsi_qla_host *); | |||
31 | extern void qla24xx_update_fw_options(scsi_qla_host_t *); | 31 | extern void qla24xx_update_fw_options(scsi_qla_host_t *); |
32 | extern int qla2x00_load_risc(struct scsi_qla_host *, uint32_t *); | 32 | extern int qla2x00_load_risc(struct scsi_qla_host *, uint32_t *); |
33 | extern int qla24xx_load_risc(scsi_qla_host_t *, uint32_t *); | 33 | extern int qla24xx_load_risc(scsi_qla_host_t *, uint32_t *); |
34 | extern int qla24xx_load_risc_flash(scsi_qla_host_t *, uint32_t *); | ||
35 | |||
36 | extern fc_port_t *qla2x00_alloc_fcport(scsi_qla_host_t *, gfp_t); | ||
37 | 34 | ||
38 | extern int qla2x00_loop_resync(scsi_qla_host_t *); | 35 | extern int qla2x00_loop_resync(scsi_qla_host_t *); |
39 | 36 | ||
40 | extern int qla2x00_find_new_loop_id(scsi_qla_host_t *, fc_port_t *); | ||
41 | extern int qla2x00_fabric_login(scsi_qla_host_t *, fc_port_t *, uint16_t *); | 37 | extern int qla2x00_fabric_login(scsi_qla_host_t *, fc_port_t *, uint16_t *); |
42 | extern int qla2x00_local_device_login(scsi_qla_host_t *, fc_port_t *); | 38 | extern int qla2x00_local_device_login(scsi_qla_host_t *, fc_port_t *); |
43 | 39 | ||
@@ -51,6 +47,8 @@ extern int qla2x00_abort_isp(scsi_qla_host_t *); | |||
51 | extern void qla2x00_update_fcport(scsi_qla_host_t *, fc_port_t *); | 47 | extern void qla2x00_update_fcport(scsi_qla_host_t *, fc_port_t *); |
52 | extern void qla2x00_reg_remote_port(scsi_qla_host_t *, fc_port_t *); | 48 | extern void qla2x00_reg_remote_port(scsi_qla_host_t *, fc_port_t *); |
53 | 49 | ||
50 | extern void qla2x00_alloc_fw_dump(scsi_qla_host_t *); | ||
51 | |||
54 | /* | 52 | /* |
55 | * Global Data in qla_os.c source file. | 53 | * Global Data in qla_os.c source file. |
56 | */ | 54 | */ |
@@ -61,6 +59,8 @@ extern int qlport_down_retry; | |||
61 | extern int ql2xplogiabsentdevice; | 59 | extern int ql2xplogiabsentdevice; |
62 | extern int ql2xloginretrycount; | 60 | extern int ql2xloginretrycount; |
63 | extern int ql2xfdmienable; | 61 | extern int ql2xfdmienable; |
62 | extern int ql2xallocfwdump; | ||
63 | extern int extended_error_logging; | ||
64 | 64 | ||
65 | extern void qla2x00_sp_compl(scsi_qla_host_t *, srb_t *); | 65 | extern void qla2x00_sp_compl(scsi_qla_host_t *, srb_t *); |
66 | 66 | ||
@@ -80,8 +80,6 @@ extern void qla2xxx_wake_dpc(scsi_qla_host_t *); | |||
80 | /* | 80 | /* |
81 | * Global Function Prototypes in qla_iocb.c source file. | 81 | * Global Function Prototypes in qla_iocb.c source file. |
82 | */ | 82 | */ |
83 | extern void qla2x00_isp_cmd(scsi_qla_host_t *); | ||
84 | |||
85 | extern uint16_t qla2x00_calc_iocbs_32(uint16_t); | 83 | extern uint16_t qla2x00_calc_iocbs_32(uint16_t); |
86 | extern uint16_t qla2x00_calc_iocbs_64(uint16_t); | 84 | extern uint16_t qla2x00_calc_iocbs_64(uint16_t); |
87 | extern void qla2x00_build_scsi_iocbs_32(srb_t *, cmd_entry_t *, uint16_t); | 85 | extern void qla2x00_build_scsi_iocbs_32(srb_t *, cmd_entry_t *, uint16_t); |
@@ -204,6 +202,12 @@ qla2x00_set_serdes_params(scsi_qla_host_t *, uint16_t, uint16_t, uint16_t); | |||
204 | extern int | 202 | extern int |
205 | qla2x00_stop_firmware(scsi_qla_host_t *); | 203 | qla2x00_stop_firmware(scsi_qla_host_t *); |
206 | 204 | ||
205 | extern int | ||
206 | qla2x00_trace_control(scsi_qla_host_t *, uint16_t, dma_addr_t, uint16_t); | ||
207 | |||
208 | extern int | ||
209 | qla2x00_read_sfp(scsi_qla_host_t *, dma_addr_t, uint16_t, uint16_t, uint16_t); | ||
210 | |||
207 | /* | 211 | /* |
208 | * Global Function Prototypes in qla_isr.c source file. | 212 | * Global Function Prototypes in qla_isr.c source file. |
209 | */ | 213 | */ |
@@ -254,9 +258,6 @@ extern int qla24xx_write_optrom_data(struct scsi_qla_host *, uint8_t *, | |||
254 | extern void qla2100_fw_dump(scsi_qla_host_t *, int); | 258 | extern void qla2100_fw_dump(scsi_qla_host_t *, int); |
255 | extern void qla2300_fw_dump(scsi_qla_host_t *, int); | 259 | extern void qla2300_fw_dump(scsi_qla_host_t *, int); |
256 | extern void qla24xx_fw_dump(scsi_qla_host_t *, int); | 260 | extern void qla24xx_fw_dump(scsi_qla_host_t *, int); |
257 | extern void qla2100_ascii_fw_dump(scsi_qla_host_t *); | ||
258 | extern void qla2300_ascii_fw_dump(scsi_qla_host_t *); | ||
259 | extern void qla24xx_ascii_fw_dump(scsi_qla_host_t *); | ||
260 | extern void qla2x00_dump_regs(scsi_qla_host_t *); | 261 | extern void qla2x00_dump_regs(scsi_qla_host_t *); |
261 | extern void qla2x00_dump_buffer(uint8_t *, uint32_t); | 262 | extern void qla2x00_dump_buffer(uint8_t *, uint32_t); |
262 | extern void qla2x00_print_scsi_cmd(struct scsi_cmnd *); | 263 | extern void qla2x00_print_scsi_cmd(struct scsi_cmnd *); |
@@ -280,13 +281,6 @@ extern void *qla24xx_prep_ms_fdmi_iocb(scsi_qla_host_t *, uint32_t, uint32_t); | |||
280 | extern int qla2x00_fdmi_register(scsi_qla_host_t *); | 281 | extern int qla2x00_fdmi_register(scsi_qla_host_t *); |
281 | 282 | ||
282 | /* | 283 | /* |
283 | * Global Function Prototypes in qla_xioctl.c source file. | ||
284 | */ | ||
285 | #define qla2x00_enqueue_aen(ha, cmd, mode) do { } while (0) | ||
286 | #define qla2x00_alloc_ioctl_mem(ha) (0) | ||
287 | #define qla2x00_free_ioctl_mem(ha) do { } while (0) | ||
288 | |||
289 | /* | ||
290 | * Global Function Prototypes in qla_attr.c source file. | 284 | * Global Function Prototypes in qla_attr.c source file. |
291 | */ | 285 | */ |
292 | struct class_device_attribute; | 286 | struct class_device_attribute; |
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index 3d4487eac9b7..9758dba95542 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c | |||
@@ -39,6 +39,8 @@ static int qla2x00_fabric_dev_login(scsi_qla_host_t *, fc_port_t *, | |||
39 | 39 | ||
40 | static int qla2x00_restart_isp(scsi_qla_host_t *); | 40 | static int qla2x00_restart_isp(scsi_qla_host_t *); |
41 | 41 | ||
42 | static int qla2x00_find_new_loop_id(scsi_qla_host_t *ha, fc_port_t *dev); | ||
43 | |||
42 | /****************************************************************************/ | 44 | /****************************************************************************/ |
43 | /* QLogic ISP2x00 Hardware Support Functions. */ | 45 | /* QLogic ISP2x00 Hardware Support Functions. */ |
44 | /****************************************************************************/ | 46 | /****************************************************************************/ |
@@ -89,6 +91,17 @@ qla2x00_initialize_adapter(scsi_qla_host_t *ha) | |||
89 | 91 | ||
90 | ha->isp_ops.nvram_config(ha); | 92 | ha->isp_ops.nvram_config(ha); |
91 | 93 | ||
94 | if (ha->flags.disable_serdes) { | ||
95 | /* Mask HBA via NVRAM settings? */ | ||
96 | qla_printk(KERN_INFO, ha, "Masking HBA WWPN " | ||
97 | "%02x%02x%02x%02x%02x%02x%02x%02x (via NVRAM).\n", | ||
98 | ha->port_name[0], ha->port_name[1], | ||
99 | ha->port_name[2], ha->port_name[3], | ||
100 | ha->port_name[4], ha->port_name[5], | ||
101 | ha->port_name[6], ha->port_name[7]); | ||
102 | return QLA_FUNCTION_FAILED; | ||
103 | } | ||
104 | |||
92 | qla_printk(KERN_INFO, ha, "Verifying loaded RISC code...\n"); | 105 | qla_printk(KERN_INFO, ha, "Verifying loaded RISC code...\n"); |
93 | 106 | ||
94 | retry = 10; | 107 | retry = 10; |
@@ -770,29 +783,104 @@ qla24xx_chip_diag(scsi_qla_host_t *ha) | |||
770 | return rval; | 783 | return rval; |
771 | } | 784 | } |
772 | 785 | ||
773 | static void | 786 | void |
774 | qla2x00_alloc_fw_dump(scsi_qla_host_t *ha) | 787 | qla2x00_alloc_fw_dump(scsi_qla_host_t *ha) |
775 | { | 788 | { |
776 | uint32_t dump_size = 0; | 789 | int rval; |
790 | uint32_t dump_size, fixed_size, mem_size, req_q_size, rsp_q_size, | ||
791 | eft_size; | ||
792 | dma_addr_t eft_dma; | ||
793 | void *eft; | ||
794 | |||
795 | if (ha->fw_dump) { | ||
796 | qla_printk(KERN_WARNING, ha, | ||
797 | "Firmware dump previously allocated.\n"); | ||
798 | return; | ||
799 | } | ||
777 | 800 | ||
778 | ha->fw_dumped = 0; | 801 | ha->fw_dumped = 0; |
802 | fixed_size = mem_size = eft_size = 0; | ||
779 | if (IS_QLA2100(ha) || IS_QLA2200(ha)) { | 803 | if (IS_QLA2100(ha) || IS_QLA2200(ha)) { |
780 | dump_size = sizeof(struct qla2100_fw_dump); | 804 | fixed_size = sizeof(struct qla2100_fw_dump); |
781 | } else if (IS_QLA23XX(ha)) { | 805 | } else if (IS_QLA23XX(ha)) { |
782 | dump_size = sizeof(struct qla2300_fw_dump); | 806 | fixed_size = offsetof(struct qla2300_fw_dump, data_ram); |
783 | dump_size += (ha->fw_memory_size - 0x11000) * sizeof(uint16_t); | 807 | mem_size = (ha->fw_memory_size - 0x11000 + 1) * |
784 | } else if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) { | 808 | sizeof(uint16_t); |
785 | dump_size = sizeof(struct qla24xx_fw_dump); | 809 | } else if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) { |
786 | dump_size += (ha->fw_memory_size - 0x100000) * sizeof(uint32_t); | 810 | fixed_size = offsetof(struct qla24xx_fw_dump, ext_mem); |
811 | mem_size = (ha->fw_memory_size - 0x100000 + 1) * | ||
812 | sizeof(uint32_t); | ||
813 | |||
814 | /* Allocate memory for Extended Trace Buffer. */ | ||
815 | eft = dma_alloc_coherent(&ha->pdev->dev, EFT_SIZE, &eft_dma, | ||
816 | GFP_KERNEL); | ||
817 | if (!eft) { | ||
818 | qla_printk(KERN_WARNING, ha, "Unable to allocate " | ||
819 | "(%d KB) for EFT.\n", EFT_SIZE / 1024); | ||
820 | goto cont_alloc; | ||
821 | } | ||
822 | |||
823 | rval = qla2x00_trace_control(ha, TC_ENABLE, eft_dma, | ||
824 | EFT_NUM_BUFFERS); | ||
825 | if (rval) { | ||
826 | qla_printk(KERN_WARNING, ha, "Unable to initialize " | ||
827 | "EFT (%d).\n", rval); | ||
828 | dma_free_coherent(&ha->pdev->dev, EFT_SIZE, eft, | ||
829 | eft_dma); | ||
830 | goto cont_alloc; | ||
831 | } | ||
832 | |||
833 | qla_printk(KERN_INFO, ha, "Allocated (%d KB) for EFT...\n", | ||
834 | EFT_SIZE / 1024); | ||
835 | |||
836 | eft_size = EFT_SIZE; | ||
837 | memset(eft, 0, eft_size); | ||
838 | ha->eft_dma = eft_dma; | ||
839 | ha->eft = eft; | ||
787 | } | 840 | } |
841 | cont_alloc: | ||
842 | req_q_size = ha->request_q_length * sizeof(request_t); | ||
843 | rsp_q_size = ha->response_q_length * sizeof(response_t); | ||
844 | |||
845 | dump_size = offsetof(struct qla2xxx_fw_dump, isp); | ||
846 | dump_size += fixed_size + mem_size + req_q_size + rsp_q_size + | ||
847 | eft_size; | ||
788 | 848 | ||
789 | ha->fw_dump = vmalloc(dump_size); | 849 | ha->fw_dump = vmalloc(dump_size); |
790 | if (ha->fw_dump) | 850 | if (!ha->fw_dump) { |
791 | qla_printk(KERN_INFO, ha, "Allocated (%d KB) for firmware " | ||
792 | "dump...\n", dump_size / 1024); | ||
793 | else | ||
794 | qla_printk(KERN_WARNING, ha, "Unable to allocate (%d KB) for " | 851 | qla_printk(KERN_WARNING, ha, "Unable to allocate (%d KB) for " |
795 | "firmware dump!!!\n", dump_size / 1024); | 852 | "firmware dump!!!\n", dump_size / 1024); |
853 | |||
854 | if (ha->eft) { | ||
855 | dma_free_coherent(&ha->pdev->dev, eft_size, ha->eft, | ||
856 | ha->eft_dma); | ||
857 | ha->eft = NULL; | ||
858 | ha->eft_dma = 0; | ||
859 | } | ||
860 | return; | ||
861 | } | ||
862 | |||
863 | qla_printk(KERN_INFO, ha, "Allocated (%d KB) for firmware dump...\n", | ||
864 | dump_size / 1024); | ||
865 | |||
866 | ha->fw_dump_len = dump_size; | ||
867 | ha->fw_dump->signature[0] = 'Q'; | ||
868 | ha->fw_dump->signature[1] = 'L'; | ||
869 | ha->fw_dump->signature[2] = 'G'; | ||
870 | ha->fw_dump->signature[3] = 'C'; | ||
871 | ha->fw_dump->version = __constant_htonl(1); | ||
872 | |||
873 | ha->fw_dump->fixed_size = htonl(fixed_size); | ||
874 | ha->fw_dump->mem_size = htonl(mem_size); | ||
875 | ha->fw_dump->req_q_size = htonl(req_q_size); | ||
876 | ha->fw_dump->rsp_q_size = htonl(rsp_q_size); | ||
877 | |||
878 | ha->fw_dump->eft_size = htonl(eft_size); | ||
879 | ha->fw_dump->eft_addr_l = htonl(LSD(ha->eft_dma)); | ||
880 | ha->fw_dump->eft_addr_h = htonl(MSD(ha->eft_dma)); | ||
881 | |||
882 | ha->fw_dump->header_size = | ||
883 | htonl(offsetof(struct qla2xxx_fw_dump, isp)); | ||
796 | } | 884 | } |
797 | 885 | ||
798 | /** | 886 | /** |
@@ -810,8 +898,6 @@ qla2x00_resize_request_q(scsi_qla_host_t *ha) | |||
810 | dma_addr_t request_dma; | 898 | dma_addr_t request_dma; |
811 | request_t *request_ring; | 899 | request_t *request_ring; |
812 | 900 | ||
813 | qla2x00_alloc_fw_dump(ha); | ||
814 | |||
815 | /* Valid only on recent ISPs. */ | 901 | /* Valid only on recent ISPs. */ |
816 | if (IS_QLA2100(ha) || IS_QLA2200(ha)) | 902 | if (IS_QLA2100(ha) || IS_QLA2200(ha)) |
817 | return; | 903 | return; |
@@ -883,6 +969,9 @@ qla2x00_setup_chip(scsi_qla_host_t *ha) | |||
883 | &ha->fw_subminor_version, | 969 | &ha->fw_subminor_version, |
884 | &ha->fw_attributes, &ha->fw_memory_size); | 970 | &ha->fw_attributes, &ha->fw_memory_size); |
885 | qla2x00_resize_request_q(ha); | 971 | qla2x00_resize_request_q(ha); |
972 | |||
973 | if (ql2xallocfwdump) | ||
974 | qla2x00_alloc_fw_dump(ha); | ||
886 | } | 975 | } |
887 | } else { | 976 | } else { |
888 | DEBUG2(printk(KERN_INFO | 977 | DEBUG2(printk(KERN_INFO |
@@ -1186,8 +1275,7 @@ qla2x00_fw_ready(scsi_qla_host_t *ha) | |||
1186 | rval = QLA_FUNCTION_FAILED; | 1275 | rval = QLA_FUNCTION_FAILED; |
1187 | 1276 | ||
1188 | if (atomic_read(&ha->loop_down_timer) && | 1277 | if (atomic_read(&ha->loop_down_timer) && |
1189 | (fw_state >= FSTATE_LOSS_OF_SYNC || | 1278 | fw_state != FSTATE_READY) { |
1190 | fw_state == FSTATE_WAIT_AL_PA)) { | ||
1191 | /* Loop down. Timeout on min_wait for states | 1279 | /* Loop down. Timeout on min_wait for states |
1192 | * other than Wait for Login. | 1280 | * other than Wait for Login. |
1193 | */ | 1281 | */ |
@@ -1555,6 +1643,8 @@ qla2x00_nvram_config(scsi_qla_host_t *ha) | |||
1555 | /* | 1643 | /* |
1556 | * Set host adapter parameters. | 1644 | * Set host adapter parameters. |
1557 | */ | 1645 | */ |
1646 | if (nv->host_p[0] & BIT_7) | ||
1647 | extended_error_logging = 1; | ||
1558 | ha->flags.disable_risc_code_load = ((nv->host_p[0] & BIT_4) ? 1 : 0); | 1648 | ha->flags.disable_risc_code_load = ((nv->host_p[0] & BIT_4) ? 1 : 0); |
1559 | /* Always load RISC code on non ISP2[12]00 chips. */ | 1649 | /* Always load RISC code on non ISP2[12]00 chips. */ |
1560 | if (!IS_QLA2100(ha) && !IS_QLA2200(ha)) | 1650 | if (!IS_QLA2100(ha) && !IS_QLA2200(ha)) |
@@ -1563,6 +1653,7 @@ qla2x00_nvram_config(scsi_qla_host_t *ha) | |||
1563 | ha->flags.enable_lip_full_login = ((nv->host_p[1] & BIT_2) ? 1 : 0); | 1653 | ha->flags.enable_lip_full_login = ((nv->host_p[1] & BIT_2) ? 1 : 0); |
1564 | ha->flags.enable_target_reset = ((nv->host_p[1] & BIT_3) ? 1 : 0); | 1654 | ha->flags.enable_target_reset = ((nv->host_p[1] & BIT_3) ? 1 : 0); |
1565 | ha->flags.enable_led_scheme = (nv->special_options[1] & BIT_4) ? 1 : 0; | 1655 | ha->flags.enable_led_scheme = (nv->special_options[1] & BIT_4) ? 1 : 0; |
1656 | ha->flags.disable_serdes = 0; | ||
1566 | 1657 | ||
1567 | ha->operating_mode = | 1658 | ha->operating_mode = |
1568 | (icb->add_firmware_options[0] & (BIT_6 | BIT_5 | BIT_4)) >> 4; | 1659 | (icb->add_firmware_options[0] & (BIT_6 | BIT_5 | BIT_4)) >> 4; |
@@ -1701,7 +1792,7 @@ qla2x00_rport_del(void *data) | |||
1701 | * | 1792 | * |
1702 | * Returns a pointer to the allocated fcport, or NULL, if none available. | 1793 | * Returns a pointer to the allocated fcport, or NULL, if none available. |
1703 | */ | 1794 | */ |
1704 | fc_port_t * | 1795 | static fc_port_t * |
1705 | qla2x00_alloc_fcport(scsi_qla_host_t *ha, gfp_t flags) | 1796 | qla2x00_alloc_fcport(scsi_qla_host_t *ha, gfp_t flags) |
1706 | { | 1797 | { |
1707 | fc_port_t *fcport; | 1798 | fc_port_t *fcport; |
@@ -2497,7 +2588,7 @@ qla2x00_find_all_fabric_devs(scsi_qla_host_t *ha, struct list_head *new_fcports) | |||
2497 | * Context: | 2588 | * Context: |
2498 | * Kernel context. | 2589 | * Kernel context. |
2499 | */ | 2590 | */ |
2500 | int | 2591 | static int |
2501 | qla2x00_find_new_loop_id(scsi_qla_host_t *ha, fc_port_t *dev) | 2592 | qla2x00_find_new_loop_id(scsi_qla_host_t *ha, fc_port_t *dev) |
2502 | { | 2593 | { |
2503 | int rval; | 2594 | int rval; |
@@ -3048,14 +3139,14 @@ qla2x00_abort_isp(scsi_qla_host_t *ha) | |||
3048 | ha->isp_abort_cnt--; | 3139 | ha->isp_abort_cnt--; |
3049 | DEBUG(printk("qla%ld: ISP abort - " | 3140 | DEBUG(printk("qla%ld: ISP abort - " |
3050 | "retry remaining %d\n", | 3141 | "retry remaining %d\n", |
3051 | ha->host_no, ha->isp_abort_cnt);) | 3142 | ha->host_no, ha->isp_abort_cnt)); |
3052 | status = 1; | 3143 | status = 1; |
3053 | } | 3144 | } |
3054 | } else { | 3145 | } else { |
3055 | ha->isp_abort_cnt = MAX_RETRIES_OF_ISP_ABORT; | 3146 | ha->isp_abort_cnt = MAX_RETRIES_OF_ISP_ABORT; |
3056 | DEBUG(printk("qla2x00(%ld): ISP error recovery " | 3147 | DEBUG(printk("qla2x00(%ld): ISP error recovery " |
3057 | "- retrying (%d) more times\n", | 3148 | "- retrying (%d) more times\n", |
3058 | ha->host_no, ha->isp_abort_cnt);) | 3149 | ha->host_no, ha->isp_abort_cnt)); |
3059 | set_bit(ISP_ABORT_RETRY, &ha->dpc_flags); | 3150 | set_bit(ISP_ABORT_RETRY, &ha->dpc_flags); |
3060 | status = 1; | 3151 | status = 1; |
3061 | } | 3152 | } |
@@ -3069,7 +3160,7 @@ qla2x00_abort_isp(scsi_qla_host_t *ha) | |||
3069 | } else { | 3160 | } else { |
3070 | DEBUG(printk(KERN_INFO | 3161 | DEBUG(printk(KERN_INFO |
3071 | "qla2x00_abort_isp(%ld): exiting.\n", | 3162 | "qla2x00_abort_isp(%ld): exiting.\n", |
3072 | ha->host_no);) | 3163 | ha->host_no)); |
3073 | } | 3164 | } |
3074 | 3165 | ||
3075 | return(status); | 3166 | return(status); |
@@ -3145,7 +3236,7 @@ qla2x00_restart_isp(scsi_qla_host_t *ha) | |||
3145 | clear_bit(RESET_MARKER_NEEDED, &ha->dpc_flags); | 3236 | clear_bit(RESET_MARKER_NEEDED, &ha->dpc_flags); |
3146 | if (!(status = qla2x00_fw_ready(ha))) { | 3237 | if (!(status = qla2x00_fw_ready(ha))) { |
3147 | DEBUG(printk("%s(): Start configure loop, " | 3238 | DEBUG(printk("%s(): Start configure loop, " |
3148 | "status = %d\n", __func__, status);) | 3239 | "status = %d\n", __func__, status)); |
3149 | 3240 | ||
3150 | /* Issue a marker after FW becomes ready. */ | 3241 | /* Issue a marker after FW becomes ready. */ |
3151 | qla2x00_marker(ha, 0, 0, MK_SYNC_ALL); | 3242 | qla2x00_marker(ha, 0, 0, MK_SYNC_ALL); |
@@ -3169,7 +3260,7 @@ qla2x00_restart_isp(scsi_qla_host_t *ha) | |||
3169 | 3260 | ||
3170 | DEBUG(printk("%s(): Configure loop done, status = 0x%x\n", | 3261 | DEBUG(printk("%s(): Configure loop done, status = 0x%x\n", |
3171 | __func__, | 3262 | __func__, |
3172 | status);) | 3263 | status)); |
3173 | } | 3264 | } |
3174 | return (status); | 3265 | return (status); |
3175 | } | 3266 | } |
@@ -3289,7 +3380,6 @@ qla24xx_nvram_config(scsi_qla_host_t *ha) | |||
3289 | nv->node_name[6] = 0x55; | 3380 | nv->node_name[6] = 0x55; |
3290 | nv->node_name[7] = 0x86; | 3381 | nv->node_name[7] = 0x86; |
3291 | nv->login_retry_count = __constant_cpu_to_le16(8); | 3382 | nv->login_retry_count = __constant_cpu_to_le16(8); |
3292 | nv->link_down_timeout = __constant_cpu_to_le16(200); | ||
3293 | nv->interrupt_delay_timer = __constant_cpu_to_le16(0); | 3383 | nv->interrupt_delay_timer = __constant_cpu_to_le16(0); |
3294 | nv->login_timeout = __constant_cpu_to_le16(0); | 3384 | nv->login_timeout = __constant_cpu_to_le16(0); |
3295 | nv->firmware_options_1 = | 3385 | nv->firmware_options_1 = |
@@ -3318,7 +3408,7 @@ qla24xx_nvram_config(scsi_qla_host_t *ha) | |||
3318 | *dptr1++ = *dptr2++; | 3408 | *dptr1++ = *dptr2++; |
3319 | 3409 | ||
3320 | icb->login_retry_count = nv->login_retry_count; | 3410 | icb->login_retry_count = nv->login_retry_count; |
3321 | icb->link_down_timeout = nv->link_down_timeout; | 3411 | icb->link_down_on_nos = nv->link_down_on_nos; |
3322 | 3412 | ||
3323 | /* Copy 2nd segment. */ | 3413 | /* Copy 2nd segment. */ |
3324 | dptr1 = (uint8_t *)&icb->interrupt_delay_timer; | 3414 | dptr1 = (uint8_t *)&icb->interrupt_delay_timer; |
@@ -3373,6 +3463,7 @@ qla24xx_nvram_config(scsi_qla_host_t *ha) | |||
3373 | ha->flags.enable_lip_full_login = 1; | 3463 | ha->flags.enable_lip_full_login = 1; |
3374 | ha->flags.enable_target_reset = 1; | 3464 | ha->flags.enable_target_reset = 1; |
3375 | ha->flags.enable_led_scheme = 0; | 3465 | ha->flags.enable_led_scheme = 0; |
3466 | ha->flags.disable_serdes = le32_to_cpu(nv->host_p) & BIT_5 ? 1: 0; | ||
3376 | 3467 | ||
3377 | ha->operating_mode = (le32_to_cpu(icb->firmware_options_2) & | 3468 | ha->operating_mode = (le32_to_cpu(icb->firmware_options_2) & |
3378 | (BIT_6 | BIT_5 | BIT_4)) >> 4; | 3469 | (BIT_6 | BIT_5 | BIT_4)) >> 4; |
@@ -3472,7 +3563,7 @@ qla24xx_nvram_config(scsi_qla_host_t *ha) | |||
3472 | return (rval); | 3563 | return (rval); |
3473 | } | 3564 | } |
3474 | 3565 | ||
3475 | int | 3566 | static int |
3476 | qla24xx_load_risc_flash(scsi_qla_host_t *ha, uint32_t *srisc_addr) | 3567 | qla24xx_load_risc_flash(scsi_qla_host_t *ha, uint32_t *srisc_addr) |
3477 | { | 3568 | { |
3478 | int rval; | 3569 | int rval; |
diff --git a/drivers/scsi/qla2xxx/qla_iocb.c b/drivers/scsi/qla2xxx/qla_iocb.c index 8c769cfaa14c..2b60a27eff0b 100644 --- a/drivers/scsi/qla2xxx/qla_iocb.c +++ b/drivers/scsi/qla2xxx/qla_iocb.c | |||
@@ -15,6 +15,7 @@ static inline uint16_t qla2x00_get_cmd_direction(struct scsi_cmnd *cmd); | |||
15 | static inline cont_entry_t *qla2x00_prep_cont_type0_iocb(scsi_qla_host_t *); | 15 | static inline cont_entry_t *qla2x00_prep_cont_type0_iocb(scsi_qla_host_t *); |
16 | static inline cont_a64_entry_t *qla2x00_prep_cont_type1_iocb(scsi_qla_host_t *); | 16 | static inline cont_a64_entry_t *qla2x00_prep_cont_type1_iocb(scsi_qla_host_t *); |
17 | static request_t *qla2x00_req_pkt(scsi_qla_host_t *ha); | 17 | static request_t *qla2x00_req_pkt(scsi_qla_host_t *ha); |
18 | static void qla2x00_isp_cmd(scsi_qla_host_t *ha); | ||
18 | 19 | ||
19 | /** | 20 | /** |
20 | * qla2x00_get_cmd_direction() - Determine control_flag data direction. | 21 | * qla2x00_get_cmd_direction() - Determine control_flag data direction. |
@@ -574,7 +575,7 @@ qla2x00_req_pkt(scsi_qla_host_t *ha) | |||
574 | * | 575 | * |
575 | * Note: The caller must hold the hardware lock before calling this routine. | 576 | * Note: The caller must hold the hardware lock before calling this routine. |
576 | */ | 577 | */ |
577 | void | 578 | static void |
578 | qla2x00_isp_cmd(scsi_qla_host_t *ha) | 579 | qla2x00_isp_cmd(scsi_qla_host_t *ha) |
579 | { | 580 | { |
580 | device_reg_t __iomem *reg = ha->iobase; | 581 | device_reg_t __iomem *reg = ha->iobase; |
diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c index b28ac0a27e25..795bf15b1b8f 100644 --- a/drivers/scsi/qla2xxx/qla_isr.c +++ b/drivers/scsi/qla2xxx/qla_isr.c | |||
@@ -395,10 +395,6 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb) | |||
395 | set_bit(REGISTER_FC4_NEEDED, &ha->dpc_flags); | 395 | set_bit(REGISTER_FC4_NEEDED, &ha->dpc_flags); |
396 | 396 | ||
397 | ha->flags.management_server_logged_in = 0; | 397 | ha->flags.management_server_logged_in = 0; |
398 | |||
399 | /* Update AEN queue. */ | ||
400 | qla2x00_enqueue_aen(ha, MBA_LIP_OCCURRED, NULL); | ||
401 | |||
402 | break; | 398 | break; |
403 | 399 | ||
404 | case MBA_LOOP_UP: /* Loop Up Event */ | 400 | case MBA_LOOP_UP: /* Loop Up Event */ |
@@ -418,9 +414,6 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb) | |||
418 | link_speed); | 414 | link_speed); |
419 | 415 | ||
420 | ha->flags.management_server_logged_in = 0; | 416 | ha->flags.management_server_logged_in = 0; |
421 | |||
422 | /* Update AEN queue. */ | ||
423 | qla2x00_enqueue_aen(ha, MBA_LOOP_UP, NULL); | ||
424 | break; | 417 | break; |
425 | 418 | ||
426 | case MBA_LOOP_DOWN: /* Loop Down Event */ | 419 | case MBA_LOOP_DOWN: /* Loop Down Event */ |
@@ -439,9 +432,6 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb) | |||
439 | ha->link_data_rate = LDR_UNKNOWN; | 432 | ha->link_data_rate = LDR_UNKNOWN; |
440 | if (ql2xfdmienable) | 433 | if (ql2xfdmienable) |
441 | set_bit(REGISTER_FDMI_NEEDED, &ha->dpc_flags); | 434 | set_bit(REGISTER_FDMI_NEEDED, &ha->dpc_flags); |
442 | |||
443 | /* Update AEN queue. */ | ||
444 | qla2x00_enqueue_aen(ha, MBA_LOOP_DOWN, NULL); | ||
445 | break; | 435 | break; |
446 | 436 | ||
447 | case MBA_LIP_RESET: /* LIP reset occurred */ | 437 | case MBA_LIP_RESET: /* LIP reset occurred */ |
@@ -460,10 +450,6 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb) | |||
460 | 450 | ||
461 | ha->operating_mode = LOOP; | 451 | ha->operating_mode = LOOP; |
462 | ha->flags.management_server_logged_in = 0; | 452 | ha->flags.management_server_logged_in = 0; |
463 | |||
464 | /* Update AEN queue. */ | ||
465 | qla2x00_enqueue_aen(ha, MBA_LIP_RESET, NULL); | ||
466 | |||
467 | break; | 453 | break; |
468 | 454 | ||
469 | case MBA_POINT_TO_POINT: /* Point-to-Point */ | 455 | case MBA_POINT_TO_POINT: /* Point-to-Point */ |
@@ -545,9 +531,6 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb) | |||
545 | 531 | ||
546 | set_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags); | 532 | set_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags); |
547 | set_bit(LOCAL_LOOP_UPDATE, &ha->dpc_flags); | 533 | set_bit(LOCAL_LOOP_UPDATE, &ha->dpc_flags); |
548 | |||
549 | /* Update AEN queue. */ | ||
550 | qla2x00_enqueue_aen(ha, MBA_PORT_UPDATE, NULL); | ||
551 | break; | 534 | break; |
552 | 535 | ||
553 | case MBA_RSCN_UPDATE: /* State Change Registration */ | 536 | case MBA_RSCN_UPDATE: /* State Change Registration */ |
@@ -584,9 +567,6 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb) | |||
584 | 567 | ||
585 | set_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags); | 568 | set_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags); |
586 | set_bit(RSCN_UPDATE, &ha->dpc_flags); | 569 | set_bit(RSCN_UPDATE, &ha->dpc_flags); |
587 | |||
588 | /* Update AEN queue. */ | ||
589 | qla2x00_enqueue_aen(ha, MBA_RSCN_UPDATE, &mb[0]); | ||
590 | break; | 570 | break; |
591 | 571 | ||
592 | /* case MBA_RIO_RESPONSE: */ | 572 | /* case MBA_RIO_RESPONSE: */ |
@@ -1452,8 +1432,8 @@ qla24xx_ms_entry(scsi_qla_host_t *ha, struct ct_entry_24xx *pkt) | |||
1452 | DEBUG3(printk("%s(%ld): pkt=%p pkthandle=%d.\n", | 1432 | DEBUG3(printk("%s(%ld): pkt=%p pkthandle=%d.\n", |
1453 | __func__, ha->host_no, pkt, pkt->handle)); | 1433 | __func__, ha->host_no, pkt, pkt->handle)); |
1454 | 1434 | ||
1455 | DEBUG9(printk("%s: ct pkt dump:\n", __func__);) | 1435 | DEBUG9(printk("%s: ct pkt dump:\n", __func__)); |
1456 | DEBUG9(qla2x00_dump_buffer((void *)pkt, sizeof(struct ct_entry_24xx));) | 1436 | DEBUG9(qla2x00_dump_buffer((void *)pkt, sizeof(struct ct_entry_24xx))); |
1457 | 1437 | ||
1458 | /* Validate handle. */ | 1438 | /* Validate handle. */ |
1459 | if (pkt->handle < MAX_OUTSTANDING_COMMANDS) | 1439 | if (pkt->handle < MAX_OUTSTANDING_COMMANDS) |
diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c index d6cb3bd1a29a..879f281e2ea2 100644 --- a/drivers/scsi/qla2xxx/qla_mbx.c +++ b/drivers/scsi/qla2xxx/qla_mbx.c | |||
@@ -13,13 +13,13 @@ qla2x00_mbx_sem_timeout(unsigned long data) | |||
13 | { | 13 | { |
14 | struct semaphore *sem_ptr = (struct semaphore *)data; | 14 | struct semaphore *sem_ptr = (struct semaphore *)data; |
15 | 15 | ||
16 | DEBUG11(printk("qla2x00_sem_timeout: entered.\n");) | 16 | DEBUG11(printk("qla2x00_sem_timeout: entered.\n")); |
17 | 17 | ||
18 | if (sem_ptr != NULL) { | 18 | if (sem_ptr != NULL) { |
19 | up(sem_ptr); | 19 | up(sem_ptr); |
20 | } | 20 | } |
21 | 21 | ||
22 | DEBUG11(printk("qla2x00_mbx_sem_timeout: exiting.\n");) | 22 | DEBUG11(printk("qla2x00_mbx_sem_timeout: exiting.\n")); |
23 | } | 23 | } |
24 | 24 | ||
25 | /* | 25 | /* |
@@ -61,7 +61,7 @@ qla2x00_mailbox_command(scsi_qla_host_t *ha, mbx_cmd_t *mcp) | |||
61 | rval = QLA_SUCCESS; | 61 | rval = QLA_SUCCESS; |
62 | abort_active = test_bit(ABORT_ISP_ACTIVE, &ha->dpc_flags); | 62 | abort_active = test_bit(ABORT_ISP_ACTIVE, &ha->dpc_flags); |
63 | 63 | ||
64 | DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no);) | 64 | DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no)); |
65 | 65 | ||
66 | /* | 66 | /* |
67 | * Wait for active mailbox commands to finish by waiting at most tov | 67 | * Wait for active mailbox commands to finish by waiting at most tov |
@@ -72,7 +72,7 @@ qla2x00_mailbox_command(scsi_qla_host_t *ha, mbx_cmd_t *mcp) | |||
72 | if (qla2x00_down_timeout(&ha->mbx_cmd_sem, mcp->tov * HZ)) { | 72 | if (qla2x00_down_timeout(&ha->mbx_cmd_sem, mcp->tov * HZ)) { |
73 | /* Timeout occurred. Return error. */ | 73 | /* Timeout occurred. Return error. */ |
74 | DEBUG2_3_11(printk("%s(%ld): cmd access timeout. " | 74 | DEBUG2_3_11(printk("%s(%ld): cmd access timeout. " |
75 | "Exiting.\n", __func__, ha->host_no);) | 75 | "Exiting.\n", __func__, ha->host_no)); |
76 | return QLA_FUNCTION_TIMEOUT; | 76 | return QLA_FUNCTION_TIMEOUT; |
77 | } | 77 | } |
78 | } | 78 | } |
@@ -86,7 +86,7 @@ qla2x00_mailbox_command(scsi_qla_host_t *ha, mbx_cmd_t *mcp) | |||
86 | spin_lock_irqsave(&ha->mbx_reg_lock, mbx_flags); | 86 | spin_lock_irqsave(&ha->mbx_reg_lock, mbx_flags); |
87 | 87 | ||
88 | DEBUG11(printk("scsi(%ld): prepare to issue mbox cmd=0x%x.\n", | 88 | DEBUG11(printk("scsi(%ld): prepare to issue mbox cmd=0x%x.\n", |
89 | ha->host_no, mcp->mb[0]);) | 89 | ha->host_no, mcp->mb[0])); |
90 | 90 | ||
91 | spin_lock_irqsave(&ha->hardware_lock, flags); | 91 | spin_lock_irqsave(&ha->hardware_lock, flags); |
92 | 92 | ||
@@ -131,14 +131,14 @@ qla2x00_mailbox_command(scsi_qla_host_t *ha, mbx_cmd_t *mcp) | |||
131 | 131 | ||
132 | /* Unlock mbx registers and wait for interrupt */ | 132 | /* Unlock mbx registers and wait for interrupt */ |
133 | DEBUG11(printk("%s(%ld): going to unlock irq & waiting for interrupt. " | 133 | DEBUG11(printk("%s(%ld): going to unlock irq & waiting for interrupt. " |
134 | "jiffies=%lx.\n", __func__, ha->host_no, jiffies);) | 134 | "jiffies=%lx.\n", __func__, ha->host_no, jiffies)); |
135 | 135 | ||
136 | /* Wait for mbx cmd completion until timeout */ | 136 | /* Wait for mbx cmd completion until timeout */ |
137 | 137 | ||
138 | if (!abort_active && io_lock_on) { | 138 | if (!abort_active && io_lock_on) { |
139 | /* sleep on completion semaphore */ | 139 | /* sleep on completion semaphore */ |
140 | DEBUG11(printk("%s(%ld): INTERRUPT MODE. Initializing timer.\n", | 140 | DEBUG11(printk("%s(%ld): INTERRUPT MODE. Initializing timer.\n", |
141 | __func__, ha->host_no);) | 141 | __func__, ha->host_no)); |
142 | 142 | ||
143 | init_timer(&tmp_intr_timer); | 143 | init_timer(&tmp_intr_timer); |
144 | tmp_intr_timer.data = (unsigned long)&ha->mbx_intr_sem; | 144 | tmp_intr_timer.data = (unsigned long)&ha->mbx_intr_sem; |
@@ -147,11 +147,11 @@ qla2x00_mailbox_command(scsi_qla_host_t *ha, mbx_cmd_t *mcp) | |||
147 | (void (*)(unsigned long))qla2x00_mbx_sem_timeout; | 147 | (void (*)(unsigned long))qla2x00_mbx_sem_timeout; |
148 | 148 | ||
149 | DEBUG11(printk("%s(%ld): Adding timer.\n", __func__, | 149 | DEBUG11(printk("%s(%ld): Adding timer.\n", __func__, |
150 | ha->host_no);) | 150 | ha->host_no)); |
151 | add_timer(&tmp_intr_timer); | 151 | add_timer(&tmp_intr_timer); |
152 | 152 | ||
153 | DEBUG11(printk("%s(%ld): going to unlock & sleep. " | 153 | DEBUG11(printk("%s(%ld): going to unlock & sleep. " |
154 | "time=0x%lx.\n", __func__, ha->host_no, jiffies);) | 154 | "time=0x%lx.\n", __func__, ha->host_no, jiffies)); |
155 | 155 | ||
156 | set_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags); | 156 | set_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags); |
157 | 157 | ||
@@ -170,14 +170,14 @@ qla2x00_mailbox_command(scsi_qla_host_t *ha, mbx_cmd_t *mcp) | |||
170 | down(&ha->mbx_intr_sem); | 170 | down(&ha->mbx_intr_sem); |
171 | 171 | ||
172 | DEBUG11(printk("%s(%ld): waking up. time=0x%lx\n", __func__, | 172 | DEBUG11(printk("%s(%ld): waking up. time=0x%lx\n", __func__, |
173 | ha->host_no, jiffies);) | 173 | ha->host_no, jiffies)); |
174 | clear_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags); | 174 | clear_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags); |
175 | 175 | ||
176 | /* delete the timer */ | 176 | /* delete the timer */ |
177 | del_timer(&tmp_intr_timer); | 177 | del_timer(&tmp_intr_timer); |
178 | } else { | 178 | } else { |
179 | DEBUG3_11(printk("%s(%ld): cmd=%x POLLING MODE.\n", __func__, | 179 | DEBUG3_11(printk("%s(%ld): cmd=%x POLLING MODE.\n", __func__, |
180 | ha->host_no, command);) | 180 | ha->host_no, command)); |
181 | 181 | ||
182 | if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) | 182 | if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) |
183 | WRT_REG_DWORD(®->isp24.hccr, HCCRX_SET_HOST_INT); | 183 | WRT_REG_DWORD(®->isp24.hccr, HCCRX_SET_HOST_INT); |
@@ -209,7 +209,7 @@ qla2x00_mailbox_command(scsi_qla_host_t *ha, mbx_cmd_t *mcp) | |||
209 | uint16_t *iptr2; | 209 | uint16_t *iptr2; |
210 | 210 | ||
211 | DEBUG3_11(printk("%s(%ld): cmd %x completed.\n", __func__, | 211 | DEBUG3_11(printk("%s(%ld): cmd %x completed.\n", __func__, |
212 | ha->host_no, command);) | 212 | ha->host_no, command)); |
213 | 213 | ||
214 | /* Got interrupt. Clear the flag. */ | 214 | /* Got interrupt. Clear the flag. */ |
215 | ha->flags.mbox_int = 0; | 215 | ha->flags.mbox_int = 0; |
@@ -266,7 +266,7 @@ qla2x00_mailbox_command(scsi_qla_host_t *ha, mbx_cmd_t *mcp) | |||
266 | 266 | ||
267 | if (!abort_active) { | 267 | if (!abort_active) { |
268 | DEBUG11(printk("%s(%ld): checking for additional resp " | 268 | DEBUG11(printk("%s(%ld): checking for additional resp " |
269 | "interrupt.\n", __func__, ha->host_no);) | 269 | "interrupt.\n", __func__, ha->host_no)); |
270 | 270 | ||
271 | /* polling mode for non isp_abort commands. */ | 271 | /* polling mode for non isp_abort commands. */ |
272 | qla2x00_poll(ha); | 272 | qla2x00_poll(ha); |
@@ -277,9 +277,9 @@ qla2x00_mailbox_command(scsi_qla_host_t *ha, mbx_cmd_t *mcp) | |||
277 | if (!io_lock_on || (mcp->flags & IOCTL_CMD)) { | 277 | if (!io_lock_on || (mcp->flags & IOCTL_CMD)) { |
278 | /* not in dpc. schedule it for dpc to take over. */ | 278 | /* not in dpc. schedule it for dpc to take over. */ |
279 | DEBUG(printk("%s(%ld): timeout schedule " | 279 | DEBUG(printk("%s(%ld): timeout schedule " |
280 | "isp_abort_needed.\n", __func__, ha->host_no);) | 280 | "isp_abort_needed.\n", __func__, ha->host_no)); |
281 | DEBUG2_3_11(printk("%s(%ld): timeout schedule " | 281 | DEBUG2_3_11(printk("%s(%ld): timeout schedule " |
282 | "isp_abort_needed.\n", __func__, ha->host_no);) | 282 | "isp_abort_needed.\n", __func__, ha->host_no)); |
283 | qla_printk(KERN_WARNING, ha, | 283 | qla_printk(KERN_WARNING, ha, |
284 | "Mailbox command timeout occured. Scheduling ISP " | 284 | "Mailbox command timeout occured. Scheduling ISP " |
285 | "abort.\n"); | 285 | "abort.\n"); |
@@ -288,9 +288,9 @@ qla2x00_mailbox_command(scsi_qla_host_t *ha, mbx_cmd_t *mcp) | |||
288 | } else if (!abort_active) { | 288 | } else if (!abort_active) { |
289 | /* call abort directly since we are in the DPC thread */ | 289 | /* call abort directly since we are in the DPC thread */ |
290 | DEBUG(printk("%s(%ld): timeout calling abort_isp\n", | 290 | DEBUG(printk("%s(%ld): timeout calling abort_isp\n", |
291 | __func__, ha->host_no);) | 291 | __func__, ha->host_no)); |
292 | DEBUG2_3_11(printk("%s(%ld): timeout calling " | 292 | DEBUG2_3_11(printk("%s(%ld): timeout calling " |
293 | "abort_isp\n", __func__, ha->host_no);) | 293 | "abort_isp\n", __func__, ha->host_no)); |
294 | qla_printk(KERN_WARNING, ha, | 294 | qla_printk(KERN_WARNING, ha, |
295 | "Mailbox command timeout occured. Issuing ISP " | 295 | "Mailbox command timeout occured. Issuing ISP " |
296 | "abort.\n"); | 296 | "abort.\n"); |
@@ -303,9 +303,9 @@ qla2x00_mailbox_command(scsi_qla_host_t *ha, mbx_cmd_t *mcp) | |||
303 | } | 303 | } |
304 | clear_bit(ABORT_ISP_ACTIVE, &ha->dpc_flags); | 304 | clear_bit(ABORT_ISP_ACTIVE, &ha->dpc_flags); |
305 | DEBUG(printk("%s(%ld): finished abort_isp\n", __func__, | 305 | DEBUG(printk("%s(%ld): finished abort_isp\n", __func__, |
306 | ha->host_no);) | 306 | ha->host_no)); |
307 | DEBUG2_3_11(printk("%s(%ld): finished abort_isp\n", | 307 | DEBUG2_3_11(printk("%s(%ld): finished abort_isp\n", |
308 | __func__, ha->host_no);) | 308 | __func__, ha->host_no)); |
309 | } | 309 | } |
310 | } | 310 | } |
311 | 311 | ||
@@ -316,9 +316,9 @@ qla2x00_mailbox_command(scsi_qla_host_t *ha, mbx_cmd_t *mcp) | |||
316 | if (rval) { | 316 | if (rval) { |
317 | DEBUG2_3_11(printk("%s(%ld): **** FAILED. mbx0=%x, mbx1=%x, " | 317 | DEBUG2_3_11(printk("%s(%ld): **** FAILED. mbx0=%x, mbx1=%x, " |
318 | "mbx2=%x, cmd=%x ****\n", __func__, ha->host_no, | 318 | "mbx2=%x, cmd=%x ****\n", __func__, ha->host_no, |
319 | mcp->mb[0], mcp->mb[1], mcp->mb[2], command);) | 319 | mcp->mb[0], mcp->mb[1], mcp->mb[2], command)); |
320 | } else { | 320 | } else { |
321 | DEBUG11(printk("%s(%ld): done.\n", __func__, ha->host_no);) | 321 | DEBUG11(printk("%s(%ld): done.\n", __func__, ha->host_no)); |
322 | } | 322 | } |
323 | 323 | ||
324 | return rval; | 324 | return rval; |
@@ -394,7 +394,7 @@ qla2x00_execute_fw(scsi_qla_host_t *ha, uint32_t risc_addr) | |||
394 | mbx_cmd_t mc; | 394 | mbx_cmd_t mc; |
395 | mbx_cmd_t *mcp = &mc; | 395 | mbx_cmd_t *mcp = &mc; |
396 | 396 | ||
397 | DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no);) | 397 | DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no)); |
398 | 398 | ||
399 | mcp->mb[0] = MBC_EXECUTE_FIRMWARE; | 399 | mcp->mb[0] = MBC_EXECUTE_FIRMWARE; |
400 | mcp->out_mb = MBX_0; | 400 | mcp->out_mb = MBX_0; |
@@ -424,10 +424,10 @@ qla2x00_execute_fw(scsi_qla_host_t *ha, uint32_t risc_addr) | |||
424 | } else { | 424 | } else { |
425 | if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) { | 425 | if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) { |
426 | DEBUG11(printk("%s(%ld): done exchanges=%x.\n", | 426 | DEBUG11(printk("%s(%ld): done exchanges=%x.\n", |
427 | __func__, ha->host_no, mcp->mb[1]);) | 427 | __func__, ha->host_no, mcp->mb[1])); |
428 | } else { | 428 | } else { |
429 | DEBUG11(printk("%s(%ld): done.\n", __func__, | 429 | DEBUG11(printk("%s(%ld): done.\n", __func__, |
430 | ha->host_no);) | 430 | ha->host_no)); |
431 | } | 431 | } |
432 | } | 432 | } |
433 | 433 | ||
@@ -611,7 +611,7 @@ qla2x00_mbx_reg_test(scsi_qla_host_t *ha) | |||
611 | mbx_cmd_t mc; | 611 | mbx_cmd_t mc; |
612 | mbx_cmd_t *mcp = &mc; | 612 | mbx_cmd_t *mcp = &mc; |
613 | 613 | ||
614 | DEBUG11(printk("qla2x00_mbx_reg_test(%ld): entered.\n", ha->host_no);) | 614 | DEBUG11(printk("qla2x00_mbx_reg_test(%ld): entered.\n", ha->host_no)); |
615 | 615 | ||
616 | mcp->mb[0] = MBC_MAILBOX_REGISTER_TEST; | 616 | mcp->mb[0] = MBC_MAILBOX_REGISTER_TEST; |
617 | mcp->mb[1] = 0xAAAA; | 617 | mcp->mb[1] = 0xAAAA; |
@@ -639,11 +639,11 @@ qla2x00_mbx_reg_test(scsi_qla_host_t *ha) | |||
639 | if (rval != QLA_SUCCESS) { | 639 | if (rval != QLA_SUCCESS) { |
640 | /*EMPTY*/ | 640 | /*EMPTY*/ |
641 | DEBUG2_3_11(printk("qla2x00_mbx_reg_test(%ld): failed=%x.\n", | 641 | DEBUG2_3_11(printk("qla2x00_mbx_reg_test(%ld): failed=%x.\n", |
642 | ha->host_no, rval);) | 642 | ha->host_no, rval)); |
643 | } else { | 643 | } else { |
644 | /*EMPTY*/ | 644 | /*EMPTY*/ |
645 | DEBUG11(printk("qla2x00_mbx_reg_test(%ld): done.\n", | 645 | DEBUG11(printk("qla2x00_mbx_reg_test(%ld): done.\n", |
646 | ha->host_no);) | 646 | ha->host_no)); |
647 | } | 647 | } |
648 | 648 | ||
649 | return rval; | 649 | return rval; |
@@ -671,7 +671,7 @@ qla2x00_verify_checksum(scsi_qla_host_t *ha, uint32_t risc_addr) | |||
671 | mbx_cmd_t mc; | 671 | mbx_cmd_t mc; |
672 | mbx_cmd_t *mcp = &mc; | 672 | mbx_cmd_t *mcp = &mc; |
673 | 673 | ||
674 | DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no);) | 674 | DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no)); |
675 | 675 | ||
676 | mcp->mb[0] = MBC_VERIFY_CHECKSUM; | 676 | mcp->mb[0] = MBC_VERIFY_CHECKSUM; |
677 | mcp->out_mb = MBX_0; | 677 | mcp->out_mb = MBX_0; |
@@ -694,9 +694,9 @@ qla2x00_verify_checksum(scsi_qla_host_t *ha, uint32_t risc_addr) | |||
694 | if (rval != QLA_SUCCESS) { | 694 | if (rval != QLA_SUCCESS) { |
695 | DEBUG2_3_11(printk("%s(%ld): failed=%x chk sum=%x.\n", __func__, | 695 | DEBUG2_3_11(printk("%s(%ld): failed=%x chk sum=%x.\n", __func__, |
696 | ha->host_no, rval, (IS_QLA24XX(ha) || IS_QLA54XX(ha) ? | 696 | ha->host_no, rval, (IS_QLA24XX(ha) || IS_QLA54XX(ha) ? |
697 | (mcp->mb[2] << 16) | mcp->mb[1]: mcp->mb[1]));) | 697 | (mcp->mb[2] << 16) | mcp->mb[1]: mcp->mb[1]))); |
698 | } else { | 698 | } else { |
699 | DEBUG11(printk("%s(%ld): done.\n", __func__, ha->host_no);) | 699 | DEBUG11(printk("%s(%ld): done.\n", __func__, ha->host_no)); |
700 | } | 700 | } |
701 | 701 | ||
702 | return rval; | 702 | return rval; |
@@ -743,9 +743,9 @@ qla2x00_issue_iocb(scsi_qla_host_t *ha, void* buffer, dma_addr_t phys_addr, | |||
743 | if (rval != QLA_SUCCESS) { | 743 | if (rval != QLA_SUCCESS) { |
744 | /*EMPTY*/ | 744 | /*EMPTY*/ |
745 | DEBUG(printk("qla2x00_issue_iocb(%ld): failed rval 0x%x\n", | 745 | DEBUG(printk("qla2x00_issue_iocb(%ld): failed rval 0x%x\n", |
746 | ha->host_no, rval);) | 746 | ha->host_no, rval)); |
747 | DEBUG2(printk("qla2x00_issue_iocb(%ld): failed rval 0x%x\n", | 747 | DEBUG2(printk("qla2x00_issue_iocb(%ld): failed rval 0x%x\n", |
748 | ha->host_no, rval);) | 748 | ha->host_no, rval)); |
749 | } else { | 749 | } else { |
750 | sts_entry_t *sts_entry = (sts_entry_t *) buffer; | 750 | sts_entry_t *sts_entry = (sts_entry_t *) buffer; |
751 | 751 | ||
@@ -781,7 +781,7 @@ qla2x00_abort_command(scsi_qla_host_t *ha, srb_t *sp) | |||
781 | mbx_cmd_t mc; | 781 | mbx_cmd_t mc; |
782 | mbx_cmd_t *mcp = &mc; | 782 | mbx_cmd_t *mcp = &mc; |
783 | 783 | ||
784 | DEBUG11(printk("qla2x00_abort_command(%ld): entered.\n", ha->host_no);) | 784 | DEBUG11(printk("qla2x00_abort_command(%ld): entered.\n", ha->host_no)); |
785 | 785 | ||
786 | fcport = sp->fcport; | 786 | fcport = sp->fcport; |
787 | 787 | ||
@@ -813,11 +813,11 @@ qla2x00_abort_command(scsi_qla_host_t *ha, srb_t *sp) | |||
813 | 813 | ||
814 | if (rval != QLA_SUCCESS) { | 814 | if (rval != QLA_SUCCESS) { |
815 | DEBUG2_3_11(printk("qla2x00_abort_command(%ld): failed=%x.\n", | 815 | DEBUG2_3_11(printk("qla2x00_abort_command(%ld): failed=%x.\n", |
816 | ha->host_no, rval);) | 816 | ha->host_no, rval)); |
817 | } else { | 817 | } else { |
818 | sp->flags |= SRB_ABORT_PENDING; | 818 | sp->flags |= SRB_ABORT_PENDING; |
819 | DEBUG11(printk("qla2x00_abort_command(%ld): done.\n", | 819 | DEBUG11(printk("qla2x00_abort_command(%ld): done.\n", |
820 | ha->host_no);) | 820 | ha->host_no)); |
821 | } | 821 | } |
822 | 822 | ||
823 | return rval; | 823 | return rval; |
@@ -848,7 +848,7 @@ qla2x00_abort_target(fc_port_t *fcport) | |||
848 | if (fcport == NULL) | 848 | if (fcport == NULL) |
849 | return 0; | 849 | return 0; |
850 | 850 | ||
851 | DEBUG11(printk("%s(%ld): entered.\n", __func__, fcport->ha->host_no);) | 851 | DEBUG11(printk("%s(%ld): entered.\n", __func__, fcport->ha->host_no)); |
852 | 852 | ||
853 | ha = fcport->ha; | 853 | ha = fcport->ha; |
854 | mcp->mb[0] = MBC_ABORT_TARGET; | 854 | mcp->mb[0] = MBC_ABORT_TARGET; |
@@ -872,11 +872,11 @@ qla2x00_abort_target(fc_port_t *fcport) | |||
872 | 872 | ||
873 | if (rval != QLA_SUCCESS) { | 873 | if (rval != QLA_SUCCESS) { |
874 | DEBUG2_3_11(printk("qla2x00_abort_target(%ld): failed=%x.\n", | 874 | DEBUG2_3_11(printk("qla2x00_abort_target(%ld): failed=%x.\n", |
875 | ha->host_no, rval);) | 875 | ha->host_no, rval)); |
876 | } else { | 876 | } else { |
877 | /*EMPTY*/ | 877 | /*EMPTY*/ |
878 | DEBUG11(printk("qla2x00_abort_target(%ld): done.\n", | 878 | DEBUG11(printk("qla2x00_abort_target(%ld): done.\n", |
879 | ha->host_no);) | 879 | ha->host_no)); |
880 | } | 880 | } |
881 | 881 | ||
882 | return rval; | 882 | return rval; |
@@ -912,7 +912,7 @@ qla2x00_get_adapter_id(scsi_qla_host_t *ha, uint16_t *id, uint8_t *al_pa, | |||
912 | mbx_cmd_t *mcp = &mc; | 912 | mbx_cmd_t *mcp = &mc; |
913 | 913 | ||
914 | DEBUG11(printk("qla2x00_get_adapter_id(%ld): entered.\n", | 914 | DEBUG11(printk("qla2x00_get_adapter_id(%ld): entered.\n", |
915 | ha->host_no);) | 915 | ha->host_no)); |
916 | 916 | ||
917 | mcp->mb[0] = MBC_GET_ADAPTER_LOOP_ID; | 917 | mcp->mb[0] = MBC_GET_ADAPTER_LOOP_ID; |
918 | mcp->out_mb = MBX_0; | 918 | mcp->out_mb = MBX_0; |
@@ -933,11 +933,11 @@ qla2x00_get_adapter_id(scsi_qla_host_t *ha, uint16_t *id, uint8_t *al_pa, | |||
933 | if (rval != QLA_SUCCESS) { | 933 | if (rval != QLA_SUCCESS) { |
934 | /*EMPTY*/ | 934 | /*EMPTY*/ |
935 | DEBUG2_3_11(printk("qla2x00_get_adapter_id(%ld): failed=%x.\n", | 935 | DEBUG2_3_11(printk("qla2x00_get_adapter_id(%ld): failed=%x.\n", |
936 | ha->host_no, rval);) | 936 | ha->host_no, rval)); |
937 | } else { | 937 | } else { |
938 | /*EMPTY*/ | 938 | /*EMPTY*/ |
939 | DEBUG11(printk("qla2x00_get_adapter_id(%ld): done.\n", | 939 | DEBUG11(printk("qla2x00_get_adapter_id(%ld): done.\n", |
940 | ha->host_no);) | 940 | ha->host_no)); |
941 | } | 941 | } |
942 | 942 | ||
943 | return rval; | 943 | return rval; |
@@ -968,7 +968,7 @@ qla2x00_get_retry_cnt(scsi_qla_host_t *ha, uint8_t *retry_cnt, uint8_t *tov, | |||
968 | mbx_cmd_t *mcp = &mc; | 968 | mbx_cmd_t *mcp = &mc; |
969 | 969 | ||
970 | DEBUG11(printk("qla2x00_get_retry_cnt(%ld): entered.\n", | 970 | DEBUG11(printk("qla2x00_get_retry_cnt(%ld): entered.\n", |
971 | ha->host_no);) | 971 | ha->host_no)); |
972 | 972 | ||
973 | mcp->mb[0] = MBC_GET_RETRY_COUNT; | 973 | mcp->mb[0] = MBC_GET_RETRY_COUNT; |
974 | mcp->out_mb = MBX_0; | 974 | mcp->out_mb = MBX_0; |
@@ -980,7 +980,7 @@ qla2x00_get_retry_cnt(scsi_qla_host_t *ha, uint8_t *retry_cnt, uint8_t *tov, | |||
980 | if (rval != QLA_SUCCESS) { | 980 | if (rval != QLA_SUCCESS) { |
981 | /*EMPTY*/ | 981 | /*EMPTY*/ |
982 | DEBUG2_3_11(printk("qla2x00_get_retry_cnt(%ld): failed = %x.\n", | 982 | DEBUG2_3_11(printk("qla2x00_get_retry_cnt(%ld): failed = %x.\n", |
983 | ha->host_no, mcp->mb[0]);) | 983 | ha->host_no, mcp->mb[0])); |
984 | } else { | 984 | } else { |
985 | /* Convert returned data and check our values. */ | 985 | /* Convert returned data and check our values. */ |
986 | *r_a_tov = mcp->mb[3] / 2; | 986 | *r_a_tov = mcp->mb[3] / 2; |
@@ -992,7 +992,7 @@ qla2x00_get_retry_cnt(scsi_qla_host_t *ha, uint8_t *retry_cnt, uint8_t *tov, | |||
992 | } | 992 | } |
993 | 993 | ||
994 | DEBUG11(printk("qla2x00_get_retry_cnt(%ld): done. mb3=%d " | 994 | DEBUG11(printk("qla2x00_get_retry_cnt(%ld): done. mb3=%d " |
995 | "ratov=%d.\n", ha->host_no, mcp->mb[3], ratov);) | 995 | "ratov=%d.\n", ha->host_no, mcp->mb[3], ratov)); |
996 | } | 996 | } |
997 | 997 | ||
998 | return rval; | 998 | return rval; |
@@ -1023,7 +1023,7 @@ qla2x00_init_firmware(scsi_qla_host_t *ha, uint16_t size) | |||
1023 | mbx_cmd_t *mcp = &mc; | 1023 | mbx_cmd_t *mcp = &mc; |
1024 | 1024 | ||
1025 | DEBUG11(printk("qla2x00_init_firmware(%ld): entered.\n", | 1025 | DEBUG11(printk("qla2x00_init_firmware(%ld): entered.\n", |
1026 | ha->host_no);) | 1026 | ha->host_no)); |
1027 | 1027 | ||
1028 | mcp->mb[0] = MBC_INITIALIZE_FIRMWARE; | 1028 | mcp->mb[0] = MBC_INITIALIZE_FIRMWARE; |
1029 | mcp->mb[2] = MSW(ha->init_cb_dma); | 1029 | mcp->mb[2] = MSW(ha->init_cb_dma); |
@@ -1043,11 +1043,11 @@ qla2x00_init_firmware(scsi_qla_host_t *ha, uint16_t size) | |||
1043 | /*EMPTY*/ | 1043 | /*EMPTY*/ |
1044 | DEBUG2_3_11(printk("qla2x00_init_firmware(%ld): failed=%x " | 1044 | DEBUG2_3_11(printk("qla2x00_init_firmware(%ld): failed=%x " |
1045 | "mb0=%x.\n", | 1045 | "mb0=%x.\n", |
1046 | ha->host_no, rval, mcp->mb[0]);) | 1046 | ha->host_no, rval, mcp->mb[0])); |
1047 | } else { | 1047 | } else { |
1048 | /*EMPTY*/ | 1048 | /*EMPTY*/ |
1049 | DEBUG11(printk("qla2x00_init_firmware(%ld): done.\n", | 1049 | DEBUG11(printk("qla2x00_init_firmware(%ld): done.\n", |
1050 | ha->host_no);) | 1050 | ha->host_no)); |
1051 | } | 1051 | } |
1052 | 1052 | ||
1053 | return rval; | 1053 | return rval; |
@@ -1079,7 +1079,7 @@ qla2x00_get_port_database(scsi_qla_host_t *ha, fc_port_t *fcport, uint8_t opt) | |||
1079 | struct port_database_24xx *pd24; | 1079 | struct port_database_24xx *pd24; |
1080 | dma_addr_t pd_dma; | 1080 | dma_addr_t pd_dma; |
1081 | 1081 | ||
1082 | DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no);) | 1082 | DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no)); |
1083 | 1083 | ||
1084 | pd24 = NULL; | 1084 | pd24 = NULL; |
1085 | pd = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &pd_dma); | 1085 | pd = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &pd_dma); |
@@ -1220,7 +1220,7 @@ qla2x00_get_firmware_state(scsi_qla_host_t *ha, uint16_t *dptr) | |||
1220 | mbx_cmd_t *mcp = &mc; | 1220 | mbx_cmd_t *mcp = &mc; |
1221 | 1221 | ||
1222 | DEBUG11(printk("qla2x00_get_firmware_state(%ld): entered.\n", | 1222 | DEBUG11(printk("qla2x00_get_firmware_state(%ld): entered.\n", |
1223 | ha->host_no);) | 1223 | ha->host_no)); |
1224 | 1224 | ||
1225 | mcp->mb[0] = MBC_GET_FIRMWARE_STATE; | 1225 | mcp->mb[0] = MBC_GET_FIRMWARE_STATE; |
1226 | mcp->out_mb = MBX_0; | 1226 | mcp->out_mb = MBX_0; |
@@ -1235,11 +1235,11 @@ qla2x00_get_firmware_state(scsi_qla_host_t *ha, uint16_t *dptr) | |||
1235 | if (rval != QLA_SUCCESS) { | 1235 | if (rval != QLA_SUCCESS) { |
1236 | /*EMPTY*/ | 1236 | /*EMPTY*/ |
1237 | DEBUG2_3_11(printk("qla2x00_get_firmware_state(%ld): " | 1237 | DEBUG2_3_11(printk("qla2x00_get_firmware_state(%ld): " |
1238 | "failed=%x.\n", ha->host_no, rval);) | 1238 | "failed=%x.\n", ha->host_no, rval)); |
1239 | } else { | 1239 | } else { |
1240 | /*EMPTY*/ | 1240 | /*EMPTY*/ |
1241 | DEBUG11(printk("qla2x00_get_firmware_state(%ld): done.\n", | 1241 | DEBUG11(printk("qla2x00_get_firmware_state(%ld): done.\n", |
1242 | ha->host_no);) | 1242 | ha->host_no)); |
1243 | } | 1243 | } |
1244 | 1244 | ||
1245 | return rval; | 1245 | return rval; |
@@ -1272,7 +1272,7 @@ qla2x00_get_port_name(scsi_qla_host_t *ha, uint16_t loop_id, uint8_t *name, | |||
1272 | mbx_cmd_t *mcp = &mc; | 1272 | mbx_cmd_t *mcp = &mc; |
1273 | 1273 | ||
1274 | DEBUG11(printk("qla2x00_get_port_name(%ld): entered.\n", | 1274 | DEBUG11(printk("qla2x00_get_port_name(%ld): entered.\n", |
1275 | ha->host_no);) | 1275 | ha->host_no)); |
1276 | 1276 | ||
1277 | mcp->mb[0] = MBC_GET_PORT_NAME; | 1277 | mcp->mb[0] = MBC_GET_PORT_NAME; |
1278 | mcp->out_mb = MBX_1|MBX_0; | 1278 | mcp->out_mb = MBX_1|MBX_0; |
@@ -1292,7 +1292,7 @@ qla2x00_get_port_name(scsi_qla_host_t *ha, uint16_t loop_id, uint8_t *name, | |||
1292 | if (rval != QLA_SUCCESS) { | 1292 | if (rval != QLA_SUCCESS) { |
1293 | /*EMPTY*/ | 1293 | /*EMPTY*/ |
1294 | DEBUG2_3_11(printk("qla2x00_get_port_name(%ld): failed=%x.\n", | 1294 | DEBUG2_3_11(printk("qla2x00_get_port_name(%ld): failed=%x.\n", |
1295 | ha->host_no, rval);) | 1295 | ha->host_no, rval)); |
1296 | } else { | 1296 | } else { |
1297 | if (name != NULL) { | 1297 | if (name != NULL) { |
1298 | /* This function returns name in big endian. */ | 1298 | /* This function returns name in big endian. */ |
@@ -1307,7 +1307,7 @@ qla2x00_get_port_name(scsi_qla_host_t *ha, uint16_t loop_id, uint8_t *name, | |||
1307 | } | 1307 | } |
1308 | 1308 | ||
1309 | DEBUG11(printk("qla2x00_get_port_name(%ld): done.\n", | 1309 | DEBUG11(printk("qla2x00_get_port_name(%ld): done.\n", |
1310 | ha->host_no);) | 1310 | ha->host_no)); |
1311 | } | 1311 | } |
1312 | 1312 | ||
1313 | return rval; | 1313 | return rval; |
@@ -1335,7 +1335,7 @@ qla2x00_lip_reset(scsi_qla_host_t *ha) | |||
1335 | mbx_cmd_t mc; | 1335 | mbx_cmd_t mc; |
1336 | mbx_cmd_t *mcp = &mc; | 1336 | mbx_cmd_t *mcp = &mc; |
1337 | 1337 | ||
1338 | DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no);) | 1338 | DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no)); |
1339 | 1339 | ||
1340 | if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) { | 1340 | if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) { |
1341 | mcp->mb[0] = MBC_LIP_FULL_LOGIN; | 1341 | mcp->mb[0] = MBC_LIP_FULL_LOGIN; |
@@ -1364,10 +1364,10 @@ qla2x00_lip_reset(scsi_qla_host_t *ha) | |||
1364 | if (rval != QLA_SUCCESS) { | 1364 | if (rval != QLA_SUCCESS) { |
1365 | /*EMPTY*/ | 1365 | /*EMPTY*/ |
1366 | DEBUG2_3_11(printk("%s(%ld): failed=%x.\n", | 1366 | DEBUG2_3_11(printk("%s(%ld): failed=%x.\n", |
1367 | __func__, ha->host_no, rval);) | 1367 | __func__, ha->host_no, rval)); |
1368 | } else { | 1368 | } else { |
1369 | /*EMPTY*/ | 1369 | /*EMPTY*/ |
1370 | DEBUG11(printk("%s(%ld): done.\n", __func__, ha->host_no);) | 1370 | DEBUG11(printk("%s(%ld): done.\n", __func__, ha->host_no)); |
1371 | } | 1371 | } |
1372 | 1372 | ||
1373 | return rval; | 1373 | return rval; |
@@ -1400,10 +1400,10 @@ qla2x00_send_sns(scsi_qla_host_t *ha, dma_addr_t sns_phys_address, | |||
1400 | mbx_cmd_t *mcp = &mc; | 1400 | mbx_cmd_t *mcp = &mc; |
1401 | 1401 | ||
1402 | DEBUG11(printk("qla2x00_send_sns(%ld): entered.\n", | 1402 | DEBUG11(printk("qla2x00_send_sns(%ld): entered.\n", |
1403 | ha->host_no);) | 1403 | ha->host_no)); |
1404 | 1404 | ||
1405 | DEBUG11(printk("qla2x00_send_sns: retry cnt=%d ratov=%d total " | 1405 | DEBUG11(printk("qla2x00_send_sns: retry cnt=%d ratov=%d total " |
1406 | "tov=%d.\n", ha->retry_count, ha->login_timeout, mcp->tov);) | 1406 | "tov=%d.\n", ha->retry_count, ha->login_timeout, mcp->tov)); |
1407 | 1407 | ||
1408 | mcp->mb[0] = MBC_SEND_SNS_COMMAND; | 1408 | mcp->mb[0] = MBC_SEND_SNS_COMMAND; |
1409 | mcp->mb[1] = cmd_size; | 1409 | mcp->mb[1] = cmd_size; |
@@ -1421,12 +1421,12 @@ qla2x00_send_sns(scsi_qla_host_t *ha, dma_addr_t sns_phys_address, | |||
1421 | if (rval != QLA_SUCCESS) { | 1421 | if (rval != QLA_SUCCESS) { |
1422 | /*EMPTY*/ | 1422 | /*EMPTY*/ |
1423 | DEBUG(printk("qla2x00_send_sns(%ld): failed=%x mb[0]=%x " | 1423 | DEBUG(printk("qla2x00_send_sns(%ld): failed=%x mb[0]=%x " |
1424 | "mb[1]=%x.\n", ha->host_no, rval, mcp->mb[0], mcp->mb[1]);) | 1424 | "mb[1]=%x.\n", ha->host_no, rval, mcp->mb[0], mcp->mb[1])); |
1425 | DEBUG2_3_11(printk("qla2x00_send_sns(%ld): failed=%x mb[0]=%x " | 1425 | DEBUG2_3_11(printk("qla2x00_send_sns(%ld): failed=%x mb[0]=%x " |
1426 | "mb[1]=%x.\n", ha->host_no, rval, mcp->mb[0], mcp->mb[1]);) | 1426 | "mb[1]=%x.\n", ha->host_no, rval, mcp->mb[0], mcp->mb[1])); |
1427 | } else { | 1427 | } else { |
1428 | /*EMPTY*/ | 1428 | /*EMPTY*/ |
1429 | DEBUG11(printk("qla2x00_send_sns(%ld): done.\n", ha->host_no);) | 1429 | DEBUG11(printk("qla2x00_send_sns(%ld): done.\n", ha->host_no)); |
1430 | } | 1430 | } |
1431 | 1431 | ||
1432 | return rval; | 1432 | return rval; |
@@ -1442,7 +1442,7 @@ qla24xx_login_fabric(scsi_qla_host_t *ha, uint16_t loop_id, uint8_t domain, | |||
1442 | dma_addr_t lg_dma; | 1442 | dma_addr_t lg_dma; |
1443 | uint32_t iop[2]; | 1443 | uint32_t iop[2]; |
1444 | 1444 | ||
1445 | DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no);) | 1445 | DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no)); |
1446 | 1446 | ||
1447 | lg = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &lg_dma); | 1447 | lg = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &lg_dma); |
1448 | if (lg == NULL) { | 1448 | if (lg == NULL) { |
@@ -1458,13 +1458,15 @@ qla24xx_login_fabric(scsi_qla_host_t *ha, uint16_t loop_id, uint8_t domain, | |||
1458 | lg->control_flags = __constant_cpu_to_le16(LCF_COMMAND_PLOGI); | 1458 | lg->control_flags = __constant_cpu_to_le16(LCF_COMMAND_PLOGI); |
1459 | if (opt & BIT_0) | 1459 | if (opt & BIT_0) |
1460 | lg->control_flags |= __constant_cpu_to_le16(LCF_COND_PLOGI); | 1460 | lg->control_flags |= __constant_cpu_to_le16(LCF_COND_PLOGI); |
1461 | if (opt & BIT_1) | ||
1462 | lg->control_flags |= __constant_cpu_to_le16(LCF_SKIP_PRLI); | ||
1461 | lg->port_id[0] = al_pa; | 1463 | lg->port_id[0] = al_pa; |
1462 | lg->port_id[1] = area; | 1464 | lg->port_id[1] = area; |
1463 | lg->port_id[2] = domain; | 1465 | lg->port_id[2] = domain; |
1464 | rval = qla2x00_issue_iocb(ha, lg, lg_dma, 0); | 1466 | rval = qla2x00_issue_iocb(ha, lg, lg_dma, 0); |
1465 | if (rval != QLA_SUCCESS) { | 1467 | if (rval != QLA_SUCCESS) { |
1466 | DEBUG2_3_11(printk("%s(%ld): failed to issue Login IOCB " | 1468 | DEBUG2_3_11(printk("%s(%ld): failed to issue Login IOCB " |
1467 | "(%x).\n", __func__, ha->host_no, rval);) | 1469 | "(%x).\n", __func__, ha->host_no, rval)); |
1468 | } else if (lg->entry_status != 0) { | 1470 | } else if (lg->entry_status != 0) { |
1469 | DEBUG2_3_11(printk("%s(%ld): failed to complete IOCB " | 1471 | DEBUG2_3_11(printk("%s(%ld): failed to complete IOCB " |
1470 | "-- error status (%x).\n", __func__, ha->host_no, | 1472 | "-- error status (%x).\n", __func__, ha->host_no, |
@@ -1505,7 +1507,7 @@ qla24xx_login_fabric(scsi_qla_host_t *ha, uint16_t loop_id, uint8_t domain, | |||
1505 | break; | 1507 | break; |
1506 | } | 1508 | } |
1507 | } else { | 1509 | } else { |
1508 | DEBUG11(printk("%s(%ld): done.\n", __func__, ha->host_no);) | 1510 | DEBUG11(printk("%s(%ld): done.\n", __func__, ha->host_no)); |
1509 | 1511 | ||
1510 | iop[0] = le32_to_cpu(lg->io_parameter[0]); | 1512 | iop[0] = le32_to_cpu(lg->io_parameter[0]); |
1511 | 1513 | ||
@@ -1559,7 +1561,7 @@ qla2x00_login_fabric(scsi_qla_host_t *ha, uint16_t loop_id, uint8_t domain, | |||
1559 | mbx_cmd_t mc; | 1561 | mbx_cmd_t mc; |
1560 | mbx_cmd_t *mcp = &mc; | 1562 | mbx_cmd_t *mcp = &mc; |
1561 | 1563 | ||
1562 | DEBUG11(printk("qla2x00_login_fabric(%ld): entered.\n", ha->host_no);) | 1564 | DEBUG11(printk("qla2x00_login_fabric(%ld): entered.\n", ha->host_no)); |
1563 | 1565 | ||
1564 | mcp->mb[0] = MBC_LOGIN_FABRIC_PORT; | 1566 | mcp->mb[0] = MBC_LOGIN_FABRIC_PORT; |
1565 | mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0; | 1567 | mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0; |
@@ -1604,11 +1606,11 @@ qla2x00_login_fabric(scsi_qla_host_t *ha, uint16_t loop_id, uint8_t domain, | |||
1604 | /*EMPTY*/ | 1606 | /*EMPTY*/ |
1605 | DEBUG2_3_11(printk("qla2x00_login_fabric(%ld): failed=%x " | 1607 | DEBUG2_3_11(printk("qla2x00_login_fabric(%ld): failed=%x " |
1606 | "mb[0]=%x mb[1]=%x mb[2]=%x.\n", ha->host_no, rval, | 1608 | "mb[0]=%x mb[1]=%x mb[2]=%x.\n", ha->host_no, rval, |
1607 | mcp->mb[0], mcp->mb[1], mcp->mb[2]);) | 1609 | mcp->mb[0], mcp->mb[1], mcp->mb[2])); |
1608 | } else { | 1610 | } else { |
1609 | /*EMPTY*/ | 1611 | /*EMPTY*/ |
1610 | DEBUG11(printk("qla2x00_login_fabric(%ld): done.\n", | 1612 | DEBUG11(printk("qla2x00_login_fabric(%ld): done.\n", |
1611 | ha->host_no);) | 1613 | ha->host_no)); |
1612 | } | 1614 | } |
1613 | 1615 | ||
1614 | return rval; | 1616 | return rval; |
@@ -1643,7 +1645,7 @@ qla2x00_login_local_device(scsi_qla_host_t *ha, fc_port_t *fcport, | |||
1643 | fcport->d_id.b.domain, fcport->d_id.b.area, | 1645 | fcport->d_id.b.domain, fcport->d_id.b.area, |
1644 | fcport->d_id.b.al_pa, mb_ret, opt); | 1646 | fcport->d_id.b.al_pa, mb_ret, opt); |
1645 | 1647 | ||
1646 | DEBUG3(printk("%s(%ld): entered.\n", __func__, ha->host_no);) | 1648 | DEBUG3(printk("%s(%ld): entered.\n", __func__, ha->host_no)); |
1647 | 1649 | ||
1648 | mcp->mb[0] = MBC_LOGIN_LOOP_PORT; | 1650 | mcp->mb[0] = MBC_LOGIN_LOOP_PORT; |
1649 | if (HAS_EXTENDED_IDS(ha)) | 1651 | if (HAS_EXTENDED_IDS(ha)) |
@@ -1677,13 +1679,13 @@ qla2x00_login_local_device(scsi_qla_host_t *ha, fc_port_t *fcport, | |||
1677 | 1679 | ||
1678 | DEBUG(printk("%s(%ld): failed=%x mb[0]=%x mb[1]=%x " | 1680 | DEBUG(printk("%s(%ld): failed=%x mb[0]=%x mb[1]=%x " |
1679 | "mb[6]=%x mb[7]=%x.\n", __func__, ha->host_no, rval, | 1681 | "mb[6]=%x mb[7]=%x.\n", __func__, ha->host_no, rval, |
1680 | mcp->mb[0], mcp->mb[1], mcp->mb[6], mcp->mb[7]);) | 1682 | mcp->mb[0], mcp->mb[1], mcp->mb[6], mcp->mb[7])); |
1681 | DEBUG2_3(printk("%s(%ld): failed=%x mb[0]=%x mb[1]=%x " | 1683 | DEBUG2_3(printk("%s(%ld): failed=%x mb[0]=%x mb[1]=%x " |
1682 | "mb[6]=%x mb[7]=%x.\n", __func__, ha->host_no, rval, | 1684 | "mb[6]=%x mb[7]=%x.\n", __func__, ha->host_no, rval, |
1683 | mcp->mb[0], mcp->mb[1], mcp->mb[6], mcp->mb[7]);) | 1685 | mcp->mb[0], mcp->mb[1], mcp->mb[6], mcp->mb[7])); |
1684 | } else { | 1686 | } else { |
1685 | /*EMPTY*/ | 1687 | /*EMPTY*/ |
1686 | DEBUG3(printk("%s(%ld): done.\n", __func__, ha->host_no);) | 1688 | DEBUG3(printk("%s(%ld): done.\n", __func__, ha->host_no)); |
1687 | } | 1689 | } |
1688 | 1690 | ||
1689 | return (rval); | 1691 | return (rval); |
@@ -1697,7 +1699,7 @@ qla24xx_fabric_logout(scsi_qla_host_t *ha, uint16_t loop_id, uint8_t domain, | |||
1697 | struct logio_entry_24xx *lg; | 1699 | struct logio_entry_24xx *lg; |
1698 | dma_addr_t lg_dma; | 1700 | dma_addr_t lg_dma; |
1699 | 1701 | ||
1700 | DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no);) | 1702 | DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no)); |
1701 | 1703 | ||
1702 | lg = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &lg_dma); | 1704 | lg = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &lg_dma); |
1703 | if (lg == NULL) { | 1705 | if (lg == NULL) { |
@@ -1718,7 +1720,7 @@ qla24xx_fabric_logout(scsi_qla_host_t *ha, uint16_t loop_id, uint8_t domain, | |||
1718 | rval = qla2x00_issue_iocb(ha, lg, lg_dma, 0); | 1720 | rval = qla2x00_issue_iocb(ha, lg, lg_dma, 0); |
1719 | if (rval != QLA_SUCCESS) { | 1721 | if (rval != QLA_SUCCESS) { |
1720 | DEBUG2_3_11(printk("%s(%ld): failed to issue Logout IOCB " | 1722 | DEBUG2_3_11(printk("%s(%ld): failed to issue Logout IOCB " |
1721 | "(%x).\n", __func__, ha->host_no, rval);) | 1723 | "(%x).\n", __func__, ha->host_no, rval)); |
1722 | } else if (lg->entry_status != 0) { | 1724 | } else if (lg->entry_status != 0) { |
1723 | DEBUG2_3_11(printk("%s(%ld): failed to complete IOCB " | 1725 | DEBUG2_3_11(printk("%s(%ld): failed to complete IOCB " |
1724 | "-- error status (%x).\n", __func__, ha->host_no, | 1726 | "-- error status (%x).\n", __func__, ha->host_no, |
@@ -1729,10 +1731,10 @@ qla24xx_fabric_logout(scsi_qla_host_t *ha, uint16_t loop_id, uint8_t domain, | |||
1729 | "-- completion status (%x) ioparam=%x/%x.\n", __func__, | 1731 | "-- completion status (%x) ioparam=%x/%x.\n", __func__, |
1730 | ha->host_no, le16_to_cpu(lg->comp_status), | 1732 | ha->host_no, le16_to_cpu(lg->comp_status), |
1731 | le32_to_cpu(lg->io_parameter[0]), | 1733 | le32_to_cpu(lg->io_parameter[0]), |
1732 | le32_to_cpu(lg->io_parameter[1]));) | 1734 | le32_to_cpu(lg->io_parameter[1]))); |
1733 | } else { | 1735 | } else { |
1734 | /*EMPTY*/ | 1736 | /*EMPTY*/ |
1735 | DEBUG11(printk("%s(%ld): done.\n", __func__, ha->host_no);) | 1737 | DEBUG11(printk("%s(%ld): done.\n", __func__, ha->host_no)); |
1736 | } | 1738 | } |
1737 | 1739 | ||
1738 | dma_pool_free(ha->s_dma_pool, lg, lg_dma); | 1740 | dma_pool_free(ha->s_dma_pool, lg, lg_dma); |
@@ -1765,7 +1767,7 @@ qla2x00_fabric_logout(scsi_qla_host_t *ha, uint16_t loop_id, uint8_t domain, | |||
1765 | mbx_cmd_t *mcp = &mc; | 1767 | mbx_cmd_t *mcp = &mc; |
1766 | 1768 | ||
1767 | DEBUG11(printk("qla2x00_fabric_logout(%ld): entered.\n", | 1769 | DEBUG11(printk("qla2x00_fabric_logout(%ld): entered.\n", |
1768 | ha->host_no);) | 1770 | ha->host_no)); |
1769 | 1771 | ||
1770 | mcp->mb[0] = MBC_LOGOUT_FABRIC_PORT; | 1772 | mcp->mb[0] = MBC_LOGOUT_FABRIC_PORT; |
1771 | mcp->out_mb = MBX_1|MBX_0; | 1773 | mcp->out_mb = MBX_1|MBX_0; |
@@ -1785,11 +1787,11 @@ qla2x00_fabric_logout(scsi_qla_host_t *ha, uint16_t loop_id, uint8_t domain, | |||
1785 | if (rval != QLA_SUCCESS) { | 1787 | if (rval != QLA_SUCCESS) { |
1786 | /*EMPTY*/ | 1788 | /*EMPTY*/ |
1787 | DEBUG2_3_11(printk("qla2x00_fabric_logout(%ld): failed=%x " | 1789 | DEBUG2_3_11(printk("qla2x00_fabric_logout(%ld): failed=%x " |
1788 | "mbx1=%x.\n", ha->host_no, rval, mcp->mb[1]);) | 1790 | "mbx1=%x.\n", ha->host_no, rval, mcp->mb[1])); |
1789 | } else { | 1791 | } else { |
1790 | /*EMPTY*/ | 1792 | /*EMPTY*/ |
1791 | DEBUG11(printk("qla2x00_fabric_logout(%ld): done.\n", | 1793 | DEBUG11(printk("qla2x00_fabric_logout(%ld): done.\n", |
1792 | ha->host_no);) | 1794 | ha->host_no)); |
1793 | } | 1795 | } |
1794 | 1796 | ||
1795 | return rval; | 1797 | return rval; |
@@ -1818,7 +1820,7 @@ qla2x00_full_login_lip(scsi_qla_host_t *ha) | |||
1818 | mbx_cmd_t *mcp = &mc; | 1820 | mbx_cmd_t *mcp = &mc; |
1819 | 1821 | ||
1820 | DEBUG11(printk("qla2x00_full_login_lip(%ld): entered.\n", | 1822 | DEBUG11(printk("qla2x00_full_login_lip(%ld): entered.\n", |
1821 | ha->host_no);) | 1823 | ha->host_no)); |
1822 | 1824 | ||
1823 | mcp->mb[0] = MBC_LIP_FULL_LOGIN; | 1825 | mcp->mb[0] = MBC_LIP_FULL_LOGIN; |
1824 | mcp->mb[1] = 0; | 1826 | mcp->mb[1] = 0; |
@@ -1833,11 +1835,11 @@ qla2x00_full_login_lip(scsi_qla_host_t *ha) | |||
1833 | if (rval != QLA_SUCCESS) { | 1835 | if (rval != QLA_SUCCESS) { |
1834 | /*EMPTY*/ | 1836 | /*EMPTY*/ |
1835 | DEBUG2_3_11(printk("qla2x00_full_login_lip(%ld): failed=%x.\n", | 1837 | DEBUG2_3_11(printk("qla2x00_full_login_lip(%ld): failed=%x.\n", |
1836 | ha->host_no, rval);) | 1838 | ha->host_no, rval)); |
1837 | } else { | 1839 | } else { |
1838 | /*EMPTY*/ | 1840 | /*EMPTY*/ |
1839 | DEBUG11(printk("qla2x00_full_login_lip(%ld): done.\n", | 1841 | DEBUG11(printk("qla2x00_full_login_lip(%ld): done.\n", |
1840 | ha->host_no);) | 1842 | ha->host_no)); |
1841 | } | 1843 | } |
1842 | 1844 | ||
1843 | return rval; | 1845 | return rval; |
@@ -1864,7 +1866,7 @@ qla2x00_get_id_list(scsi_qla_host_t *ha, void *id_list, dma_addr_t id_list_dma, | |||
1864 | mbx_cmd_t *mcp = &mc; | 1866 | mbx_cmd_t *mcp = &mc; |
1865 | 1867 | ||
1866 | DEBUG11(printk("qla2x00_get_id_list(%ld): entered.\n", | 1868 | DEBUG11(printk("qla2x00_get_id_list(%ld): entered.\n", |
1867 | ha->host_no);) | 1869 | ha->host_no)); |
1868 | 1870 | ||
1869 | if (id_list == NULL) | 1871 | if (id_list == NULL) |
1870 | return QLA_FUNCTION_FAILED; | 1872 | return QLA_FUNCTION_FAILED; |
@@ -1893,11 +1895,11 @@ qla2x00_get_id_list(scsi_qla_host_t *ha, void *id_list, dma_addr_t id_list_dma, | |||
1893 | if (rval != QLA_SUCCESS) { | 1895 | if (rval != QLA_SUCCESS) { |
1894 | /*EMPTY*/ | 1896 | /*EMPTY*/ |
1895 | DEBUG2_3_11(printk("qla2x00_get_id_list(%ld): failed=%x.\n", | 1897 | DEBUG2_3_11(printk("qla2x00_get_id_list(%ld): failed=%x.\n", |
1896 | ha->host_no, rval);) | 1898 | ha->host_no, rval)); |
1897 | } else { | 1899 | } else { |
1898 | *entries = mcp->mb[1]; | 1900 | *entries = mcp->mb[1]; |
1899 | DEBUG11(printk("qla2x00_get_id_list(%ld): done.\n", | 1901 | DEBUG11(printk("qla2x00_get_id_list(%ld): done.\n", |
1900 | ha->host_no);) | 1902 | ha->host_no)); |
1901 | } | 1903 | } |
1902 | 1904 | ||
1903 | return rval; | 1905 | return rval; |
@@ -1936,7 +1938,7 @@ qla2x00_get_resource_cnts(scsi_qla_host_t *ha, uint16_t *cur_xchg_cnt, | |||
1936 | if (rval != QLA_SUCCESS) { | 1938 | if (rval != QLA_SUCCESS) { |
1937 | /*EMPTY*/ | 1939 | /*EMPTY*/ |
1938 | DEBUG2_3_11(printk("%s(%ld): failed = %x.\n", __func__, | 1940 | DEBUG2_3_11(printk("%s(%ld): failed = %x.\n", __func__, |
1939 | ha->host_no, mcp->mb[0]);) | 1941 | ha->host_no, mcp->mb[0])); |
1940 | } else { | 1942 | } else { |
1941 | DEBUG11(printk("%s(%ld): done. mb1=%x mb2=%x mb3=%x mb6=%x " | 1943 | DEBUG11(printk("%s(%ld): done. mb1=%x mb2=%x mb3=%x mb6=%x " |
1942 | "mb7=%x mb10=%x.\n", __func__, ha->host_no, | 1944 | "mb7=%x mb10=%x.\n", __func__, ha->host_no, |
@@ -2045,7 +2047,7 @@ qla2x00_get_link_status(scsi_qla_host_t *ha, uint16_t loop_id, | |||
2045 | link_stat_t *stat_buf; | 2047 | link_stat_t *stat_buf; |
2046 | dma_addr_t stat_buf_dma; | 2048 | dma_addr_t stat_buf_dma; |
2047 | 2049 | ||
2048 | DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no);) | 2050 | DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no)); |
2049 | 2051 | ||
2050 | stat_buf = dma_pool_alloc(ha->s_dma_pool, GFP_ATOMIC, &stat_buf_dma); | 2052 | stat_buf = dma_pool_alloc(ha->s_dma_pool, GFP_ATOMIC, &stat_buf_dma); |
2051 | if (stat_buf == NULL) { | 2053 | if (stat_buf == NULL) { |
@@ -2083,7 +2085,7 @@ qla2x00_get_link_status(scsi_qla_host_t *ha, uint16_t loop_id, | |||
2083 | if (rval == QLA_SUCCESS) { | 2085 | if (rval == QLA_SUCCESS) { |
2084 | if (mcp->mb[0] != MBS_COMMAND_COMPLETE) { | 2086 | if (mcp->mb[0] != MBS_COMMAND_COMPLETE) { |
2085 | DEBUG2_3_11(printk("%s(%ld): cmd failed. mbx0=%x.\n", | 2087 | DEBUG2_3_11(printk("%s(%ld): cmd failed. mbx0=%x.\n", |
2086 | __func__, ha->host_no, mcp->mb[0]);) | 2088 | __func__, ha->host_no, mcp->mb[0])); |
2087 | status[0] = mcp->mb[0]; | 2089 | status[0] = mcp->mb[0]; |
2088 | rval = BIT_1; | 2090 | rval = BIT_1; |
2089 | } else { | 2091 | } else { |
@@ -2108,12 +2110,12 @@ qla2x00_get_link_status(scsi_qla_host_t *ha, uint16_t loop_id, | |||
2108 | stat_buf->loss_sync_cnt, stat_buf->loss_sig_cnt, | 2110 | stat_buf->loss_sync_cnt, stat_buf->loss_sig_cnt, |
2109 | stat_buf->prim_seq_err_cnt, | 2111 | stat_buf->prim_seq_err_cnt, |
2110 | stat_buf->inval_xmit_word_cnt, | 2112 | stat_buf->inval_xmit_word_cnt, |
2111 | stat_buf->inval_crc_cnt);) | 2113 | stat_buf->inval_crc_cnt)); |
2112 | } | 2114 | } |
2113 | } else { | 2115 | } else { |
2114 | /* Failed. */ | 2116 | /* Failed. */ |
2115 | DEBUG2_3_11(printk("%s(%ld): failed=%x.\n", __func__, | 2117 | DEBUG2_3_11(printk("%s(%ld): failed=%x.\n", __func__, |
2116 | ha->host_no, rval);) | 2118 | ha->host_no, rval)); |
2117 | rval = BIT_1; | 2119 | rval = BIT_1; |
2118 | } | 2120 | } |
2119 | 2121 | ||
@@ -2132,7 +2134,7 @@ qla24xx_get_isp_stats(scsi_qla_host_t *ha, uint32_t *dwbuf, uint32_t dwords, | |||
2132 | uint32_t *sbuf, *siter; | 2134 | uint32_t *sbuf, *siter; |
2133 | dma_addr_t sbuf_dma; | 2135 | dma_addr_t sbuf_dma; |
2134 | 2136 | ||
2135 | DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no);) | 2137 | DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no)); |
2136 | 2138 | ||
2137 | if (dwords > (DMA_POOL_SIZE / 4)) { | 2139 | if (dwords > (DMA_POOL_SIZE / 4)) { |
2138 | DEBUG2_3_11(printk("%s(%ld): Unabled to retrieve %d DWORDs " | 2140 | DEBUG2_3_11(printk("%s(%ld): Unabled to retrieve %d DWORDs " |
@@ -2196,7 +2198,7 @@ qla24xx_abort_command(scsi_qla_host_t *ha, srb_t *sp) | |||
2196 | dma_addr_t abt_dma; | 2198 | dma_addr_t abt_dma; |
2197 | uint32_t handle; | 2199 | uint32_t handle; |
2198 | 2200 | ||
2199 | DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no);) | 2201 | DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no)); |
2200 | 2202 | ||
2201 | fcport = sp->fcport; | 2203 | fcport = sp->fcport; |
2202 | 2204 | ||
@@ -2229,7 +2231,7 @@ qla24xx_abort_command(scsi_qla_host_t *ha, srb_t *sp) | |||
2229 | rval = qla2x00_issue_iocb(ha, abt, abt_dma, 0); | 2231 | rval = qla2x00_issue_iocb(ha, abt, abt_dma, 0); |
2230 | if (rval != QLA_SUCCESS) { | 2232 | if (rval != QLA_SUCCESS) { |
2231 | DEBUG2_3_11(printk("%s(%ld): failed to issue IOCB (%x).\n", | 2233 | DEBUG2_3_11(printk("%s(%ld): failed to issue IOCB (%x).\n", |
2232 | __func__, ha->host_no, rval);) | 2234 | __func__, ha->host_no, rval)); |
2233 | } else if (abt->entry_status != 0) { | 2235 | } else if (abt->entry_status != 0) { |
2234 | DEBUG2_3_11(printk("%s(%ld): failed to complete IOCB " | 2236 | DEBUG2_3_11(printk("%s(%ld): failed to complete IOCB " |
2235 | "-- error status (%x).\n", __func__, ha->host_no, | 2237 | "-- error status (%x).\n", __func__, ha->host_no, |
@@ -2238,10 +2240,10 @@ qla24xx_abort_command(scsi_qla_host_t *ha, srb_t *sp) | |||
2238 | } else if (abt->nport_handle != __constant_cpu_to_le16(0)) { | 2240 | } else if (abt->nport_handle != __constant_cpu_to_le16(0)) { |
2239 | DEBUG2_3_11(printk("%s(%ld): failed to complete IOCB " | 2241 | DEBUG2_3_11(printk("%s(%ld): failed to complete IOCB " |
2240 | "-- completion status (%x).\n", __func__, ha->host_no, | 2242 | "-- completion status (%x).\n", __func__, ha->host_no, |
2241 | le16_to_cpu(abt->nport_handle));) | 2243 | le16_to_cpu(abt->nport_handle))); |
2242 | rval = QLA_FUNCTION_FAILED; | 2244 | rval = QLA_FUNCTION_FAILED; |
2243 | } else { | 2245 | } else { |
2244 | DEBUG11(printk("%s(%ld): done.\n", __func__, ha->host_no);) | 2246 | DEBUG11(printk("%s(%ld): done.\n", __func__, ha->host_no)); |
2245 | sp->flags |= SRB_ABORT_PENDING; | 2247 | sp->flags |= SRB_ABORT_PENDING; |
2246 | } | 2248 | } |
2247 | 2249 | ||
@@ -2268,7 +2270,7 @@ qla24xx_abort_target(fc_port_t *fcport) | |||
2268 | if (fcport == NULL) | 2270 | if (fcport == NULL) |
2269 | return 0; | 2271 | return 0; |
2270 | 2272 | ||
2271 | DEBUG11(printk("%s(%ld): entered.\n", __func__, fcport->ha->host_no);) | 2273 | DEBUG11(printk("%s(%ld): entered.\n", __func__, fcport->ha->host_no)); |
2272 | 2274 | ||
2273 | ha = fcport->ha; | 2275 | ha = fcport->ha; |
2274 | tsk = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &tsk_dma); | 2276 | tsk = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &tsk_dma); |
@@ -2290,7 +2292,7 @@ qla24xx_abort_target(fc_port_t *fcport) | |||
2290 | rval = qla2x00_issue_iocb(ha, tsk, tsk_dma, 0); | 2292 | rval = qla2x00_issue_iocb(ha, tsk, tsk_dma, 0); |
2291 | if (rval != QLA_SUCCESS) { | 2293 | if (rval != QLA_SUCCESS) { |
2292 | DEBUG2_3_11(printk("%s(%ld): failed to issue Target Reset IOCB " | 2294 | DEBUG2_3_11(printk("%s(%ld): failed to issue Target Reset IOCB " |
2293 | "(%x).\n", __func__, ha->host_no, rval);) | 2295 | "(%x).\n", __func__, ha->host_no, rval)); |
2294 | goto atarget_done; | 2296 | goto atarget_done; |
2295 | } else if (tsk->p.sts.entry_status != 0) { | 2297 | } else if (tsk->p.sts.entry_status != 0) { |
2296 | DEBUG2_3_11(printk("%s(%ld): failed to complete IOCB " | 2298 | DEBUG2_3_11(printk("%s(%ld): failed to complete IOCB " |
@@ -2302,7 +2304,7 @@ qla24xx_abort_target(fc_port_t *fcport) | |||
2302 | __constant_cpu_to_le16(CS_COMPLETE)) { | 2304 | __constant_cpu_to_le16(CS_COMPLETE)) { |
2303 | DEBUG2_3_11(printk("%s(%ld): failed to complete IOCB " | 2305 | DEBUG2_3_11(printk("%s(%ld): failed to complete IOCB " |
2304 | "-- completion status (%x).\n", __func__, | 2306 | "-- completion status (%x).\n", __func__, |
2305 | ha->host_no, le16_to_cpu(tsk->p.sts.comp_status));) | 2307 | ha->host_no, le16_to_cpu(tsk->p.sts.comp_status))); |
2306 | rval = QLA_FUNCTION_FAILED; | 2308 | rval = QLA_FUNCTION_FAILED; |
2307 | goto atarget_done; | 2309 | goto atarget_done; |
2308 | } | 2310 | } |
@@ -2311,9 +2313,9 @@ qla24xx_abort_target(fc_port_t *fcport) | |||
2311 | rval = qla2x00_marker(ha, fcport->loop_id, 0, MK_SYNC_ID); | 2313 | rval = qla2x00_marker(ha, fcport->loop_id, 0, MK_SYNC_ID); |
2312 | if (rval != QLA_SUCCESS) { | 2314 | if (rval != QLA_SUCCESS) { |
2313 | DEBUG2_3_11(printk("%s(%ld): failed to issue Marker IOCB " | 2315 | DEBUG2_3_11(printk("%s(%ld): failed to issue Marker IOCB " |
2314 | "(%x).\n", __func__, ha->host_no, rval);) | 2316 | "(%x).\n", __func__, ha->host_no, rval)); |
2315 | } else { | 2317 | } else { |
2316 | DEBUG11(printk("%s(%ld): done.\n", __func__, ha->host_no);) | 2318 | DEBUG11(printk("%s(%ld): done.\n", __func__, ha->host_no)); |
2317 | } | 2319 | } |
2318 | 2320 | ||
2319 | atarget_done: | 2321 | atarget_done: |
@@ -2460,3 +2462,81 @@ qla2x00_stop_firmware(scsi_qla_host_t *ha) | |||
2460 | 2462 | ||
2461 | return rval; | 2463 | return rval; |
2462 | } | 2464 | } |
2465 | |||
2466 | int | ||
2467 | qla2x00_trace_control(scsi_qla_host_t *ha, uint16_t ctrl, dma_addr_t eft_dma, | ||
2468 | uint16_t buffers) | ||
2469 | { | ||
2470 | int rval; | ||
2471 | mbx_cmd_t mc; | ||
2472 | mbx_cmd_t *mcp = &mc; | ||
2473 | |||
2474 | if (!IS_QLA24XX(ha) && !IS_QLA54XX(ha)) | ||
2475 | return QLA_FUNCTION_FAILED; | ||
2476 | |||
2477 | DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no)); | ||
2478 | |||
2479 | mcp->mb[0] = MBC_TRACE_CONTROL; | ||
2480 | mcp->mb[1] = ctrl; | ||
2481 | mcp->out_mb = MBX_1|MBX_0; | ||
2482 | mcp->in_mb = MBX_1|MBX_0; | ||
2483 | if (ctrl == TC_ENABLE) { | ||
2484 | mcp->mb[2] = LSW(eft_dma); | ||
2485 | mcp->mb[3] = MSW(eft_dma); | ||
2486 | mcp->mb[4] = LSW(MSD(eft_dma)); | ||
2487 | mcp->mb[5] = MSW(MSD(eft_dma)); | ||
2488 | mcp->mb[6] = buffers; | ||
2489 | mcp->mb[7] = buffers; | ||
2490 | mcp->out_mb |= MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2; | ||
2491 | } | ||
2492 | mcp->tov = 30; | ||
2493 | mcp->flags = 0; | ||
2494 | rval = qla2x00_mailbox_command(ha, mcp); | ||
2495 | |||
2496 | if (rval != QLA_SUCCESS) { | ||
2497 | DEBUG2_3_11(printk("%s(%ld): failed=%x mb[0]=%x mb[1]=%x.\n", | ||
2498 | __func__, ha->host_no, rval, mcp->mb[0], mcp->mb[1])); | ||
2499 | } else { | ||
2500 | DEBUG11(printk("%s(%ld): done.\n", __func__, ha->host_no)); | ||
2501 | } | ||
2502 | |||
2503 | return rval; | ||
2504 | } | ||
2505 | |||
2506 | int | ||
2507 | qla2x00_read_sfp(scsi_qla_host_t *ha, dma_addr_t sfp_dma, uint16_t addr, | ||
2508 | uint16_t off, uint16_t count) | ||
2509 | { | ||
2510 | int rval; | ||
2511 | mbx_cmd_t mc; | ||
2512 | mbx_cmd_t *mcp = &mc; | ||
2513 | |||
2514 | if (!IS_QLA24XX(ha) && !IS_QLA54XX(ha)) | ||
2515 | return QLA_FUNCTION_FAILED; | ||
2516 | |||
2517 | DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no)); | ||
2518 | |||
2519 | mcp->mb[0] = MBC_READ_SFP; | ||
2520 | mcp->mb[1] = addr; | ||
2521 | mcp->mb[2] = MSW(sfp_dma); | ||
2522 | mcp->mb[3] = LSW(sfp_dma); | ||
2523 | mcp->mb[6] = MSW(MSD(sfp_dma)); | ||
2524 | mcp->mb[7] = LSW(MSD(sfp_dma)); | ||
2525 | mcp->mb[8] = count; | ||
2526 | mcp->mb[9] = off; | ||
2527 | mcp->mb[10] = 0; | ||
2528 | mcp->out_mb = MBX_10|MBX_9|MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0; | ||
2529 | mcp->in_mb = MBX_0; | ||
2530 | mcp->tov = 30; | ||
2531 | mcp->flags = 0; | ||
2532 | rval = qla2x00_mailbox_command(ha, mcp); | ||
2533 | |||
2534 | if (rval != QLA_SUCCESS) { | ||
2535 | DEBUG2_3_11(printk("%s(%ld): failed=%x (%x).\n", __func__, | ||
2536 | ha->host_no, rval, mcp->mb[0])); | ||
2537 | } else { | ||
2538 | DEBUG11(printk("%s(%ld): done.\n", __func__, ha->host_no)); | ||
2539 | } | ||
2540 | |||
2541 | return rval; | ||
2542 | } | ||
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index 93062593ebe7..ec7ebb6037e6 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c | |||
@@ -39,14 +39,14 @@ MODULE_PARM_DESC(ql2xlogintimeout, | |||
39 | int qlport_down_retry = 30; | 39 | int qlport_down_retry = 30; |
40 | module_param(qlport_down_retry, int, S_IRUGO|S_IRUSR); | 40 | module_param(qlport_down_retry, int, S_IRUGO|S_IRUSR); |
41 | MODULE_PARM_DESC(qlport_down_retry, | 41 | MODULE_PARM_DESC(qlport_down_retry, |
42 | "Maximum number of command retries to a port that returns" | 42 | "Maximum number of command retries to a port that returns " |
43 | "a PORT-DOWN status."); | 43 | "a PORT-DOWN status."); |
44 | 44 | ||
45 | int ql2xplogiabsentdevice; | 45 | int ql2xplogiabsentdevice; |
46 | module_param(ql2xplogiabsentdevice, int, S_IRUGO|S_IWUSR); | 46 | module_param(ql2xplogiabsentdevice, int, S_IRUGO|S_IWUSR); |
47 | MODULE_PARM_DESC(ql2xplogiabsentdevice, | 47 | MODULE_PARM_DESC(ql2xplogiabsentdevice, |
48 | "Option to enable PLOGI to devices that are not present after " | 48 | "Option to enable PLOGI to devices that are not present after " |
49 | "a Fabric scan. This is needed for several broken switches." | 49 | "a Fabric scan. This is needed for several broken switches. " |
50 | "Default is 0 - no PLOGI. 1 - perfom PLOGI."); | 50 | "Default is 0 - no PLOGI. 1 - perfom PLOGI."); |
51 | 51 | ||
52 | int ql2xloginretrycount = 0; | 52 | int ql2xloginretrycount = 0; |
@@ -54,6 +54,19 @@ module_param(ql2xloginretrycount, int, S_IRUGO|S_IRUSR); | |||
54 | MODULE_PARM_DESC(ql2xloginretrycount, | 54 | MODULE_PARM_DESC(ql2xloginretrycount, |
55 | "Specify an alternate value for the NVRAM login retry count."); | 55 | "Specify an alternate value for the NVRAM login retry count."); |
56 | 56 | ||
57 | int ql2xallocfwdump = 1; | ||
58 | module_param(ql2xallocfwdump, int, S_IRUGO|S_IRUSR); | ||
59 | MODULE_PARM_DESC(ql2xallocfwdump, | ||
60 | "Option to enable allocation of memory for a firmware dump " | ||
61 | "during HBA initialization. Memory allocation requirements " | ||
62 | "vary by ISP type. Default is 1 - allocate memory."); | ||
63 | |||
64 | int extended_error_logging; | ||
65 | module_param(extended_error_logging, int, S_IRUGO|S_IRUSR); | ||
66 | MODULE_PARM_DESC(extended_error_logging, | ||
67 | "Option to enable extended error logging, " | ||
68 | "Default is 0 - no logging. 1 - log errors."); | ||
69 | |||
57 | static void qla2x00_free_device(scsi_qla_host_t *); | 70 | static void qla2x00_free_device(scsi_qla_host_t *); |
58 | 71 | ||
59 | static void qla2x00_config_dma_addressing(scsi_qla_host_t *ha); | 72 | static void qla2x00_config_dma_addressing(scsi_qla_host_t *ha); |
@@ -624,7 +637,7 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd) | |||
624 | 637 | ||
625 | DEBUG2(printk("%s(%ld): aborting sp %p from RISC. pid=%ld.\n", | 638 | DEBUG2(printk("%s(%ld): aborting sp %p from RISC. pid=%ld.\n", |
626 | __func__, ha->host_no, sp, serial)); | 639 | __func__, ha->host_no, sp, serial)); |
627 | DEBUG3(qla2x00_print_scsi_cmd(cmd);) | 640 | DEBUG3(qla2x00_print_scsi_cmd(cmd)); |
628 | 641 | ||
629 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | 642 | spin_unlock_irqrestore(&ha->hardware_lock, flags); |
630 | if (ha->isp_ops.abort_command(ha, sp)) { | 643 | if (ha->isp_ops.abort_command(ha, sp)) { |
@@ -766,7 +779,7 @@ qla2xxx_eh_device_reset(struct scsi_cmnd *cmd) | |||
766 | #endif | 779 | #endif |
767 | } else { | 780 | } else { |
768 | DEBUG2(printk(KERN_INFO | 781 | DEBUG2(printk(KERN_INFO |
769 | "%s failed: loop not ready\n",__func__);) | 782 | "%s failed: loop not ready\n",__func__)); |
770 | } | 783 | } |
771 | 784 | ||
772 | if (ret == FAILED) { | 785 | if (ret == FAILED) { |
@@ -1021,12 +1034,12 @@ qla2x00_loop_reset(scsi_qla_host_t *ha) | |||
1021 | /* Empty */ | 1034 | /* Empty */ |
1022 | DEBUG2_3(printk("%s(%ld): **** FAILED ****\n", | 1035 | DEBUG2_3(printk("%s(%ld): **** FAILED ****\n", |
1023 | __func__, | 1036 | __func__, |
1024 | ha->host_no);) | 1037 | ha->host_no)); |
1025 | } else { | 1038 | } else { |
1026 | /* Empty */ | 1039 | /* Empty */ |
1027 | DEBUG3(printk("%s(%ld): exiting normally.\n", | 1040 | DEBUG3(printk("%s(%ld): exiting normally.\n", |
1028 | __func__, | 1041 | __func__, |
1029 | ha->host_no);) | 1042 | ha->host_no)); |
1030 | } | 1043 | } |
1031 | 1044 | ||
1032 | return(status); | 1045 | return(status); |
@@ -1324,7 +1337,8 @@ qla24xx_disable_intrs(scsi_qla_host_t *ha) | |||
1324 | /* | 1337 | /* |
1325 | * PCI driver interface | 1338 | * PCI driver interface |
1326 | */ | 1339 | */ |
1327 | static int qla2x00_probe_one(struct pci_dev *pdev) | 1340 | static int __devinit |
1341 | qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) | ||
1328 | { | 1342 | { |
1329 | int ret = -ENODEV; | 1343 | int ret = -ENODEV; |
1330 | device_reg_t __iomem *reg; | 1344 | device_reg_t __iomem *reg; |
@@ -1405,7 +1419,6 @@ static int qla2x00_probe_one(struct pci_dev *pdev) | |||
1405 | ha->isp_ops.read_nvram = qla2x00_read_nvram_data; | 1419 | ha->isp_ops.read_nvram = qla2x00_read_nvram_data; |
1406 | ha->isp_ops.write_nvram = qla2x00_write_nvram_data; | 1420 | ha->isp_ops.write_nvram = qla2x00_write_nvram_data; |
1407 | ha->isp_ops.fw_dump = qla2100_fw_dump; | 1421 | ha->isp_ops.fw_dump = qla2100_fw_dump; |
1408 | ha->isp_ops.ascii_fw_dump = qla2100_ascii_fw_dump; | ||
1409 | ha->isp_ops.read_optrom = qla2x00_read_optrom_data; | 1422 | ha->isp_ops.read_optrom = qla2x00_read_optrom_data; |
1410 | ha->isp_ops.write_optrom = qla2x00_write_optrom_data; | 1423 | ha->isp_ops.write_optrom = qla2x00_write_optrom_data; |
1411 | if (IS_QLA2100(ha)) { | 1424 | if (IS_QLA2100(ha)) { |
@@ -1432,7 +1445,6 @@ static int qla2x00_probe_one(struct pci_dev *pdev) | |||
1432 | ha->isp_ops.pci_config = qla2300_pci_config; | 1445 | ha->isp_ops.pci_config = qla2300_pci_config; |
1433 | ha->isp_ops.intr_handler = qla2300_intr_handler; | 1446 | ha->isp_ops.intr_handler = qla2300_intr_handler; |
1434 | ha->isp_ops.fw_dump = qla2300_fw_dump; | 1447 | ha->isp_ops.fw_dump = qla2300_fw_dump; |
1435 | ha->isp_ops.ascii_fw_dump = qla2300_ascii_fw_dump; | ||
1436 | ha->isp_ops.beacon_on = qla2x00_beacon_on; | 1448 | ha->isp_ops.beacon_on = qla2x00_beacon_on; |
1437 | ha->isp_ops.beacon_off = qla2x00_beacon_off; | 1449 | ha->isp_ops.beacon_off = qla2x00_beacon_off; |
1438 | ha->isp_ops.beacon_blink = qla2x00_beacon_blink; | 1450 | ha->isp_ops.beacon_blink = qla2x00_beacon_blink; |
@@ -1469,7 +1481,6 @@ static int qla2x00_probe_one(struct pci_dev *pdev) | |||
1469 | ha->isp_ops.read_nvram = qla24xx_read_nvram_data; | 1481 | ha->isp_ops.read_nvram = qla24xx_read_nvram_data; |
1470 | ha->isp_ops.write_nvram = qla24xx_write_nvram_data; | 1482 | ha->isp_ops.write_nvram = qla24xx_write_nvram_data; |
1471 | ha->isp_ops.fw_dump = qla24xx_fw_dump; | 1483 | ha->isp_ops.fw_dump = qla24xx_fw_dump; |
1472 | ha->isp_ops.ascii_fw_dump = qla24xx_ascii_fw_dump; | ||
1473 | ha->isp_ops.read_optrom = qla24xx_read_optrom_data; | 1484 | ha->isp_ops.read_optrom = qla24xx_read_optrom_data; |
1474 | ha->isp_ops.write_optrom = qla24xx_write_optrom_data; | 1485 | ha->isp_ops.write_optrom = qla24xx_write_optrom_data; |
1475 | ha->isp_ops.beacon_on = qla24xx_beacon_on; | 1486 | ha->isp_ops.beacon_on = qla24xx_beacon_on; |
@@ -1640,7 +1651,8 @@ probe_out: | |||
1640 | return ret; | 1651 | return ret; |
1641 | } | 1652 | } |
1642 | 1653 | ||
1643 | static void qla2x00_remove_one(struct pci_dev *pdev) | 1654 | static void __devexit |
1655 | qla2x00_remove_one(struct pci_dev *pdev) | ||
1644 | { | 1656 | { |
1645 | scsi_qla_host_t *ha; | 1657 | scsi_qla_host_t *ha; |
1646 | 1658 | ||
@@ -1678,6 +1690,9 @@ qla2x00_free_device(scsi_qla_host_t *ha) | |||
1678 | kthread_stop(t); | 1690 | kthread_stop(t); |
1679 | } | 1691 | } |
1680 | 1692 | ||
1693 | if (ha->eft) | ||
1694 | qla2x00_trace_control(ha, TC_DISABLE, 0, 0); | ||
1695 | |||
1681 | /* Stop currently executing firmware. */ | 1696 | /* Stop currently executing firmware. */ |
1682 | qla2x00_stop_firmware(ha); | 1697 | qla2x00_stop_firmware(ha); |
1683 | 1698 | ||
@@ -1899,17 +1914,6 @@ qla2x00_mem_alloc(scsi_qla_host_t *ha) | |||
1899 | } | 1914 | } |
1900 | memset(ha->init_cb, 0, ha->init_cb_size); | 1915 | memset(ha->init_cb, 0, ha->init_cb_size); |
1901 | 1916 | ||
1902 | /* Allocate ioctl related memory. */ | ||
1903 | if (qla2x00_alloc_ioctl_mem(ha)) { | ||
1904 | qla_printk(KERN_WARNING, ha, | ||
1905 | "Memory Allocation failed - ioctl_mem\n"); | ||
1906 | |||
1907 | qla2x00_mem_free(ha); | ||
1908 | msleep(100); | ||
1909 | |||
1910 | continue; | ||
1911 | } | ||
1912 | |||
1913 | if (qla2x00_allocate_sp_pool(ha)) { | 1917 | if (qla2x00_allocate_sp_pool(ha)) { |
1914 | qla_printk(KERN_WARNING, ha, | 1918 | qla_printk(KERN_WARNING, ha, |
1915 | "Memory Allocation failed - " | 1919 | "Memory Allocation failed - " |
@@ -1972,6 +1976,26 @@ qla2x00_mem_alloc(scsi_qla_host_t *ha) | |||
1972 | continue; | 1976 | continue; |
1973 | } | 1977 | } |
1974 | memset(ha->ct_sns, 0, sizeof(struct ct_sns_pkt)); | 1978 | memset(ha->ct_sns, 0, sizeof(struct ct_sns_pkt)); |
1979 | |||
1980 | if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) { | ||
1981 | /* | ||
1982 | * Get consistent memory allocated for SFP | ||
1983 | * block. | ||
1984 | */ | ||
1985 | ha->sfp_data = dma_pool_alloc(ha->s_dma_pool, | ||
1986 | GFP_KERNEL, &ha->sfp_data_dma); | ||
1987 | if (ha->sfp_data == NULL) { | ||
1988 | qla_printk(KERN_WARNING, ha, | ||
1989 | "Memory Allocation failed - " | ||
1990 | "sfp_data\n"); | ||
1991 | |||
1992 | qla2x00_mem_free(ha); | ||
1993 | msleep(100); | ||
1994 | |||
1995 | continue; | ||
1996 | } | ||
1997 | memset(ha->sfp_data, 0, SFP_BLOCK_SIZE); | ||
1998 | } | ||
1975 | } | 1999 | } |
1976 | 2000 | ||
1977 | /* Done all allocations without any error. */ | 2001 | /* Done all allocations without any error. */ |
@@ -2006,12 +2030,16 @@ qla2x00_mem_free(scsi_qla_host_t *ha) | |||
2006 | return; | 2030 | return; |
2007 | } | 2031 | } |
2008 | 2032 | ||
2009 | /* free ioctl memory */ | ||
2010 | qla2x00_free_ioctl_mem(ha); | ||
2011 | |||
2012 | /* free sp pool */ | 2033 | /* free sp pool */ |
2013 | qla2x00_free_sp_pool(ha); | 2034 | qla2x00_free_sp_pool(ha); |
2014 | 2035 | ||
2036 | if (ha->fw_dump) { | ||
2037 | if (ha->eft) | ||
2038 | dma_free_coherent(&ha->pdev->dev, | ||
2039 | ntohl(ha->fw_dump->eft_size), ha->eft, ha->eft_dma); | ||
2040 | vfree(ha->fw_dump); | ||
2041 | } | ||
2042 | |||
2015 | if (ha->sns_cmd) | 2043 | if (ha->sns_cmd) |
2016 | dma_free_coherent(&ha->pdev->dev, sizeof(struct sns_cmd_pkt), | 2044 | dma_free_coherent(&ha->pdev->dev, sizeof(struct sns_cmd_pkt), |
2017 | ha->sns_cmd, ha->sns_cmd_dma); | 2045 | ha->sns_cmd, ha->sns_cmd_dma); |
@@ -2020,6 +2048,9 @@ qla2x00_mem_free(scsi_qla_host_t *ha) | |||
2020 | dma_free_coherent(&ha->pdev->dev, sizeof(struct ct_sns_pkt), | 2048 | dma_free_coherent(&ha->pdev->dev, sizeof(struct ct_sns_pkt), |
2021 | ha->ct_sns, ha->ct_sns_dma); | 2049 | ha->ct_sns, ha->ct_sns_dma); |
2022 | 2050 | ||
2051 | if (ha->sfp_data) | ||
2052 | dma_pool_free(ha->s_dma_pool, ha->sfp_data, ha->sfp_data_dma); | ||
2053 | |||
2023 | if (ha->ms_iocb) | 2054 | if (ha->ms_iocb) |
2024 | dma_pool_free(ha->s_dma_pool, ha->ms_iocb, ha->ms_iocb_dma); | 2055 | dma_pool_free(ha->s_dma_pool, ha->ms_iocb, ha->ms_iocb_dma); |
2025 | 2056 | ||
@@ -2043,6 +2074,8 @@ qla2x00_mem_free(scsi_qla_host_t *ha) | |||
2043 | (ha->request_q_length + 1) * sizeof(request_t), | 2074 | (ha->request_q_length + 1) * sizeof(request_t), |
2044 | ha->request_ring, ha->request_dma); | 2075 | ha->request_ring, ha->request_dma); |
2045 | 2076 | ||
2077 | ha->eft = NULL; | ||
2078 | ha->eft_dma = 0; | ||
2046 | ha->sns_cmd = NULL; | 2079 | ha->sns_cmd = NULL; |
2047 | ha->sns_cmd_dma = 0; | 2080 | ha->sns_cmd_dma = 0; |
2048 | ha->ct_sns = NULL; | 2081 | ha->ct_sns = NULL; |
@@ -2071,13 +2104,9 @@ qla2x00_mem_free(scsi_qla_host_t *ha) | |||
2071 | } | 2104 | } |
2072 | INIT_LIST_HEAD(&ha->fcports); | 2105 | INIT_LIST_HEAD(&ha->fcports); |
2073 | 2106 | ||
2074 | vfree(ha->fw_dump); | ||
2075 | vfree(ha->fw_dump_buffer); | ||
2076 | |||
2077 | ha->fw_dump = NULL; | 2107 | ha->fw_dump = NULL; |
2078 | ha->fw_dumped = 0; | 2108 | ha->fw_dumped = 0; |
2079 | ha->fw_dump_reading = 0; | 2109 | ha->fw_dump_reading = 0; |
2080 | ha->fw_dump_buffer = NULL; | ||
2081 | 2110 | ||
2082 | vfree(ha->optrom_buffer); | 2111 | vfree(ha->optrom_buffer); |
2083 | } | 2112 | } |
@@ -2617,40 +2646,16 @@ static struct pci_device_id qla2xxx_pci_tbl[] = { | |||
2617 | }; | 2646 | }; |
2618 | MODULE_DEVICE_TABLE(pci, qla2xxx_pci_tbl); | 2647 | MODULE_DEVICE_TABLE(pci, qla2xxx_pci_tbl); |
2619 | 2648 | ||
2620 | static int __devinit | ||
2621 | qla2xxx_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) | ||
2622 | { | ||
2623 | return qla2x00_probe_one(pdev); | ||
2624 | } | ||
2625 | |||
2626 | static void __devexit | ||
2627 | qla2xxx_remove_one(struct pci_dev *pdev) | ||
2628 | { | ||
2629 | qla2x00_remove_one(pdev); | ||
2630 | } | ||
2631 | |||
2632 | static struct pci_driver qla2xxx_pci_driver = { | 2649 | static struct pci_driver qla2xxx_pci_driver = { |
2633 | .name = QLA2XXX_DRIVER_NAME, | 2650 | .name = QLA2XXX_DRIVER_NAME, |
2634 | .driver = { | 2651 | .driver = { |
2635 | .owner = THIS_MODULE, | 2652 | .owner = THIS_MODULE, |
2636 | }, | 2653 | }, |
2637 | .id_table = qla2xxx_pci_tbl, | 2654 | .id_table = qla2xxx_pci_tbl, |
2638 | .probe = qla2xxx_probe_one, | 2655 | .probe = qla2x00_probe_one, |
2639 | .remove = __devexit_p(qla2xxx_remove_one), | 2656 | .remove = __devexit_p(qla2x00_remove_one), |
2640 | }; | 2657 | }; |
2641 | 2658 | ||
2642 | static inline int | ||
2643 | qla2x00_pci_module_init(void) | ||
2644 | { | ||
2645 | return pci_module_init(&qla2xxx_pci_driver); | ||
2646 | } | ||
2647 | |||
2648 | static inline void | ||
2649 | qla2x00_pci_module_exit(void) | ||
2650 | { | ||
2651 | pci_unregister_driver(&qla2xxx_pci_driver); | ||
2652 | } | ||
2653 | |||
2654 | /** | 2659 | /** |
2655 | * qla2x00_module_init - Module initialization. | 2660 | * qla2x00_module_init - Module initialization. |
2656 | **/ | 2661 | **/ |
@@ -2670,16 +2675,16 @@ qla2x00_module_init(void) | |||
2670 | 2675 | ||
2671 | /* Derive version string. */ | 2676 | /* Derive version string. */ |
2672 | strcpy(qla2x00_version_str, QLA2XXX_VERSION); | 2677 | strcpy(qla2x00_version_str, QLA2XXX_VERSION); |
2673 | #if DEBUG_QLA2100 | 2678 | if (extended_error_logging) |
2674 | strcat(qla2x00_version_str, "-debug"); | 2679 | strcat(qla2x00_version_str, "-debug"); |
2675 | #endif | 2680 | |
2676 | qla2xxx_transport_template = | 2681 | qla2xxx_transport_template = |
2677 | fc_attach_transport(&qla2xxx_transport_functions); | 2682 | fc_attach_transport(&qla2xxx_transport_functions); |
2678 | if (!qla2xxx_transport_template) | 2683 | if (!qla2xxx_transport_template) |
2679 | return -ENODEV; | 2684 | return -ENODEV; |
2680 | 2685 | ||
2681 | printk(KERN_INFO "QLogic Fibre Channel HBA Driver\n"); | 2686 | printk(KERN_INFO "QLogic Fibre Channel HBA Driver\n"); |
2682 | ret = qla2x00_pci_module_init(); | 2687 | ret = pci_register_driver(&qla2xxx_pci_driver); |
2683 | if (ret) { | 2688 | if (ret) { |
2684 | kmem_cache_destroy(srb_cachep); | 2689 | kmem_cache_destroy(srb_cachep); |
2685 | fc_release_transport(qla2xxx_transport_template); | 2690 | fc_release_transport(qla2xxx_transport_template); |
@@ -2693,7 +2698,7 @@ qla2x00_module_init(void) | |||
2693 | static void __exit | 2698 | static void __exit |
2694 | qla2x00_module_exit(void) | 2699 | qla2x00_module_exit(void) |
2695 | { | 2700 | { |
2696 | qla2x00_pci_module_exit(); | 2701 | pci_unregister_driver(&qla2xxx_pci_driver); |
2697 | qla2x00_release_firmware(); | 2702 | qla2x00_release_firmware(); |
2698 | kmem_cache_destroy(srb_cachep); | 2703 | kmem_cache_destroy(srb_cachep); |
2699 | fc_release_transport(qla2xxx_transport_template); | 2704 | fc_release_transport(qla2xxx_transport_template); |
diff --git a/drivers/scsi/qla2xxx/qla_version.h b/drivers/scsi/qla2xxx/qla_version.h index 6b315521bd89..d2d683440659 100644 --- a/drivers/scsi/qla2xxx/qla_version.h +++ b/drivers/scsi/qla2xxx/qla_version.h | |||
@@ -7,7 +7,7 @@ | |||
7 | /* | 7 | /* |
8 | * Driver version | 8 | * Driver version |
9 | */ | 9 | */ |
10 | #define QLA2XXX_VERSION "8.01.05-k2" | 10 | #define QLA2XXX_VERSION "8.01.05-k3" |
11 | 11 | ||
12 | #define QLA_DRIVER_MAJOR_VER 8 | 12 | #define QLA_DRIVER_MAJOR_VER 8 |
13 | #define QLA_DRIVER_MINOR_VER 1 | 13 | #define QLA_DRIVER_MINOR_VER 1 |
diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c index e1168860045c..9c63b00773c4 100644 --- a/drivers/scsi/scsi_debug.c +++ b/drivers/scsi/scsi_debug.c | |||
@@ -50,18 +50,22 @@ | |||
50 | #include "scsi_logging.h" | 50 | #include "scsi_logging.h" |
51 | #include "scsi_debug.h" | 51 | #include "scsi_debug.h" |
52 | 52 | ||
53 | #define SCSI_DEBUG_VERSION "1.75" | 53 | #define SCSI_DEBUG_VERSION "1.79" |
54 | static const char * scsi_debug_version_date = "20050113"; | 54 | static const char * scsi_debug_version_date = "20060604"; |
55 | 55 | ||
56 | /* Additional Sense Code (ASC) used */ | 56 | /* Additional Sense Code (ASC) used */ |
57 | #define NO_ADDED_SENSE 0x0 | 57 | #define NO_ADDITIONAL_SENSE 0x0 |
58 | #define LOGICAL_UNIT_NOT_READY 0x4 | ||
58 | #define UNRECOVERED_READ_ERR 0x11 | 59 | #define UNRECOVERED_READ_ERR 0x11 |
60 | #define PARAMETER_LIST_LENGTH_ERR 0x1a | ||
59 | #define INVALID_OPCODE 0x20 | 61 | #define INVALID_OPCODE 0x20 |
60 | #define ADDR_OUT_OF_RANGE 0x21 | 62 | #define ADDR_OUT_OF_RANGE 0x21 |
61 | #define INVALID_FIELD_IN_CDB 0x24 | 63 | #define INVALID_FIELD_IN_CDB 0x24 |
64 | #define INVALID_FIELD_IN_PARAM_LIST 0x26 | ||
62 | #define POWERON_RESET 0x29 | 65 | #define POWERON_RESET 0x29 |
63 | #define SAVING_PARAMS_UNSUP 0x39 | 66 | #define SAVING_PARAMS_UNSUP 0x39 |
64 | #define THRESHHOLD_EXCEEDED 0x5d | 67 | #define THRESHOLD_EXCEEDED 0x5d |
68 | #define LOW_POWER_COND_ON 0x5e | ||
65 | 69 | ||
66 | #define SDEBUG_TAGGED_QUEUING 0 /* 0 | MSG_SIMPLE_TAG | MSG_ORDERED_TAG */ | 70 | #define SDEBUG_TAGGED_QUEUING 0 /* 0 | MSG_SIMPLE_TAG | MSG_ORDERED_TAG */ |
67 | 71 | ||
@@ -80,6 +84,8 @@ static const char * scsi_debug_version_date = "20050113"; | |||
80 | #define DEF_SCSI_LEVEL 5 /* INQUIRY, byte2 [5->SPC-3] */ | 84 | #define DEF_SCSI_LEVEL 5 /* INQUIRY, byte2 [5->SPC-3] */ |
81 | #define DEF_PTYPE 0 | 85 | #define DEF_PTYPE 0 |
82 | #define DEF_D_SENSE 0 | 86 | #define DEF_D_SENSE 0 |
87 | #define DEF_NO_LUN_0 0 | ||
88 | #define DEF_VIRTUAL_GB 0 | ||
83 | 89 | ||
84 | /* bit mask values for scsi_debug_opts */ | 90 | /* bit mask values for scsi_debug_opts */ |
85 | #define SCSI_DEBUG_OPT_NOISE 1 | 91 | #define SCSI_DEBUG_OPT_NOISE 1 |
@@ -106,6 +112,7 @@ static const char * scsi_debug_version_date = "20050113"; | |||
106 | /* If REPORT LUNS has luns >= 256 it can choose "flat space" (value 1) | 112 | /* If REPORT LUNS has luns >= 256 it can choose "flat space" (value 1) |
107 | * or "peripheral device" addressing (value 0) */ | 113 | * or "peripheral device" addressing (value 0) */ |
108 | #define SAM2_LUN_ADDRESS_METHOD 0 | 114 | #define SAM2_LUN_ADDRESS_METHOD 0 |
115 | #define SAM2_WLUN_REPORT_LUNS 0xc101 | ||
109 | 116 | ||
110 | static int scsi_debug_add_host = DEF_NUM_HOST; | 117 | static int scsi_debug_add_host = DEF_NUM_HOST; |
111 | static int scsi_debug_delay = DEF_DELAY; | 118 | static int scsi_debug_delay = DEF_DELAY; |
@@ -118,13 +125,16 @@ static int scsi_debug_opts = DEF_OPTS; | |||
118 | static int scsi_debug_scsi_level = DEF_SCSI_LEVEL; | 125 | static int scsi_debug_scsi_level = DEF_SCSI_LEVEL; |
119 | static int scsi_debug_ptype = DEF_PTYPE; /* SCSI peripheral type (0==disk) */ | 126 | static int scsi_debug_ptype = DEF_PTYPE; /* SCSI peripheral type (0==disk) */ |
120 | static int scsi_debug_dsense = DEF_D_SENSE; | 127 | static int scsi_debug_dsense = DEF_D_SENSE; |
128 | static int scsi_debug_no_lun_0 = DEF_NO_LUN_0; | ||
129 | static int scsi_debug_virtual_gb = DEF_VIRTUAL_GB; | ||
121 | 130 | ||
122 | static int scsi_debug_cmnd_count = 0; | 131 | static int scsi_debug_cmnd_count = 0; |
123 | 132 | ||
124 | #define DEV_READONLY(TGT) (0) | 133 | #define DEV_READONLY(TGT) (0) |
125 | #define DEV_REMOVEABLE(TGT) (0) | 134 | #define DEV_REMOVEABLE(TGT) (0) |
126 | 135 | ||
127 | static unsigned long sdebug_store_size; /* in bytes */ | 136 | static unsigned int sdebug_store_size; /* in bytes */ |
137 | static unsigned int sdebug_store_sectors; | ||
128 | static sector_t sdebug_capacity; /* in sectors */ | 138 | static sector_t sdebug_capacity; /* in sectors */ |
129 | 139 | ||
130 | /* old BIOS stuff, kernel may get rid of them but some mode sense pages | 140 | /* old BIOS stuff, kernel may get rid of them but some mode sense pages |
@@ -149,7 +159,9 @@ struct sdebug_dev_info { | |||
149 | unsigned int target; | 159 | unsigned int target; |
150 | unsigned int lun; | 160 | unsigned int lun; |
151 | struct sdebug_host_info *sdbg_host; | 161 | struct sdebug_host_info *sdbg_host; |
162 | unsigned int wlun; | ||
152 | char reset; | 163 | char reset; |
164 | char stopped; | ||
153 | char used; | 165 | char used; |
154 | }; | 166 | }; |
155 | 167 | ||
@@ -193,11 +205,11 @@ static struct scsi_host_template sdebug_driver_template = { | |||
193 | .bios_param = scsi_debug_biosparam, | 205 | .bios_param = scsi_debug_biosparam, |
194 | .can_queue = SCSI_DEBUG_CANQUEUE, | 206 | .can_queue = SCSI_DEBUG_CANQUEUE, |
195 | .this_id = 7, | 207 | .this_id = 7, |
196 | .sg_tablesize = 64, | 208 | .sg_tablesize = 256, |
197 | .cmd_per_lun = 3, | 209 | .cmd_per_lun = 16, |
198 | .max_sectors = 4096, | 210 | .max_sectors = 0xffff, |
199 | .unchecked_isa_dma = 0, | 211 | .unchecked_isa_dma = 0, |
200 | .use_clustering = DISABLE_CLUSTERING, | 212 | .use_clustering = ENABLE_CLUSTERING, |
201 | .module = THIS_MODULE, | 213 | .module = THIS_MODULE, |
202 | }; | 214 | }; |
203 | 215 | ||
@@ -225,19 +237,32 @@ static struct device_driver sdebug_driverfs_driver = { | |||
225 | static const int check_condition_result = | 237 | static const int check_condition_result = |
226 | (DRIVER_SENSE << 24) | SAM_STAT_CHECK_CONDITION; | 238 | (DRIVER_SENSE << 24) | SAM_STAT_CHECK_CONDITION; |
227 | 239 | ||
240 | static unsigned char ctrl_m_pg[] = {0xa, 10, 2, 0, 0, 0, 0, 0, | ||
241 | 0, 0, 0x2, 0x4b}; | ||
242 | static unsigned char iec_m_pg[] = {0x1c, 0xa, 0x08, 0, 0, 0, 0, 0, | ||
243 | 0, 0, 0x0, 0x0}; | ||
244 | |||
228 | /* function declarations */ | 245 | /* function declarations */ |
229 | static int resp_inquiry(struct scsi_cmnd * SCpnt, int target, | 246 | static int resp_inquiry(struct scsi_cmnd * SCpnt, int target, |
230 | struct sdebug_dev_info * devip); | 247 | struct sdebug_dev_info * devip); |
231 | static int resp_requests(struct scsi_cmnd * SCpnt, | 248 | static int resp_requests(struct scsi_cmnd * SCpnt, |
232 | struct sdebug_dev_info * devip); | 249 | struct sdebug_dev_info * devip); |
250 | static int resp_start_stop(struct scsi_cmnd * scp, | ||
251 | struct sdebug_dev_info * devip); | ||
233 | static int resp_readcap(struct scsi_cmnd * SCpnt, | 252 | static int resp_readcap(struct scsi_cmnd * SCpnt, |
234 | struct sdebug_dev_info * devip); | 253 | struct sdebug_dev_info * devip); |
235 | static int resp_mode_sense(struct scsi_cmnd * SCpnt, int target, | 254 | static int resp_readcap16(struct scsi_cmnd * SCpnt, |
255 | struct sdebug_dev_info * devip); | ||
256 | static int resp_mode_sense(struct scsi_cmnd * scp, int target, | ||
236 | struct sdebug_dev_info * devip); | 257 | struct sdebug_dev_info * devip); |
237 | static int resp_read(struct scsi_cmnd * SCpnt, int upper_blk, int block, | 258 | static int resp_mode_select(struct scsi_cmnd * scp, int mselect6, |
238 | int num, struct sdebug_dev_info * devip); | 259 | struct sdebug_dev_info * devip); |
239 | static int resp_write(struct scsi_cmnd * SCpnt, int upper_blk, int block, | 260 | static int resp_log_sense(struct scsi_cmnd * scp, |
240 | int num, struct sdebug_dev_info * devip); | 261 | struct sdebug_dev_info * devip); |
262 | static int resp_read(struct scsi_cmnd * SCpnt, unsigned long long lba, | ||
263 | unsigned int num, struct sdebug_dev_info * devip); | ||
264 | static int resp_write(struct scsi_cmnd * SCpnt, unsigned long long lba, | ||
265 | unsigned int num, struct sdebug_dev_info * devip); | ||
241 | static int resp_report_luns(struct scsi_cmnd * SCpnt, | 266 | static int resp_report_luns(struct scsi_cmnd * SCpnt, |
242 | struct sdebug_dev_info * devip); | 267 | struct sdebug_dev_info * devip); |
243 | static int fill_from_dev_buffer(struct scsi_cmnd * scp, unsigned char * arr, | 268 | static int fill_from_dev_buffer(struct scsi_cmnd * scp, unsigned char * arr, |
@@ -248,8 +273,8 @@ static void timer_intr_handler(unsigned long); | |||
248 | static struct sdebug_dev_info * devInfoReg(struct scsi_device * sdev); | 273 | static struct sdebug_dev_info * devInfoReg(struct scsi_device * sdev); |
249 | static void mk_sense_buffer(struct sdebug_dev_info * devip, int key, | 274 | static void mk_sense_buffer(struct sdebug_dev_info * devip, int key, |
250 | int asc, int asq); | 275 | int asc, int asq); |
251 | static int check_reset(struct scsi_cmnd * SCpnt, | 276 | static int check_readiness(struct scsi_cmnd * SCpnt, int reset_only, |
252 | struct sdebug_dev_info * devip); | 277 | struct sdebug_dev_info * devip); |
253 | static int schedule_resp(struct scsi_cmnd * cmnd, | 278 | static int schedule_resp(struct scsi_cmnd * cmnd, |
254 | struct sdebug_dev_info * devip, | 279 | struct sdebug_dev_info * devip, |
255 | done_funct_t done, int scsi_result, int delta_jiff); | 280 | done_funct_t done, int scsi_result, int delta_jiff); |
@@ -257,8 +282,10 @@ static void __init sdebug_build_parts(unsigned char * ramp); | |||
257 | static void __init init_all_queued(void); | 282 | static void __init init_all_queued(void); |
258 | static void stop_all_queued(void); | 283 | static void stop_all_queued(void); |
259 | static int stop_queued_cmnd(struct scsi_cmnd * cmnd); | 284 | static int stop_queued_cmnd(struct scsi_cmnd * cmnd); |
260 | static int inquiry_evpd_83(unsigned char * arr, int dev_id_num, | 285 | static int inquiry_evpd_83(unsigned char * arr, int target_dev_id, |
261 | const char * dev_id_str, int dev_id_str_len); | 286 | int dev_id_num, const char * dev_id_str, |
287 | int dev_id_str_len); | ||
288 | static int inquiry_evpd_88(unsigned char * arr, int target_dev_id); | ||
262 | static void do_create_driverfs_files(void); | 289 | static void do_create_driverfs_files(void); |
263 | static void do_remove_driverfs_files(void); | 290 | static void do_remove_driverfs_files(void); |
264 | 291 | ||
@@ -274,18 +301,22 @@ static | |||
274 | int scsi_debug_queuecommand(struct scsi_cmnd * SCpnt, done_funct_t done) | 301 | int scsi_debug_queuecommand(struct scsi_cmnd * SCpnt, done_funct_t done) |
275 | { | 302 | { |
276 | unsigned char *cmd = (unsigned char *) SCpnt->cmnd; | 303 | unsigned char *cmd = (unsigned char *) SCpnt->cmnd; |
277 | int block, upper_blk, num, k; | 304 | int len, k, j; |
305 | unsigned int num; | ||
306 | unsigned long long lba; | ||
278 | int errsts = 0; | 307 | int errsts = 0; |
279 | int target = scmd_id(SCpnt); | 308 | int target = SCpnt->device->id; |
280 | struct sdebug_dev_info * devip = NULL; | 309 | struct sdebug_dev_info * devip = NULL; |
281 | int inj_recovered = 0; | 310 | int inj_recovered = 0; |
311 | int delay_override = 0; | ||
282 | 312 | ||
283 | if (done == NULL) | 313 | if (done == NULL) |
284 | return 0; /* assume mid level reprocessing command */ | 314 | return 0; /* assume mid level reprocessing command */ |
285 | 315 | ||
316 | SCpnt->resid = 0; | ||
286 | if ((SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) && cmd) { | 317 | if ((SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) && cmd) { |
287 | printk(KERN_INFO "scsi_debug: cmd "); | 318 | printk(KERN_INFO "scsi_debug: cmd "); |
288 | for (k = 0, num = SCpnt->cmd_len; k < num; ++k) | 319 | for (k = 0, len = SCpnt->cmd_len; k < len; ++k) |
289 | printk("%02x ", (int)cmd[k]); | 320 | printk("%02x ", (int)cmd[k]); |
290 | printk("\n"); | 321 | printk("\n"); |
291 | } | 322 | } |
@@ -296,7 +327,8 @@ int scsi_debug_queuecommand(struct scsi_cmnd * SCpnt, done_funct_t done) | |||
296 | DID_NO_CONNECT << 16, 0); | 327 | DID_NO_CONNECT << 16, 0); |
297 | } | 328 | } |
298 | 329 | ||
299 | if (SCpnt->device->lun >= scsi_debug_max_luns) | 330 | if ((SCpnt->device->lun >= scsi_debug_max_luns) && |
331 | (SCpnt->device->lun != SAM2_WLUN_REPORT_LUNS)) | ||
300 | return schedule_resp(SCpnt, NULL, done, | 332 | return schedule_resp(SCpnt, NULL, done, |
301 | DID_NO_CONNECT << 16, 0); | 333 | DID_NO_CONNECT << 16, 0); |
302 | devip = devInfoReg(SCpnt->device); | 334 | devip = devInfoReg(SCpnt->device); |
@@ -315,118 +347,150 @@ int scsi_debug_queuecommand(struct scsi_cmnd * SCpnt, done_funct_t done) | |||
315 | inj_recovered = 1; /* to reads and writes below */ | 347 | inj_recovered = 1; /* to reads and writes below */ |
316 | } | 348 | } |
317 | 349 | ||
350 | if (devip->wlun) { | ||
351 | switch (*cmd) { | ||
352 | case INQUIRY: | ||
353 | case REQUEST_SENSE: | ||
354 | case TEST_UNIT_READY: | ||
355 | case REPORT_LUNS: | ||
356 | break; /* only allowable wlun commands */ | ||
357 | default: | ||
358 | if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) | ||
359 | printk(KERN_INFO "scsi_debug: Opcode: 0x%x " | ||
360 | "not supported for wlun\n", *cmd); | ||
361 | mk_sense_buffer(devip, ILLEGAL_REQUEST, | ||
362 | INVALID_OPCODE, 0); | ||
363 | errsts = check_condition_result; | ||
364 | return schedule_resp(SCpnt, devip, done, errsts, | ||
365 | 0); | ||
366 | } | ||
367 | } | ||
368 | |||
318 | switch (*cmd) { | 369 | switch (*cmd) { |
319 | case INQUIRY: /* mandatory, ignore unit attention */ | 370 | case INQUIRY: /* mandatory, ignore unit attention */ |
371 | delay_override = 1; | ||
320 | errsts = resp_inquiry(SCpnt, target, devip); | 372 | errsts = resp_inquiry(SCpnt, target, devip); |
321 | break; | 373 | break; |
322 | case REQUEST_SENSE: /* mandatory, ignore unit attention */ | 374 | case REQUEST_SENSE: /* mandatory, ignore unit attention */ |
375 | delay_override = 1; | ||
323 | errsts = resp_requests(SCpnt, devip); | 376 | errsts = resp_requests(SCpnt, devip); |
324 | break; | 377 | break; |
325 | case REZERO_UNIT: /* actually this is REWIND for SSC */ | 378 | case REZERO_UNIT: /* actually this is REWIND for SSC */ |
326 | case START_STOP: | 379 | case START_STOP: |
327 | errsts = check_reset(SCpnt, devip); | 380 | errsts = resp_start_stop(SCpnt, devip); |
328 | break; | 381 | break; |
329 | case ALLOW_MEDIUM_REMOVAL: | 382 | case ALLOW_MEDIUM_REMOVAL: |
330 | if ((errsts = check_reset(SCpnt, devip))) | 383 | if ((errsts = check_readiness(SCpnt, 1, devip))) |
331 | break; | 384 | break; |
332 | if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) | 385 | if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) |
333 | printk(KERN_INFO "scsi_debug: Medium removal %s\n", | 386 | printk(KERN_INFO "scsi_debug: Medium removal %s\n", |
334 | cmd[4] ? "inhibited" : "enabled"); | 387 | cmd[4] ? "inhibited" : "enabled"); |
335 | break; | 388 | break; |
336 | case SEND_DIAGNOSTIC: /* mandatory */ | 389 | case SEND_DIAGNOSTIC: /* mandatory */ |
337 | errsts = check_reset(SCpnt, devip); | 390 | errsts = check_readiness(SCpnt, 1, devip); |
338 | break; | 391 | break; |
339 | case TEST_UNIT_READY: /* mandatory */ | 392 | case TEST_UNIT_READY: /* mandatory */ |
340 | errsts = check_reset(SCpnt, devip); | 393 | delay_override = 1; |
394 | errsts = check_readiness(SCpnt, 0, devip); | ||
341 | break; | 395 | break; |
342 | case RESERVE: | 396 | case RESERVE: |
343 | errsts = check_reset(SCpnt, devip); | 397 | errsts = check_readiness(SCpnt, 1, devip); |
344 | break; | 398 | break; |
345 | case RESERVE_10: | 399 | case RESERVE_10: |
346 | errsts = check_reset(SCpnt, devip); | 400 | errsts = check_readiness(SCpnt, 1, devip); |
347 | break; | 401 | break; |
348 | case RELEASE: | 402 | case RELEASE: |
349 | errsts = check_reset(SCpnt, devip); | 403 | errsts = check_readiness(SCpnt, 1, devip); |
350 | break; | 404 | break; |
351 | case RELEASE_10: | 405 | case RELEASE_10: |
352 | errsts = check_reset(SCpnt, devip); | 406 | errsts = check_readiness(SCpnt, 1, devip); |
353 | break; | 407 | break; |
354 | case READ_CAPACITY: | 408 | case READ_CAPACITY: |
355 | errsts = resp_readcap(SCpnt, devip); | 409 | errsts = resp_readcap(SCpnt, devip); |
356 | break; | 410 | break; |
411 | case SERVICE_ACTION_IN: | ||
412 | if (SAI_READ_CAPACITY_16 != cmd[1]) { | ||
413 | mk_sense_buffer(devip, ILLEGAL_REQUEST, | ||
414 | INVALID_OPCODE, 0); | ||
415 | errsts = check_condition_result; | ||
416 | break; | ||
417 | } | ||
418 | errsts = resp_readcap16(SCpnt, devip); | ||
419 | break; | ||
357 | case READ_16: | 420 | case READ_16: |
358 | case READ_12: | 421 | case READ_12: |
359 | case READ_10: | 422 | case READ_10: |
360 | case READ_6: | 423 | case READ_6: |
361 | if ((errsts = check_reset(SCpnt, devip))) | 424 | if ((errsts = check_readiness(SCpnt, 0, devip))) |
362 | break; | 425 | break; |
363 | upper_blk = 0; | ||
364 | if ((*cmd) == READ_16) { | 426 | if ((*cmd) == READ_16) { |
365 | upper_blk = cmd[5] + (cmd[4] << 8) + | 427 | for (lba = 0, j = 0; j < 8; ++j) { |
366 | (cmd[3] << 16) + (cmd[2] << 24); | 428 | if (j > 0) |
367 | block = cmd[9] + (cmd[8] << 8) + | 429 | lba <<= 8; |
368 | (cmd[7] << 16) + (cmd[6] << 24); | 430 | lba += cmd[2 + j]; |
431 | } | ||
369 | num = cmd[13] + (cmd[12] << 8) + | 432 | num = cmd[13] + (cmd[12] << 8) + |
370 | (cmd[11] << 16) + (cmd[10] << 24); | 433 | (cmd[11] << 16) + (cmd[10] << 24); |
371 | } else if ((*cmd) == READ_12) { | 434 | } else if ((*cmd) == READ_12) { |
372 | block = cmd[5] + (cmd[4] << 8) + | 435 | lba = cmd[5] + (cmd[4] << 8) + |
373 | (cmd[3] << 16) + (cmd[2] << 24); | 436 | (cmd[3] << 16) + (cmd[2] << 24); |
374 | num = cmd[9] + (cmd[8] << 8) + | 437 | num = cmd[9] + (cmd[8] << 8) + |
375 | (cmd[7] << 16) + (cmd[6] << 24); | 438 | (cmd[7] << 16) + (cmd[6] << 24); |
376 | } else if ((*cmd) == READ_10) { | 439 | } else if ((*cmd) == READ_10) { |
377 | block = cmd[5] + (cmd[4] << 8) + | 440 | lba = cmd[5] + (cmd[4] << 8) + |
378 | (cmd[3] << 16) + (cmd[2] << 24); | 441 | (cmd[3] << 16) + (cmd[2] << 24); |
379 | num = cmd[8] + (cmd[7] << 8); | 442 | num = cmd[8] + (cmd[7] << 8); |
380 | } else { | 443 | } else { /* READ (6) */ |
381 | block = cmd[3] + (cmd[2] << 8) + | 444 | lba = cmd[3] + (cmd[2] << 8) + |
382 | ((cmd[1] & 0x1f) << 16); | 445 | ((cmd[1] & 0x1f) << 16); |
383 | num = cmd[4]; | 446 | num = (0 == cmd[4]) ? 256 : cmd[4]; |
384 | } | 447 | } |
385 | errsts = resp_read(SCpnt, upper_blk, block, num, devip); | 448 | errsts = resp_read(SCpnt, lba, num, devip); |
386 | if (inj_recovered && (0 == errsts)) { | 449 | if (inj_recovered && (0 == errsts)) { |
387 | mk_sense_buffer(devip, RECOVERED_ERROR, | 450 | mk_sense_buffer(devip, RECOVERED_ERROR, |
388 | THRESHHOLD_EXCEEDED, 0); | 451 | THRESHOLD_EXCEEDED, 0); |
389 | errsts = check_condition_result; | 452 | errsts = check_condition_result; |
390 | } | 453 | } |
391 | break; | 454 | break; |
392 | case REPORT_LUNS: /* mandatory, ignore unit attention */ | 455 | case REPORT_LUNS: /* mandatory, ignore unit attention */ |
456 | delay_override = 1; | ||
393 | errsts = resp_report_luns(SCpnt, devip); | 457 | errsts = resp_report_luns(SCpnt, devip); |
394 | break; | 458 | break; |
395 | case VERIFY: /* 10 byte SBC-2 command */ | 459 | case VERIFY: /* 10 byte SBC-2 command */ |
396 | errsts = check_reset(SCpnt, devip); | 460 | errsts = check_readiness(SCpnt, 0, devip); |
397 | break; | 461 | break; |
398 | case WRITE_16: | 462 | case WRITE_16: |
399 | case WRITE_12: | 463 | case WRITE_12: |
400 | case WRITE_10: | 464 | case WRITE_10: |
401 | case WRITE_6: | 465 | case WRITE_6: |
402 | if ((errsts = check_reset(SCpnt, devip))) | 466 | if ((errsts = check_readiness(SCpnt, 0, devip))) |
403 | break; | 467 | break; |
404 | upper_blk = 0; | ||
405 | if ((*cmd) == WRITE_16) { | 468 | if ((*cmd) == WRITE_16) { |
406 | upper_blk = cmd[5] + (cmd[4] << 8) + | 469 | for (lba = 0, j = 0; j < 8; ++j) { |
407 | (cmd[3] << 16) + (cmd[2] << 24); | 470 | if (j > 0) |
408 | block = cmd[9] + (cmd[8] << 8) + | 471 | lba <<= 8; |
409 | (cmd[7] << 16) + (cmd[6] << 24); | 472 | lba += cmd[2 + j]; |
473 | } | ||
410 | num = cmd[13] + (cmd[12] << 8) + | 474 | num = cmd[13] + (cmd[12] << 8) + |
411 | (cmd[11] << 16) + (cmd[10] << 24); | 475 | (cmd[11] << 16) + (cmd[10] << 24); |
412 | } else if ((*cmd) == WRITE_12) { | 476 | } else if ((*cmd) == WRITE_12) { |
413 | block = cmd[5] + (cmd[4] << 8) + | 477 | lba = cmd[5] + (cmd[4] << 8) + |
414 | (cmd[3] << 16) + (cmd[2] << 24); | 478 | (cmd[3] << 16) + (cmd[2] << 24); |
415 | num = cmd[9] + (cmd[8] << 8) + | 479 | num = cmd[9] + (cmd[8] << 8) + |
416 | (cmd[7] << 16) + (cmd[6] << 24); | 480 | (cmd[7] << 16) + (cmd[6] << 24); |
417 | } else if ((*cmd) == WRITE_10) { | 481 | } else if ((*cmd) == WRITE_10) { |
418 | block = cmd[5] + (cmd[4] << 8) + | 482 | lba = cmd[5] + (cmd[4] << 8) + |
419 | (cmd[3] << 16) + (cmd[2] << 24); | 483 | (cmd[3] << 16) + (cmd[2] << 24); |
420 | num = cmd[8] + (cmd[7] << 8); | 484 | num = cmd[8] + (cmd[7] << 8); |
421 | } else { | 485 | } else { /* WRITE (6) */ |
422 | block = cmd[3] + (cmd[2] << 8) + | 486 | lba = cmd[3] + (cmd[2] << 8) + |
423 | ((cmd[1] & 0x1f) << 16); | 487 | ((cmd[1] & 0x1f) << 16); |
424 | num = cmd[4]; | 488 | num = (0 == cmd[4]) ? 256 : cmd[4]; |
425 | } | 489 | } |
426 | errsts = resp_write(SCpnt, upper_blk, block, num, devip); | 490 | errsts = resp_write(SCpnt, lba, num, devip); |
427 | if (inj_recovered && (0 == errsts)) { | 491 | if (inj_recovered && (0 == errsts)) { |
428 | mk_sense_buffer(devip, RECOVERED_ERROR, | 492 | mk_sense_buffer(devip, RECOVERED_ERROR, |
429 | THRESHHOLD_EXCEEDED, 0); | 493 | THRESHOLD_EXCEEDED, 0); |
430 | errsts = check_condition_result; | 494 | errsts = check_condition_result; |
431 | } | 495 | } |
432 | break; | 496 | break; |
@@ -434,20 +498,31 @@ int scsi_debug_queuecommand(struct scsi_cmnd * SCpnt, done_funct_t done) | |||
434 | case MODE_SENSE_10: | 498 | case MODE_SENSE_10: |
435 | errsts = resp_mode_sense(SCpnt, target, devip); | 499 | errsts = resp_mode_sense(SCpnt, target, devip); |
436 | break; | 500 | break; |
501 | case MODE_SELECT: | ||
502 | errsts = resp_mode_select(SCpnt, 1, devip); | ||
503 | break; | ||
504 | case MODE_SELECT_10: | ||
505 | errsts = resp_mode_select(SCpnt, 0, devip); | ||
506 | break; | ||
507 | case LOG_SENSE: | ||
508 | errsts = resp_log_sense(SCpnt, devip); | ||
509 | break; | ||
437 | case SYNCHRONIZE_CACHE: | 510 | case SYNCHRONIZE_CACHE: |
438 | errsts = check_reset(SCpnt, devip); | 511 | delay_override = 1; |
512 | errsts = check_readiness(SCpnt, 0, devip); | ||
439 | break; | 513 | break; |
440 | default: | 514 | default: |
441 | if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) | 515 | if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) |
442 | printk(KERN_INFO "scsi_debug: Opcode: 0x%x not " | 516 | printk(KERN_INFO "scsi_debug: Opcode: 0x%x not " |
443 | "supported\n", *cmd); | 517 | "supported\n", *cmd); |
444 | if ((errsts = check_reset(SCpnt, devip))) | 518 | if ((errsts = check_readiness(SCpnt, 1, devip))) |
445 | break; /* Unit attention takes precedence */ | 519 | break; /* Unit attention takes precedence */ |
446 | mk_sense_buffer(devip, ILLEGAL_REQUEST, INVALID_OPCODE, 0); | 520 | mk_sense_buffer(devip, ILLEGAL_REQUEST, INVALID_OPCODE, 0); |
447 | errsts = check_condition_result; | 521 | errsts = check_condition_result; |
448 | break; | 522 | break; |
449 | } | 523 | } |
450 | return schedule_resp(SCpnt, devip, done, errsts, scsi_debug_delay); | 524 | return schedule_resp(SCpnt, devip, done, errsts, |
525 | (delay_override ? 0 : scsi_debug_delay)); | ||
451 | } | 526 | } |
452 | 527 | ||
453 | static int scsi_debug_ioctl(struct scsi_device *dev, int cmd, void __user *arg) | 528 | static int scsi_debug_ioctl(struct scsi_device *dev, int cmd, void __user *arg) |
@@ -459,7 +534,8 @@ static int scsi_debug_ioctl(struct scsi_device *dev, int cmd, void __user *arg) | |||
459 | /* return -ENOTTY; // correct return but upsets fdisk */ | 534 | /* return -ENOTTY; // correct return but upsets fdisk */ |
460 | } | 535 | } |
461 | 536 | ||
462 | static int check_reset(struct scsi_cmnd * SCpnt, struct sdebug_dev_info * devip) | 537 | static int check_readiness(struct scsi_cmnd * SCpnt, int reset_only, |
538 | struct sdebug_dev_info * devip) | ||
463 | { | 539 | { |
464 | if (devip->reset) { | 540 | if (devip->reset) { |
465 | if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) | 541 | if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) |
@@ -469,6 +545,14 @@ static int check_reset(struct scsi_cmnd * SCpnt, struct sdebug_dev_info * devip) | |||
469 | mk_sense_buffer(devip, UNIT_ATTENTION, POWERON_RESET, 0); | 545 | mk_sense_buffer(devip, UNIT_ATTENTION, POWERON_RESET, 0); |
470 | return check_condition_result; | 546 | return check_condition_result; |
471 | } | 547 | } |
548 | if ((0 == reset_only) && devip->stopped) { | ||
549 | if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) | ||
550 | printk(KERN_INFO "scsi_debug: Reporting Not " | ||
551 | "ready: initializing command required\n"); | ||
552 | mk_sense_buffer(devip, NOT_READY, LOGICAL_UNIT_NOT_READY, | ||
553 | 0x2); | ||
554 | return check_condition_result; | ||
555 | } | ||
472 | return 0; | 556 | return 0; |
473 | } | 557 | } |
474 | 558 | ||
@@ -492,7 +576,10 @@ static int fill_from_dev_buffer(struct scsi_cmnd * scp, unsigned char * arr, | |||
492 | req_len = scp->request_bufflen; | 576 | req_len = scp->request_bufflen; |
493 | act_len = (req_len < arr_len) ? req_len : arr_len; | 577 | act_len = (req_len < arr_len) ? req_len : arr_len; |
494 | memcpy(scp->request_buffer, arr, act_len); | 578 | memcpy(scp->request_buffer, arr, act_len); |
495 | scp->resid = req_len - act_len; | 579 | if (scp->resid) |
580 | scp->resid -= act_len; | ||
581 | else | ||
582 | scp->resid = req_len - act_len; | ||
496 | return 0; | 583 | return 0; |
497 | } | 584 | } |
498 | sgpnt = (struct scatterlist *)scp->request_buffer; | 585 | sgpnt = (struct scatterlist *)scp->request_buffer; |
@@ -515,7 +602,10 @@ static int fill_from_dev_buffer(struct scsi_cmnd * scp, unsigned char * arr, | |||
515 | } | 602 | } |
516 | req_len += sgpnt->length; | 603 | req_len += sgpnt->length; |
517 | } | 604 | } |
518 | scp->resid = req_len - act_len; | 605 | if (scp->resid) |
606 | scp->resid -= act_len; | ||
607 | else | ||
608 | scp->resid = req_len - act_len; | ||
519 | return 0; | 609 | return 0; |
520 | } | 610 | } |
521 | 611 | ||
@@ -566,12 +656,14 @@ static const char * inq_vendor_id = "Linux "; | |||
566 | static const char * inq_product_id = "scsi_debug "; | 656 | static const char * inq_product_id = "scsi_debug "; |
567 | static const char * inq_product_rev = "0004"; | 657 | static const char * inq_product_rev = "0004"; |
568 | 658 | ||
569 | static int inquiry_evpd_83(unsigned char * arr, int dev_id_num, | 659 | static int inquiry_evpd_83(unsigned char * arr, int target_dev_id, |
570 | const char * dev_id_str, int dev_id_str_len) | 660 | int dev_id_num, const char * dev_id_str, |
661 | int dev_id_str_len) | ||
571 | { | 662 | { |
572 | int num; | 663 | int num, port_a; |
664 | char b[32]; | ||
573 | 665 | ||
574 | /* Two identification descriptors: */ | 666 | port_a = target_dev_id + 1; |
575 | /* T10 vendor identifier field format (faked) */ | 667 | /* T10 vendor identifier field format (faked) */ |
576 | arr[0] = 0x2; /* ASCII */ | 668 | arr[0] = 0x2; /* ASCII */ |
577 | arr[1] = 0x1; | 669 | arr[1] = 0x1; |
@@ -582,25 +674,246 @@ static int inquiry_evpd_83(unsigned char * arr, int dev_id_num, | |||
582 | num = 8 + 16 + dev_id_str_len; | 674 | num = 8 + 16 + dev_id_str_len; |
583 | arr[3] = num; | 675 | arr[3] = num; |
584 | num += 4; | 676 | num += 4; |
585 | /* NAA IEEE registered identifier (faked) */ | 677 | if (dev_id_num >= 0) { |
586 | arr[num] = 0x1; /* binary */ | 678 | /* NAA-5, Logical unit identifier (binary) */ |
587 | arr[num + 1] = 0x3; | 679 | arr[num++] = 0x1; /* binary (not necessarily sas) */ |
588 | arr[num + 2] = 0x0; | 680 | arr[num++] = 0x3; /* PIV=0, lu, naa */ |
589 | arr[num + 3] = 0x8; | 681 | arr[num++] = 0x0; |
590 | arr[num + 4] = 0x51; /* ieee company id=0x123456 (faked) */ | 682 | arr[num++] = 0x8; |
591 | arr[num + 5] = 0x23; | 683 | arr[num++] = 0x53; /* naa-5 ieee company id=0x333333 (fake) */ |
592 | arr[num + 6] = 0x45; | 684 | arr[num++] = 0x33; |
593 | arr[num + 7] = 0x60; | 685 | arr[num++] = 0x33; |
594 | arr[num + 8] = (dev_id_num >> 24); | 686 | arr[num++] = 0x30; |
595 | arr[num + 9] = (dev_id_num >> 16) & 0xff; | 687 | arr[num++] = (dev_id_num >> 24); |
596 | arr[num + 10] = (dev_id_num >> 8) & 0xff; | 688 | arr[num++] = (dev_id_num >> 16) & 0xff; |
597 | arr[num + 11] = dev_id_num & 0xff; | 689 | arr[num++] = (dev_id_num >> 8) & 0xff; |
598 | return num + 12; | 690 | arr[num++] = dev_id_num & 0xff; |
691 | /* Target relative port number */ | ||
692 | arr[num++] = 0x61; /* proto=sas, binary */ | ||
693 | arr[num++] = 0x94; /* PIV=1, target port, rel port */ | ||
694 | arr[num++] = 0x0; /* reserved */ | ||
695 | arr[num++] = 0x4; /* length */ | ||
696 | arr[num++] = 0x0; /* reserved */ | ||
697 | arr[num++] = 0x0; /* reserved */ | ||
698 | arr[num++] = 0x0; | ||
699 | arr[num++] = 0x1; /* relative port A */ | ||
700 | } | ||
701 | /* NAA-5, Target port identifier */ | ||
702 | arr[num++] = 0x61; /* proto=sas, binary */ | ||
703 | arr[num++] = 0x93; /* piv=1, target port, naa */ | ||
704 | arr[num++] = 0x0; | ||
705 | arr[num++] = 0x8; | ||
706 | arr[num++] = 0x52; /* naa-5, company id=0x222222 (fake) */ | ||
707 | arr[num++] = 0x22; | ||
708 | arr[num++] = 0x22; | ||
709 | arr[num++] = 0x20; | ||
710 | arr[num++] = (port_a >> 24); | ||
711 | arr[num++] = (port_a >> 16) & 0xff; | ||
712 | arr[num++] = (port_a >> 8) & 0xff; | ||
713 | arr[num++] = port_a & 0xff; | ||
714 | /* NAA-5, Target device identifier */ | ||
715 | arr[num++] = 0x61; /* proto=sas, binary */ | ||
716 | arr[num++] = 0xa3; /* piv=1, target device, naa */ | ||
717 | arr[num++] = 0x0; | ||
718 | arr[num++] = 0x8; | ||
719 | arr[num++] = 0x52; /* naa-5, company id=0x222222 (fake) */ | ||
720 | arr[num++] = 0x22; | ||
721 | arr[num++] = 0x22; | ||
722 | arr[num++] = 0x20; | ||
723 | arr[num++] = (target_dev_id >> 24); | ||
724 | arr[num++] = (target_dev_id >> 16) & 0xff; | ||
725 | arr[num++] = (target_dev_id >> 8) & 0xff; | ||
726 | arr[num++] = target_dev_id & 0xff; | ||
727 | /* SCSI name string: Target device identifier */ | ||
728 | arr[num++] = 0x63; /* proto=sas, UTF-8 */ | ||
729 | arr[num++] = 0xa8; /* piv=1, target device, SCSI name string */ | ||
730 | arr[num++] = 0x0; | ||
731 | arr[num++] = 24; | ||
732 | memcpy(arr + num, "naa.52222220", 12); | ||
733 | num += 12; | ||
734 | snprintf(b, sizeof(b), "%08X", target_dev_id); | ||
735 | memcpy(arr + num, b, 8); | ||
736 | num += 8; | ||
737 | memset(arr + num, 0, 4); | ||
738 | num += 4; | ||
739 | return num; | ||
740 | } | ||
741 | |||
742 | |||
743 | static unsigned char vpd84_data[] = { | ||
744 | /* from 4th byte */ 0x22,0x22,0x22,0x0,0xbb,0x0, | ||
745 | 0x22,0x22,0x22,0x0,0xbb,0x1, | ||
746 | 0x22,0x22,0x22,0x0,0xbb,0x2, | ||
747 | }; | ||
748 | |||
749 | static int inquiry_evpd_84(unsigned char * arr) | ||
750 | { | ||
751 | memcpy(arr, vpd84_data, sizeof(vpd84_data)); | ||
752 | return sizeof(vpd84_data); | ||
753 | } | ||
754 | |||
755 | static int inquiry_evpd_85(unsigned char * arr) | ||
756 | { | ||
757 | int num = 0; | ||
758 | const char * na1 = "https://www.kernel.org/config"; | ||
759 | const char * na2 = "http://www.kernel.org/log"; | ||
760 | int plen, olen; | ||
761 | |||
762 | arr[num++] = 0x1; /* lu, storage config */ | ||
763 | arr[num++] = 0x0; /* reserved */ | ||
764 | arr[num++] = 0x0; | ||
765 | olen = strlen(na1); | ||
766 | plen = olen + 1; | ||
767 | if (plen % 4) | ||
768 | plen = ((plen / 4) + 1) * 4; | ||
769 | arr[num++] = plen; /* length, null termianted, padded */ | ||
770 | memcpy(arr + num, na1, olen); | ||
771 | memset(arr + num + olen, 0, plen - olen); | ||
772 | num += plen; | ||
773 | |||
774 | arr[num++] = 0x4; /* lu, logging */ | ||
775 | arr[num++] = 0x0; /* reserved */ | ||
776 | arr[num++] = 0x0; | ||
777 | olen = strlen(na2); | ||
778 | plen = olen + 1; | ||
779 | if (plen % 4) | ||
780 | plen = ((plen / 4) + 1) * 4; | ||
781 | arr[num++] = plen; /* length, null terminated, padded */ | ||
782 | memcpy(arr + num, na2, olen); | ||
783 | memset(arr + num + olen, 0, plen - olen); | ||
784 | num += plen; | ||
785 | |||
786 | return num; | ||
787 | } | ||
788 | |||
789 | /* SCSI ports VPD page */ | ||
790 | static int inquiry_evpd_88(unsigned char * arr, int target_dev_id) | ||
791 | { | ||
792 | int num = 0; | ||
793 | int port_a, port_b; | ||
794 | |||
795 | port_a = target_dev_id + 1; | ||
796 | port_b = port_a + 1; | ||
797 | arr[num++] = 0x0; /* reserved */ | ||
798 | arr[num++] = 0x0; /* reserved */ | ||
799 | arr[num++] = 0x0; | ||
800 | arr[num++] = 0x1; /* relative port 1 (primary) */ | ||
801 | memset(arr + num, 0, 6); | ||
802 | num += 6; | ||
803 | arr[num++] = 0x0; | ||
804 | arr[num++] = 12; /* length tp descriptor */ | ||
805 | /* naa-5 target port identifier (A) */ | ||
806 | arr[num++] = 0x61; /* proto=sas, binary */ | ||
807 | arr[num++] = 0x93; /* PIV=1, target port, NAA */ | ||
808 | arr[num++] = 0x0; /* reserved */ | ||
809 | arr[num++] = 0x8; /* length */ | ||
810 | arr[num++] = 0x52; /* NAA-5, company_id=0x222222 (fake) */ | ||
811 | arr[num++] = 0x22; | ||
812 | arr[num++] = 0x22; | ||
813 | arr[num++] = 0x20; | ||
814 | arr[num++] = (port_a >> 24); | ||
815 | arr[num++] = (port_a >> 16) & 0xff; | ||
816 | arr[num++] = (port_a >> 8) & 0xff; | ||
817 | arr[num++] = port_a & 0xff; | ||
818 | |||
819 | arr[num++] = 0x0; /* reserved */ | ||
820 | arr[num++] = 0x0; /* reserved */ | ||
821 | arr[num++] = 0x0; | ||
822 | arr[num++] = 0x2; /* relative port 2 (secondary) */ | ||
823 | memset(arr + num, 0, 6); | ||
824 | num += 6; | ||
825 | arr[num++] = 0x0; | ||
826 | arr[num++] = 12; /* length tp descriptor */ | ||
827 | /* naa-5 target port identifier (B) */ | ||
828 | arr[num++] = 0x61; /* proto=sas, binary */ | ||
829 | arr[num++] = 0x93; /* PIV=1, target port, NAA */ | ||
830 | arr[num++] = 0x0; /* reserved */ | ||
831 | arr[num++] = 0x8; /* length */ | ||
832 | arr[num++] = 0x52; /* NAA-5, company_id=0x222222 (fake) */ | ||
833 | arr[num++] = 0x22; | ||
834 | arr[num++] = 0x22; | ||
835 | arr[num++] = 0x20; | ||
836 | arr[num++] = (port_b >> 24); | ||
837 | arr[num++] = (port_b >> 16) & 0xff; | ||
838 | arr[num++] = (port_b >> 8) & 0xff; | ||
839 | arr[num++] = port_b & 0xff; | ||
840 | |||
841 | return num; | ||
842 | } | ||
843 | |||
844 | |||
845 | static unsigned char vpd89_data[] = { | ||
846 | /* from 4th byte */ 0,0,0,0, | ||
847 | 'l','i','n','u','x',' ',' ',' ', | ||
848 | 'S','A','T',' ','s','c','s','i','_','d','e','b','u','g',' ',' ', | ||
849 | '1','2','3','4', | ||
850 | 0x34,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0, | ||
851 | 0xec,0,0,0, | ||
852 | 0x5a,0xc,0xff,0x3f,0x37,0xc8,0x10,0,0,0,0,0,0x3f,0,0,0, | ||
853 | 0,0,0,0,0x58,0x58,0x58,0x58,0x58,0x58,0x58,0x58,0x20,0x20,0x20,0x20, | ||
854 | 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0,0,0,0x40,0x4,0,0x2e,0x33, | ||
855 | 0x38,0x31,0x20,0x20,0x20,0x20,0x54,0x53,0x38,0x33,0x30,0x30,0x33,0x31, | ||
856 | 0x53,0x41, | ||
857 | 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, | ||
858 | 0x20,0x20, | ||
859 | 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, | ||
860 | 0x10,0x80, | ||
861 | 0,0,0,0x2f,0,0,0,0x2,0,0x2,0x7,0,0xff,0xff,0x1,0, | ||
862 | 0x3f,0,0xc1,0xff,0x3e,0,0x10,0x1,0xb0,0xf8,0x50,0x9,0,0,0x7,0, | ||
863 | 0x3,0,0x78,0,0x78,0,0xf0,0,0x78,0,0,0,0,0,0,0, | ||
864 | 0,0,0,0,0,0,0,0,0x2,0,0,0,0,0,0,0, | ||
865 | 0x7e,0,0x1b,0,0x6b,0x34,0x1,0x7d,0x3,0x40,0x69,0x34,0x1,0x3c,0x3,0x40, | ||
866 | 0x7f,0x40,0,0,0,0,0xfe,0xfe,0,0,0,0,0,0xfe,0,0, | ||
867 | 0,0,0,0,0,0,0,0,0xb0,0xf8,0x50,0x9,0,0,0,0, | ||
868 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, | ||
869 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, | ||
870 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, | ||
871 | 0x1,0,0xb0,0xf8,0x50,0x9,0xb0,0xf8,0x50,0x9,0x20,0x20,0x2,0,0xb6,0x42, | ||
872 | 0,0x80,0x8a,0,0x6,0x3c,0xa,0x3c,0xff,0xff,0xc6,0x7,0,0x1,0,0x8, | ||
873 | 0xf0,0xf,0,0x10,0x2,0,0x30,0,0,0,0,0,0,0,0x6,0xfe, | ||
874 | 0,0,0x2,0,0x50,0,0x8a,0,0x4f,0x95,0,0,0x21,0,0xb,0, | ||
875 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, | ||
876 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, | ||
877 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, | ||
878 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, | ||
879 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, | ||
880 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, | ||
881 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, | ||
882 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, | ||
883 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, | ||
884 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, | ||
885 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, | ||
886 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0xa5,0x51, | ||
887 | }; | ||
888 | |||
889 | static int inquiry_evpd_89(unsigned char * arr) | ||
890 | { | ||
891 | memcpy(arr, vpd89_data, sizeof(vpd89_data)); | ||
892 | return sizeof(vpd89_data); | ||
893 | } | ||
894 | |||
895 | |||
896 | static unsigned char vpdb0_data[] = { | ||
897 | /* from 4th byte */ 0,0,0,4, | ||
898 | 0,0,0x4,0, | ||
899 | 0,0,0,64, | ||
900 | }; | ||
901 | |||
902 | static int inquiry_evpd_b0(unsigned char * arr) | ||
903 | { | ||
904 | memcpy(arr, vpdb0_data, sizeof(vpdb0_data)); | ||
905 | if (sdebug_store_sectors > 0x400) { | ||
906 | arr[4] = (sdebug_store_sectors >> 24) & 0xff; | ||
907 | arr[5] = (sdebug_store_sectors >> 16) & 0xff; | ||
908 | arr[6] = (sdebug_store_sectors >> 8) & 0xff; | ||
909 | arr[7] = sdebug_store_sectors & 0xff; | ||
910 | } | ||
911 | return sizeof(vpdb0_data); | ||
599 | } | 912 | } |
600 | 913 | ||
601 | 914 | ||
602 | #define SDEBUG_LONG_INQ_SZ 96 | 915 | #define SDEBUG_LONG_INQ_SZ 96 |
603 | #define SDEBUG_MAX_INQ_ARR_SZ 128 | 916 | #define SDEBUG_MAX_INQ_ARR_SZ 584 |
604 | 917 | ||
605 | static int resp_inquiry(struct scsi_cmnd * scp, int target, | 918 | static int resp_inquiry(struct scsi_cmnd * scp, int target, |
606 | struct sdebug_dev_info * devip) | 919 | struct sdebug_dev_info * devip) |
@@ -608,64 +921,113 @@ static int resp_inquiry(struct scsi_cmnd * scp, int target, | |||
608 | unsigned char pq_pdt; | 921 | unsigned char pq_pdt; |
609 | unsigned char arr[SDEBUG_MAX_INQ_ARR_SZ]; | 922 | unsigned char arr[SDEBUG_MAX_INQ_ARR_SZ]; |
610 | unsigned char *cmd = (unsigned char *)scp->cmnd; | 923 | unsigned char *cmd = (unsigned char *)scp->cmnd; |
611 | int alloc_len; | 924 | int alloc_len, n; |
612 | 925 | ||
613 | alloc_len = (cmd[3] << 8) + cmd[4]; | 926 | alloc_len = (cmd[3] << 8) + cmd[4]; |
614 | memset(arr, 0, SDEBUG_MAX_INQ_ARR_SZ); | 927 | memset(arr, 0, SDEBUG_MAX_INQ_ARR_SZ); |
615 | pq_pdt = (scsi_debug_ptype & 0x1f); | 928 | if (devip->wlun) |
929 | pq_pdt = 0x1e; /* present, wlun */ | ||
930 | else if (scsi_debug_no_lun_0 && (0 == devip->lun)) | ||
931 | pq_pdt = 0x7f; /* not present, no device type */ | ||
932 | else | ||
933 | pq_pdt = (scsi_debug_ptype & 0x1f); | ||
616 | arr[0] = pq_pdt; | 934 | arr[0] = pq_pdt; |
617 | if (0x2 & cmd[1]) { /* CMDDT bit set */ | 935 | if (0x2 & cmd[1]) { /* CMDDT bit set */ |
618 | mk_sense_buffer(devip, ILLEGAL_REQUEST, INVALID_FIELD_IN_CDB, | 936 | mk_sense_buffer(devip, ILLEGAL_REQUEST, INVALID_FIELD_IN_CDB, |
619 | 0); | 937 | 0); |
620 | return check_condition_result; | 938 | return check_condition_result; |
621 | } else if (0x1 & cmd[1]) { /* EVPD bit set */ | 939 | } else if (0x1 & cmd[1]) { /* EVPD bit set */ |
622 | int dev_id_num, len; | 940 | int lu_id_num, target_dev_id, len; |
623 | char dev_id_str[6]; | 941 | char lu_id_str[6]; |
942 | int host_no = devip->sdbg_host->shost->host_no; | ||
624 | 943 | ||
625 | dev_id_num = ((devip->sdbg_host->shost->host_no + 1) * 2000) + | 944 | lu_id_num = devip->wlun ? -1 : (((host_no + 1) * 2000) + |
626 | (devip->target * 1000) + devip->lun; | 945 | (devip->target * 1000) + devip->lun); |
627 | len = scnprintf(dev_id_str, 6, "%d", dev_id_num); | 946 | target_dev_id = ((host_no + 1) * 2000) + |
947 | (devip->target * 1000) - 3; | ||
948 | len = scnprintf(lu_id_str, 6, "%d", lu_id_num); | ||
628 | if (0 == cmd[2]) { /* supported vital product data pages */ | 949 | if (0 == cmd[2]) { /* supported vital product data pages */ |
629 | arr[3] = 3; | 950 | arr[1] = cmd[2]; /*sanity */ |
630 | arr[4] = 0x0; /* this page */ | 951 | n = 4; |
631 | arr[5] = 0x80; /* unit serial number */ | 952 | arr[n++] = 0x0; /* this page */ |
632 | arr[6] = 0x83; /* device identification */ | 953 | arr[n++] = 0x80; /* unit serial number */ |
954 | arr[n++] = 0x83; /* device identification */ | ||
955 | arr[n++] = 0x84; /* software interface ident. */ | ||
956 | arr[n++] = 0x85; /* management network addresses */ | ||
957 | arr[n++] = 0x86; /* extended inquiry */ | ||
958 | arr[n++] = 0x87; /* mode page policy */ | ||
959 | arr[n++] = 0x88; /* SCSI ports */ | ||
960 | arr[n++] = 0x89; /* ATA information */ | ||
961 | arr[n++] = 0xb0; /* Block limits (SBC) */ | ||
962 | arr[3] = n - 4; /* number of supported VPD pages */ | ||
633 | } else if (0x80 == cmd[2]) { /* unit serial number */ | 963 | } else if (0x80 == cmd[2]) { /* unit serial number */ |
634 | arr[1] = 0x80; | 964 | arr[1] = cmd[2]; /*sanity */ |
635 | arr[3] = len; | 965 | arr[3] = len; |
636 | memcpy(&arr[4], dev_id_str, len); | 966 | memcpy(&arr[4], lu_id_str, len); |
637 | } else if (0x83 == cmd[2]) { /* device identification */ | 967 | } else if (0x83 == cmd[2]) { /* device identification */ |
638 | arr[1] = 0x83; | 968 | arr[1] = cmd[2]; /*sanity */ |
639 | arr[3] = inquiry_evpd_83(&arr[4], dev_id_num, | 969 | arr[3] = inquiry_evpd_83(&arr[4], target_dev_id, |
640 | dev_id_str, len); | 970 | lu_id_num, lu_id_str, len); |
971 | } else if (0x84 == cmd[2]) { /* Software interface ident. */ | ||
972 | arr[1] = cmd[2]; /*sanity */ | ||
973 | arr[3] = inquiry_evpd_84(&arr[4]); | ||
974 | } else if (0x85 == cmd[2]) { /* Management network addresses */ | ||
975 | arr[1] = cmd[2]; /*sanity */ | ||
976 | arr[3] = inquiry_evpd_85(&arr[4]); | ||
977 | } else if (0x86 == cmd[2]) { /* extended inquiry */ | ||
978 | arr[1] = cmd[2]; /*sanity */ | ||
979 | arr[3] = 0x3c; /* number of following entries */ | ||
980 | arr[4] = 0x0; /* no protection stuff */ | ||
981 | arr[5] = 0x7; /* head of q, ordered + simple q's */ | ||
982 | } else if (0x87 == cmd[2]) { /* mode page policy */ | ||
983 | arr[1] = cmd[2]; /*sanity */ | ||
984 | arr[3] = 0x8; /* number of following entries */ | ||
985 | arr[4] = 0x2; /* disconnect-reconnect mp */ | ||
986 | arr[6] = 0x80; /* mlus, shared */ | ||
987 | arr[8] = 0x18; /* protocol specific lu */ | ||
988 | arr[10] = 0x82; /* mlus, per initiator port */ | ||
989 | } else if (0x88 == cmd[2]) { /* SCSI Ports */ | ||
990 | arr[1] = cmd[2]; /*sanity */ | ||
991 | arr[3] = inquiry_evpd_88(&arr[4], target_dev_id); | ||
992 | } else if (0x89 == cmd[2]) { /* ATA information */ | ||
993 | arr[1] = cmd[2]; /*sanity */ | ||
994 | n = inquiry_evpd_89(&arr[4]); | ||
995 | arr[2] = (n >> 8); | ||
996 | arr[3] = (n & 0xff); | ||
997 | } else if (0xb0 == cmd[2]) { /* Block limits (SBC) */ | ||
998 | arr[1] = cmd[2]; /*sanity */ | ||
999 | arr[3] = inquiry_evpd_b0(&arr[4]); | ||
641 | } else { | 1000 | } else { |
642 | /* Illegal request, invalid field in cdb */ | 1001 | /* Illegal request, invalid field in cdb */ |
643 | mk_sense_buffer(devip, ILLEGAL_REQUEST, | 1002 | mk_sense_buffer(devip, ILLEGAL_REQUEST, |
644 | INVALID_FIELD_IN_CDB, 0); | 1003 | INVALID_FIELD_IN_CDB, 0); |
645 | return check_condition_result; | 1004 | return check_condition_result; |
646 | } | 1005 | } |
1006 | len = min(((arr[2] << 8) + arr[3]) + 4, alloc_len); | ||
647 | return fill_from_dev_buffer(scp, arr, | 1007 | return fill_from_dev_buffer(scp, arr, |
648 | min(alloc_len, SDEBUG_MAX_INQ_ARR_SZ)); | 1008 | min(len, SDEBUG_MAX_INQ_ARR_SZ)); |
649 | } | 1009 | } |
650 | /* drops through here for a standard inquiry */ | 1010 | /* drops through here for a standard inquiry */ |
651 | arr[1] = DEV_REMOVEABLE(target) ? 0x80 : 0; /* Removable disk */ | 1011 | arr[1] = DEV_REMOVEABLE(target) ? 0x80 : 0; /* Removable disk */ |
652 | arr[2] = scsi_debug_scsi_level; | 1012 | arr[2] = scsi_debug_scsi_level; |
653 | arr[3] = 2; /* response_data_format==2 */ | 1013 | arr[3] = 2; /* response_data_format==2 */ |
654 | arr[4] = SDEBUG_LONG_INQ_SZ - 5; | 1014 | arr[4] = SDEBUG_LONG_INQ_SZ - 5; |
655 | arr[6] = 0x1; /* claim: ADDR16 */ | 1015 | arr[6] = 0x10; /* claim: MultiP */ |
656 | /* arr[6] |= 0x40; ... claim: EncServ (enclosure services) */ | 1016 | /* arr[6] |= 0x40; ... claim: EncServ (enclosure services) */ |
657 | arr[7] = 0x3a; /* claim: WBUS16, SYNC, LINKED + CMDQUE */ | 1017 | arr[7] = 0xa; /* claim: LINKED + CMDQUE */ |
658 | memcpy(&arr[8], inq_vendor_id, 8); | 1018 | memcpy(&arr[8], inq_vendor_id, 8); |
659 | memcpy(&arr[16], inq_product_id, 16); | 1019 | memcpy(&arr[16], inq_product_id, 16); |
660 | memcpy(&arr[32], inq_product_rev, 4); | 1020 | memcpy(&arr[32], inq_product_rev, 4); |
661 | /* version descriptors (2 bytes each) follow */ | 1021 | /* version descriptors (2 bytes each) follow */ |
662 | arr[58] = 0x0; arr[59] = 0x40; /* SAM-2 */ | 1022 | arr[58] = 0x0; arr[59] = 0x77; /* SAM-3 ANSI */ |
663 | arr[60] = 0x3; arr[61] = 0x0; /* SPC-3 */ | 1023 | arr[60] = 0x3; arr[61] = 0x14; /* SPC-3 ANSI */ |
1024 | n = 62; | ||
664 | if (scsi_debug_ptype == 0) { | 1025 | if (scsi_debug_ptype == 0) { |
665 | arr[62] = 0x1; arr[63] = 0x80; /* SBC */ | 1026 | arr[n++] = 0x3; arr[n++] = 0x3d; /* SBC-2 ANSI */ |
666 | } else if (scsi_debug_ptype == 1) { | 1027 | } else if (scsi_debug_ptype == 1) { |
667 | arr[62] = 0x2; arr[63] = 0x00; /* SSC */ | 1028 | arr[n++] = 0x3; arr[n++] = 0x60; /* SSC-2 no version */ |
668 | } | 1029 | } |
1030 | arr[n++] = 0xc; arr[n++] = 0xf; /* SAS-1.1 rev 10 */ | ||
669 | return fill_from_dev_buffer(scp, arr, | 1031 | return fill_from_dev_buffer(scp, arr, |
670 | min(alloc_len, SDEBUG_LONG_INQ_SZ)); | 1032 | min(alloc_len, SDEBUG_LONG_INQ_SZ)); |
671 | } | 1033 | } |
@@ -676,46 +1038,141 @@ static int resp_requests(struct scsi_cmnd * scp, | |||
676 | unsigned char * sbuff; | 1038 | unsigned char * sbuff; |
677 | unsigned char *cmd = (unsigned char *)scp->cmnd; | 1039 | unsigned char *cmd = (unsigned char *)scp->cmnd; |
678 | unsigned char arr[SDEBUG_SENSE_LEN]; | 1040 | unsigned char arr[SDEBUG_SENSE_LEN]; |
1041 | int want_dsense; | ||
679 | int len = 18; | 1042 | int len = 18; |
680 | 1043 | ||
681 | memset(arr, 0, SDEBUG_SENSE_LEN); | 1044 | memset(arr, 0, sizeof(arr)); |
682 | if (devip->reset == 1) | 1045 | if (devip->reset == 1) |
683 | mk_sense_buffer(devip, 0, NO_ADDED_SENSE, 0); | 1046 | mk_sense_buffer(devip, 0, NO_ADDITIONAL_SENSE, 0); |
1047 | want_dsense = !!(cmd[1] & 1) || scsi_debug_dsense; | ||
684 | sbuff = devip->sense_buff; | 1048 | sbuff = devip->sense_buff; |
685 | if ((cmd[1] & 1) && (! scsi_debug_dsense)) { | 1049 | if ((iec_m_pg[2] & 0x4) && (6 == (iec_m_pg[3] & 0xf))) { |
686 | /* DESC bit set and sense_buff in fixed format */ | 1050 | if (want_dsense) { |
687 | arr[0] = 0x72; | 1051 | arr[0] = 0x72; |
688 | arr[1] = sbuff[2]; /* sense key */ | 1052 | arr[1] = 0x0; /* NO_SENSE in sense_key */ |
689 | arr[2] = sbuff[12]; /* asc */ | 1053 | arr[2] = THRESHOLD_EXCEEDED; |
690 | arr[3] = sbuff[13]; /* ascq */ | 1054 | arr[3] = 0xff; /* TEST set and MRIE==6 */ |
691 | len = 8; | 1055 | } else { |
692 | } else | 1056 | arr[0] = 0x70; |
1057 | arr[2] = 0x0; /* NO_SENSE in sense_key */ | ||
1058 | arr[7] = 0xa; /* 18 byte sense buffer */ | ||
1059 | arr[12] = THRESHOLD_EXCEEDED; | ||
1060 | arr[13] = 0xff; /* TEST set and MRIE==6 */ | ||
1061 | } | ||
1062 | } else if (devip->stopped) { | ||
1063 | if (want_dsense) { | ||
1064 | arr[0] = 0x72; | ||
1065 | arr[1] = 0x0; /* NO_SENSE in sense_key */ | ||
1066 | arr[2] = LOW_POWER_COND_ON; | ||
1067 | arr[3] = 0x0; /* TEST set and MRIE==6 */ | ||
1068 | } else { | ||
1069 | arr[0] = 0x70; | ||
1070 | arr[2] = 0x0; /* NO_SENSE in sense_key */ | ||
1071 | arr[7] = 0xa; /* 18 byte sense buffer */ | ||
1072 | arr[12] = LOW_POWER_COND_ON; | ||
1073 | arr[13] = 0x0; /* TEST set and MRIE==6 */ | ||
1074 | } | ||
1075 | } else { | ||
693 | memcpy(arr, sbuff, SDEBUG_SENSE_LEN); | 1076 | memcpy(arr, sbuff, SDEBUG_SENSE_LEN); |
694 | mk_sense_buffer(devip, 0, NO_ADDED_SENSE, 0); | 1077 | if ((cmd[1] & 1) && (! scsi_debug_dsense)) { |
1078 | /* DESC bit set and sense_buff in fixed format */ | ||
1079 | memset(arr, 0, sizeof(arr)); | ||
1080 | arr[0] = 0x72; | ||
1081 | arr[1] = sbuff[2]; /* sense key */ | ||
1082 | arr[2] = sbuff[12]; /* asc */ | ||
1083 | arr[3] = sbuff[13]; /* ascq */ | ||
1084 | len = 8; | ||
1085 | } | ||
1086 | } | ||
1087 | mk_sense_buffer(devip, 0, NO_ADDITIONAL_SENSE, 0); | ||
695 | return fill_from_dev_buffer(scp, arr, len); | 1088 | return fill_from_dev_buffer(scp, arr, len); |
696 | } | 1089 | } |
697 | 1090 | ||
1091 | static int resp_start_stop(struct scsi_cmnd * scp, | ||
1092 | struct sdebug_dev_info * devip) | ||
1093 | { | ||
1094 | unsigned char *cmd = (unsigned char *)scp->cmnd; | ||
1095 | int power_cond, errsts, start; | ||
1096 | |||
1097 | if ((errsts = check_readiness(scp, 1, devip))) | ||
1098 | return errsts; | ||
1099 | power_cond = (cmd[4] & 0xf0) >> 4; | ||
1100 | if (power_cond) { | ||
1101 | mk_sense_buffer(devip, ILLEGAL_REQUEST, INVALID_FIELD_IN_CDB, | ||
1102 | 0); | ||
1103 | return check_condition_result; | ||
1104 | } | ||
1105 | start = cmd[4] & 1; | ||
1106 | if (start == devip->stopped) | ||
1107 | devip->stopped = !start; | ||
1108 | return 0; | ||
1109 | } | ||
1110 | |||
698 | #define SDEBUG_READCAP_ARR_SZ 8 | 1111 | #define SDEBUG_READCAP_ARR_SZ 8 |
699 | static int resp_readcap(struct scsi_cmnd * scp, | 1112 | static int resp_readcap(struct scsi_cmnd * scp, |
700 | struct sdebug_dev_info * devip) | 1113 | struct sdebug_dev_info * devip) |
701 | { | 1114 | { |
702 | unsigned char arr[SDEBUG_READCAP_ARR_SZ]; | 1115 | unsigned char arr[SDEBUG_READCAP_ARR_SZ]; |
703 | unsigned long capac; | 1116 | unsigned int capac; |
704 | int errsts; | 1117 | int errsts; |
705 | 1118 | ||
706 | if ((errsts = check_reset(scp, devip))) | 1119 | if ((errsts = check_readiness(scp, 1, devip))) |
707 | return errsts; | 1120 | return errsts; |
1121 | /* following just in case virtual_gb changed */ | ||
1122 | if (scsi_debug_virtual_gb > 0) { | ||
1123 | sdebug_capacity = 2048 * 1024; | ||
1124 | sdebug_capacity *= scsi_debug_virtual_gb; | ||
1125 | } else | ||
1126 | sdebug_capacity = sdebug_store_sectors; | ||
708 | memset(arr, 0, SDEBUG_READCAP_ARR_SZ); | 1127 | memset(arr, 0, SDEBUG_READCAP_ARR_SZ); |
709 | capac = (unsigned long)sdebug_capacity - 1; | 1128 | if (sdebug_capacity < 0xffffffff) { |
710 | arr[0] = (capac >> 24); | 1129 | capac = (unsigned int)sdebug_capacity - 1; |
711 | arr[1] = (capac >> 16) & 0xff; | 1130 | arr[0] = (capac >> 24); |
712 | arr[2] = (capac >> 8) & 0xff; | 1131 | arr[1] = (capac >> 16) & 0xff; |
713 | arr[3] = capac & 0xff; | 1132 | arr[2] = (capac >> 8) & 0xff; |
1133 | arr[3] = capac & 0xff; | ||
1134 | } else { | ||
1135 | arr[0] = 0xff; | ||
1136 | arr[1] = 0xff; | ||
1137 | arr[2] = 0xff; | ||
1138 | arr[3] = 0xff; | ||
1139 | } | ||
714 | arr[6] = (SECT_SIZE_PER(target) >> 8) & 0xff; | 1140 | arr[6] = (SECT_SIZE_PER(target) >> 8) & 0xff; |
715 | arr[7] = SECT_SIZE_PER(target) & 0xff; | 1141 | arr[7] = SECT_SIZE_PER(target) & 0xff; |
716 | return fill_from_dev_buffer(scp, arr, SDEBUG_READCAP_ARR_SZ); | 1142 | return fill_from_dev_buffer(scp, arr, SDEBUG_READCAP_ARR_SZ); |
717 | } | 1143 | } |
718 | 1144 | ||
1145 | #define SDEBUG_READCAP16_ARR_SZ 32 | ||
1146 | static int resp_readcap16(struct scsi_cmnd * scp, | ||
1147 | struct sdebug_dev_info * devip) | ||
1148 | { | ||
1149 | unsigned char *cmd = (unsigned char *)scp->cmnd; | ||
1150 | unsigned char arr[SDEBUG_READCAP16_ARR_SZ]; | ||
1151 | unsigned long long capac; | ||
1152 | int errsts, k, alloc_len; | ||
1153 | |||
1154 | if ((errsts = check_readiness(scp, 1, devip))) | ||
1155 | return errsts; | ||
1156 | alloc_len = ((cmd[10] << 24) + (cmd[11] << 16) + (cmd[12] << 8) | ||
1157 | + cmd[13]); | ||
1158 | /* following just in case virtual_gb changed */ | ||
1159 | if (scsi_debug_virtual_gb > 0) { | ||
1160 | sdebug_capacity = 2048 * 1024; | ||
1161 | sdebug_capacity *= scsi_debug_virtual_gb; | ||
1162 | } else | ||
1163 | sdebug_capacity = sdebug_store_sectors; | ||
1164 | memset(arr, 0, SDEBUG_READCAP16_ARR_SZ); | ||
1165 | capac = sdebug_capacity - 1; | ||
1166 | for (k = 0; k < 8; ++k, capac >>= 8) | ||
1167 | arr[7 - k] = capac & 0xff; | ||
1168 | arr[8] = (SECT_SIZE_PER(target) >> 24) & 0xff; | ||
1169 | arr[9] = (SECT_SIZE_PER(target) >> 16) & 0xff; | ||
1170 | arr[10] = (SECT_SIZE_PER(target) >> 8) & 0xff; | ||
1171 | arr[11] = SECT_SIZE_PER(target) & 0xff; | ||
1172 | return fill_from_dev_buffer(scp, arr, | ||
1173 | min(alloc_len, SDEBUG_READCAP16_ARR_SZ)); | ||
1174 | } | ||
1175 | |||
719 | /* <<Following mode page info copied from ST318451LW>> */ | 1176 | /* <<Following mode page info copied from ST318451LW>> */ |
720 | 1177 | ||
721 | static int resp_err_recov_pg(unsigned char * p, int pcontrol, int target) | 1178 | static int resp_err_recov_pg(unsigned char * p, int pcontrol, int target) |
@@ -771,27 +1228,98 @@ static int resp_caching_pg(unsigned char * p, int pcontrol, int target) | |||
771 | 1228 | ||
772 | static int resp_ctrl_m_pg(unsigned char * p, int pcontrol, int target) | 1229 | static int resp_ctrl_m_pg(unsigned char * p, int pcontrol, int target) |
773 | { /* Control mode page for mode_sense */ | 1230 | { /* Control mode page for mode_sense */ |
774 | unsigned char ctrl_m_pg[] = {0xa, 10, 2, 0, 0, 0, 0, 0, | 1231 | unsigned char ch_ctrl_m_pg[] = {/* 0xa, 10, */ 0x6, 0, 0, 0, 0, 0, |
1232 | 0, 0, 0, 0}; | ||
1233 | unsigned char d_ctrl_m_pg[] = {0xa, 10, 2, 0, 0, 0, 0, 0, | ||
775 | 0, 0, 0x2, 0x4b}; | 1234 | 0, 0, 0x2, 0x4b}; |
776 | 1235 | ||
777 | if (scsi_debug_dsense) | 1236 | if (scsi_debug_dsense) |
778 | ctrl_m_pg[2] |= 0x4; | 1237 | ctrl_m_pg[2] |= 0x4; |
1238 | else | ||
1239 | ctrl_m_pg[2] &= ~0x4; | ||
779 | memcpy(p, ctrl_m_pg, sizeof(ctrl_m_pg)); | 1240 | memcpy(p, ctrl_m_pg, sizeof(ctrl_m_pg)); |
780 | if (1 == pcontrol) | 1241 | if (1 == pcontrol) |
781 | memset(p + 2, 0, sizeof(ctrl_m_pg) - 2); | 1242 | memcpy(p + 2, ch_ctrl_m_pg, sizeof(ch_ctrl_m_pg)); |
1243 | else if (2 == pcontrol) | ||
1244 | memcpy(p, d_ctrl_m_pg, sizeof(d_ctrl_m_pg)); | ||
782 | return sizeof(ctrl_m_pg); | 1245 | return sizeof(ctrl_m_pg); |
783 | } | 1246 | } |
784 | 1247 | ||
1248 | |||
785 | static int resp_iec_m_pg(unsigned char * p, int pcontrol, int target) | 1249 | static int resp_iec_m_pg(unsigned char * p, int pcontrol, int target) |
786 | { /* Informational Exceptions control mode page for mode_sense */ | 1250 | { /* Informational Exceptions control mode page for mode_sense */ |
787 | unsigned char iec_m_pg[] = {0x1c, 0xa, 0x08, 0, 0, 0, 0, 0, | 1251 | unsigned char ch_iec_m_pg[] = {/* 0x1c, 0xa, */ 0x4, 0xf, 0, 0, 0, 0, |
788 | 0, 0, 0x0, 0x0}; | 1252 | 0, 0, 0x0, 0x0}; |
1253 | unsigned char d_iec_m_pg[] = {0x1c, 0xa, 0x08, 0, 0, 0, 0, 0, | ||
1254 | 0, 0, 0x0, 0x0}; | ||
1255 | |||
789 | memcpy(p, iec_m_pg, sizeof(iec_m_pg)); | 1256 | memcpy(p, iec_m_pg, sizeof(iec_m_pg)); |
790 | if (1 == pcontrol) | 1257 | if (1 == pcontrol) |
791 | memset(p + 2, 0, sizeof(iec_m_pg) - 2); | 1258 | memcpy(p + 2, ch_iec_m_pg, sizeof(ch_iec_m_pg)); |
1259 | else if (2 == pcontrol) | ||
1260 | memcpy(p, d_iec_m_pg, sizeof(d_iec_m_pg)); | ||
792 | return sizeof(iec_m_pg); | 1261 | return sizeof(iec_m_pg); |
793 | } | 1262 | } |
794 | 1263 | ||
1264 | static int resp_sas_sf_m_pg(unsigned char * p, int pcontrol, int target) | ||
1265 | { /* SAS SSP mode page - short format for mode_sense */ | ||
1266 | unsigned char sas_sf_m_pg[] = {0x19, 0x6, | ||
1267 | 0x6, 0x0, 0x7, 0xd0, 0x0, 0x0}; | ||
1268 | |||
1269 | memcpy(p, sas_sf_m_pg, sizeof(sas_sf_m_pg)); | ||
1270 | if (1 == pcontrol) | ||
1271 | memset(p + 2, 0, sizeof(sas_sf_m_pg) - 2); | ||
1272 | return sizeof(sas_sf_m_pg); | ||
1273 | } | ||
1274 | |||
1275 | |||
1276 | static int resp_sas_pcd_m_spg(unsigned char * p, int pcontrol, int target, | ||
1277 | int target_dev_id) | ||
1278 | { /* SAS phy control and discover mode page for mode_sense */ | ||
1279 | unsigned char sas_pcd_m_pg[] = {0x59, 0x1, 0, 0x64, 0, 0x6, 0, 2, | ||
1280 | 0, 0, 0, 0, 0x10, 0x9, 0x8, 0x0, | ||
1281 | 0x52, 0x22, 0x22, 0x20, 0x0, 0x0, 0x0, 0x0, | ||
1282 | 0x51, 0x11, 0x11, 0x10, 0x0, 0x0, 0x0, 0x1, | ||
1283 | 0x2, 0, 0, 0, 0, 0, 0, 0, | ||
1284 | 0x88, 0x99, 0, 0, 0, 0, 0, 0, | ||
1285 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
1286 | 0, 1, 0, 0, 0x10, 0x9, 0x8, 0x0, | ||
1287 | 0x52, 0x22, 0x22, 0x20, 0x0, 0x0, 0x0, 0x0, | ||
1288 | 0x51, 0x11, 0x11, 0x10, 0x0, 0x0, 0x0, 0x1, | ||
1289 | 0x3, 0, 0, 0, 0, 0, 0, 0, | ||
1290 | 0x88, 0x99, 0, 0, 0, 0, 0, 0, | ||
1291 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
1292 | }; | ||
1293 | int port_a, port_b; | ||
1294 | |||
1295 | port_a = target_dev_id + 1; | ||
1296 | port_b = port_a + 1; | ||
1297 | memcpy(p, sas_pcd_m_pg, sizeof(sas_pcd_m_pg)); | ||
1298 | p[20] = (port_a >> 24); | ||
1299 | p[21] = (port_a >> 16) & 0xff; | ||
1300 | p[22] = (port_a >> 8) & 0xff; | ||
1301 | p[23] = port_a & 0xff; | ||
1302 | p[48 + 20] = (port_b >> 24); | ||
1303 | p[48 + 21] = (port_b >> 16) & 0xff; | ||
1304 | p[48 + 22] = (port_b >> 8) & 0xff; | ||
1305 | p[48 + 23] = port_b & 0xff; | ||
1306 | if (1 == pcontrol) | ||
1307 | memset(p + 4, 0, sizeof(sas_pcd_m_pg) - 4); | ||
1308 | return sizeof(sas_pcd_m_pg); | ||
1309 | } | ||
1310 | |||
1311 | static int resp_sas_sha_m_spg(unsigned char * p, int pcontrol) | ||
1312 | { /* SAS SSP shared protocol specific port mode subpage */ | ||
1313 | unsigned char sas_sha_m_pg[] = {0x59, 0x2, 0, 0xc, 0, 0x6, 0x10, 0, | ||
1314 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
1315 | }; | ||
1316 | |||
1317 | memcpy(p, sas_sha_m_pg, sizeof(sas_sha_m_pg)); | ||
1318 | if (1 == pcontrol) | ||
1319 | memset(p + 4, 0, sizeof(sas_sha_m_pg) - 4); | ||
1320 | return sizeof(sas_sha_m_pg); | ||
1321 | } | ||
1322 | |||
795 | #define SDEBUG_MAX_MSENSE_SZ 256 | 1323 | #define SDEBUG_MAX_MSENSE_SZ 256 |
796 | 1324 | ||
797 | static int resp_mode_sense(struct scsi_cmnd * scp, int target, | 1325 | static int resp_mode_sense(struct scsi_cmnd * scp, int target, |
@@ -800,12 +1328,12 @@ static int resp_mode_sense(struct scsi_cmnd * scp, int target, | |||
800 | unsigned char dbd; | 1328 | unsigned char dbd; |
801 | int pcontrol, pcode, subpcode; | 1329 | int pcontrol, pcode, subpcode; |
802 | unsigned char dev_spec; | 1330 | unsigned char dev_spec; |
803 | int alloc_len, msense_6, offset, len, errsts; | 1331 | int alloc_len, msense_6, offset, len, errsts, target_dev_id; |
804 | unsigned char * ap; | 1332 | unsigned char * ap; |
805 | unsigned char arr[SDEBUG_MAX_MSENSE_SZ]; | 1333 | unsigned char arr[SDEBUG_MAX_MSENSE_SZ]; |
806 | unsigned char *cmd = (unsigned char *)scp->cmnd; | 1334 | unsigned char *cmd = (unsigned char *)scp->cmnd; |
807 | 1335 | ||
808 | if ((errsts = check_reset(scp, devip))) | 1336 | if ((errsts = check_readiness(scp, 1, devip))) |
809 | return errsts; | 1337 | return errsts; |
810 | dbd = cmd[1] & 0x8; | 1338 | dbd = cmd[1] & 0x8; |
811 | pcontrol = (cmd[2] & 0xc0) >> 6; | 1339 | pcontrol = (cmd[2] & 0xc0) >> 6; |
@@ -819,6 +1347,8 @@ static int resp_mode_sense(struct scsi_cmnd * scp, int target, | |||
819 | 0); | 1347 | 0); |
820 | return check_condition_result; | 1348 | return check_condition_result; |
821 | } | 1349 | } |
1350 | target_dev_id = ((devip->sdbg_host->shost->host_no + 1) * 2000) + | ||
1351 | (devip->target * 1000) - 3; | ||
822 | dev_spec = DEV_READONLY(target) ? 0x80 : 0x0; | 1352 | dev_spec = DEV_READONLY(target) ? 0x80 : 0x0; |
823 | if (msense_6) { | 1353 | if (msense_6) { |
824 | arr[2] = dev_spec; | 1354 | arr[2] = dev_spec; |
@@ -829,7 +1359,8 @@ static int resp_mode_sense(struct scsi_cmnd * scp, int target, | |||
829 | } | 1359 | } |
830 | ap = arr + offset; | 1360 | ap = arr + offset; |
831 | 1361 | ||
832 | if (0 != subpcode) { /* TODO: Control Extension page */ | 1362 | if ((subpcode > 0x0) && (subpcode < 0xff) && (0x19 != pcode)) { |
1363 | /* TODO: Control Extension page */ | ||
833 | mk_sense_buffer(devip, ILLEGAL_REQUEST, INVALID_FIELD_IN_CDB, | 1364 | mk_sense_buffer(devip, ILLEGAL_REQUEST, INVALID_FIELD_IN_CDB, |
834 | 0); | 1365 | 0); |
835 | return check_condition_result; | 1366 | return check_condition_result; |
@@ -855,17 +1386,45 @@ static int resp_mode_sense(struct scsi_cmnd * scp, int target, | |||
855 | len = resp_ctrl_m_pg(ap, pcontrol, target); | 1386 | len = resp_ctrl_m_pg(ap, pcontrol, target); |
856 | offset += len; | 1387 | offset += len; |
857 | break; | 1388 | break; |
1389 | case 0x19: /* if spc==1 then sas phy, control+discover */ | ||
1390 | if ((subpcode > 0x2) && (subpcode < 0xff)) { | ||
1391 | mk_sense_buffer(devip, ILLEGAL_REQUEST, | ||
1392 | INVALID_FIELD_IN_CDB, 0); | ||
1393 | return check_condition_result; | ||
1394 | } | ||
1395 | len = 0; | ||
1396 | if ((0x0 == subpcode) || (0xff == subpcode)) | ||
1397 | len += resp_sas_sf_m_pg(ap + len, pcontrol, target); | ||
1398 | if ((0x1 == subpcode) || (0xff == subpcode)) | ||
1399 | len += resp_sas_pcd_m_spg(ap + len, pcontrol, target, | ||
1400 | target_dev_id); | ||
1401 | if ((0x2 == subpcode) || (0xff == subpcode)) | ||
1402 | len += resp_sas_sha_m_spg(ap + len, pcontrol); | ||
1403 | offset += len; | ||
1404 | break; | ||
858 | case 0x1c: /* Informational Exceptions Mode page, all devices */ | 1405 | case 0x1c: /* Informational Exceptions Mode page, all devices */ |
859 | len = resp_iec_m_pg(ap, pcontrol, target); | 1406 | len = resp_iec_m_pg(ap, pcontrol, target); |
860 | offset += len; | 1407 | offset += len; |
861 | break; | 1408 | break; |
862 | case 0x3f: /* Read all Mode pages */ | 1409 | case 0x3f: /* Read all Mode pages */ |
863 | len = resp_err_recov_pg(ap, pcontrol, target); | 1410 | if ((0 == subpcode) || (0xff == subpcode)) { |
864 | len += resp_disconnect_pg(ap + len, pcontrol, target); | 1411 | len = resp_err_recov_pg(ap, pcontrol, target); |
865 | len += resp_format_pg(ap + len, pcontrol, target); | 1412 | len += resp_disconnect_pg(ap + len, pcontrol, target); |
866 | len += resp_caching_pg(ap + len, pcontrol, target); | 1413 | len += resp_format_pg(ap + len, pcontrol, target); |
867 | len += resp_ctrl_m_pg(ap + len, pcontrol, target); | 1414 | len += resp_caching_pg(ap + len, pcontrol, target); |
868 | len += resp_iec_m_pg(ap + len, pcontrol, target); | 1415 | len += resp_ctrl_m_pg(ap + len, pcontrol, target); |
1416 | len += resp_sas_sf_m_pg(ap + len, pcontrol, target); | ||
1417 | if (0xff == subpcode) { | ||
1418 | len += resp_sas_pcd_m_spg(ap + len, pcontrol, | ||
1419 | target, target_dev_id); | ||
1420 | len += resp_sas_sha_m_spg(ap + len, pcontrol); | ||
1421 | } | ||
1422 | len += resp_iec_m_pg(ap + len, pcontrol, target); | ||
1423 | } else { | ||
1424 | mk_sense_buffer(devip, ILLEGAL_REQUEST, | ||
1425 | INVALID_FIELD_IN_CDB, 0); | ||
1426 | return check_condition_result; | ||
1427 | } | ||
869 | offset += len; | 1428 | offset += len; |
870 | break; | 1429 | break; |
871 | default: | 1430 | default: |
@@ -882,71 +1441,274 @@ static int resp_mode_sense(struct scsi_cmnd * scp, int target, | |||
882 | return fill_from_dev_buffer(scp, arr, min(alloc_len, offset)); | 1441 | return fill_from_dev_buffer(scp, arr, min(alloc_len, offset)); |
883 | } | 1442 | } |
884 | 1443 | ||
885 | static int resp_read(struct scsi_cmnd * SCpnt, int upper_blk, int block, | 1444 | #define SDEBUG_MAX_MSELECT_SZ 512 |
886 | int num, struct sdebug_dev_info * devip) | 1445 | |
1446 | static int resp_mode_select(struct scsi_cmnd * scp, int mselect6, | ||
1447 | struct sdebug_dev_info * devip) | ||
1448 | { | ||
1449 | int pf, sp, ps, md_len, bd_len, off, spf, pg_len; | ||
1450 | int param_len, res, errsts, mpage; | ||
1451 | unsigned char arr[SDEBUG_MAX_MSELECT_SZ]; | ||
1452 | unsigned char *cmd = (unsigned char *)scp->cmnd; | ||
1453 | |||
1454 | if ((errsts = check_readiness(scp, 1, devip))) | ||
1455 | return errsts; | ||
1456 | memset(arr, 0, sizeof(arr)); | ||
1457 | pf = cmd[1] & 0x10; | ||
1458 | sp = cmd[1] & 0x1; | ||
1459 | param_len = mselect6 ? cmd[4] : ((cmd[7] << 8) + cmd[8]); | ||
1460 | if ((0 == pf) || sp || (param_len > SDEBUG_MAX_MSELECT_SZ)) { | ||
1461 | mk_sense_buffer(devip, ILLEGAL_REQUEST, | ||
1462 | INVALID_FIELD_IN_CDB, 0); | ||
1463 | return check_condition_result; | ||
1464 | } | ||
1465 | res = fetch_to_dev_buffer(scp, arr, param_len); | ||
1466 | if (-1 == res) | ||
1467 | return (DID_ERROR << 16); | ||
1468 | else if ((res < param_len) && | ||
1469 | (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts)) | ||
1470 | printk(KERN_INFO "scsi_debug: mode_select: cdb indicated=%d, " | ||
1471 | " IO sent=%d bytes\n", param_len, res); | ||
1472 | md_len = mselect6 ? (arr[0] + 1) : ((arr[0] << 8) + arr[1] + 2); | ||
1473 | bd_len = mselect6 ? arr[3] : ((arr[6] << 8) + arr[7]); | ||
1474 | if ((md_len > 2) || (0 != bd_len)) { | ||
1475 | mk_sense_buffer(devip, ILLEGAL_REQUEST, | ||
1476 | INVALID_FIELD_IN_PARAM_LIST, 0); | ||
1477 | return check_condition_result; | ||
1478 | } | ||
1479 | off = bd_len + (mselect6 ? 4 : 8); | ||
1480 | mpage = arr[off] & 0x3f; | ||
1481 | ps = !!(arr[off] & 0x80); | ||
1482 | if (ps) { | ||
1483 | mk_sense_buffer(devip, ILLEGAL_REQUEST, | ||
1484 | INVALID_FIELD_IN_PARAM_LIST, 0); | ||
1485 | return check_condition_result; | ||
1486 | } | ||
1487 | spf = !!(arr[off] & 0x40); | ||
1488 | pg_len = spf ? ((arr[off + 2] << 8) + arr[off + 3] + 4) : | ||
1489 | (arr[off + 1] + 2); | ||
1490 | if ((pg_len + off) > param_len) { | ||
1491 | mk_sense_buffer(devip, ILLEGAL_REQUEST, | ||
1492 | PARAMETER_LIST_LENGTH_ERR, 0); | ||
1493 | return check_condition_result; | ||
1494 | } | ||
1495 | switch (mpage) { | ||
1496 | case 0xa: /* Control Mode page */ | ||
1497 | if (ctrl_m_pg[1] == arr[off + 1]) { | ||
1498 | memcpy(ctrl_m_pg + 2, arr + off + 2, | ||
1499 | sizeof(ctrl_m_pg) - 2); | ||
1500 | scsi_debug_dsense = !!(ctrl_m_pg[2] & 0x4); | ||
1501 | return 0; | ||
1502 | } | ||
1503 | break; | ||
1504 | case 0x1c: /* Informational Exceptions Mode page */ | ||
1505 | if (iec_m_pg[1] == arr[off + 1]) { | ||
1506 | memcpy(iec_m_pg + 2, arr + off + 2, | ||
1507 | sizeof(iec_m_pg) - 2); | ||
1508 | return 0; | ||
1509 | } | ||
1510 | break; | ||
1511 | default: | ||
1512 | break; | ||
1513 | } | ||
1514 | mk_sense_buffer(devip, ILLEGAL_REQUEST, | ||
1515 | INVALID_FIELD_IN_PARAM_LIST, 0); | ||
1516 | return check_condition_result; | ||
1517 | } | ||
1518 | |||
1519 | static int resp_temp_l_pg(unsigned char * arr) | ||
1520 | { | ||
1521 | unsigned char temp_l_pg[] = {0x0, 0x0, 0x3, 0x2, 0x0, 38, | ||
1522 | 0x0, 0x1, 0x3, 0x2, 0x0, 65, | ||
1523 | }; | ||
1524 | |||
1525 | memcpy(arr, temp_l_pg, sizeof(temp_l_pg)); | ||
1526 | return sizeof(temp_l_pg); | ||
1527 | } | ||
1528 | |||
1529 | static int resp_ie_l_pg(unsigned char * arr) | ||
1530 | { | ||
1531 | unsigned char ie_l_pg[] = {0x0, 0x0, 0x3, 0x3, 0x0, 0x0, 38, | ||
1532 | }; | ||
1533 | |||
1534 | memcpy(arr, ie_l_pg, sizeof(ie_l_pg)); | ||
1535 | if (iec_m_pg[2] & 0x4) { /* TEST bit set */ | ||
1536 | arr[4] = THRESHOLD_EXCEEDED; | ||
1537 | arr[5] = 0xff; | ||
1538 | } | ||
1539 | return sizeof(ie_l_pg); | ||
1540 | } | ||
1541 | |||
1542 | #define SDEBUG_MAX_LSENSE_SZ 512 | ||
1543 | |||
1544 | static int resp_log_sense(struct scsi_cmnd * scp, | ||
1545 | struct sdebug_dev_info * devip) | ||
1546 | { | ||
1547 | int ppc, sp, pcontrol, pcode, alloc_len, errsts, len, n; | ||
1548 | unsigned char arr[SDEBUG_MAX_LSENSE_SZ]; | ||
1549 | unsigned char *cmd = (unsigned char *)scp->cmnd; | ||
1550 | |||
1551 | if ((errsts = check_readiness(scp, 1, devip))) | ||
1552 | return errsts; | ||
1553 | memset(arr, 0, sizeof(arr)); | ||
1554 | ppc = cmd[1] & 0x2; | ||
1555 | sp = cmd[1] & 0x1; | ||
1556 | if (ppc || sp) { | ||
1557 | mk_sense_buffer(devip, ILLEGAL_REQUEST, | ||
1558 | INVALID_FIELD_IN_CDB, 0); | ||
1559 | return check_condition_result; | ||
1560 | } | ||
1561 | pcontrol = (cmd[2] & 0xc0) >> 6; | ||
1562 | pcode = cmd[2] & 0x3f; | ||
1563 | alloc_len = (cmd[7] << 8) + cmd[8]; | ||
1564 | arr[0] = pcode; | ||
1565 | switch (pcode) { | ||
1566 | case 0x0: /* Supported log pages log page */ | ||
1567 | n = 4; | ||
1568 | arr[n++] = 0x0; /* this page */ | ||
1569 | arr[n++] = 0xd; /* Temperature */ | ||
1570 | arr[n++] = 0x2f; /* Informational exceptions */ | ||
1571 | arr[3] = n - 4; | ||
1572 | break; | ||
1573 | case 0xd: /* Temperature log page */ | ||
1574 | arr[3] = resp_temp_l_pg(arr + 4); | ||
1575 | break; | ||
1576 | case 0x2f: /* Informational exceptions log page */ | ||
1577 | arr[3] = resp_ie_l_pg(arr + 4); | ||
1578 | break; | ||
1579 | default: | ||
1580 | mk_sense_buffer(devip, ILLEGAL_REQUEST, | ||
1581 | INVALID_FIELD_IN_CDB, 0); | ||
1582 | return check_condition_result; | ||
1583 | } | ||
1584 | len = min(((arr[2] << 8) + arr[3]) + 4, alloc_len); | ||
1585 | return fill_from_dev_buffer(scp, arr, | ||
1586 | min(len, SDEBUG_MAX_INQ_ARR_SZ)); | ||
1587 | } | ||
1588 | |||
1589 | static int resp_read(struct scsi_cmnd * SCpnt, unsigned long long lba, | ||
1590 | unsigned int num, struct sdebug_dev_info * devip) | ||
887 | { | 1591 | { |
888 | unsigned long iflags; | 1592 | unsigned long iflags; |
1593 | unsigned int block, from_bottom; | ||
1594 | unsigned long long u; | ||
889 | int ret; | 1595 | int ret; |
890 | 1596 | ||
891 | if (upper_blk || (block + num > sdebug_capacity)) { | 1597 | if (lba + num > sdebug_capacity) { |
892 | mk_sense_buffer(devip, ILLEGAL_REQUEST, ADDR_OUT_OF_RANGE, | 1598 | mk_sense_buffer(devip, ILLEGAL_REQUEST, ADDR_OUT_OF_RANGE, |
893 | 0); | 1599 | 0); |
894 | return check_condition_result; | 1600 | return check_condition_result; |
895 | } | 1601 | } |
1602 | /* transfer length excessive (tie in to block limits VPD page) */ | ||
1603 | if (num > sdebug_store_sectors) { | ||
1604 | mk_sense_buffer(devip, ILLEGAL_REQUEST, INVALID_FIELD_IN_CDB, | ||
1605 | 0); | ||
1606 | return check_condition_result; | ||
1607 | } | ||
896 | if ((SCSI_DEBUG_OPT_MEDIUM_ERR & scsi_debug_opts) && | 1608 | if ((SCSI_DEBUG_OPT_MEDIUM_ERR & scsi_debug_opts) && |
897 | (block <= OPT_MEDIUM_ERR_ADDR) && | 1609 | (lba <= OPT_MEDIUM_ERR_ADDR) && |
898 | ((block + num) > OPT_MEDIUM_ERR_ADDR)) { | 1610 | ((lba + num) > OPT_MEDIUM_ERR_ADDR)) { |
1611 | /* claim unrecoverable read error */ | ||
899 | mk_sense_buffer(devip, MEDIUM_ERROR, UNRECOVERED_READ_ERR, | 1612 | mk_sense_buffer(devip, MEDIUM_ERROR, UNRECOVERED_READ_ERR, |
900 | 0); | 1613 | 0); |
901 | /* claim unrecoverable read error */ | 1614 | /* set info field and valid bit for fixed descriptor */ |
1615 | if (0x70 == (devip->sense_buff[0] & 0x7f)) { | ||
1616 | devip->sense_buff[0] |= 0x80; /* Valid bit */ | ||
1617 | ret = OPT_MEDIUM_ERR_ADDR; | ||
1618 | devip->sense_buff[3] = (ret >> 24) & 0xff; | ||
1619 | devip->sense_buff[4] = (ret >> 16) & 0xff; | ||
1620 | devip->sense_buff[5] = (ret >> 8) & 0xff; | ||
1621 | devip->sense_buff[6] = ret & 0xff; | ||
1622 | } | ||
902 | return check_condition_result; | 1623 | return check_condition_result; |
903 | } | 1624 | } |
904 | read_lock_irqsave(&atomic_rw, iflags); | 1625 | read_lock_irqsave(&atomic_rw, iflags); |
905 | ret = fill_from_dev_buffer(SCpnt, fake_storep + (block * SECT_SIZE), | 1626 | if ((lba + num) <= sdebug_store_sectors) |
906 | num * SECT_SIZE); | 1627 | ret = fill_from_dev_buffer(SCpnt, |
1628 | fake_storep + (lba * SECT_SIZE), | ||
1629 | num * SECT_SIZE); | ||
1630 | else { | ||
1631 | /* modulo when one arg is 64 bits needs do_div() */ | ||
1632 | u = lba; | ||
1633 | block = do_div(u, sdebug_store_sectors); | ||
1634 | from_bottom = 0; | ||
1635 | if ((block + num) > sdebug_store_sectors) | ||
1636 | from_bottom = (block + num) - sdebug_store_sectors; | ||
1637 | ret = fill_from_dev_buffer(SCpnt, | ||
1638 | fake_storep + (block * SECT_SIZE), | ||
1639 | (num - from_bottom) * SECT_SIZE); | ||
1640 | if ((0 == ret) && (from_bottom > 0)) | ||
1641 | ret = fill_from_dev_buffer(SCpnt, fake_storep, | ||
1642 | from_bottom * SECT_SIZE); | ||
1643 | } | ||
907 | read_unlock_irqrestore(&atomic_rw, iflags); | 1644 | read_unlock_irqrestore(&atomic_rw, iflags); |
908 | return ret; | 1645 | return ret; |
909 | } | 1646 | } |
910 | 1647 | ||
911 | static int resp_write(struct scsi_cmnd * SCpnt, int upper_blk, int block, | 1648 | static int resp_write(struct scsi_cmnd * SCpnt, unsigned long long lba, |
912 | int num, struct sdebug_dev_info * devip) | 1649 | unsigned int num, struct sdebug_dev_info * devip) |
913 | { | 1650 | { |
914 | unsigned long iflags; | 1651 | unsigned long iflags; |
1652 | unsigned int block, to_bottom; | ||
1653 | unsigned long long u; | ||
915 | int res; | 1654 | int res; |
916 | 1655 | ||
917 | if (upper_blk || (block + num > sdebug_capacity)) { | 1656 | if (lba + num > sdebug_capacity) { |
918 | mk_sense_buffer(devip, ILLEGAL_REQUEST, ADDR_OUT_OF_RANGE, | 1657 | mk_sense_buffer(devip, ILLEGAL_REQUEST, ADDR_OUT_OF_RANGE, |
919 | 0); | 1658 | 0); |
920 | return check_condition_result; | 1659 | return check_condition_result; |
921 | } | 1660 | } |
1661 | /* transfer length excessive (tie in to block limits VPD page) */ | ||
1662 | if (num > sdebug_store_sectors) { | ||
1663 | mk_sense_buffer(devip, ILLEGAL_REQUEST, INVALID_FIELD_IN_CDB, | ||
1664 | 0); | ||
1665 | return check_condition_result; | ||
1666 | } | ||
922 | 1667 | ||
923 | write_lock_irqsave(&atomic_rw, iflags); | 1668 | write_lock_irqsave(&atomic_rw, iflags); |
924 | res = fetch_to_dev_buffer(SCpnt, fake_storep + (block * SECT_SIZE), | 1669 | if ((lba + num) <= sdebug_store_sectors) |
925 | num * SECT_SIZE); | 1670 | res = fetch_to_dev_buffer(SCpnt, |
1671 | fake_storep + (lba * SECT_SIZE), | ||
1672 | num * SECT_SIZE); | ||
1673 | else { | ||
1674 | /* modulo when one arg is 64 bits needs do_div() */ | ||
1675 | u = lba; | ||
1676 | block = do_div(u, sdebug_store_sectors); | ||
1677 | to_bottom = 0; | ||
1678 | if ((block + num) > sdebug_store_sectors) | ||
1679 | to_bottom = (block + num) - sdebug_store_sectors; | ||
1680 | res = fetch_to_dev_buffer(SCpnt, | ||
1681 | fake_storep + (block * SECT_SIZE), | ||
1682 | (num - to_bottom) * SECT_SIZE); | ||
1683 | if ((0 == res) && (to_bottom > 0)) | ||
1684 | res = fetch_to_dev_buffer(SCpnt, fake_storep, | ||
1685 | to_bottom * SECT_SIZE); | ||
1686 | } | ||
926 | write_unlock_irqrestore(&atomic_rw, iflags); | 1687 | write_unlock_irqrestore(&atomic_rw, iflags); |
927 | if (-1 == res) | 1688 | if (-1 == res) |
928 | return (DID_ERROR << 16); | 1689 | return (DID_ERROR << 16); |
929 | else if ((res < (num * SECT_SIZE)) && | 1690 | else if ((res < (num * SECT_SIZE)) && |
930 | (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts)) | 1691 | (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts)) |
931 | printk(KERN_INFO "scsi_debug: write: cdb indicated=%d, " | 1692 | printk(KERN_INFO "scsi_debug: write: cdb indicated=%u, " |
932 | " IO sent=%d bytes\n", num * SECT_SIZE, res); | 1693 | " IO sent=%d bytes\n", num * SECT_SIZE, res); |
933 | return 0; | 1694 | return 0; |
934 | } | 1695 | } |
935 | 1696 | ||
936 | #define SDEBUG_RLUN_ARR_SZ 128 | 1697 | #define SDEBUG_RLUN_ARR_SZ 256 |
937 | 1698 | ||
938 | static int resp_report_luns(struct scsi_cmnd * scp, | 1699 | static int resp_report_luns(struct scsi_cmnd * scp, |
939 | struct sdebug_dev_info * devip) | 1700 | struct sdebug_dev_info * devip) |
940 | { | 1701 | { |
941 | unsigned int alloc_len; | 1702 | unsigned int alloc_len; |
942 | int lun_cnt, i, upper; | 1703 | int lun_cnt, i, upper, num, n, wlun, lun; |
943 | unsigned char *cmd = (unsigned char *)scp->cmnd; | 1704 | unsigned char *cmd = (unsigned char *)scp->cmnd; |
944 | int select_report = (int)cmd[2]; | 1705 | int select_report = (int)cmd[2]; |
945 | struct scsi_lun *one_lun; | 1706 | struct scsi_lun *one_lun; |
946 | unsigned char arr[SDEBUG_RLUN_ARR_SZ]; | 1707 | unsigned char arr[SDEBUG_RLUN_ARR_SZ]; |
1708 | unsigned char * max_addr; | ||
947 | 1709 | ||
948 | alloc_len = cmd[9] + (cmd[8] << 8) + (cmd[7] << 16) + (cmd[6] << 24); | 1710 | alloc_len = cmd[9] + (cmd[8] << 8) + (cmd[7] << 16) + (cmd[6] << 24); |
949 | if ((alloc_len < 16) || (select_report > 2)) { | 1711 | if ((alloc_len < 4) || (select_report > 2)) { |
950 | mk_sense_buffer(devip, ILLEGAL_REQUEST, INVALID_FIELD_IN_CDB, | 1712 | mk_sense_buffer(devip, ILLEGAL_REQUEST, INVALID_FIELD_IN_CDB, |
951 | 0); | 1713 | 0); |
952 | return check_condition_result; | 1714 | return check_condition_result; |
@@ -954,18 +1716,37 @@ static int resp_report_luns(struct scsi_cmnd * scp, | |||
954 | /* can produce response with up to 16k luns (lun 0 to lun 16383) */ | 1716 | /* can produce response with up to 16k luns (lun 0 to lun 16383) */ |
955 | memset(arr, 0, SDEBUG_RLUN_ARR_SZ); | 1717 | memset(arr, 0, SDEBUG_RLUN_ARR_SZ); |
956 | lun_cnt = scsi_debug_max_luns; | 1718 | lun_cnt = scsi_debug_max_luns; |
957 | arr[2] = ((sizeof(struct scsi_lun) * lun_cnt) >> 8) & 0xff; | 1719 | if (1 == select_report) |
958 | arr[3] = (sizeof(struct scsi_lun) * lun_cnt) & 0xff; | 1720 | lun_cnt = 0; |
959 | lun_cnt = min((int)((SDEBUG_RLUN_ARR_SZ - 8) / | 1721 | else if (scsi_debug_no_lun_0 && (lun_cnt > 0)) |
960 | sizeof(struct scsi_lun)), lun_cnt); | 1722 | --lun_cnt; |
1723 | wlun = (select_report > 0) ? 1 : 0; | ||
1724 | num = lun_cnt + wlun; | ||
1725 | arr[2] = ((sizeof(struct scsi_lun) * num) >> 8) & 0xff; | ||
1726 | arr[3] = (sizeof(struct scsi_lun) * num) & 0xff; | ||
1727 | n = min((int)((SDEBUG_RLUN_ARR_SZ - 8) / | ||
1728 | sizeof(struct scsi_lun)), num); | ||
1729 | if (n < num) { | ||
1730 | wlun = 0; | ||
1731 | lun_cnt = n; | ||
1732 | } | ||
961 | one_lun = (struct scsi_lun *) &arr[8]; | 1733 | one_lun = (struct scsi_lun *) &arr[8]; |
962 | for (i = 0; i < lun_cnt; i++) { | 1734 | max_addr = arr + SDEBUG_RLUN_ARR_SZ; |
963 | upper = (i >> 8) & 0x3f; | 1735 | for (i = 0, lun = (scsi_debug_no_lun_0 ? 1 : 0); |
1736 | ((i < lun_cnt) && ((unsigned char *)(one_lun + i) < max_addr)); | ||
1737 | i++, lun++) { | ||
1738 | upper = (lun >> 8) & 0x3f; | ||
964 | if (upper) | 1739 | if (upper) |
965 | one_lun[i].scsi_lun[0] = | 1740 | one_lun[i].scsi_lun[0] = |
966 | (upper | (SAM2_LUN_ADDRESS_METHOD << 6)); | 1741 | (upper | (SAM2_LUN_ADDRESS_METHOD << 6)); |
967 | one_lun[i].scsi_lun[1] = i & 0xff; | 1742 | one_lun[i].scsi_lun[1] = lun & 0xff; |
1743 | } | ||
1744 | if (wlun) { | ||
1745 | one_lun[i].scsi_lun[0] = (SAM2_WLUN_REPORT_LUNS >> 8) & 0xff; | ||
1746 | one_lun[i].scsi_lun[1] = SAM2_WLUN_REPORT_LUNS & 0xff; | ||
1747 | i++; | ||
968 | } | 1748 | } |
1749 | alloc_len = (unsigned char *)(one_lun + i) - arr; | ||
969 | return fill_from_dev_buffer(scp, arr, | 1750 | return fill_from_dev_buffer(scp, arr, |
970 | min((int)alloc_len, SDEBUG_RLUN_ARR_SZ)); | 1751 | min((int)alloc_len, SDEBUG_RLUN_ARR_SZ)); |
971 | } | 1752 | } |
@@ -1001,7 +1782,8 @@ static void timer_intr_handler(unsigned long indx) | |||
1001 | static int scsi_debug_slave_alloc(struct scsi_device * sdp) | 1782 | static int scsi_debug_slave_alloc(struct scsi_device * sdp) |
1002 | { | 1783 | { |
1003 | if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) | 1784 | if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) |
1004 | sdev_printk(KERN_INFO, sdp, "scsi_debug: slave_alloc\n"); | 1785 | printk(KERN_INFO "scsi_debug: slave_alloc <%u %u %u %u>\n", |
1786 | sdp->host->host_no, sdp->channel, sdp->id, sdp->lun); | ||
1005 | return 0; | 1787 | return 0; |
1006 | } | 1788 | } |
1007 | 1789 | ||
@@ -1010,7 +1792,8 @@ static int scsi_debug_slave_configure(struct scsi_device * sdp) | |||
1010 | struct sdebug_dev_info * devip; | 1792 | struct sdebug_dev_info * devip; |
1011 | 1793 | ||
1012 | if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) | 1794 | if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) |
1013 | sdev_printk(KERN_INFO, sdp, "scsi_debug: slave_configure\n"); | 1795 | printk(KERN_INFO "scsi_debug: slave_configure <%u %u %u %u>\n", |
1796 | sdp->host->host_no, sdp->channel, sdp->id, sdp->lun); | ||
1014 | if (sdp->host->max_cmd_len != SCSI_DEBUG_MAX_CMD_LEN) | 1797 | if (sdp->host->max_cmd_len != SCSI_DEBUG_MAX_CMD_LEN) |
1015 | sdp->host->max_cmd_len = SCSI_DEBUG_MAX_CMD_LEN; | 1798 | sdp->host->max_cmd_len = SCSI_DEBUG_MAX_CMD_LEN; |
1016 | devip = devInfoReg(sdp); | 1799 | devip = devInfoReg(sdp); |
@@ -1018,6 +1801,7 @@ static int scsi_debug_slave_configure(struct scsi_device * sdp) | |||
1018 | if (sdp->host->cmd_per_lun) | 1801 | if (sdp->host->cmd_per_lun) |
1019 | scsi_adjust_queue_depth(sdp, SDEBUG_TAGGED_QUEUING, | 1802 | scsi_adjust_queue_depth(sdp, SDEBUG_TAGGED_QUEUING, |
1020 | sdp->host->cmd_per_lun); | 1803 | sdp->host->cmd_per_lun); |
1804 | blk_queue_max_segment_size(sdp->request_queue, 256 * 1024); | ||
1021 | return 0; | 1805 | return 0; |
1022 | } | 1806 | } |
1023 | 1807 | ||
@@ -1027,7 +1811,8 @@ static void scsi_debug_slave_destroy(struct scsi_device * sdp) | |||
1027 | (struct sdebug_dev_info *)sdp->hostdata; | 1811 | (struct sdebug_dev_info *)sdp->hostdata; |
1028 | 1812 | ||
1029 | if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) | 1813 | if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) |
1030 | sdev_printk(KERN_INFO, sdp, "scsi_debug: slave_destroy\n"); | 1814 | printk(KERN_INFO "scsi_debug: slave_destroy <%u %u %u %u>\n", |
1815 | sdp->host->host_no, sdp->channel, sdp->id, sdp->lun); | ||
1031 | if (devip) { | 1816 | if (devip) { |
1032 | /* make this slot avaliable for re-use */ | 1817 | /* make this slot avaliable for re-use */ |
1033 | devip->used = 0; | 1818 | devip->used = 0; |
@@ -1084,6 +1869,8 @@ static struct sdebug_dev_info * devInfoReg(struct scsi_device * sdev) | |||
1084 | open_devip->sense_buff[0] = 0x70; | 1869 | open_devip->sense_buff[0] = 0x70; |
1085 | open_devip->sense_buff[7] = 0xa; | 1870 | open_devip->sense_buff[7] = 0xa; |
1086 | } | 1871 | } |
1872 | if (sdev->lun == SAM2_WLUN_REPORT_LUNS) | ||
1873 | open_devip->wlun = SAM2_WLUN_REPORT_LUNS & 0xff; | ||
1087 | return open_devip; | 1874 | return open_devip; |
1088 | } | 1875 | } |
1089 | return NULL; | 1876 | return NULL; |
@@ -1272,7 +2059,7 @@ static void __init sdebug_build_parts(unsigned char * ramp) | |||
1272 | printk(KERN_WARNING "scsi_debug:build_parts: reducing " | 2059 | printk(KERN_WARNING "scsi_debug:build_parts: reducing " |
1273 | "partitions to %d\n", SDEBUG_MAX_PARTS); | 2060 | "partitions to %d\n", SDEBUG_MAX_PARTS); |
1274 | } | 2061 | } |
1275 | num_sectors = (int)(sdebug_store_size / SECT_SIZE); | 2062 | num_sectors = (int)sdebug_store_sectors; |
1276 | sectors_per_part = (num_sectors - sdebug_sectors_per) | 2063 | sectors_per_part = (num_sectors - sdebug_sectors_per) |
1277 | / scsi_debug_num_parts; | 2064 | / scsi_debug_num_parts; |
1278 | heads_by_sects = sdebug_heads * sdebug_sectors_per; | 2065 | heads_by_sects = sdebug_heads * sdebug_sectors_per; |
@@ -1315,9 +2102,9 @@ static int schedule_resp(struct scsi_cmnd * cmnd, | |||
1315 | if (scsi_result) { | 2102 | if (scsi_result) { |
1316 | struct scsi_device * sdp = cmnd->device; | 2103 | struct scsi_device * sdp = cmnd->device; |
1317 | 2104 | ||
1318 | sdev_printk(KERN_INFO, sdp, | 2105 | printk(KERN_INFO "scsi_debug: <%u %u %u %u> " |
1319 | "non-zero result=0x%x\n", | 2106 | "non-zero result=0x%x\n", sdp->host->host_no, |
1320 | scsi_result); | 2107 | sdp->channel, sdp->id, sdp->lun, scsi_result); |
1321 | } | 2108 | } |
1322 | } | 2109 | } |
1323 | if (cmnd && devip) { | 2110 | if (cmnd && devip) { |
@@ -1364,21 +2151,19 @@ static int schedule_resp(struct scsi_cmnd * cmnd, | |||
1364 | } | 2151 | } |
1365 | } | 2152 | } |
1366 | 2153 | ||
1367 | /* Set 'perm' (4th argument) to 0 to disable module_param's definition | 2154 | module_param_named(add_host, scsi_debug_add_host, int, S_IRUGO | S_IWUSR); |
1368 | * of sysfs parameters (which module_param doesn't yet support). | 2155 | module_param_named(delay, scsi_debug_delay, int, S_IRUGO | S_IWUSR); |
1369 | * Sysfs parameters defined explicitly below. | 2156 | module_param_named(dev_size_mb, scsi_debug_dev_size_mb, int, S_IRUGO); |
1370 | */ | 2157 | module_param_named(dsense, scsi_debug_dsense, int, S_IRUGO | S_IWUSR); |
1371 | module_param_named(add_host, scsi_debug_add_host, int, 0); /* perm=0644 */ | 2158 | module_param_named(every_nth, scsi_debug_every_nth, int, S_IRUGO | S_IWUSR); |
1372 | module_param_named(delay, scsi_debug_delay, int, 0); /* perm=0644 */ | 2159 | module_param_named(max_luns, scsi_debug_max_luns, int, S_IRUGO | S_IWUSR); |
1373 | module_param_named(dev_size_mb, scsi_debug_dev_size_mb, int, 0); | 2160 | module_param_named(no_lun_0, scsi_debug_no_lun_0, int, S_IRUGO | S_IWUSR); |
1374 | module_param_named(dsense, scsi_debug_dsense, int, 0); | 2161 | module_param_named(num_parts, scsi_debug_num_parts, int, S_IRUGO); |
1375 | module_param_named(every_nth, scsi_debug_every_nth, int, 0); | 2162 | module_param_named(num_tgts, scsi_debug_num_tgts, int, S_IRUGO | S_IWUSR); |
1376 | module_param_named(max_luns, scsi_debug_max_luns, int, 0); | 2163 | module_param_named(opts, scsi_debug_opts, int, S_IRUGO | S_IWUSR); |
1377 | module_param_named(num_parts, scsi_debug_num_parts, int, 0); | 2164 | module_param_named(ptype, scsi_debug_ptype, int, S_IRUGO | S_IWUSR); |
1378 | module_param_named(num_tgts, scsi_debug_num_tgts, int, 0); | 2165 | module_param_named(scsi_level, scsi_debug_scsi_level, int, S_IRUGO); |
1379 | module_param_named(opts, scsi_debug_opts, int, 0); /* perm=0644 */ | 2166 | module_param_named(virtual_gb, scsi_debug_virtual_gb, int, S_IRUGO | S_IWUSR); |
1380 | module_param_named(ptype, scsi_debug_ptype, int, 0); | ||
1381 | module_param_named(scsi_level, scsi_debug_scsi_level, int, 0); | ||
1382 | 2167 | ||
1383 | MODULE_AUTHOR("Eric Youngdale + Douglas Gilbert"); | 2168 | MODULE_AUTHOR("Eric Youngdale + Douglas Gilbert"); |
1384 | MODULE_DESCRIPTION("SCSI debug adapter driver"); | 2169 | MODULE_DESCRIPTION("SCSI debug adapter driver"); |
@@ -1387,15 +2172,17 @@ MODULE_VERSION(SCSI_DEBUG_VERSION); | |||
1387 | 2172 | ||
1388 | MODULE_PARM_DESC(add_host, "0..127 hosts allowed(def=1)"); | 2173 | MODULE_PARM_DESC(add_host, "0..127 hosts allowed(def=1)"); |
1389 | MODULE_PARM_DESC(delay, "# of jiffies to delay response(def=1)"); | 2174 | MODULE_PARM_DESC(delay, "# of jiffies to delay response(def=1)"); |
1390 | MODULE_PARM_DESC(dev_size_mb, "size in MB of ram shared by devs"); | 2175 | MODULE_PARM_DESC(dev_size_mb, "size in MB of ram shared by devs(def=8)"); |
1391 | MODULE_PARM_DESC(dsense, "use descriptor sense format(def: fixed)"); | 2176 | MODULE_PARM_DESC(dsense, "use descriptor sense format(def=0 -> fixed)"); |
1392 | MODULE_PARM_DESC(every_nth, "timeout every nth command(def=100)"); | 2177 | MODULE_PARM_DESC(every_nth, "timeout every nth command(def=100)"); |
1393 | MODULE_PARM_DESC(max_luns, "number of SCSI LUNs per target to simulate"); | 2178 | MODULE_PARM_DESC(max_luns, "number of LUNs per target to simulate(def=1)"); |
2179 | MODULE_PARM_DESC(no_lun_0, "no LU number 0 (def=0 -> have lun 0)"); | ||
1394 | MODULE_PARM_DESC(num_parts, "number of partitions(def=0)"); | 2180 | MODULE_PARM_DESC(num_parts, "number of partitions(def=0)"); |
1395 | MODULE_PARM_DESC(num_tgts, "number of SCSI targets per host to simulate"); | 2181 | MODULE_PARM_DESC(num_tgts, "number of targets per host to simulate(def=1)"); |
1396 | MODULE_PARM_DESC(opts, "1->noise, 2->medium_error, 4->..."); | 2182 | MODULE_PARM_DESC(opts, "1->noise, 2->medium_error, 4->... (def=0)"); |
1397 | MODULE_PARM_DESC(ptype, "SCSI peripheral type(def=0[disk])"); | 2183 | MODULE_PARM_DESC(ptype, "SCSI peripheral type(def=0[disk])"); |
1398 | MODULE_PARM_DESC(scsi_level, "SCSI level to simulate(def=5[SPC-3])"); | 2184 | MODULE_PARM_DESC(scsi_level, "SCSI level to simulate(def=5[SPC-3])"); |
2185 | MODULE_PARM_DESC(virtual_gb, "virtual gigabyte size (def=0 -> use dev_size_mb)"); | ||
1399 | 2186 | ||
1400 | 2187 | ||
1401 | static char sdebug_info[256]; | 2188 | static char sdebug_info[256]; |
@@ -1547,6 +2334,24 @@ static ssize_t sdebug_dsense_store(struct device_driver * ddp, | |||
1547 | DRIVER_ATTR(dsense, S_IRUGO | S_IWUSR, sdebug_dsense_show, | 2334 | DRIVER_ATTR(dsense, S_IRUGO | S_IWUSR, sdebug_dsense_show, |
1548 | sdebug_dsense_store); | 2335 | sdebug_dsense_store); |
1549 | 2336 | ||
2337 | static ssize_t sdebug_no_lun_0_show(struct device_driver * ddp, char * buf) | ||
2338 | { | ||
2339 | return scnprintf(buf, PAGE_SIZE, "%d\n", scsi_debug_no_lun_0); | ||
2340 | } | ||
2341 | static ssize_t sdebug_no_lun_0_store(struct device_driver * ddp, | ||
2342 | const char * buf, size_t count) | ||
2343 | { | ||
2344 | int n; | ||
2345 | |||
2346 | if ((count > 0) && (1 == sscanf(buf, "%d", &n)) && (n >= 0)) { | ||
2347 | scsi_debug_no_lun_0 = n; | ||
2348 | return count; | ||
2349 | } | ||
2350 | return -EINVAL; | ||
2351 | } | ||
2352 | DRIVER_ATTR(no_lun_0, S_IRUGO | S_IWUSR, sdebug_no_lun_0_show, | ||
2353 | sdebug_no_lun_0_store); | ||
2354 | |||
1550 | static ssize_t sdebug_num_tgts_show(struct device_driver * ddp, char * buf) | 2355 | static ssize_t sdebug_num_tgts_show(struct device_driver * ddp, char * buf) |
1551 | { | 2356 | { |
1552 | return scnprintf(buf, PAGE_SIZE, "%d\n", scsi_debug_num_tgts); | 2357 | return scnprintf(buf, PAGE_SIZE, "%d\n", scsi_debug_num_tgts); |
@@ -1622,6 +2427,29 @@ static ssize_t sdebug_scsi_level_show(struct device_driver * ddp, char * buf) | |||
1622 | } | 2427 | } |
1623 | DRIVER_ATTR(scsi_level, S_IRUGO, sdebug_scsi_level_show, NULL); | 2428 | DRIVER_ATTR(scsi_level, S_IRUGO, sdebug_scsi_level_show, NULL); |
1624 | 2429 | ||
2430 | static ssize_t sdebug_virtual_gb_show(struct device_driver * ddp, char * buf) | ||
2431 | { | ||
2432 | return scnprintf(buf, PAGE_SIZE, "%d\n", scsi_debug_virtual_gb); | ||
2433 | } | ||
2434 | static ssize_t sdebug_virtual_gb_store(struct device_driver * ddp, | ||
2435 | const char * buf, size_t count) | ||
2436 | { | ||
2437 | int n; | ||
2438 | |||
2439 | if ((count > 0) && (1 == sscanf(buf, "%d", &n)) && (n >= 0)) { | ||
2440 | scsi_debug_virtual_gb = n; | ||
2441 | if (scsi_debug_virtual_gb > 0) { | ||
2442 | sdebug_capacity = 2048 * 1024; | ||
2443 | sdebug_capacity *= scsi_debug_virtual_gb; | ||
2444 | } else | ||
2445 | sdebug_capacity = sdebug_store_sectors; | ||
2446 | return count; | ||
2447 | } | ||
2448 | return -EINVAL; | ||
2449 | } | ||
2450 | DRIVER_ATTR(virtual_gb, S_IRUGO | S_IWUSR, sdebug_virtual_gb_show, | ||
2451 | sdebug_virtual_gb_store); | ||
2452 | |||
1625 | static ssize_t sdebug_add_host_show(struct device_driver * ddp, char * buf) | 2453 | static ssize_t sdebug_add_host_show(struct device_driver * ddp, char * buf) |
1626 | { | 2454 | { |
1627 | return scnprintf(buf, PAGE_SIZE, "%d\n", scsi_debug_add_host); | 2455 | return scnprintf(buf, PAGE_SIZE, "%d\n", scsi_debug_add_host); |
@@ -1691,14 +2519,19 @@ static void do_remove_driverfs_files(void) | |||
1691 | 2519 | ||
1692 | static int __init scsi_debug_init(void) | 2520 | static int __init scsi_debug_init(void) |
1693 | { | 2521 | { |
1694 | unsigned long sz; | 2522 | unsigned int sz; |
1695 | int host_to_add; | 2523 | int host_to_add; |
1696 | int k; | 2524 | int k; |
1697 | 2525 | ||
1698 | if (scsi_debug_dev_size_mb < 1) | 2526 | if (scsi_debug_dev_size_mb < 1) |
1699 | scsi_debug_dev_size_mb = 1; /* force minimum 1 MB ramdisk */ | 2527 | scsi_debug_dev_size_mb = 1; /* force minimum 1 MB ramdisk */ |
1700 | sdebug_store_size = (unsigned long)scsi_debug_dev_size_mb * 1048576; | 2528 | sdebug_store_size = (unsigned int)scsi_debug_dev_size_mb * 1048576; |
1701 | sdebug_capacity = sdebug_store_size / SECT_SIZE; | 2529 | sdebug_store_sectors = sdebug_store_size / SECT_SIZE; |
2530 | if (scsi_debug_virtual_gb > 0) { | ||
2531 | sdebug_capacity = 2048 * 1024; | ||
2532 | sdebug_capacity *= scsi_debug_virtual_gb; | ||
2533 | } else | ||
2534 | sdebug_capacity = sdebug_store_sectors; | ||
1702 | 2535 | ||
1703 | /* play around with geometry, don't waste too much on track 0 */ | 2536 | /* play around with geometry, don't waste too much on track 0 */ |
1704 | sdebug_heads = 8; | 2537 | sdebug_heads = 8; |
@@ -1812,7 +2645,7 @@ static int sdebug_add_adapter(void) | |||
1812 | struct sdebug_dev_info *sdbg_devinfo; | 2645 | struct sdebug_dev_info *sdbg_devinfo; |
1813 | struct list_head *lh, *lh_sf; | 2646 | struct list_head *lh, *lh_sf; |
1814 | 2647 | ||
1815 | sdbg_host = kzalloc(sizeof(*sdbg_host), GFP_KERNEL); | 2648 | sdbg_host = kzalloc(sizeof(*sdbg_host),GFP_KERNEL); |
1816 | 2649 | ||
1817 | if (NULL == sdbg_host) { | 2650 | if (NULL == sdbg_host) { |
1818 | printk(KERN_ERR "%s: out of memory at line %d\n", | 2651 | printk(KERN_ERR "%s: out of memory at line %d\n", |
@@ -1824,7 +2657,7 @@ static int sdebug_add_adapter(void) | |||
1824 | 2657 | ||
1825 | devs_per_host = scsi_debug_num_tgts * scsi_debug_max_luns; | 2658 | devs_per_host = scsi_debug_num_tgts * scsi_debug_max_luns; |
1826 | for (k = 0; k < devs_per_host; k++) { | 2659 | for (k = 0; k < devs_per_host; k++) { |
1827 | sdbg_devinfo = kzalloc(sizeof(*sdbg_devinfo), GFP_KERNEL); | 2660 | sdbg_devinfo = kzalloc(sizeof(*sdbg_devinfo),GFP_KERNEL); |
1828 | if (NULL == sdbg_devinfo) { | 2661 | if (NULL == sdbg_devinfo) { |
1829 | printk(KERN_ERR "%s: out of memory at line %d\n", | 2662 | printk(KERN_ERR "%s: out of memory at line %d\n", |
1830 | __FUNCTION__, __LINE__); | 2663 | __FUNCTION__, __LINE__); |
@@ -1905,7 +2738,7 @@ static int sdebug_driver_probe(struct device * dev) | |||
1905 | hpnt->max_id = scsi_debug_num_tgts + 1; | 2738 | hpnt->max_id = scsi_debug_num_tgts + 1; |
1906 | else | 2739 | else |
1907 | hpnt->max_id = scsi_debug_num_tgts; | 2740 | hpnt->max_id = scsi_debug_num_tgts; |
1908 | hpnt->max_lun = scsi_debug_max_luns; | 2741 | hpnt->max_lun = SAM2_WLUN_REPORT_LUNS; /* = scsi_debug_max_luns; */ |
1909 | 2742 | ||
1910 | error = scsi_add_host(hpnt, &sdbg_host->dev); | 2743 | error = scsi_add_host(hpnt, &sdbg_host->dev); |
1911 | if (error) { | 2744 | if (error) { |
@@ -1959,7 +2792,7 @@ static void sdebug_max_tgts_luns(void) | |||
1959 | hpnt->max_id = scsi_debug_num_tgts + 1; | 2792 | hpnt->max_id = scsi_debug_num_tgts + 1; |
1960 | else | 2793 | else |
1961 | hpnt->max_id = scsi_debug_num_tgts; | 2794 | hpnt->max_id = scsi_debug_num_tgts; |
1962 | hpnt->max_lun = scsi_debug_max_luns; | 2795 | hpnt->max_lun = SAM2_WLUN_REPORT_LUNS; /* scsi_debug_max_luns; */ |
1963 | } | 2796 | } |
1964 | spin_unlock(&sdebug_host_list_lock); | 2797 | spin_unlock(&sdebug_host_list_lock); |
1965 | } | 2798 | } |
diff --git a/drivers/scsi/scsi_devinfo.c b/drivers/scsi/scsi_devinfo.c index fb5cb4c9ac65..3d0429bc14ab 100644 --- a/drivers/scsi/scsi_devinfo.c +++ b/drivers/scsi/scsi_devinfo.c | |||
@@ -162,7 +162,7 @@ static struct { | |||
162 | {"HITACHI", "DISK-SUBSYSTEM", "*", BLIST_ATTACH_PQ3 | BLIST_SPARSELUN | BLIST_LARGELUN}, | 162 | {"HITACHI", "DISK-SUBSYSTEM", "*", BLIST_ATTACH_PQ3 | BLIST_SPARSELUN | BLIST_LARGELUN}, |
163 | {"HITACHI", "OPEN-E", "*", BLIST_ATTACH_PQ3 | BLIST_SPARSELUN | BLIST_LARGELUN}, | 163 | {"HITACHI", "OPEN-E", "*", BLIST_ATTACH_PQ3 | BLIST_SPARSELUN | BLIST_LARGELUN}, |
164 | {"HP", "A6189A", NULL, BLIST_SPARSELUN | BLIST_LARGELUN}, /* HP VA7400 */ | 164 | {"HP", "A6189A", NULL, BLIST_SPARSELUN | BLIST_LARGELUN}, /* HP VA7400 */ |
165 | {"HP", "OPEN-", "*", BLIST_SPARSELUN | BLIST_LARGELUN}, /* HP XP Arrays */ | 165 | {"HP", "OPEN-", "*", BLIST_REPORTLUN2}, /* HP XP Arrays */ |
166 | {"HP", "NetRAID-4M", NULL, BLIST_FORCELUN}, | 166 | {"HP", "NetRAID-4M", NULL, BLIST_FORCELUN}, |
167 | {"HP", "HSV100", NULL, BLIST_REPORTLUN2 | BLIST_NOSTARTONADD}, | 167 | {"HP", "HSV100", NULL, BLIST_REPORTLUN2 | BLIST_NOSTARTONADD}, |
168 | {"HP", "C1557A", NULL, BLIST_FORCELUN}, | 168 | {"HP", "C1557A", NULL, BLIST_FORCELUN}, |
diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c index 6a7a60fc0a4e..6683d596234a 100644 --- a/drivers/scsi/scsi_error.c +++ b/drivers/scsi/scsi_error.c | |||
@@ -1672,7 +1672,9 @@ int | |||
1672 | scsi_reset_provider(struct scsi_device *dev, int flag) | 1672 | scsi_reset_provider(struct scsi_device *dev, int flag) |
1673 | { | 1673 | { |
1674 | struct scsi_cmnd *scmd = scsi_get_command(dev, GFP_KERNEL); | 1674 | struct scsi_cmnd *scmd = scsi_get_command(dev, GFP_KERNEL); |
1675 | struct Scsi_Host *shost = dev->host; | ||
1675 | struct request req; | 1676 | struct request req; |
1677 | unsigned long flags; | ||
1676 | int rtn; | 1678 | int rtn; |
1677 | 1679 | ||
1678 | scmd->request = &req; | 1680 | scmd->request = &req; |
@@ -1699,6 +1701,10 @@ scsi_reset_provider(struct scsi_device *dev, int flag) | |||
1699 | */ | 1701 | */ |
1700 | scmd->pid = 0; | 1702 | scmd->pid = 0; |
1701 | 1703 | ||
1704 | spin_lock_irqsave(shost->host_lock, flags); | ||
1705 | shost->tmf_in_progress = 1; | ||
1706 | spin_unlock_irqrestore(shost->host_lock, flags); | ||
1707 | |||
1702 | switch (flag) { | 1708 | switch (flag) { |
1703 | case SCSI_TRY_RESET_DEVICE: | 1709 | case SCSI_TRY_RESET_DEVICE: |
1704 | rtn = scsi_try_bus_device_reset(scmd); | 1710 | rtn = scsi_try_bus_device_reset(scmd); |
@@ -1717,6 +1723,22 @@ scsi_reset_provider(struct scsi_device *dev, int flag) | |||
1717 | rtn = FAILED; | 1723 | rtn = FAILED; |
1718 | } | 1724 | } |
1719 | 1725 | ||
1726 | spin_lock_irqsave(shost->host_lock, flags); | ||
1727 | shost->tmf_in_progress = 0; | ||
1728 | spin_unlock_irqrestore(shost->host_lock, flags); | ||
1729 | |||
1730 | /* | ||
1731 | * be sure to wake up anyone who was sleeping or had their queue | ||
1732 | * suspended while we performed the TMF. | ||
1733 | */ | ||
1734 | SCSI_LOG_ERROR_RECOVERY(3, | ||
1735 | printk("%s: waking up host to restart after TMF\n", | ||
1736 | __FUNCTION__)); | ||
1737 | |||
1738 | wake_up(&shost->host_wait); | ||
1739 | |||
1740 | scsi_run_host_queues(shost); | ||
1741 | |||
1720 | scsi_next_command(scmd); | 1742 | scsi_next_command(scmd); |
1721 | return rtn; | 1743 | return rtn; |
1722 | } | 1744 | } |
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index 3d04a9f386ac..08af9aae7df3 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c | |||
@@ -855,8 +855,7 @@ static void scsi_release_buffers(struct scsi_cmnd *cmd) | |||
855 | * b) We can just use scsi_requeue_command() here. This would | 855 | * b) We can just use scsi_requeue_command() here. This would |
856 | * be used if we just wanted to retry, for example. | 856 | * be used if we just wanted to retry, for example. |
857 | */ | 857 | */ |
858 | void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes, | 858 | void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes) |
859 | unsigned int block_bytes) | ||
860 | { | 859 | { |
861 | int result = cmd->result; | 860 | int result = cmd->result; |
862 | int this_count = cmd->bufflen; | 861 | int this_count = cmd->bufflen; |
@@ -921,87 +920,70 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes, | |||
921 | * Next deal with any sectors which we were able to correctly | 920 | * Next deal with any sectors which we were able to correctly |
922 | * handle. | 921 | * handle. |
923 | */ | 922 | */ |
924 | if (good_bytes >= 0) { | 923 | SCSI_LOG_HLCOMPLETE(1, printk("%ld sectors total, " |
925 | SCSI_LOG_HLCOMPLETE(1, printk("%ld sectors total, %d bytes done.\n", | 924 | "%d bytes done.\n", |
926 | req->nr_sectors, good_bytes)); | 925 | req->nr_sectors, good_bytes)); |
927 | SCSI_LOG_HLCOMPLETE(1, printk("use_sg is %d\n", cmd->use_sg)); | 926 | SCSI_LOG_HLCOMPLETE(1, printk("use_sg is %d\n", cmd->use_sg)); |
928 | 927 | ||
929 | if (clear_errors) | 928 | if (clear_errors) |
930 | req->errors = 0; | 929 | req->errors = 0; |
931 | /* | ||
932 | * If multiple sectors are requested in one buffer, then | ||
933 | * they will have been finished off by the first command. | ||
934 | * If not, then we have a multi-buffer command. | ||
935 | * | ||
936 | * If block_bytes != 0, it means we had a medium error | ||
937 | * of some sort, and that we want to mark some number of | ||
938 | * sectors as not uptodate. Thus we want to inhibit | ||
939 | * requeueing right here - we will requeue down below | ||
940 | * when we handle the bad sectors. | ||
941 | */ | ||
942 | 930 | ||
943 | /* | 931 | /* A number of bytes were successfully read. If there |
944 | * If the command completed without error, then either | 932 | * are leftovers and there is some kind of error |
945 | * finish off the rest of the command, or start a new one. | 933 | * (result != 0), retry the rest. |
946 | */ | 934 | */ |
947 | if (scsi_end_request(cmd, 1, good_bytes, result == 0) == NULL) | 935 | if (scsi_end_request(cmd, 1, good_bytes, result == 0) == NULL) |
948 | return; | 936 | return; |
949 | } | 937 | |
950 | /* | 938 | /* good_bytes = 0, or (inclusive) there were leftovers and |
951 | * Now, if we were good little boys and girls, Santa left us a request | 939 | * result = 0, so scsi_end_request couldn't retry. |
952 | * sense buffer. We can extract information from this, so we | ||
953 | * can choose a block to remap, etc. | ||
954 | */ | 940 | */ |
955 | if (sense_valid && !sense_deferred) { | 941 | if (sense_valid && !sense_deferred) { |
956 | switch (sshdr.sense_key) { | 942 | switch (sshdr.sense_key) { |
957 | case UNIT_ATTENTION: | 943 | case UNIT_ATTENTION: |
958 | if (cmd->device->removable) { | 944 | if (cmd->device->removable) { |
959 | /* detected disc change. set a bit | 945 | /* Detected disc change. Set a bit |
960 | * and quietly refuse further access. | 946 | * and quietly refuse further access. |
961 | */ | 947 | */ |
962 | cmd->device->changed = 1; | 948 | cmd->device->changed = 1; |
963 | scsi_end_request(cmd, 0, | 949 | scsi_end_request(cmd, 0, this_count, 1); |
964 | this_count, 1); | ||
965 | return; | 950 | return; |
966 | } else { | 951 | } else { |
967 | /* | 952 | /* Must have been a power glitch, or a |
968 | * Must have been a power glitch, or a | 953 | * bus reset. Could not have been a |
969 | * bus reset. Could not have been a | 954 | * media change, so we just retry the |
970 | * media change, so we just retry the | 955 | * request and see what happens. |
971 | * request and see what happens. | 956 | */ |
972 | */ | ||
973 | scsi_requeue_command(q, cmd); | 957 | scsi_requeue_command(q, cmd); |
974 | return; | 958 | return; |
975 | } | 959 | } |
976 | break; | 960 | break; |
977 | case ILLEGAL_REQUEST: | 961 | case ILLEGAL_REQUEST: |
978 | /* | 962 | /* If we had an ILLEGAL REQUEST returned, then |
979 | * If we had an ILLEGAL REQUEST returned, then we may | 963 | * we may have performed an unsupported |
980 | * have performed an unsupported command. The only | 964 | * command. The only thing this should be |
981 | * thing this should be would be a ten byte read where | 965 | * would be a ten byte read where only a six |
982 | * only a six byte read was supported. Also, on a | 966 | * byte read was supported. Also, on a system |
983 | * system where READ CAPACITY failed, we may have read | 967 | * where READ CAPACITY failed, we may have |
984 | * past the end of the disk. | 968 | * read past the end of the disk. |
985 | */ | 969 | */ |
986 | if ((cmd->device->use_10_for_rw && | 970 | if ((cmd->device->use_10_for_rw && |
987 | sshdr.asc == 0x20 && sshdr.ascq == 0x00) && | 971 | sshdr.asc == 0x20 && sshdr.ascq == 0x00) && |
988 | (cmd->cmnd[0] == READ_10 || | 972 | (cmd->cmnd[0] == READ_10 || |
989 | cmd->cmnd[0] == WRITE_10)) { | 973 | cmd->cmnd[0] == WRITE_10)) { |
990 | cmd->device->use_10_for_rw = 0; | 974 | cmd->device->use_10_for_rw = 0; |
991 | /* | 975 | /* This will cause a retry with a |
992 | * This will cause a retry with a 6-byte | 976 | * 6-byte command. |
993 | * command. | ||
994 | */ | 977 | */ |
995 | scsi_requeue_command(q, cmd); | 978 | scsi_requeue_command(q, cmd); |
996 | result = 0; | 979 | return; |
997 | } else { | 980 | } else { |
998 | scsi_end_request(cmd, 0, this_count, 1); | 981 | scsi_end_request(cmd, 0, this_count, 1); |
999 | return; | 982 | return; |
1000 | } | 983 | } |
1001 | break; | 984 | break; |
1002 | case NOT_READY: | 985 | case NOT_READY: |
1003 | /* | 986 | /* If the device is in the process of becoming |
1004 | * If the device is in the process of becoming | ||
1005 | * ready, or has a temporary blockage, retry. | 987 | * ready, or has a temporary blockage, retry. |
1006 | */ | 988 | */ |
1007 | if (sshdr.asc == 0x04) { | 989 | if (sshdr.asc == 0x04) { |
@@ -1021,7 +1003,7 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes, | |||
1021 | } | 1003 | } |
1022 | if (!(req->flags & REQ_QUIET)) { | 1004 | if (!(req->flags & REQ_QUIET)) { |
1023 | scmd_printk(KERN_INFO, cmd, | 1005 | scmd_printk(KERN_INFO, cmd, |
1024 | "Device not ready: "); | 1006 | "Device not ready: "); |
1025 | scsi_print_sense_hdr("", &sshdr); | 1007 | scsi_print_sense_hdr("", &sshdr); |
1026 | } | 1008 | } |
1027 | scsi_end_request(cmd, 0, this_count, 1); | 1009 | scsi_end_request(cmd, 0, this_count, 1); |
@@ -1029,21 +1011,21 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes, | |||
1029 | case VOLUME_OVERFLOW: | 1011 | case VOLUME_OVERFLOW: |
1030 | if (!(req->flags & REQ_QUIET)) { | 1012 | if (!(req->flags & REQ_QUIET)) { |
1031 | scmd_printk(KERN_INFO, cmd, | 1013 | scmd_printk(KERN_INFO, cmd, |
1032 | "Volume overflow, CDB: "); | 1014 | "Volume overflow, CDB: "); |
1033 | __scsi_print_command(cmd->data_cmnd); | 1015 | __scsi_print_command(cmd->data_cmnd); |
1034 | scsi_print_sense("", cmd); | 1016 | scsi_print_sense("", cmd); |
1035 | } | 1017 | } |
1036 | scsi_end_request(cmd, 0, block_bytes, 1); | 1018 | /* See SSC3rXX or current. */ |
1019 | scsi_end_request(cmd, 0, this_count, 1); | ||
1037 | return; | 1020 | return; |
1038 | default: | 1021 | default: |
1039 | break; | 1022 | break; |
1040 | } | 1023 | } |
1041 | } /* driver byte != 0 */ | 1024 | } |
1042 | if (host_byte(result) == DID_RESET) { | 1025 | if (host_byte(result) == DID_RESET) { |
1043 | /* | 1026 | /* Third party bus reset or reset for error recovery |
1044 | * Third party bus reset or reset for error | 1027 | * reasons. Just retry the request and see what |
1045 | * recovery reasons. Just retry the request | 1028 | * happens. |
1046 | * and see what happens. | ||
1047 | */ | 1029 | */ |
1048 | scsi_requeue_command(q, cmd); | 1030 | scsi_requeue_command(q, cmd); |
1049 | return; | 1031 | return; |
@@ -1051,21 +1033,13 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes, | |||
1051 | if (result) { | 1033 | if (result) { |
1052 | if (!(req->flags & REQ_QUIET)) { | 1034 | if (!(req->flags & REQ_QUIET)) { |
1053 | scmd_printk(KERN_INFO, cmd, | 1035 | scmd_printk(KERN_INFO, cmd, |
1054 | "SCSI error: return code = 0x%x\n", result); | 1036 | "SCSI error: return code = 0x%08x\n", |
1055 | 1037 | result); | |
1056 | if (driver_byte(result) & DRIVER_SENSE) | 1038 | if (driver_byte(result) & DRIVER_SENSE) |
1057 | scsi_print_sense("", cmd); | 1039 | scsi_print_sense("", cmd); |
1058 | } | 1040 | } |
1059 | /* | ||
1060 | * Mark a single buffer as not uptodate. Queue the remainder. | ||
1061 | * We sometimes get this cruft in the event that a medium error | ||
1062 | * isn't properly reported. | ||
1063 | */ | ||
1064 | block_bytes = req->hard_cur_sectors << 9; | ||
1065 | if (!block_bytes) | ||
1066 | block_bytes = req->data_len; | ||
1067 | scsi_end_request(cmd, 0, block_bytes, 1); | ||
1068 | } | 1041 | } |
1042 | scsi_end_request(cmd, 0, this_count, !result); | ||
1069 | } | 1043 | } |
1070 | EXPORT_SYMBOL(scsi_io_completion); | 1044 | EXPORT_SYMBOL(scsi_io_completion); |
1071 | 1045 | ||
@@ -1169,7 +1143,7 @@ static void scsi_blk_pc_done(struct scsi_cmnd *cmd) | |||
1169 | * successfully. Since this is a REQ_BLOCK_PC command the | 1143 | * successfully. Since this is a REQ_BLOCK_PC command the |
1170 | * caller should check the request's errors value | 1144 | * caller should check the request's errors value |
1171 | */ | 1145 | */ |
1172 | scsi_io_completion(cmd, cmd->bufflen, 0); | 1146 | scsi_io_completion(cmd, cmd->bufflen); |
1173 | } | 1147 | } |
1174 | 1148 | ||
1175 | static void scsi_setup_blk_pc_cmnd(struct scsi_cmnd *cmd) | 1149 | static void scsi_setup_blk_pc_cmnd(struct scsi_cmnd *cmd) |
@@ -2050,6 +2024,7 @@ scsi_device_set_state(struct scsi_device *sdev, enum scsi_device_state state) | |||
2050 | switch (oldstate) { | 2024 | switch (oldstate) { |
2051 | case SDEV_CREATED: | 2025 | case SDEV_CREATED: |
2052 | case SDEV_RUNNING: | 2026 | case SDEV_RUNNING: |
2027 | case SDEV_QUIESCE: | ||
2053 | case SDEV_OFFLINE: | 2028 | case SDEV_OFFLINE: |
2054 | case SDEV_BLOCK: | 2029 | case SDEV_BLOCK: |
2055 | break; | 2030 | break; |
@@ -2060,6 +2035,9 @@ scsi_device_set_state(struct scsi_device *sdev, enum scsi_device_state state) | |||
2060 | 2035 | ||
2061 | case SDEV_DEL: | 2036 | case SDEV_DEL: |
2062 | switch (oldstate) { | 2037 | switch (oldstate) { |
2038 | case SDEV_CREATED: | ||
2039 | case SDEV_RUNNING: | ||
2040 | case SDEV_OFFLINE: | ||
2063 | case SDEV_CANCEL: | 2041 | case SDEV_CANCEL: |
2064 | break; | 2042 | break; |
2065 | default: | 2043 | default: |
diff --git a/drivers/scsi/scsi_priv.h b/drivers/scsi/scsi_priv.h index 015c90cf3abc..e2fbe9a9d5a9 100644 --- a/drivers/scsi/scsi_priv.h +++ b/drivers/scsi/scsi_priv.h | |||
@@ -116,7 +116,7 @@ extern struct bus_type scsi_bus_type; | |||
116 | * classes. | 116 | * classes. |
117 | */ | 117 | */ |
118 | 118 | ||
119 | #define SCSI_DEVICE_BLOCK_MAX_TIMEOUT (HZ*60) | 119 | #define SCSI_DEVICE_BLOCK_MAX_TIMEOUT 600 /* units in seconds */ |
120 | extern int scsi_internal_device_block(struct scsi_device *sdev); | 120 | extern int scsi_internal_device_block(struct scsi_device *sdev); |
121 | extern int scsi_internal_device_unblock(struct scsi_device *sdev); | 121 | extern int scsi_internal_device_unblock(struct scsi_device *sdev); |
122 | 122 | ||
diff --git a/drivers/scsi/scsi_sas_internal.h b/drivers/scsi/scsi_sas_internal.h index d76e6e3d8ca5..e1edab45a37b 100644 --- a/drivers/scsi/scsi_sas_internal.h +++ b/drivers/scsi/scsi_sas_internal.h | |||
@@ -2,7 +2,8 @@ | |||
2 | #define _SCSI_SAS_INTERNAL_H | 2 | #define _SCSI_SAS_INTERNAL_H |
3 | 3 | ||
4 | #define SAS_HOST_ATTRS 0 | 4 | #define SAS_HOST_ATTRS 0 |
5 | #define SAS_PORT_ATTRS 17 | 5 | #define SAS_PHY_ATTRS 17 |
6 | #define SAS_PORT_ATTRS 1 | ||
6 | #define SAS_RPORT_ATTRS 7 | 7 | #define SAS_RPORT_ATTRS 7 |
7 | #define SAS_END_DEV_ATTRS 3 | 8 | #define SAS_END_DEV_ATTRS 3 |
8 | #define SAS_EXPANDER_ATTRS 7 | 9 | #define SAS_EXPANDER_ATTRS 7 |
@@ -13,12 +14,14 @@ struct sas_internal { | |||
13 | struct sas_domain_function_template *dft; | 14 | struct sas_domain_function_template *dft; |
14 | 15 | ||
15 | struct class_device_attribute private_host_attrs[SAS_HOST_ATTRS]; | 16 | struct class_device_attribute private_host_attrs[SAS_HOST_ATTRS]; |
16 | struct class_device_attribute private_phy_attrs[SAS_PORT_ATTRS]; | 17 | struct class_device_attribute private_phy_attrs[SAS_PHY_ATTRS]; |
18 | struct class_device_attribute private_port_attrs[SAS_PORT_ATTRS]; | ||
17 | struct class_device_attribute private_rphy_attrs[SAS_RPORT_ATTRS]; | 19 | struct class_device_attribute private_rphy_attrs[SAS_RPORT_ATTRS]; |
18 | struct class_device_attribute private_end_dev_attrs[SAS_END_DEV_ATTRS]; | 20 | struct class_device_attribute private_end_dev_attrs[SAS_END_DEV_ATTRS]; |
19 | struct class_device_attribute private_expander_attrs[SAS_EXPANDER_ATTRS]; | 21 | struct class_device_attribute private_expander_attrs[SAS_EXPANDER_ATTRS]; |
20 | 22 | ||
21 | struct transport_container phy_attr_cont; | 23 | struct transport_container phy_attr_cont; |
24 | struct transport_container port_attr_cont; | ||
22 | struct transport_container rphy_attr_cont; | 25 | struct transport_container rphy_attr_cont; |
23 | struct transport_container end_dev_attr_cont; | 26 | struct transport_container end_dev_attr_cont; |
24 | struct transport_container expander_attr_cont; | 27 | struct transport_container expander_attr_cont; |
@@ -28,7 +31,8 @@ struct sas_internal { | |||
28 | * needed by scsi_sysfs.c | 31 | * needed by scsi_sysfs.c |
29 | */ | 32 | */ |
30 | struct class_device_attribute *host_attrs[SAS_HOST_ATTRS + 1]; | 33 | struct class_device_attribute *host_attrs[SAS_HOST_ATTRS + 1]; |
31 | struct class_device_attribute *phy_attrs[SAS_PORT_ATTRS + 1]; | 34 | struct class_device_attribute *phy_attrs[SAS_PHY_ATTRS + 1]; |
35 | struct class_device_attribute *port_attrs[SAS_PORT_ATTRS + 1]; | ||
32 | struct class_device_attribute *rphy_attrs[SAS_RPORT_ATTRS + 1]; | 36 | struct class_device_attribute *rphy_attrs[SAS_RPORT_ATTRS + 1]; |
33 | struct class_device_attribute *end_dev_attrs[SAS_END_DEV_ATTRS + 1]; | 37 | struct class_device_attribute *end_dev_attrs[SAS_END_DEV_ATTRS + 1]; |
34 | struct class_device_attribute *expander_attrs[SAS_EXPANDER_ATTRS + 1]; | 38 | struct class_device_attribute *expander_attrs[SAS_EXPANDER_ATTRS + 1]; |
diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c index 1341608e9e3b..1bd92b9b46d9 100644 --- a/drivers/scsi/scsi_scan.c +++ b/drivers/scsi/scsi_scan.c | |||
@@ -809,6 +809,7 @@ static int scsi_add_lun(struct scsi_device *sdev, char *inq_result, int *bflags) | |||
809 | 809 | ||
810 | static inline void scsi_destroy_sdev(struct scsi_device *sdev) | 810 | static inline void scsi_destroy_sdev(struct scsi_device *sdev) |
811 | { | 811 | { |
812 | scsi_device_set_state(sdev, SDEV_DEL); | ||
812 | if (sdev->host->hostt->slave_destroy) | 813 | if (sdev->host->hostt->slave_destroy) |
813 | sdev->host->hostt->slave_destroy(sdev); | 814 | sdev->host->hostt->slave_destroy(sdev); |
814 | transport_destroy_device(&sdev->sdev_gendev); | 815 | transport_destroy_device(&sdev->sdev_gendev); |
diff --git a/drivers/scsi/scsi_transport_fc.c b/drivers/scsi/scsi_transport_fc.c index f2db7a41cf1d..b03aa85108e5 100644 --- a/drivers/scsi/scsi_transport_fc.c +++ b/drivers/scsi/scsi_transport_fc.c | |||
@@ -368,7 +368,7 @@ static DECLARE_TRANSPORT_CLASS(fc_rport_class, | |||
368 | * should insulate the loss of a remote port. | 368 | * should insulate the loss of a remote port. |
369 | * The maximum will be capped by the value of SCSI_DEVICE_BLOCK_MAX_TIMEOUT. | 369 | * The maximum will be capped by the value of SCSI_DEVICE_BLOCK_MAX_TIMEOUT. |
370 | */ | 370 | */ |
371 | static unsigned int fc_dev_loss_tmo = SCSI_DEVICE_BLOCK_MAX_TIMEOUT; | 371 | static unsigned int fc_dev_loss_tmo = 60; /* seconds */ |
372 | 372 | ||
373 | module_param_named(dev_loss_tmo, fc_dev_loss_tmo, int, S_IRUGO|S_IWUSR); | 373 | module_param_named(dev_loss_tmo, fc_dev_loss_tmo, int, S_IRUGO|S_IWUSR); |
374 | MODULE_PARM_DESC(dev_loss_tmo, | 374 | MODULE_PARM_DESC(dev_loss_tmo, |
@@ -1284,7 +1284,9 @@ EXPORT_SYMBOL(fc_release_transport); | |||
1284 | * @work: Work to queue for execution. | 1284 | * @work: Work to queue for execution. |
1285 | * | 1285 | * |
1286 | * Return value: | 1286 | * Return value: |
1287 | * 0 on success / != 0 for error | 1287 | * 1 - work queued for execution |
1288 | * 0 - work is already queued | ||
1289 | * -EINVAL - work queue doesn't exist | ||
1288 | **/ | 1290 | **/ |
1289 | static int | 1291 | static int |
1290 | fc_queue_work(struct Scsi_Host *shost, struct work_struct *work) | 1292 | fc_queue_work(struct Scsi_Host *shost, struct work_struct *work) |
@@ -1434,8 +1436,6 @@ fc_starget_delete(void *data) | |||
1434 | struct Scsi_Host *shost = rport_to_shost(rport); | 1436 | struct Scsi_Host *shost = rport_to_shost(rport); |
1435 | unsigned long flags; | 1437 | unsigned long flags; |
1436 | 1438 | ||
1437 | scsi_target_unblock(&rport->dev); | ||
1438 | |||
1439 | spin_lock_irqsave(shost->host_lock, flags); | 1439 | spin_lock_irqsave(shost->host_lock, flags); |
1440 | if (rport->flags & FC_RPORT_DEVLOSS_PENDING) { | 1440 | if (rport->flags & FC_RPORT_DEVLOSS_PENDING) { |
1441 | spin_unlock_irqrestore(shost->host_lock, flags); | 1441 | spin_unlock_irqrestore(shost->host_lock, flags); |
@@ -1476,7 +1476,8 @@ fc_rport_final_delete(void *data) | |||
1476 | transport_remove_device(dev); | 1476 | transport_remove_device(dev); |
1477 | device_del(dev); | 1477 | device_del(dev); |
1478 | transport_destroy_device(dev); | 1478 | transport_destroy_device(dev); |
1479 | put_device(&shost->shost_gendev); | 1479 | put_device(&shost->shost_gendev); /* for fc_host->rport list */ |
1480 | put_device(dev); /* for self-reference */ | ||
1480 | } | 1481 | } |
1481 | 1482 | ||
1482 | 1483 | ||
@@ -1537,13 +1538,13 @@ fc_rport_create(struct Scsi_Host *shost, int channel, | |||
1537 | else | 1538 | else |
1538 | rport->scsi_target_id = -1; | 1539 | rport->scsi_target_id = -1; |
1539 | list_add_tail(&rport->peers, &fc_host->rports); | 1540 | list_add_tail(&rport->peers, &fc_host->rports); |
1540 | get_device(&shost->shost_gendev); | 1541 | get_device(&shost->shost_gendev); /* for fc_host->rport list */ |
1541 | 1542 | ||
1542 | spin_unlock_irqrestore(shost->host_lock, flags); | 1543 | spin_unlock_irqrestore(shost->host_lock, flags); |
1543 | 1544 | ||
1544 | dev = &rport->dev; | 1545 | dev = &rport->dev; |
1545 | device_initialize(dev); | 1546 | device_initialize(dev); /* takes self reference */ |
1546 | dev->parent = get_device(&shost->shost_gendev); | 1547 | dev->parent = get_device(&shost->shost_gendev); /* parent reference */ |
1547 | dev->release = fc_rport_dev_release; | 1548 | dev->release = fc_rport_dev_release; |
1548 | sprintf(dev->bus_id, "rport-%d:%d-%d", | 1549 | sprintf(dev->bus_id, "rport-%d:%d-%d", |
1549 | shost->host_no, channel, rport->number); | 1550 | shost->host_no, channel, rport->number); |
@@ -1567,10 +1568,9 @@ fc_rport_create(struct Scsi_Host *shost, int channel, | |||
1567 | 1568 | ||
1568 | delete_rport: | 1569 | delete_rport: |
1569 | transport_destroy_device(dev); | 1570 | transport_destroy_device(dev); |
1570 | put_device(dev->parent); | ||
1571 | spin_lock_irqsave(shost->host_lock, flags); | 1571 | spin_lock_irqsave(shost->host_lock, flags); |
1572 | list_del(&rport->peers); | 1572 | list_del(&rport->peers); |
1573 | put_device(&shost->shost_gendev); | 1573 | put_device(&shost->shost_gendev); /* for fc_host->rport list */ |
1574 | spin_unlock_irqrestore(shost->host_lock, flags); | 1574 | spin_unlock_irqrestore(shost->host_lock, flags); |
1575 | put_device(dev->parent); | 1575 | put_device(dev->parent); |
1576 | kfree(rport); | 1576 | kfree(rport); |
@@ -1707,6 +1707,8 @@ fc_remote_port_add(struct Scsi_Host *shost, int channel, | |||
1707 | 1707 | ||
1708 | spin_unlock_irqrestore(shost->host_lock, flags); | 1708 | spin_unlock_irqrestore(shost->host_lock, flags); |
1709 | 1709 | ||
1710 | scsi_target_unblock(&rport->dev); | ||
1711 | |||
1710 | return rport; | 1712 | return rport; |
1711 | } | 1713 | } |
1712 | } | 1714 | } |
@@ -1762,9 +1764,10 @@ fc_remote_port_add(struct Scsi_Host *shost, int channel, | |||
1762 | /* initiate a scan of the target */ | 1764 | /* initiate a scan of the target */ |
1763 | rport->flags |= FC_RPORT_SCAN_PENDING; | 1765 | rport->flags |= FC_RPORT_SCAN_PENDING; |
1764 | scsi_queue_work(shost, &rport->scan_work); | 1766 | scsi_queue_work(shost, &rport->scan_work); |
1765 | } | 1767 | spin_unlock_irqrestore(shost->host_lock, flags); |
1766 | 1768 | scsi_target_unblock(&rport->dev); | |
1767 | spin_unlock_irqrestore(shost->host_lock, flags); | 1769 | } else |
1770 | spin_unlock_irqrestore(shost->host_lock, flags); | ||
1768 | 1771 | ||
1769 | return rport; | 1772 | return rport; |
1770 | } | 1773 | } |
@@ -1938,6 +1941,7 @@ fc_remote_port_rolechg(struct fc_rport *rport, u32 roles) | |||
1938 | rport->flags |= FC_RPORT_SCAN_PENDING; | 1941 | rport->flags |= FC_RPORT_SCAN_PENDING; |
1939 | scsi_queue_work(shost, &rport->scan_work); | 1942 | scsi_queue_work(shost, &rport->scan_work); |
1940 | spin_unlock_irqrestore(shost->host_lock, flags); | 1943 | spin_unlock_irqrestore(shost->host_lock, flags); |
1944 | scsi_target_unblock(&rport->dev); | ||
1941 | } | 1945 | } |
1942 | } | 1946 | } |
1943 | EXPORT_SYMBOL(fc_remote_port_rolechg); | 1947 | EXPORT_SYMBOL(fc_remote_port_rolechg); |
@@ -1970,8 +1974,9 @@ fc_timeout_deleted_rport(void *data) | |||
1970 | dev_printk(KERN_ERR, &rport->dev, | 1974 | dev_printk(KERN_ERR, &rport->dev, |
1971 | "blocked FC remote port time out: no longer" | 1975 | "blocked FC remote port time out: no longer" |
1972 | " a FCP target, removing starget\n"); | 1976 | " a FCP target, removing starget\n"); |
1973 | fc_queue_work(shost, &rport->stgt_delete_work); | ||
1974 | spin_unlock_irqrestore(shost->host_lock, flags); | 1977 | spin_unlock_irqrestore(shost->host_lock, flags); |
1978 | scsi_target_unblock(&rport->dev); | ||
1979 | fc_queue_work(shost, &rport->stgt_delete_work); | ||
1975 | return; | 1980 | return; |
1976 | } | 1981 | } |
1977 | 1982 | ||
@@ -2035,17 +2040,15 @@ fc_timeout_deleted_rport(void *data) | |||
2035 | * went away and didn't come back - we'll remove | 2040 | * went away and didn't come back - we'll remove |
2036 | * all attached scsi devices. | 2041 | * all attached scsi devices. |
2037 | */ | 2042 | */ |
2038 | fc_queue_work(shost, &rport->stgt_delete_work); | ||
2039 | |||
2040 | spin_unlock_irqrestore(shost->host_lock, flags); | 2043 | spin_unlock_irqrestore(shost->host_lock, flags); |
2044 | |||
2045 | scsi_target_unblock(&rport->dev); | ||
2046 | fc_queue_work(shost, &rport->stgt_delete_work); | ||
2041 | } | 2047 | } |
2042 | 2048 | ||
2043 | /** | 2049 | /** |
2044 | * fc_scsi_scan_rport - called to perform a scsi scan on a remote port. | 2050 | * fc_scsi_scan_rport - called to perform a scsi scan on a remote port. |
2045 | * | 2051 | * |
2046 | * Will unblock the target (in case it went away and has now come back), | ||
2047 | * then invoke a scan. | ||
2048 | * | ||
2049 | * @data: remote port to be scanned. | 2052 | * @data: remote port to be scanned. |
2050 | **/ | 2053 | **/ |
2051 | static void | 2054 | static void |
@@ -2057,7 +2060,6 @@ fc_scsi_scan_rport(void *data) | |||
2057 | 2060 | ||
2058 | if ((rport->port_state == FC_PORTSTATE_ONLINE) && | 2061 | if ((rport->port_state == FC_PORTSTATE_ONLINE) && |
2059 | (rport->roles & FC_RPORT_ROLE_FCP_TARGET)) { | 2062 | (rport->roles & FC_RPORT_ROLE_FCP_TARGET)) { |
2060 | scsi_target_unblock(&rport->dev); | ||
2061 | scsi_scan_target(&rport->dev, rport->channel, | 2063 | scsi_scan_target(&rport->dev, rport->channel, |
2062 | rport->scsi_target_id, SCAN_WILD_CARD, 1); | 2064 | rport->scsi_target_id, SCAN_WILD_CARD, 1); |
2063 | } | 2065 | } |
diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c index 5569fdcfd621..7b9e8fa1a4e0 100644 --- a/drivers/scsi/scsi_transport_iscsi.c +++ b/drivers/scsi/scsi_transport_iscsi.c | |||
@@ -228,14 +228,11 @@ static struct iscsi_cls_conn *iscsi_conn_lookup(uint32_t sid, uint32_t cid) | |||
228 | static void iscsi_session_release(struct device *dev) | 228 | static void iscsi_session_release(struct device *dev) |
229 | { | 229 | { |
230 | struct iscsi_cls_session *session = iscsi_dev_to_session(dev); | 230 | struct iscsi_cls_session *session = iscsi_dev_to_session(dev); |
231 | struct iscsi_transport *transport = session->transport; | ||
232 | struct Scsi_Host *shost; | 231 | struct Scsi_Host *shost; |
233 | 232 | ||
234 | shost = iscsi_session_to_shost(session); | 233 | shost = iscsi_session_to_shost(session); |
235 | scsi_host_put(shost); | 234 | scsi_host_put(shost); |
236 | kfree(session->targetname); | ||
237 | kfree(session); | 235 | kfree(session); |
238 | module_put(transport->owner); | ||
239 | } | 236 | } |
240 | 237 | ||
241 | static int iscsi_is_session_dev(const struct device *dev) | 238 | static int iscsi_is_session_dev(const struct device *dev) |
@@ -251,10 +248,9 @@ static int iscsi_user_scan(struct Scsi_Host *shost, uint channel, | |||
251 | 248 | ||
252 | mutex_lock(&ihost->mutex); | 249 | mutex_lock(&ihost->mutex); |
253 | list_for_each_entry(session, &ihost->sessions, host_list) { | 250 | list_for_each_entry(session, &ihost->sessions, host_list) { |
254 | if ((channel == SCAN_WILD_CARD || | 251 | if ((channel == SCAN_WILD_CARD || channel == 0) && |
255 | channel == session->channel) && | ||
256 | (id == SCAN_WILD_CARD || id == session->target_id)) | 252 | (id == SCAN_WILD_CARD || id == session->target_id)) |
257 | scsi_scan_target(&session->dev, session->channel, | 253 | scsi_scan_target(&session->dev, 0, |
258 | session->target_id, lun, 1); | 254 | session->target_id, lun, 1); |
259 | } | 255 | } |
260 | mutex_unlock(&ihost->mutex); | 256 | mutex_unlock(&ihost->mutex); |
@@ -291,80 +287,92 @@ void iscsi_block_session(struct iscsi_cls_session *session) | |||
291 | } | 287 | } |
292 | EXPORT_SYMBOL_GPL(iscsi_block_session); | 288 | EXPORT_SYMBOL_GPL(iscsi_block_session); |
293 | 289 | ||
294 | /** | ||
295 | * iscsi_create_session - create iscsi class session | ||
296 | * @shost: scsi host | ||
297 | * @transport: iscsi transport | ||
298 | * | ||
299 | * This can be called from a LLD or iscsi_transport. | ||
300 | **/ | ||
301 | struct iscsi_cls_session * | 290 | struct iscsi_cls_session * |
302 | iscsi_create_session(struct Scsi_Host *shost, | 291 | iscsi_alloc_session(struct Scsi_Host *shost, |
303 | struct iscsi_transport *transport, int channel) | 292 | struct iscsi_transport *transport) |
304 | { | 293 | { |
305 | struct iscsi_host *ihost; | ||
306 | struct iscsi_cls_session *session; | 294 | struct iscsi_cls_session *session; |
307 | int err; | ||
308 | |||
309 | if (!try_module_get(transport->owner)) | ||
310 | return NULL; | ||
311 | 295 | ||
312 | session = kzalloc(sizeof(*session) + transport->sessiondata_size, | 296 | session = kzalloc(sizeof(*session) + transport->sessiondata_size, |
313 | GFP_KERNEL); | 297 | GFP_KERNEL); |
314 | if (!session) | 298 | if (!session) |
315 | goto module_put; | 299 | return NULL; |
300 | |||
316 | session->transport = transport; | 301 | session->transport = transport; |
317 | session->recovery_tmo = 120; | 302 | session->recovery_tmo = 120; |
318 | INIT_WORK(&session->recovery_work, session_recovery_timedout, session); | 303 | INIT_WORK(&session->recovery_work, session_recovery_timedout, session); |
319 | INIT_LIST_HEAD(&session->host_list); | 304 | INIT_LIST_HEAD(&session->host_list); |
320 | INIT_LIST_HEAD(&session->sess_list); | 305 | INIT_LIST_HEAD(&session->sess_list); |
321 | 306 | ||
307 | /* this is released in the dev's release function */ | ||
308 | scsi_host_get(shost); | ||
309 | session->dev.parent = &shost->shost_gendev; | ||
310 | session->dev.release = iscsi_session_release; | ||
311 | device_initialize(&session->dev); | ||
322 | if (transport->sessiondata_size) | 312 | if (transport->sessiondata_size) |
323 | session->dd_data = &session[1]; | 313 | session->dd_data = &session[1]; |
314 | return session; | ||
315 | } | ||
316 | EXPORT_SYMBOL_GPL(iscsi_alloc_session); | ||
324 | 317 | ||
325 | /* this is released in the dev's release function */ | 318 | int iscsi_add_session(struct iscsi_cls_session *session, unsigned int target_id) |
326 | scsi_host_get(shost); | 319 | { |
327 | ihost = shost->shost_data; | 320 | struct Scsi_Host *shost = iscsi_session_to_shost(session); |
321 | struct iscsi_host *ihost; | ||
322 | int err; | ||
328 | 323 | ||
324 | ihost = shost->shost_data; | ||
329 | session->sid = iscsi_session_nr++; | 325 | session->sid = iscsi_session_nr++; |
330 | session->channel = channel; | 326 | session->target_id = target_id; |
331 | session->target_id = ihost->next_target_id++; | ||
332 | 327 | ||
333 | snprintf(session->dev.bus_id, BUS_ID_SIZE, "session%u", | 328 | snprintf(session->dev.bus_id, BUS_ID_SIZE, "session%u", |
334 | session->sid); | 329 | session->sid); |
335 | session->dev.parent = &shost->shost_gendev; | 330 | err = device_add(&session->dev); |
336 | session->dev.release = iscsi_session_release; | ||
337 | err = device_register(&session->dev); | ||
338 | if (err) { | 331 | if (err) { |
339 | dev_printk(KERN_ERR, &session->dev, "iscsi: could not " | 332 | dev_printk(KERN_ERR, &session->dev, "iscsi: could not " |
340 | "register session's dev\n"); | 333 | "register session's dev\n"); |
341 | goto free_session; | 334 | goto release_host; |
342 | } | 335 | } |
343 | transport_register_device(&session->dev); | 336 | transport_register_device(&session->dev); |
344 | 337 | ||
345 | mutex_lock(&ihost->mutex); | 338 | mutex_lock(&ihost->mutex); |
346 | list_add(&session->host_list, &ihost->sessions); | 339 | list_add(&session->host_list, &ihost->sessions); |
347 | mutex_unlock(&ihost->mutex); | 340 | mutex_unlock(&ihost->mutex); |
341 | return 0; | ||
348 | 342 | ||
349 | return session; | 343 | release_host: |
350 | 344 | scsi_host_put(shost); | |
351 | free_session: | 345 | return err; |
352 | kfree(session); | ||
353 | module_put: | ||
354 | module_put(transport->owner); | ||
355 | return NULL; | ||
356 | } | 346 | } |
357 | 347 | EXPORT_SYMBOL_GPL(iscsi_add_session); | |
358 | EXPORT_SYMBOL_GPL(iscsi_create_session); | ||
359 | 348 | ||
360 | /** | 349 | /** |
361 | * iscsi_destroy_session - destroy iscsi session | 350 | * iscsi_create_session - create iscsi class session |
362 | * @session: iscsi_session | 351 | * @shost: scsi host |
352 | * @transport: iscsi transport | ||
363 | * | 353 | * |
364 | * Can be called by a LLD or iscsi_transport. There must not be | 354 | * This can be called from a LLD or iscsi_transport. |
365 | * any running connections. | ||
366 | **/ | 355 | **/ |
367 | int iscsi_destroy_session(struct iscsi_cls_session *session) | 356 | struct iscsi_cls_session * |
357 | iscsi_create_session(struct Scsi_Host *shost, | ||
358 | struct iscsi_transport *transport, | ||
359 | unsigned int target_id) | ||
360 | { | ||
361 | struct iscsi_cls_session *session; | ||
362 | |||
363 | session = iscsi_alloc_session(shost, transport); | ||
364 | if (!session) | ||
365 | return NULL; | ||
366 | |||
367 | if (iscsi_add_session(session, target_id)) { | ||
368 | iscsi_free_session(session); | ||
369 | return NULL; | ||
370 | } | ||
371 | return session; | ||
372 | } | ||
373 | EXPORT_SYMBOL_GPL(iscsi_create_session); | ||
374 | |||
375 | void iscsi_remove_session(struct iscsi_cls_session *session) | ||
368 | { | 376 | { |
369 | struct Scsi_Host *shost = iscsi_session_to_shost(session); | 377 | struct Scsi_Host *shost = iscsi_session_to_shost(session); |
370 | struct iscsi_host *ihost = shost->shost_data; | 378 | struct iscsi_host *ihost = shost->shost_data; |
@@ -376,19 +384,88 @@ int iscsi_destroy_session(struct iscsi_cls_session *session) | |||
376 | list_del(&session->host_list); | 384 | list_del(&session->host_list); |
377 | mutex_unlock(&ihost->mutex); | 385 | mutex_unlock(&ihost->mutex); |
378 | 386 | ||
387 | scsi_remove_target(&session->dev); | ||
388 | |||
379 | transport_unregister_device(&session->dev); | 389 | transport_unregister_device(&session->dev); |
380 | device_unregister(&session->dev); | 390 | device_del(&session->dev); |
381 | return 0; | 391 | } |
392 | EXPORT_SYMBOL_GPL(iscsi_remove_session); | ||
393 | |||
394 | void iscsi_free_session(struct iscsi_cls_session *session) | ||
395 | { | ||
396 | put_device(&session->dev); | ||
382 | } | 397 | } |
383 | 398 | ||
399 | EXPORT_SYMBOL_GPL(iscsi_free_session); | ||
400 | |||
401 | /** | ||
402 | * iscsi_destroy_session - destroy iscsi session | ||
403 | * @session: iscsi_session | ||
404 | * | ||
405 | * Can be called by a LLD or iscsi_transport. There must not be | ||
406 | * any running connections. | ||
407 | **/ | ||
408 | int iscsi_destroy_session(struct iscsi_cls_session *session) | ||
409 | { | ||
410 | iscsi_remove_session(session); | ||
411 | iscsi_free_session(session); | ||
412 | return 0; | ||
413 | } | ||
384 | EXPORT_SYMBOL_GPL(iscsi_destroy_session); | 414 | EXPORT_SYMBOL_GPL(iscsi_destroy_session); |
385 | 415 | ||
416 | static void mempool_zone_destroy(struct mempool_zone *zp) | ||
417 | { | ||
418 | mempool_destroy(zp->pool); | ||
419 | kfree(zp); | ||
420 | } | ||
421 | |||
422 | static void* | ||
423 | mempool_zone_alloc_skb(gfp_t gfp_mask, void *pool_data) | ||
424 | { | ||
425 | struct mempool_zone *zone = pool_data; | ||
426 | |||
427 | return alloc_skb(zone->size, gfp_mask); | ||
428 | } | ||
429 | |||
430 | static void | ||
431 | mempool_zone_free_skb(void *element, void *pool_data) | ||
432 | { | ||
433 | kfree_skb(element); | ||
434 | } | ||
435 | |||
436 | static struct mempool_zone * | ||
437 | mempool_zone_init(unsigned max, unsigned size, unsigned hiwat) | ||
438 | { | ||
439 | struct mempool_zone *zp; | ||
440 | |||
441 | zp = kzalloc(sizeof(*zp), GFP_KERNEL); | ||
442 | if (!zp) | ||
443 | return NULL; | ||
444 | |||
445 | zp->size = size; | ||
446 | zp->hiwat = hiwat; | ||
447 | INIT_LIST_HEAD(&zp->freequeue); | ||
448 | spin_lock_init(&zp->freelock); | ||
449 | atomic_set(&zp->allocated, 0); | ||
450 | |||
451 | zp->pool = mempool_create(max, mempool_zone_alloc_skb, | ||
452 | mempool_zone_free_skb, zp); | ||
453 | if (!zp->pool) { | ||
454 | kfree(zp); | ||
455 | return NULL; | ||
456 | } | ||
457 | |||
458 | return zp; | ||
459 | } | ||
460 | |||
386 | static void iscsi_conn_release(struct device *dev) | 461 | static void iscsi_conn_release(struct device *dev) |
387 | { | 462 | { |
388 | struct iscsi_cls_conn *conn = iscsi_dev_to_conn(dev); | 463 | struct iscsi_cls_conn *conn = iscsi_dev_to_conn(dev); |
389 | struct device *parent = conn->dev.parent; | 464 | struct device *parent = conn->dev.parent; |
390 | 465 | ||
391 | kfree(conn->persistent_address); | 466 | mempool_zone_destroy(conn->z_pdu); |
467 | mempool_zone_destroy(conn->z_error); | ||
468 | |||
392 | kfree(conn); | 469 | kfree(conn); |
393 | put_device(parent); | 470 | put_device(parent); |
394 | } | 471 | } |
@@ -398,6 +475,31 @@ static int iscsi_is_conn_dev(const struct device *dev) | |||
398 | return dev->release == iscsi_conn_release; | 475 | return dev->release == iscsi_conn_release; |
399 | } | 476 | } |
400 | 477 | ||
478 | static int iscsi_create_event_pools(struct iscsi_cls_conn *conn) | ||
479 | { | ||
480 | conn->z_pdu = mempool_zone_init(Z_MAX_PDU, | ||
481 | NLMSG_SPACE(sizeof(struct iscsi_uevent) + | ||
482 | sizeof(struct iscsi_hdr) + | ||
483 | DEFAULT_MAX_RECV_DATA_SEGMENT_LENGTH), | ||
484 | Z_HIWAT_PDU); | ||
485 | if (!conn->z_pdu) { | ||
486 | dev_printk(KERN_ERR, &conn->dev, "iscsi: can not allocate " | ||
487 | "pdu zone for new conn\n"); | ||
488 | return -ENOMEM; | ||
489 | } | ||
490 | |||
491 | conn->z_error = mempool_zone_init(Z_MAX_ERROR, | ||
492 | NLMSG_SPACE(sizeof(struct iscsi_uevent)), | ||
493 | Z_HIWAT_ERROR); | ||
494 | if (!conn->z_error) { | ||
495 | dev_printk(KERN_ERR, &conn->dev, "iscsi: can not allocate " | ||
496 | "error zone for new conn\n"); | ||
497 | mempool_zone_destroy(conn->z_pdu); | ||
498 | return -ENOMEM; | ||
499 | } | ||
500 | return 0; | ||
501 | } | ||
502 | |||
401 | /** | 503 | /** |
402 | * iscsi_create_conn - create iscsi class connection | 504 | * iscsi_create_conn - create iscsi class connection |
403 | * @session: iscsi cls session | 505 | * @session: iscsi cls session |
@@ -430,9 +532,12 @@ iscsi_create_conn(struct iscsi_cls_session *session, uint32_t cid) | |||
430 | conn->transport = transport; | 532 | conn->transport = transport; |
431 | conn->cid = cid; | 533 | conn->cid = cid; |
432 | 534 | ||
535 | if (iscsi_create_event_pools(conn)) | ||
536 | goto free_conn; | ||
537 | |||
433 | /* this is released in the dev's release function */ | 538 | /* this is released in the dev's release function */ |
434 | if (!get_device(&session->dev)) | 539 | if (!get_device(&session->dev)) |
435 | goto free_conn; | 540 | goto free_conn_pools; |
436 | 541 | ||
437 | snprintf(conn->dev.bus_id, BUS_ID_SIZE, "connection%d:%u", | 542 | snprintf(conn->dev.bus_id, BUS_ID_SIZE, "connection%d:%u", |
438 | session->sid, cid); | 543 | session->sid, cid); |
@@ -449,6 +554,8 @@ iscsi_create_conn(struct iscsi_cls_session *session, uint32_t cid) | |||
449 | 554 | ||
450 | release_parent_ref: | 555 | release_parent_ref: |
451 | put_device(&session->dev); | 556 | put_device(&session->dev); |
557 | free_conn_pools: | ||
558 | |||
452 | free_conn: | 559 | free_conn: |
453 | kfree(conn); | 560 | kfree(conn); |
454 | return NULL; | 561 | return NULL; |
@@ -496,20 +603,6 @@ static inline struct list_head *skb_to_lh(struct sk_buff *skb) | |||
496 | return (struct list_head *)&skb->cb; | 603 | return (struct list_head *)&skb->cb; |
497 | } | 604 | } |
498 | 605 | ||
499 | static void* | ||
500 | mempool_zone_alloc_skb(gfp_t gfp_mask, void *pool_data) | ||
501 | { | ||
502 | struct mempool_zone *zone = pool_data; | ||
503 | |||
504 | return alloc_skb(zone->size, gfp_mask); | ||
505 | } | ||
506 | |||
507 | static void | ||
508 | mempool_zone_free_skb(void *element, void *pool_data) | ||
509 | { | ||
510 | kfree_skb(element); | ||
511 | } | ||
512 | |||
513 | static void | 606 | static void |
514 | mempool_zone_complete(struct mempool_zone *zone) | 607 | mempool_zone_complete(struct mempool_zone *zone) |
515 | { | 608 | { |
@@ -529,37 +622,6 @@ mempool_zone_complete(struct mempool_zone *zone) | |||
529 | spin_unlock_irqrestore(&zone->freelock, flags); | 622 | spin_unlock_irqrestore(&zone->freelock, flags); |
530 | } | 623 | } |
531 | 624 | ||
532 | static struct mempool_zone * | ||
533 | mempool_zone_init(unsigned max, unsigned size, unsigned hiwat) | ||
534 | { | ||
535 | struct mempool_zone *zp; | ||
536 | |||
537 | zp = kzalloc(sizeof(*zp), GFP_KERNEL); | ||
538 | if (!zp) | ||
539 | return NULL; | ||
540 | |||
541 | zp->size = size; | ||
542 | zp->hiwat = hiwat; | ||
543 | INIT_LIST_HEAD(&zp->freequeue); | ||
544 | spin_lock_init(&zp->freelock); | ||
545 | atomic_set(&zp->allocated, 0); | ||
546 | |||
547 | zp->pool = mempool_create(max, mempool_zone_alloc_skb, | ||
548 | mempool_zone_free_skb, zp); | ||
549 | if (!zp->pool) { | ||
550 | kfree(zp); | ||
551 | return NULL; | ||
552 | } | ||
553 | |||
554 | return zp; | ||
555 | } | ||
556 | |||
557 | static void mempool_zone_destroy(struct mempool_zone *zp) | ||
558 | { | ||
559 | mempool_destroy(zp->pool); | ||
560 | kfree(zp); | ||
561 | } | ||
562 | |||
563 | static struct sk_buff* | 625 | static struct sk_buff* |
564 | mempool_zone_get_skb(struct mempool_zone *zone) | 626 | mempool_zone_get_skb(struct mempool_zone *zone) |
565 | { | 627 | { |
@@ -572,6 +634,27 @@ mempool_zone_get_skb(struct mempool_zone *zone) | |||
572 | } | 634 | } |
573 | 635 | ||
574 | static int | 636 | static int |
637 | iscsi_broadcast_skb(struct mempool_zone *zone, struct sk_buff *skb) | ||
638 | { | ||
639 | unsigned long flags; | ||
640 | int rc; | ||
641 | |||
642 | skb_get(skb); | ||
643 | rc = netlink_broadcast(nls, skb, 0, 1, GFP_KERNEL); | ||
644 | if (rc < 0) { | ||
645 | mempool_free(skb, zone->pool); | ||
646 | printk(KERN_ERR "iscsi: can not broadcast skb (%d)\n", rc); | ||
647 | return rc; | ||
648 | } | ||
649 | |||
650 | spin_lock_irqsave(&zone->freelock, flags); | ||
651 | INIT_LIST_HEAD(skb_to_lh(skb)); | ||
652 | list_add(skb_to_lh(skb), &zone->freequeue); | ||
653 | spin_unlock_irqrestore(&zone->freelock, flags); | ||
654 | return 0; | ||
655 | } | ||
656 | |||
657 | static int | ||
575 | iscsi_unicast_skb(struct mempool_zone *zone, struct sk_buff *skb, int pid) | 658 | iscsi_unicast_skb(struct mempool_zone *zone, struct sk_buff *skb, int pid) |
576 | { | 659 | { |
577 | unsigned long flags; | 660 | unsigned long flags; |
@@ -666,7 +749,7 @@ void iscsi_conn_error(struct iscsi_cls_conn *conn, enum iscsi_err error) | |||
666 | ev->r.connerror.cid = conn->cid; | 749 | ev->r.connerror.cid = conn->cid; |
667 | ev->r.connerror.sid = iscsi_conn_get_sid(conn); | 750 | ev->r.connerror.sid = iscsi_conn_get_sid(conn); |
668 | 751 | ||
669 | iscsi_unicast_skb(conn->z_error, skb, priv->daemon_pid); | 752 | iscsi_broadcast_skb(conn->z_error, skb); |
670 | 753 | ||
671 | dev_printk(KERN_INFO, &conn->dev, "iscsi: detected conn error (%d)\n", | 754 | dev_printk(KERN_INFO, &conn->dev, "iscsi: detected conn error (%d)\n", |
672 | error); | 755 | error); |
@@ -767,6 +850,131 @@ iscsi_if_get_stats(struct iscsi_transport *transport, struct nlmsghdr *nlh) | |||
767 | return err; | 850 | return err; |
768 | } | 851 | } |
769 | 852 | ||
853 | /** | ||
854 | * iscsi_if_destroy_session_done - send session destr. completion event | ||
855 | * @conn: last connection for session | ||
856 | * | ||
857 | * This is called by HW iscsi LLDs to notify userpsace that its HW has | ||
858 | * removed a session. | ||
859 | **/ | ||
860 | int iscsi_if_destroy_session_done(struct iscsi_cls_conn *conn) | ||
861 | { | ||
862 | struct iscsi_internal *priv; | ||
863 | struct iscsi_cls_session *session; | ||
864 | struct Scsi_Host *shost; | ||
865 | struct iscsi_uevent *ev; | ||
866 | struct sk_buff *skb; | ||
867 | struct nlmsghdr *nlh; | ||
868 | unsigned long flags; | ||
869 | int rc, len = NLMSG_SPACE(sizeof(*ev)); | ||
870 | |||
871 | priv = iscsi_if_transport_lookup(conn->transport); | ||
872 | if (!priv) | ||
873 | return -EINVAL; | ||
874 | |||
875 | session = iscsi_dev_to_session(conn->dev.parent); | ||
876 | shost = iscsi_session_to_shost(session); | ||
877 | |||
878 | mempool_zone_complete(conn->z_pdu); | ||
879 | |||
880 | skb = mempool_zone_get_skb(conn->z_pdu); | ||
881 | if (!skb) { | ||
882 | dev_printk(KERN_ERR, &conn->dev, "Cannot notify userspace of " | ||
883 | "session creation event\n"); | ||
884 | return -ENOMEM; | ||
885 | } | ||
886 | |||
887 | nlh = __nlmsg_put(skb, priv->daemon_pid, 0, 0, (len - sizeof(*nlh)), 0); | ||
888 | ev = NLMSG_DATA(nlh); | ||
889 | ev->transport_handle = iscsi_handle(conn->transport); | ||
890 | ev->type = ISCSI_KEVENT_DESTROY_SESSION; | ||
891 | ev->r.d_session.host_no = shost->host_no; | ||
892 | ev->r.d_session.sid = session->sid; | ||
893 | |||
894 | /* | ||
895 | * this will occur if the daemon is not up, so we just warn | ||
896 | * the user and when the daemon is restarted it will handle it | ||
897 | */ | ||
898 | rc = iscsi_broadcast_skb(conn->z_pdu, skb); | ||
899 | if (rc < 0) | ||
900 | dev_printk(KERN_ERR, &conn->dev, "Cannot notify userspace of " | ||
901 | "session destruction event. Check iscsi daemon\n"); | ||
902 | |||
903 | spin_lock_irqsave(&sesslock, flags); | ||
904 | list_del(&session->sess_list); | ||
905 | spin_unlock_irqrestore(&sesslock, flags); | ||
906 | |||
907 | spin_lock_irqsave(&connlock, flags); | ||
908 | conn->active = 0; | ||
909 | list_del(&conn->conn_list); | ||
910 | spin_unlock_irqrestore(&connlock, flags); | ||
911 | |||
912 | return rc; | ||
913 | } | ||
914 | EXPORT_SYMBOL_GPL(iscsi_if_destroy_session_done); | ||
915 | |||
916 | /** | ||
917 | * iscsi_if_create_session_done - send session creation completion event | ||
918 | * @conn: leading connection for session | ||
919 | * | ||
920 | * This is called by HW iscsi LLDs to notify userpsace that its HW has | ||
921 | * created a session or a existing session is back in the logged in state. | ||
922 | **/ | ||
923 | int iscsi_if_create_session_done(struct iscsi_cls_conn *conn) | ||
924 | { | ||
925 | struct iscsi_internal *priv; | ||
926 | struct iscsi_cls_session *session; | ||
927 | struct Scsi_Host *shost; | ||
928 | struct iscsi_uevent *ev; | ||
929 | struct sk_buff *skb; | ||
930 | struct nlmsghdr *nlh; | ||
931 | unsigned long flags; | ||
932 | int rc, len = NLMSG_SPACE(sizeof(*ev)); | ||
933 | |||
934 | priv = iscsi_if_transport_lookup(conn->transport); | ||
935 | if (!priv) | ||
936 | return -EINVAL; | ||
937 | |||
938 | session = iscsi_dev_to_session(conn->dev.parent); | ||
939 | shost = iscsi_session_to_shost(session); | ||
940 | |||
941 | mempool_zone_complete(conn->z_pdu); | ||
942 | |||
943 | skb = mempool_zone_get_skb(conn->z_pdu); | ||
944 | if (!skb) { | ||
945 | dev_printk(KERN_ERR, &conn->dev, "Cannot notify userspace of " | ||
946 | "session creation event\n"); | ||
947 | return -ENOMEM; | ||
948 | } | ||
949 | |||
950 | nlh = __nlmsg_put(skb, priv->daemon_pid, 0, 0, (len - sizeof(*nlh)), 0); | ||
951 | ev = NLMSG_DATA(nlh); | ||
952 | ev->transport_handle = iscsi_handle(conn->transport); | ||
953 | ev->type = ISCSI_UEVENT_CREATE_SESSION; | ||
954 | ev->r.c_session_ret.host_no = shost->host_no; | ||
955 | ev->r.c_session_ret.sid = session->sid; | ||
956 | |||
957 | /* | ||
958 | * this will occur if the daemon is not up, so we just warn | ||
959 | * the user and when the daemon is restarted it will handle it | ||
960 | */ | ||
961 | rc = iscsi_broadcast_skb(conn->z_pdu, skb); | ||
962 | if (rc < 0) | ||
963 | dev_printk(KERN_ERR, &conn->dev, "Cannot notify userspace of " | ||
964 | "session creation event. Check iscsi daemon\n"); | ||
965 | |||
966 | spin_lock_irqsave(&sesslock, flags); | ||
967 | list_add(&session->sess_list, &sesslist); | ||
968 | spin_unlock_irqrestore(&sesslock, flags); | ||
969 | |||
970 | spin_lock_irqsave(&connlock, flags); | ||
971 | list_add(&conn->conn_list, &connlist); | ||
972 | conn->active = 1; | ||
973 | spin_unlock_irqrestore(&connlock, flags); | ||
974 | return rc; | ||
975 | } | ||
976 | EXPORT_SYMBOL_GPL(iscsi_if_create_session_done); | ||
977 | |||
770 | static int | 978 | static int |
771 | iscsi_if_create_session(struct iscsi_internal *priv, struct iscsi_uevent *ev) | 979 | iscsi_if_create_session(struct iscsi_internal *priv, struct iscsi_uevent *ev) |
772 | { | 980 | { |
@@ -812,26 +1020,6 @@ iscsi_if_create_conn(struct iscsi_transport *transport, struct iscsi_uevent *ev) | |||
812 | return -ENOMEM; | 1020 | return -ENOMEM; |
813 | } | 1021 | } |
814 | 1022 | ||
815 | conn->z_pdu = mempool_zone_init(Z_MAX_PDU, | ||
816 | NLMSG_SPACE(sizeof(struct iscsi_uevent) + | ||
817 | sizeof(struct iscsi_hdr) + | ||
818 | DEFAULT_MAX_RECV_DATA_SEGMENT_LENGTH), | ||
819 | Z_HIWAT_PDU); | ||
820 | if (!conn->z_pdu) { | ||
821 | dev_printk(KERN_ERR, &conn->dev, "iscsi: can not allocate " | ||
822 | "pdu zone for new conn\n"); | ||
823 | goto destroy_conn; | ||
824 | } | ||
825 | |||
826 | conn->z_error = mempool_zone_init(Z_MAX_ERROR, | ||
827 | NLMSG_SPACE(sizeof(struct iscsi_uevent)), | ||
828 | Z_HIWAT_ERROR); | ||
829 | if (!conn->z_error) { | ||
830 | dev_printk(KERN_ERR, &conn->dev, "iscsi: can not allocate " | ||
831 | "error zone for new conn\n"); | ||
832 | goto free_pdu_pool; | ||
833 | } | ||
834 | |||
835 | ev->r.c_conn_ret.sid = session->sid; | 1023 | ev->r.c_conn_ret.sid = session->sid; |
836 | ev->r.c_conn_ret.cid = conn->cid; | 1024 | ev->r.c_conn_ret.cid = conn->cid; |
837 | 1025 | ||
@@ -841,13 +1029,6 @@ iscsi_if_create_conn(struct iscsi_transport *transport, struct iscsi_uevent *ev) | |||
841 | spin_unlock_irqrestore(&connlock, flags); | 1029 | spin_unlock_irqrestore(&connlock, flags); |
842 | 1030 | ||
843 | return 0; | 1031 | return 0; |
844 | |||
845 | free_pdu_pool: | ||
846 | mempool_zone_destroy(conn->z_pdu); | ||
847 | destroy_conn: | ||
848 | if (transport->destroy_conn) | ||
849 | transport->destroy_conn(conn->dd_data); | ||
850 | return -ENOMEM; | ||
851 | } | 1032 | } |
852 | 1033 | ||
853 | static int | 1034 | static int |
@@ -855,7 +1036,6 @@ iscsi_if_destroy_conn(struct iscsi_transport *transport, struct iscsi_uevent *ev | |||
855 | { | 1036 | { |
856 | unsigned long flags; | 1037 | unsigned long flags; |
857 | struct iscsi_cls_conn *conn; | 1038 | struct iscsi_cls_conn *conn; |
858 | struct mempool_zone *z_error, *z_pdu; | ||
859 | 1039 | ||
860 | conn = iscsi_conn_lookup(ev->u.d_conn.sid, ev->u.d_conn.cid); | 1040 | conn = iscsi_conn_lookup(ev->u.d_conn.sid, ev->u.d_conn.cid); |
861 | if (!conn) | 1041 | if (!conn) |
@@ -865,35 +1045,18 @@ iscsi_if_destroy_conn(struct iscsi_transport *transport, struct iscsi_uevent *ev | |||
865 | list_del(&conn->conn_list); | 1045 | list_del(&conn->conn_list); |
866 | spin_unlock_irqrestore(&connlock, flags); | 1046 | spin_unlock_irqrestore(&connlock, flags); |
867 | 1047 | ||
868 | z_pdu = conn->z_pdu; | ||
869 | z_error = conn->z_error; | ||
870 | |||
871 | if (transport->destroy_conn) | 1048 | if (transport->destroy_conn) |
872 | transport->destroy_conn(conn); | 1049 | transport->destroy_conn(conn); |
873 | |||
874 | mempool_zone_destroy(z_pdu); | ||
875 | mempool_zone_destroy(z_error); | ||
876 | |||
877 | return 0; | 1050 | return 0; |
878 | } | 1051 | } |
879 | 1052 | ||
880 | static void | ||
881 | iscsi_copy_param(struct iscsi_uevent *ev, uint32_t *value, char *data) | ||
882 | { | ||
883 | if (ev->u.set_param.len != sizeof(uint32_t)) | ||
884 | BUG(); | ||
885 | memcpy(value, data, min_t(uint32_t, sizeof(uint32_t), | ||
886 | ev->u.set_param.len)); | ||
887 | } | ||
888 | |||
889 | static int | 1053 | static int |
890 | iscsi_set_param(struct iscsi_transport *transport, struct iscsi_uevent *ev) | 1054 | iscsi_set_param(struct iscsi_transport *transport, struct iscsi_uevent *ev) |
891 | { | 1055 | { |
892 | char *data = (char*)ev + sizeof(*ev); | 1056 | char *data = (char*)ev + sizeof(*ev); |
893 | struct iscsi_cls_conn *conn; | 1057 | struct iscsi_cls_conn *conn; |
894 | struct iscsi_cls_session *session; | 1058 | struct iscsi_cls_session *session; |
895 | int err = 0; | 1059 | int err = 0, value = 0; |
896 | uint32_t value = 0; | ||
897 | 1060 | ||
898 | session = iscsi_session_lookup(ev->u.set_param.sid); | 1061 | session = iscsi_session_lookup(ev->u.set_param.sid); |
899 | conn = iscsi_conn_lookup(ev->u.set_param.sid, ev->u.set_param.cid); | 1062 | conn = iscsi_conn_lookup(ev->u.set_param.sid, ev->u.set_param.cid); |
@@ -902,42 +1065,13 @@ iscsi_set_param(struct iscsi_transport *transport, struct iscsi_uevent *ev) | |||
902 | 1065 | ||
903 | switch (ev->u.set_param.param) { | 1066 | switch (ev->u.set_param.param) { |
904 | case ISCSI_PARAM_SESS_RECOVERY_TMO: | 1067 | case ISCSI_PARAM_SESS_RECOVERY_TMO: |
905 | iscsi_copy_param(ev, &value, data); | 1068 | sscanf(data, "%d", &value); |
906 | if (value != 0) | 1069 | if (value != 0) |
907 | session->recovery_tmo = value; | 1070 | session->recovery_tmo = value; |
908 | break; | 1071 | break; |
909 | case ISCSI_PARAM_TARGET_NAME: | ||
910 | /* this should not change between logins */ | ||
911 | if (session->targetname) | ||
912 | return 0; | ||
913 | |||
914 | session->targetname = kstrdup(data, GFP_KERNEL); | ||
915 | if (!session->targetname) | ||
916 | return -ENOMEM; | ||
917 | break; | ||
918 | case ISCSI_PARAM_TPGT: | ||
919 | iscsi_copy_param(ev, &value, data); | ||
920 | session->tpgt = value; | ||
921 | break; | ||
922 | case ISCSI_PARAM_PERSISTENT_PORT: | ||
923 | iscsi_copy_param(ev, &value, data); | ||
924 | conn->persistent_port = value; | ||
925 | break; | ||
926 | case ISCSI_PARAM_PERSISTENT_ADDRESS: | ||
927 | /* | ||
928 | * this is the address returned in discovery so it should | ||
929 | * not change between logins. | ||
930 | */ | ||
931 | if (conn->persistent_address) | ||
932 | return 0; | ||
933 | |||
934 | conn->persistent_address = kstrdup(data, GFP_KERNEL); | ||
935 | if (!conn->persistent_address) | ||
936 | return -ENOMEM; | ||
937 | break; | ||
938 | default: | 1072 | default: |
939 | iscsi_copy_param(ev, &value, data); | 1073 | err = transport->set_param(conn, ev->u.set_param.param, |
940 | err = transport->set_param(conn, ev->u.set_param.param, value); | 1074 | data, ev->u.set_param.len); |
941 | } | 1075 | } |
942 | 1076 | ||
943 | return err; | 1077 | return err; |
@@ -978,6 +1112,21 @@ iscsi_if_transport_ep(struct iscsi_transport *transport, | |||
978 | } | 1112 | } |
979 | 1113 | ||
980 | static int | 1114 | static int |
1115 | iscsi_tgt_dscvr(struct iscsi_transport *transport, | ||
1116 | struct iscsi_uevent *ev) | ||
1117 | { | ||
1118 | struct sockaddr *dst_addr; | ||
1119 | |||
1120 | if (!transport->tgt_dscvr) | ||
1121 | return -EINVAL; | ||
1122 | |||
1123 | dst_addr = (struct sockaddr *)((char*)ev + sizeof(*ev)); | ||
1124 | return transport->tgt_dscvr(ev->u.tgt_dscvr.type, | ||
1125 | ev->u.tgt_dscvr.host_no, | ||
1126 | ev->u.tgt_dscvr.enable, dst_addr); | ||
1127 | } | ||
1128 | |||
1129 | static int | ||
981 | iscsi_if_recv_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | 1130 | iscsi_if_recv_msg(struct sk_buff *skb, struct nlmsghdr *nlh) |
982 | { | 1131 | { |
983 | int err = 0; | 1132 | int err = 0; |
@@ -1065,6 +1214,9 @@ iscsi_if_recv_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
1065 | case ISCSI_UEVENT_TRANSPORT_EP_DISCONNECT: | 1214 | case ISCSI_UEVENT_TRANSPORT_EP_DISCONNECT: |
1066 | err = iscsi_if_transport_ep(transport, ev, nlh->nlmsg_type); | 1215 | err = iscsi_if_transport_ep(transport, ev, nlh->nlmsg_type); |
1067 | break; | 1216 | break; |
1217 | case ISCSI_UEVENT_TGT_DSCVR: | ||
1218 | err = iscsi_tgt_dscvr(transport, ev); | ||
1219 | break; | ||
1068 | default: | 1220 | default: |
1069 | err = -EINVAL; | 1221 | err = -EINVAL; |
1070 | break; | 1222 | break; |
@@ -1147,49 +1299,31 @@ struct class_device_attribute class_device_attr_##_prefix##_##_name = \ | |||
1147 | /* | 1299 | /* |
1148 | * iSCSI connection attrs | 1300 | * iSCSI connection attrs |
1149 | */ | 1301 | */ |
1150 | #define iscsi_conn_int_attr_show(param, format) \ | 1302 | #define iscsi_conn_attr_show(param) \ |
1151 | static ssize_t \ | ||
1152 | show_conn_int_param_##param(struct class_device *cdev, char *buf) \ | ||
1153 | { \ | ||
1154 | uint32_t value = 0; \ | ||
1155 | struct iscsi_cls_conn *conn = iscsi_cdev_to_conn(cdev); \ | ||
1156 | struct iscsi_transport *t = conn->transport; \ | ||
1157 | \ | ||
1158 | t->get_conn_param(conn, param, &value); \ | ||
1159 | return snprintf(buf, 20, format"\n", value); \ | ||
1160 | } | ||
1161 | |||
1162 | #define iscsi_conn_int_attr(field, param, format) \ | ||
1163 | iscsi_conn_int_attr_show(param, format) \ | ||
1164 | static ISCSI_CLASS_ATTR(conn, field, S_IRUGO, show_conn_int_param_##param, \ | ||
1165 | NULL); | ||
1166 | |||
1167 | iscsi_conn_int_attr(max_recv_dlength, ISCSI_PARAM_MAX_RECV_DLENGTH, "%u"); | ||
1168 | iscsi_conn_int_attr(max_xmit_dlength, ISCSI_PARAM_MAX_XMIT_DLENGTH, "%u"); | ||
1169 | iscsi_conn_int_attr(header_digest, ISCSI_PARAM_HDRDGST_EN, "%d"); | ||
1170 | iscsi_conn_int_attr(data_digest, ISCSI_PARAM_DATADGST_EN, "%d"); | ||
1171 | iscsi_conn_int_attr(ifmarker, ISCSI_PARAM_IFMARKER_EN, "%d"); | ||
1172 | iscsi_conn_int_attr(ofmarker, ISCSI_PARAM_OFMARKER_EN, "%d"); | ||
1173 | iscsi_conn_int_attr(persistent_port, ISCSI_PARAM_PERSISTENT_PORT, "%d"); | ||
1174 | iscsi_conn_int_attr(port, ISCSI_PARAM_CONN_PORT, "%d"); | ||
1175 | iscsi_conn_int_attr(exp_statsn, ISCSI_PARAM_EXP_STATSN, "%u"); | ||
1176 | |||
1177 | #define iscsi_conn_str_attr_show(param) \ | ||
1178 | static ssize_t \ | 1303 | static ssize_t \ |
1179 | show_conn_str_param_##param(struct class_device *cdev, char *buf) \ | 1304 | show_conn_param_##param(struct class_device *cdev, char *buf) \ |
1180 | { \ | 1305 | { \ |
1181 | struct iscsi_cls_conn *conn = iscsi_cdev_to_conn(cdev); \ | 1306 | struct iscsi_cls_conn *conn = iscsi_cdev_to_conn(cdev); \ |
1182 | struct iscsi_transport *t = conn->transport; \ | 1307 | struct iscsi_transport *t = conn->transport; \ |
1183 | return t->get_conn_str_param(conn, param, buf); \ | 1308 | return t->get_conn_param(conn, param, buf); \ |
1184 | } | 1309 | } |
1185 | 1310 | ||
1186 | #define iscsi_conn_str_attr(field, param) \ | 1311 | #define iscsi_conn_attr(field, param) \ |
1187 | iscsi_conn_str_attr_show(param) \ | 1312 | iscsi_conn_attr_show(param) \ |
1188 | static ISCSI_CLASS_ATTR(conn, field, S_IRUGO, show_conn_str_param_##param, \ | 1313 | static ISCSI_CLASS_ATTR(conn, field, S_IRUGO, show_conn_param_##param, \ |
1189 | NULL); | 1314 | NULL); |
1190 | 1315 | ||
1191 | iscsi_conn_str_attr(persistent_address, ISCSI_PARAM_PERSISTENT_ADDRESS); | 1316 | iscsi_conn_attr(max_recv_dlength, ISCSI_PARAM_MAX_RECV_DLENGTH); |
1192 | iscsi_conn_str_attr(address, ISCSI_PARAM_CONN_ADDRESS); | 1317 | iscsi_conn_attr(max_xmit_dlength, ISCSI_PARAM_MAX_XMIT_DLENGTH); |
1318 | iscsi_conn_attr(header_digest, ISCSI_PARAM_HDRDGST_EN); | ||
1319 | iscsi_conn_attr(data_digest, ISCSI_PARAM_DATADGST_EN); | ||
1320 | iscsi_conn_attr(ifmarker, ISCSI_PARAM_IFMARKER_EN); | ||
1321 | iscsi_conn_attr(ofmarker, ISCSI_PARAM_OFMARKER_EN); | ||
1322 | iscsi_conn_attr(persistent_port, ISCSI_PARAM_PERSISTENT_PORT); | ||
1323 | iscsi_conn_attr(port, ISCSI_PARAM_CONN_PORT); | ||
1324 | iscsi_conn_attr(exp_statsn, ISCSI_PARAM_EXP_STATSN); | ||
1325 | iscsi_conn_attr(persistent_address, ISCSI_PARAM_PERSISTENT_ADDRESS); | ||
1326 | iscsi_conn_attr(address, ISCSI_PARAM_CONN_ADDRESS); | ||
1193 | 1327 | ||
1194 | #define iscsi_cdev_to_session(_cdev) \ | 1328 | #define iscsi_cdev_to_session(_cdev) \ |
1195 | iscsi_dev_to_session(_cdev->dev) | 1329 | iscsi_dev_to_session(_cdev->dev) |
@@ -1197,61 +1331,36 @@ iscsi_conn_str_attr(address, ISCSI_PARAM_CONN_ADDRESS); | |||
1197 | /* | 1331 | /* |
1198 | * iSCSI session attrs | 1332 | * iSCSI session attrs |
1199 | */ | 1333 | */ |
1200 | #define iscsi_session_int_attr_show(param, format) \ | 1334 | #define iscsi_session_attr_show(param) \ |
1201 | static ssize_t \ | ||
1202 | show_session_int_param_##param(struct class_device *cdev, char *buf) \ | ||
1203 | { \ | ||
1204 | uint32_t value = 0; \ | ||
1205 | struct iscsi_cls_session *session = iscsi_cdev_to_session(cdev); \ | ||
1206 | struct iscsi_transport *t = session->transport; \ | ||
1207 | \ | ||
1208 | t->get_session_param(session, param, &value); \ | ||
1209 | return snprintf(buf, 20, format"\n", value); \ | ||
1210 | } | ||
1211 | |||
1212 | #define iscsi_session_int_attr(field, param, format) \ | ||
1213 | iscsi_session_int_attr_show(param, format) \ | ||
1214 | static ISCSI_CLASS_ATTR(sess, field, S_IRUGO, show_session_int_param_##param, \ | ||
1215 | NULL); | ||
1216 | |||
1217 | iscsi_session_int_attr(initial_r2t, ISCSI_PARAM_INITIAL_R2T_EN, "%d"); | ||
1218 | iscsi_session_int_attr(max_outstanding_r2t, ISCSI_PARAM_MAX_R2T, "%hu"); | ||
1219 | iscsi_session_int_attr(immediate_data, ISCSI_PARAM_IMM_DATA_EN, "%d"); | ||
1220 | iscsi_session_int_attr(first_burst_len, ISCSI_PARAM_FIRST_BURST, "%u"); | ||
1221 | iscsi_session_int_attr(max_burst_len, ISCSI_PARAM_MAX_BURST, "%u"); | ||
1222 | iscsi_session_int_attr(data_pdu_in_order, ISCSI_PARAM_PDU_INORDER_EN, "%d"); | ||
1223 | iscsi_session_int_attr(data_seq_in_order, ISCSI_PARAM_DATASEQ_INORDER_EN, "%d"); | ||
1224 | iscsi_session_int_attr(erl, ISCSI_PARAM_ERL, "%d"); | ||
1225 | iscsi_session_int_attr(tpgt, ISCSI_PARAM_TPGT, "%d"); | ||
1226 | |||
1227 | #define iscsi_session_str_attr_show(param) \ | ||
1228 | static ssize_t \ | 1335 | static ssize_t \ |
1229 | show_session_str_param_##param(struct class_device *cdev, char *buf) \ | 1336 | show_session_param_##param(struct class_device *cdev, char *buf) \ |
1230 | { \ | 1337 | { \ |
1231 | struct iscsi_cls_session *session = iscsi_cdev_to_session(cdev); \ | 1338 | struct iscsi_cls_session *session = iscsi_cdev_to_session(cdev); \ |
1232 | struct iscsi_transport *t = session->transport; \ | 1339 | struct iscsi_transport *t = session->transport; \ |
1233 | return t->get_session_str_param(session, param, buf); \ | 1340 | return t->get_session_param(session, param, buf); \ |
1234 | } | 1341 | } |
1235 | 1342 | ||
1236 | #define iscsi_session_str_attr(field, param) \ | 1343 | #define iscsi_session_attr(field, param) \ |
1237 | iscsi_session_str_attr_show(param) \ | 1344 | iscsi_session_attr_show(param) \ |
1238 | static ISCSI_CLASS_ATTR(sess, field, S_IRUGO, show_session_str_param_##param, \ | 1345 | static ISCSI_CLASS_ATTR(sess, field, S_IRUGO, show_session_param_##param, \ |
1239 | NULL); | 1346 | NULL); |
1240 | 1347 | ||
1241 | iscsi_session_str_attr(targetname, ISCSI_PARAM_TARGET_NAME); | 1348 | iscsi_session_attr(targetname, ISCSI_PARAM_TARGET_NAME); |
1349 | iscsi_session_attr(initial_r2t, ISCSI_PARAM_INITIAL_R2T_EN); | ||
1350 | iscsi_session_attr(max_outstanding_r2t, ISCSI_PARAM_MAX_R2T); | ||
1351 | iscsi_session_attr(immediate_data, ISCSI_PARAM_IMM_DATA_EN); | ||
1352 | iscsi_session_attr(first_burst_len, ISCSI_PARAM_FIRST_BURST); | ||
1353 | iscsi_session_attr(max_burst_len, ISCSI_PARAM_MAX_BURST); | ||
1354 | iscsi_session_attr(data_pdu_in_order, ISCSI_PARAM_PDU_INORDER_EN); | ||
1355 | iscsi_session_attr(data_seq_in_order, ISCSI_PARAM_DATASEQ_INORDER_EN); | ||
1356 | iscsi_session_attr(erl, ISCSI_PARAM_ERL); | ||
1357 | iscsi_session_attr(tpgt, ISCSI_PARAM_TPGT); | ||
1242 | 1358 | ||
1243 | /* | ||
1244 | * Private session and conn attrs. userspace uses several iscsi values | ||
1245 | * to identify each session between reboots. Some of these values may not | ||
1246 | * be present in the iscsi_transport/LLD driver becuase userspace handles | ||
1247 | * login (and failback for login redirect) so for these type of drivers | ||
1248 | * the class manages the attrs and values for the iscsi_transport/LLD | ||
1249 | */ | ||
1250 | #define iscsi_priv_session_attr_show(field, format) \ | 1359 | #define iscsi_priv_session_attr_show(field, format) \ |
1251 | static ssize_t \ | 1360 | static ssize_t \ |
1252 | show_priv_session_##field(struct class_device *cdev, char *buf) \ | 1361 | show_priv_session_##field(struct class_device *cdev, char *buf) \ |
1253 | { \ | 1362 | { \ |
1254 | struct iscsi_cls_session *session = iscsi_cdev_to_session(cdev); \ | 1363 | struct iscsi_cls_session *session = iscsi_cdev_to_session(cdev);\ |
1255 | return sprintf(buf, format"\n", session->field); \ | 1364 | return sprintf(buf, format"\n", session->field); \ |
1256 | } | 1365 | } |
1257 | 1366 | ||
@@ -1259,31 +1368,15 @@ show_priv_session_##field(struct class_device *cdev, char *buf) \ | |||
1259 | iscsi_priv_session_attr_show(field, format) \ | 1368 | iscsi_priv_session_attr_show(field, format) \ |
1260 | static ISCSI_CLASS_ATTR(priv_sess, field, S_IRUGO, show_priv_session_##field, \ | 1369 | static ISCSI_CLASS_ATTR(priv_sess, field, S_IRUGO, show_priv_session_##field, \ |
1261 | NULL) | 1370 | NULL) |
1262 | iscsi_priv_session_attr(targetname, "%s"); | ||
1263 | iscsi_priv_session_attr(tpgt, "%d"); | ||
1264 | iscsi_priv_session_attr(recovery_tmo, "%d"); | 1371 | iscsi_priv_session_attr(recovery_tmo, "%d"); |
1265 | 1372 | ||
1266 | #define iscsi_priv_conn_attr_show(field, format) \ | ||
1267 | static ssize_t \ | ||
1268 | show_priv_conn_##field(struct class_device *cdev, char *buf) \ | ||
1269 | { \ | ||
1270 | struct iscsi_cls_conn *conn = iscsi_cdev_to_conn(cdev); \ | ||
1271 | return sprintf(buf, format"\n", conn->field); \ | ||
1272 | } | ||
1273 | |||
1274 | #define iscsi_priv_conn_attr(field, format) \ | ||
1275 | iscsi_priv_conn_attr_show(field, format) \ | ||
1276 | static ISCSI_CLASS_ATTR(priv_conn, field, S_IRUGO, show_priv_conn_##field, \ | ||
1277 | NULL) | ||
1278 | iscsi_priv_conn_attr(persistent_address, "%s"); | ||
1279 | iscsi_priv_conn_attr(persistent_port, "%d"); | ||
1280 | |||
1281 | #define SETUP_PRIV_SESSION_RD_ATTR(field) \ | 1373 | #define SETUP_PRIV_SESSION_RD_ATTR(field) \ |
1282 | do { \ | 1374 | do { \ |
1283 | priv->session_attrs[count] = &class_device_attr_priv_sess_##field; \ | 1375 | priv->session_attrs[count] = &class_device_attr_priv_sess_##field; \ |
1284 | count++; \ | 1376 | count++; \ |
1285 | } while (0) | 1377 | } while (0) |
1286 | 1378 | ||
1379 | |||
1287 | #define SETUP_SESSION_RD_ATTR(field, param_flag) \ | 1380 | #define SETUP_SESSION_RD_ATTR(field, param_flag) \ |
1288 | do { \ | 1381 | do { \ |
1289 | if (tt->param_mask & param_flag) { \ | 1382 | if (tt->param_mask & param_flag) { \ |
@@ -1292,12 +1385,6 @@ do { \ | |||
1292 | } \ | 1385 | } \ |
1293 | } while (0) | 1386 | } while (0) |
1294 | 1387 | ||
1295 | #define SETUP_PRIV_CONN_RD_ATTR(field) \ | ||
1296 | do { \ | ||
1297 | priv->conn_attrs[count] = &class_device_attr_priv_conn_##field; \ | ||
1298 | count++; \ | ||
1299 | } while (0) | ||
1300 | |||
1301 | #define SETUP_CONN_RD_ATTR(field, param_flag) \ | 1388 | #define SETUP_CONN_RD_ATTR(field, param_flag) \ |
1302 | do { \ | 1389 | do { \ |
1303 | if (tt->param_mask & param_flag) { \ | 1390 | if (tt->param_mask & param_flag) { \ |
@@ -1388,6 +1475,7 @@ iscsi_register_transport(struct iscsi_transport *tt) | |||
1388 | if (!priv) | 1475 | if (!priv) |
1389 | return NULL; | 1476 | return NULL; |
1390 | INIT_LIST_HEAD(&priv->list); | 1477 | INIT_LIST_HEAD(&priv->list); |
1478 | priv->daemon_pid = -1; | ||
1391 | priv->iscsi_transport = tt; | 1479 | priv->iscsi_transport = tt; |
1392 | priv->t.user_scan = iscsi_user_scan; | 1480 | priv->t.user_scan = iscsi_user_scan; |
1393 | 1481 | ||
@@ -1424,16 +1512,8 @@ iscsi_register_transport(struct iscsi_transport *tt) | |||
1424 | SETUP_CONN_RD_ATTR(address, ISCSI_CONN_ADDRESS); | 1512 | SETUP_CONN_RD_ATTR(address, ISCSI_CONN_ADDRESS); |
1425 | SETUP_CONN_RD_ATTR(port, ISCSI_CONN_PORT); | 1513 | SETUP_CONN_RD_ATTR(port, ISCSI_CONN_PORT); |
1426 | SETUP_CONN_RD_ATTR(exp_statsn, ISCSI_EXP_STATSN); | 1514 | SETUP_CONN_RD_ATTR(exp_statsn, ISCSI_EXP_STATSN); |
1427 | 1515 | SETUP_CONN_RD_ATTR(persistent_address, ISCSI_PERSISTENT_ADDRESS); | |
1428 | if (tt->param_mask & ISCSI_PERSISTENT_ADDRESS) | 1516 | SETUP_CONN_RD_ATTR(persistent_port, ISCSI_PERSISTENT_PORT); |
1429 | SETUP_CONN_RD_ATTR(persistent_address, ISCSI_PERSISTENT_ADDRESS); | ||
1430 | else | ||
1431 | SETUP_PRIV_CONN_RD_ATTR(persistent_address); | ||
1432 | |||
1433 | if (tt->param_mask & ISCSI_PERSISTENT_PORT) | ||
1434 | SETUP_CONN_RD_ATTR(persistent_port, ISCSI_PERSISTENT_PORT); | ||
1435 | else | ||
1436 | SETUP_PRIV_CONN_RD_ATTR(persistent_port); | ||
1437 | 1517 | ||
1438 | BUG_ON(count > ISCSI_CONN_ATTRS); | 1518 | BUG_ON(count > ISCSI_CONN_ATTRS); |
1439 | priv->conn_attrs[count] = NULL; | 1519 | priv->conn_attrs[count] = NULL; |
@@ -1453,18 +1533,10 @@ iscsi_register_transport(struct iscsi_transport *tt) | |||
1453 | SETUP_SESSION_RD_ATTR(data_pdu_in_order, ISCSI_PDU_INORDER_EN); | 1533 | SETUP_SESSION_RD_ATTR(data_pdu_in_order, ISCSI_PDU_INORDER_EN); |
1454 | SETUP_SESSION_RD_ATTR(data_seq_in_order, ISCSI_DATASEQ_INORDER_EN); | 1534 | SETUP_SESSION_RD_ATTR(data_seq_in_order, ISCSI_DATASEQ_INORDER_EN); |
1455 | SETUP_SESSION_RD_ATTR(erl, ISCSI_ERL); | 1535 | SETUP_SESSION_RD_ATTR(erl, ISCSI_ERL); |
1536 | SETUP_SESSION_RD_ATTR(targetname, ISCSI_TARGET_NAME); | ||
1537 | SETUP_SESSION_RD_ATTR(tpgt, ISCSI_TPGT); | ||
1456 | SETUP_PRIV_SESSION_RD_ATTR(recovery_tmo); | 1538 | SETUP_PRIV_SESSION_RD_ATTR(recovery_tmo); |
1457 | 1539 | ||
1458 | if (tt->param_mask & ISCSI_TARGET_NAME) | ||
1459 | SETUP_SESSION_RD_ATTR(targetname, ISCSI_TARGET_NAME); | ||
1460 | else | ||
1461 | SETUP_PRIV_SESSION_RD_ATTR(targetname); | ||
1462 | |||
1463 | if (tt->param_mask & ISCSI_TPGT) | ||
1464 | SETUP_SESSION_RD_ATTR(tpgt, ISCSI_TPGT); | ||
1465 | else | ||
1466 | SETUP_PRIV_SESSION_RD_ATTR(tpgt); | ||
1467 | |||
1468 | BUG_ON(count > ISCSI_SESSION_ATTRS); | 1540 | BUG_ON(count > ISCSI_SESSION_ATTRS); |
1469 | priv->session_attrs[count] = NULL; | 1541 | priv->session_attrs[count] = NULL; |
1470 | 1542 | ||
diff --git a/drivers/scsi/scsi_transport_sas.c b/drivers/scsi/scsi_transport_sas.c index 1fe6b2d01853..dd075627e605 100644 --- a/drivers/scsi/scsi_transport_sas.c +++ b/drivers/scsi/scsi_transport_sas.c | |||
@@ -174,12 +174,29 @@ static int sas_host_match(struct attribute_container *cont, | |||
174 | 174 | ||
175 | static int do_sas_phy_delete(struct device *dev, void *data) | 175 | static int do_sas_phy_delete(struct device *dev, void *data) |
176 | { | 176 | { |
177 | if (scsi_is_sas_phy(dev)) | 177 | int pass = (int)(unsigned long)data; |
178 | |||
179 | if (pass == 0 && scsi_is_sas_port(dev)) | ||
180 | sas_port_delete(dev_to_sas_port(dev)); | ||
181 | else if (pass == 1 && scsi_is_sas_phy(dev)) | ||
178 | sas_phy_delete(dev_to_phy(dev)); | 182 | sas_phy_delete(dev_to_phy(dev)); |
179 | return 0; | 183 | return 0; |
180 | } | 184 | } |
181 | 185 | ||
182 | /** | 186 | /** |
187 | * sas_remove_children -- tear down a devices SAS data structures | ||
188 | * @dev: device belonging to the sas object | ||
189 | * | ||
190 | * Removes all SAS PHYs and remote PHYs for a given object | ||
191 | */ | ||
192 | void sas_remove_children(struct device *dev) | ||
193 | { | ||
194 | device_for_each_child(dev, (void *)0, do_sas_phy_delete); | ||
195 | device_for_each_child(dev, (void *)1, do_sas_phy_delete); | ||
196 | } | ||
197 | EXPORT_SYMBOL(sas_remove_children); | ||
198 | |||
199 | /** | ||
183 | * sas_remove_host -- tear down a Scsi_Host's SAS data structures | 200 | * sas_remove_host -- tear down a Scsi_Host's SAS data structures |
184 | * @shost: Scsi Host that is torn down | 201 | * @shost: Scsi Host that is torn down |
185 | * | 202 | * |
@@ -188,13 +205,13 @@ static int do_sas_phy_delete(struct device *dev, void *data) | |||
188 | */ | 205 | */ |
189 | void sas_remove_host(struct Scsi_Host *shost) | 206 | void sas_remove_host(struct Scsi_Host *shost) |
190 | { | 207 | { |
191 | device_for_each_child(&shost->shost_gendev, NULL, do_sas_phy_delete); | 208 | sas_remove_children(&shost->shost_gendev); |
192 | } | 209 | } |
193 | EXPORT_SYMBOL(sas_remove_host); | 210 | EXPORT_SYMBOL(sas_remove_host); |
194 | 211 | ||
195 | 212 | ||
196 | /* | 213 | /* |
197 | * SAS Port attributes | 214 | * SAS Phy attributes |
198 | */ | 215 | */ |
199 | 216 | ||
200 | #define sas_phy_show_simple(field, name, format_string, cast) \ | 217 | #define sas_phy_show_simple(field, name, format_string, cast) \ |
@@ -310,7 +327,7 @@ sas_phy_protocol_attr(identify.target_port_protocols, | |||
310 | sas_phy_simple_attr(identify.sas_address, sas_address, "0x%016llx\n", | 327 | sas_phy_simple_attr(identify.sas_address, sas_address, "0x%016llx\n", |
311 | unsigned long long); | 328 | unsigned long long); |
312 | sas_phy_simple_attr(identify.phy_identifier, phy_identifier, "%d\n", u8); | 329 | sas_phy_simple_attr(identify.phy_identifier, phy_identifier, "%d\n", u8); |
313 | sas_phy_simple_attr(port_identifier, port_identifier, "%d\n", u8); | 330 | //sas_phy_simple_attr(port_identifier, port_identifier, "%d\n", u8); |
314 | sas_phy_linkspeed_attr(negotiated_linkrate); | 331 | sas_phy_linkspeed_attr(negotiated_linkrate); |
315 | sas_phy_linkspeed_attr(minimum_linkrate_hw); | 332 | sas_phy_linkspeed_attr(minimum_linkrate_hw); |
316 | sas_phy_linkspeed_attr(minimum_linkrate); | 333 | sas_phy_linkspeed_attr(minimum_linkrate); |
@@ -378,9 +395,10 @@ struct sas_phy *sas_phy_alloc(struct device *parent, int number) | |||
378 | device_initialize(&phy->dev); | 395 | device_initialize(&phy->dev); |
379 | phy->dev.parent = get_device(parent); | 396 | phy->dev.parent = get_device(parent); |
380 | phy->dev.release = sas_phy_release; | 397 | phy->dev.release = sas_phy_release; |
398 | INIT_LIST_HEAD(&phy->port_siblings); | ||
381 | if (scsi_is_sas_expander_device(parent)) { | 399 | if (scsi_is_sas_expander_device(parent)) { |
382 | struct sas_rphy *rphy = dev_to_rphy(parent); | 400 | struct sas_rphy *rphy = dev_to_rphy(parent); |
383 | sprintf(phy->dev.bus_id, "phy-%d-%d:%d", shost->host_no, | 401 | sprintf(phy->dev.bus_id, "phy-%d:%d:%d", shost->host_no, |
384 | rphy->scsi_target_id, number); | 402 | rphy->scsi_target_id, number); |
385 | } else | 403 | } else |
386 | sprintf(phy->dev.bus_id, "phy-%d:%d", shost->host_no, number); | 404 | sprintf(phy->dev.bus_id, "phy-%d:%d", shost->host_no, number); |
@@ -440,8 +458,8 @@ sas_phy_delete(struct sas_phy *phy) | |||
440 | { | 458 | { |
441 | struct device *dev = &phy->dev; | 459 | struct device *dev = &phy->dev; |
442 | 460 | ||
443 | if (phy->rphy) | 461 | /* this happens if the phy is still part of a port when deleted */ |
444 | sas_rphy_delete(phy->rphy); | 462 | BUG_ON(!list_empty(&phy->port_siblings)); |
445 | 463 | ||
446 | transport_remove_device(dev); | 464 | transport_remove_device(dev); |
447 | device_del(dev); | 465 | device_del(dev); |
@@ -464,6 +482,258 @@ int scsi_is_sas_phy(const struct device *dev) | |||
464 | EXPORT_SYMBOL(scsi_is_sas_phy); | 482 | EXPORT_SYMBOL(scsi_is_sas_phy); |
465 | 483 | ||
466 | /* | 484 | /* |
485 | * SAS Port attributes | ||
486 | */ | ||
487 | #define sas_port_show_simple(field, name, format_string, cast) \ | ||
488 | static ssize_t \ | ||
489 | show_sas_port_##name(struct class_device *cdev, char *buf) \ | ||
490 | { \ | ||
491 | struct sas_port *port = transport_class_to_sas_port(cdev); \ | ||
492 | \ | ||
493 | return snprintf(buf, 20, format_string, cast port->field); \ | ||
494 | } | ||
495 | |||
496 | #define sas_port_simple_attr(field, name, format_string, type) \ | ||
497 | sas_port_show_simple(field, name, format_string, (type)) \ | ||
498 | static CLASS_DEVICE_ATTR(name, S_IRUGO, show_sas_port_##name, NULL) | ||
499 | |||
500 | sas_port_simple_attr(num_phys, num_phys, "%d\n", int); | ||
501 | |||
502 | static DECLARE_TRANSPORT_CLASS(sas_port_class, | ||
503 | "sas_port", NULL, NULL, NULL); | ||
504 | |||
505 | static int sas_port_match(struct attribute_container *cont, struct device *dev) | ||
506 | { | ||
507 | struct Scsi_Host *shost; | ||
508 | struct sas_internal *i; | ||
509 | |||
510 | if (!scsi_is_sas_port(dev)) | ||
511 | return 0; | ||
512 | shost = dev_to_shost(dev->parent); | ||
513 | |||
514 | if (!shost->transportt) | ||
515 | return 0; | ||
516 | if (shost->transportt->host_attrs.ac.class != | ||
517 | &sas_host_class.class) | ||
518 | return 0; | ||
519 | |||
520 | i = to_sas_internal(shost->transportt); | ||
521 | return &i->port_attr_cont.ac == cont; | ||
522 | } | ||
523 | |||
524 | |||
525 | static void sas_port_release(struct device *dev) | ||
526 | { | ||
527 | struct sas_port *port = dev_to_sas_port(dev); | ||
528 | |||
529 | BUG_ON(!list_empty(&port->phy_list)); | ||
530 | |||
531 | put_device(dev->parent); | ||
532 | kfree(port); | ||
533 | } | ||
534 | |||
535 | static void sas_port_create_link(struct sas_port *port, | ||
536 | struct sas_phy *phy) | ||
537 | { | ||
538 | sysfs_create_link(&port->dev.kobj, &phy->dev.kobj, phy->dev.bus_id); | ||
539 | sysfs_create_link(&phy->dev.kobj, &port->dev.kobj, "port"); | ||
540 | } | ||
541 | |||
542 | static void sas_port_delete_link(struct sas_port *port, | ||
543 | struct sas_phy *phy) | ||
544 | { | ||
545 | sysfs_remove_link(&port->dev.kobj, phy->dev.bus_id); | ||
546 | sysfs_remove_link(&phy->dev.kobj, "port"); | ||
547 | } | ||
548 | |||
549 | /** sas_port_alloc - allocate and initialize a SAS port structure | ||
550 | * | ||
551 | * @parent: parent device | ||
552 | * @port_id: port number | ||
553 | * | ||
554 | * Allocates a SAS port structure. It will be added to the device tree | ||
555 | * below the device specified by @parent which must be either a Scsi_Host | ||
556 | * or a sas_expander_device. | ||
557 | * | ||
558 | * Returns %NULL on error | ||
559 | */ | ||
560 | struct sas_port *sas_port_alloc(struct device *parent, int port_id) | ||
561 | { | ||
562 | struct Scsi_Host *shost = dev_to_shost(parent); | ||
563 | struct sas_port *port; | ||
564 | |||
565 | port = kzalloc(sizeof(*port), GFP_KERNEL); | ||
566 | if (!port) | ||
567 | return NULL; | ||
568 | |||
569 | port->port_identifier = port_id; | ||
570 | |||
571 | device_initialize(&port->dev); | ||
572 | |||
573 | port->dev.parent = get_device(parent); | ||
574 | port->dev.release = sas_port_release; | ||
575 | |||
576 | mutex_init(&port->phy_list_mutex); | ||
577 | INIT_LIST_HEAD(&port->phy_list); | ||
578 | |||
579 | if (scsi_is_sas_expander_device(parent)) { | ||
580 | struct sas_rphy *rphy = dev_to_rphy(parent); | ||
581 | sprintf(port->dev.bus_id, "port-%d:%d:%d", shost->host_no, | ||
582 | rphy->scsi_target_id, port->port_identifier); | ||
583 | } else | ||
584 | sprintf(port->dev.bus_id, "port-%d:%d", shost->host_no, | ||
585 | port->port_identifier); | ||
586 | |||
587 | transport_setup_device(&port->dev); | ||
588 | |||
589 | return port; | ||
590 | } | ||
591 | EXPORT_SYMBOL(sas_port_alloc); | ||
592 | |||
593 | /** | ||
594 | * sas_port_add - add a SAS port to the device hierarchy | ||
595 | * | ||
596 | * @port: port to be added | ||
597 | * | ||
598 | * publishes a port to the rest of the system | ||
599 | */ | ||
600 | int sas_port_add(struct sas_port *port) | ||
601 | { | ||
602 | int error; | ||
603 | |||
604 | /* No phys should be added until this is made visible */ | ||
605 | BUG_ON(!list_empty(&port->phy_list)); | ||
606 | |||
607 | error = device_add(&port->dev); | ||
608 | |||
609 | if (error) | ||
610 | return error; | ||
611 | |||
612 | transport_add_device(&port->dev); | ||
613 | transport_configure_device(&port->dev); | ||
614 | |||
615 | return 0; | ||
616 | } | ||
617 | EXPORT_SYMBOL(sas_port_add); | ||
618 | |||
619 | /** | ||
620 | * sas_port_free -- free a SAS PORT | ||
621 | * @port: SAS PORT to free | ||
622 | * | ||
623 | * Frees the specified SAS PORT. | ||
624 | * | ||
625 | * Note: | ||
626 | * This function must only be called on a PORT that has not | ||
627 | * sucessfully been added using sas_port_add(). | ||
628 | */ | ||
629 | void sas_port_free(struct sas_port *port) | ||
630 | { | ||
631 | transport_destroy_device(&port->dev); | ||
632 | put_device(&port->dev); | ||
633 | } | ||
634 | EXPORT_SYMBOL(sas_port_free); | ||
635 | |||
636 | /** | ||
637 | * sas_port_delete -- remove SAS PORT | ||
638 | * @port: SAS PORT to remove | ||
639 | * | ||
640 | * Removes the specified SAS PORT. If the SAS PORT has an | ||
641 | * associated phys, unlink them from the port as well. | ||
642 | */ | ||
643 | void sas_port_delete(struct sas_port *port) | ||
644 | { | ||
645 | struct device *dev = &port->dev; | ||
646 | struct sas_phy *phy, *tmp_phy; | ||
647 | |||
648 | if (port->rphy) { | ||
649 | sas_rphy_delete(port->rphy); | ||
650 | port->rphy = NULL; | ||
651 | } | ||
652 | |||
653 | mutex_lock(&port->phy_list_mutex); | ||
654 | list_for_each_entry_safe(phy, tmp_phy, &port->phy_list, | ||
655 | port_siblings) { | ||
656 | sas_port_delete_link(port, phy); | ||
657 | list_del_init(&phy->port_siblings); | ||
658 | } | ||
659 | mutex_unlock(&port->phy_list_mutex); | ||
660 | |||
661 | transport_remove_device(dev); | ||
662 | device_del(dev); | ||
663 | transport_destroy_device(dev); | ||
664 | put_device(dev); | ||
665 | } | ||
666 | EXPORT_SYMBOL(sas_port_delete); | ||
667 | |||
668 | /** | ||
669 | * scsi_is_sas_port -- check if a struct device represents a SAS port | ||
670 | * @dev: device to check | ||
671 | * | ||
672 | * Returns: | ||
673 | * %1 if the device represents a SAS Port, %0 else | ||
674 | */ | ||
675 | int scsi_is_sas_port(const struct device *dev) | ||
676 | { | ||
677 | return dev->release == sas_port_release; | ||
678 | } | ||
679 | EXPORT_SYMBOL(scsi_is_sas_port); | ||
680 | |||
681 | /** | ||
682 | * sas_port_add_phy - add another phy to a port to form a wide port | ||
683 | * @port: port to add the phy to | ||
684 | * @phy: phy to add | ||
685 | * | ||
686 | * When a port is initially created, it is empty (has no phys). All | ||
687 | * ports must have at least one phy to operated, and all wide ports | ||
688 | * must have at least two. The current code makes no difference | ||
689 | * between ports and wide ports, but the only object that can be | ||
690 | * connected to a remote device is a port, so ports must be formed on | ||
691 | * all devices with phys if they're connected to anything. | ||
692 | */ | ||
693 | void sas_port_add_phy(struct sas_port *port, struct sas_phy *phy) | ||
694 | { | ||
695 | mutex_lock(&port->phy_list_mutex); | ||
696 | if (unlikely(!list_empty(&phy->port_siblings))) { | ||
697 | /* make sure we're already on this port */ | ||
698 | struct sas_phy *tmp; | ||
699 | |||
700 | list_for_each_entry(tmp, &port->phy_list, port_siblings) | ||
701 | if (tmp == phy) | ||
702 | break; | ||
703 | /* If this trips, you added a phy that was already | ||
704 | * part of a different port */ | ||
705 | if (unlikely(tmp != phy)) { | ||
706 | dev_printk(KERN_ERR, &port->dev, "trying to add phy %s fails: it's already part of another port\n", phy->dev.bus_id); | ||
707 | BUG(); | ||
708 | } | ||
709 | } else { | ||
710 | sas_port_create_link(port, phy); | ||
711 | list_add_tail(&phy->port_siblings, &port->phy_list); | ||
712 | port->num_phys++; | ||
713 | } | ||
714 | mutex_unlock(&port->phy_list_mutex); | ||
715 | } | ||
716 | EXPORT_SYMBOL(sas_port_add_phy); | ||
717 | |||
718 | /** | ||
719 | * sas_port_delete_phy - remove a phy from a port or wide port | ||
720 | * @port: port to remove the phy from | ||
721 | * @phy: phy to remove | ||
722 | * | ||
723 | * This operation is used for tearing down ports again. It must be | ||
724 | * done to every port or wide port before calling sas_port_delete. | ||
725 | */ | ||
726 | void sas_port_delete_phy(struct sas_port *port, struct sas_phy *phy) | ||
727 | { | ||
728 | mutex_lock(&port->phy_list_mutex); | ||
729 | sas_port_delete_link(port, phy); | ||
730 | list_del_init(&phy->port_siblings); | ||
731 | port->num_phys--; | ||
732 | mutex_unlock(&port->phy_list_mutex); | ||
733 | } | ||
734 | EXPORT_SYMBOL(sas_port_delete_phy); | ||
735 | |||
736 | /* | ||
467 | * SAS remote PHY attributes. | 737 | * SAS remote PHY attributes. |
468 | */ | 738 | */ |
469 | 739 | ||
@@ -767,7 +1037,7 @@ static void sas_rphy_initialize(struct sas_rphy *rphy) | |||
767 | * Returns: | 1037 | * Returns: |
768 | * SAS PHY allocated or %NULL if the allocation failed. | 1038 | * SAS PHY allocated or %NULL if the allocation failed. |
769 | */ | 1039 | */ |
770 | struct sas_rphy *sas_end_device_alloc(struct sas_phy *parent) | 1040 | struct sas_rphy *sas_end_device_alloc(struct sas_port *parent) |
771 | { | 1041 | { |
772 | struct Scsi_Host *shost = dev_to_shost(&parent->dev); | 1042 | struct Scsi_Host *shost = dev_to_shost(&parent->dev); |
773 | struct sas_end_device *rdev; | 1043 | struct sas_end_device *rdev; |
@@ -780,8 +1050,13 @@ struct sas_rphy *sas_end_device_alloc(struct sas_phy *parent) | |||
780 | device_initialize(&rdev->rphy.dev); | 1050 | device_initialize(&rdev->rphy.dev); |
781 | rdev->rphy.dev.parent = get_device(&parent->dev); | 1051 | rdev->rphy.dev.parent = get_device(&parent->dev); |
782 | rdev->rphy.dev.release = sas_end_device_release; | 1052 | rdev->rphy.dev.release = sas_end_device_release; |
783 | sprintf(rdev->rphy.dev.bus_id, "end_device-%d:%d-%d", | 1053 | if (scsi_is_sas_expander_device(parent->dev.parent)) { |
784 | shost->host_no, parent->port_identifier, parent->number); | 1054 | struct sas_rphy *rphy = dev_to_rphy(parent->dev.parent); |
1055 | sprintf(rdev->rphy.dev.bus_id, "end_device-%d:%d:%d", | ||
1056 | shost->host_no, rphy->scsi_target_id, parent->port_identifier); | ||
1057 | } else | ||
1058 | sprintf(rdev->rphy.dev.bus_id, "end_device-%d:%d", | ||
1059 | shost->host_no, parent->port_identifier); | ||
785 | rdev->rphy.identify.device_type = SAS_END_DEVICE; | 1060 | rdev->rphy.identify.device_type = SAS_END_DEVICE; |
786 | sas_rphy_initialize(&rdev->rphy); | 1061 | sas_rphy_initialize(&rdev->rphy); |
787 | transport_setup_device(&rdev->rphy.dev); | 1062 | transport_setup_device(&rdev->rphy.dev); |
@@ -798,7 +1073,7 @@ EXPORT_SYMBOL(sas_end_device_alloc); | |||
798 | * Returns: | 1073 | * Returns: |
799 | * SAS PHY allocated or %NULL if the allocation failed. | 1074 | * SAS PHY allocated or %NULL if the allocation failed. |
800 | */ | 1075 | */ |
801 | struct sas_rphy *sas_expander_alloc(struct sas_phy *parent, | 1076 | struct sas_rphy *sas_expander_alloc(struct sas_port *parent, |
802 | enum sas_device_type type) | 1077 | enum sas_device_type type) |
803 | { | 1078 | { |
804 | struct Scsi_Host *shost = dev_to_shost(&parent->dev); | 1079 | struct Scsi_Host *shost = dev_to_shost(&parent->dev); |
@@ -837,7 +1112,7 @@ EXPORT_SYMBOL(sas_expander_alloc); | |||
837 | */ | 1112 | */ |
838 | int sas_rphy_add(struct sas_rphy *rphy) | 1113 | int sas_rphy_add(struct sas_rphy *rphy) |
839 | { | 1114 | { |
840 | struct sas_phy *parent = dev_to_phy(rphy->dev.parent); | 1115 | struct sas_port *parent = dev_to_sas_port(rphy->dev.parent); |
841 | struct Scsi_Host *shost = dev_to_shost(parent->dev.parent); | 1116 | struct Scsi_Host *shost = dev_to_shost(parent->dev.parent); |
842 | struct sas_host_attrs *sas_host = to_sas_host_attrs(shost); | 1117 | struct sas_host_attrs *sas_host = to_sas_host_attrs(shost); |
843 | struct sas_identify *identify = &rphy->identify; | 1118 | struct sas_identify *identify = &rphy->identify; |
@@ -910,7 +1185,7 @@ void | |||
910 | sas_rphy_delete(struct sas_rphy *rphy) | 1185 | sas_rphy_delete(struct sas_rphy *rphy) |
911 | { | 1186 | { |
912 | struct device *dev = &rphy->dev; | 1187 | struct device *dev = &rphy->dev; |
913 | struct sas_phy *parent = dev_to_phy(dev->parent); | 1188 | struct sas_port *parent = dev_to_sas_port(dev->parent); |
914 | struct Scsi_Host *shost = dev_to_shost(parent->dev.parent); | 1189 | struct Scsi_Host *shost = dev_to_shost(parent->dev.parent); |
915 | struct sas_host_attrs *sas_host = to_sas_host_attrs(shost); | 1190 | struct sas_host_attrs *sas_host = to_sas_host_attrs(shost); |
916 | 1191 | ||
@@ -920,7 +1195,7 @@ sas_rphy_delete(struct sas_rphy *rphy) | |||
920 | break; | 1195 | break; |
921 | case SAS_EDGE_EXPANDER_DEVICE: | 1196 | case SAS_EDGE_EXPANDER_DEVICE: |
922 | case SAS_FANOUT_EXPANDER_DEVICE: | 1197 | case SAS_FANOUT_EXPANDER_DEVICE: |
923 | device_for_each_child(dev, NULL, do_sas_phy_delete); | 1198 | sas_remove_children(dev); |
924 | break; | 1199 | break; |
925 | default: | 1200 | default: |
926 | break; | 1201 | break; |
@@ -967,7 +1242,7 @@ static int sas_user_scan(struct Scsi_Host *shost, uint channel, | |||
967 | 1242 | ||
968 | mutex_lock(&sas_host->lock); | 1243 | mutex_lock(&sas_host->lock); |
969 | list_for_each_entry(rphy, &sas_host->rphy_list, list) { | 1244 | list_for_each_entry(rphy, &sas_host->rphy_list, list) { |
970 | struct sas_phy *parent = dev_to_phy(rphy->dev.parent); | 1245 | struct sas_port *parent = dev_to_sas_port(rphy->dev.parent); |
971 | 1246 | ||
972 | if (rphy->identify.device_type != SAS_END_DEVICE || | 1247 | if (rphy->identify.device_type != SAS_END_DEVICE || |
973 | rphy->scsi_target_id == -1) | 1248 | rphy->scsi_target_id == -1) |
@@ -1003,16 +1278,19 @@ static int sas_user_scan(struct Scsi_Host *shost, uint channel, | |||
1003 | #define SETUP_OPTIONAL_RPORT_ATTRIBUTE(field, func) \ | 1278 | #define SETUP_OPTIONAL_RPORT_ATTRIBUTE(field, func) \ |
1004 | SETUP_TEMPLATE(rphy_attrs, field, S_IRUGO, i->f->func) | 1279 | SETUP_TEMPLATE(rphy_attrs, field, S_IRUGO, i->f->func) |
1005 | 1280 | ||
1006 | #define SETUP_PORT_ATTRIBUTE(field) \ | 1281 | #define SETUP_PHY_ATTRIBUTE(field) \ |
1007 | SETUP_TEMPLATE(phy_attrs, field, S_IRUGO, 1) | 1282 | SETUP_TEMPLATE(phy_attrs, field, S_IRUGO, 1) |
1008 | 1283 | ||
1009 | #define SETUP_OPTIONAL_PORT_ATTRIBUTE(field, func) \ | 1284 | #define SETUP_PORT_ATTRIBUTE(field) \ |
1285 | SETUP_TEMPLATE(port_attrs, field, S_IRUGO, 1) | ||
1286 | |||
1287 | #define SETUP_OPTIONAL_PHY_ATTRIBUTE(field, func) \ | ||
1010 | SETUP_TEMPLATE(phy_attrs, field, S_IRUGO, i->f->func) | 1288 | SETUP_TEMPLATE(phy_attrs, field, S_IRUGO, i->f->func) |
1011 | 1289 | ||
1012 | #define SETUP_PORT_ATTRIBUTE_WRONLY(field) \ | 1290 | #define SETUP_PHY_ATTRIBUTE_WRONLY(field) \ |
1013 | SETUP_TEMPLATE(phy_attrs, field, S_IWUGO, 1) | 1291 | SETUP_TEMPLATE(phy_attrs, field, S_IWUGO, 1) |
1014 | 1292 | ||
1015 | #define SETUP_OPTIONAL_PORT_ATTRIBUTE_WRONLY(field, func) \ | 1293 | #define SETUP_OPTIONAL_PHY_ATTRIBUTE_WRONLY(field, func) \ |
1016 | SETUP_TEMPLATE(phy_attrs, field, S_IWUGO, i->f->func) | 1294 | SETUP_TEMPLATE(phy_attrs, field, S_IWUGO, i->f->func) |
1017 | 1295 | ||
1018 | #define SETUP_END_DEV_ATTRIBUTE(field) \ | 1296 | #define SETUP_END_DEV_ATTRIBUTE(field) \ |
@@ -1048,6 +1326,11 @@ sas_attach_transport(struct sas_function_template *ft) | |||
1048 | i->phy_attr_cont.ac.match = sas_phy_match; | 1326 | i->phy_attr_cont.ac.match = sas_phy_match; |
1049 | transport_container_register(&i->phy_attr_cont); | 1327 | transport_container_register(&i->phy_attr_cont); |
1050 | 1328 | ||
1329 | i->port_attr_cont.ac.class = &sas_port_class.class; | ||
1330 | i->port_attr_cont.ac.attrs = &i->port_attrs[0]; | ||
1331 | i->port_attr_cont.ac.match = sas_port_match; | ||
1332 | transport_container_register(&i->port_attr_cont); | ||
1333 | |||
1051 | i->rphy_attr_cont.ac.class = &sas_rphy_class.class; | 1334 | i->rphy_attr_cont.ac.class = &sas_rphy_class.class; |
1052 | i->rphy_attr_cont.ac.attrs = &i->rphy_attrs[0]; | 1335 | i->rphy_attr_cont.ac.attrs = &i->rphy_attrs[0]; |
1053 | i->rphy_attr_cont.ac.match = sas_rphy_match; | 1336 | i->rphy_attr_cont.ac.match = sas_rphy_match; |
@@ -1066,30 +1349,35 @@ sas_attach_transport(struct sas_function_template *ft) | |||
1066 | i->f = ft; | 1349 | i->f = ft; |
1067 | 1350 | ||
1068 | count = 0; | 1351 | count = 0; |
1352 | SETUP_PORT_ATTRIBUTE(num_phys); | ||
1069 | i->host_attrs[count] = NULL; | 1353 | i->host_attrs[count] = NULL; |
1070 | 1354 | ||
1071 | count = 0; | 1355 | count = 0; |
1072 | SETUP_PORT_ATTRIBUTE(initiator_port_protocols); | 1356 | SETUP_PHY_ATTRIBUTE(initiator_port_protocols); |
1073 | SETUP_PORT_ATTRIBUTE(target_port_protocols); | 1357 | SETUP_PHY_ATTRIBUTE(target_port_protocols); |
1074 | SETUP_PORT_ATTRIBUTE(device_type); | 1358 | SETUP_PHY_ATTRIBUTE(device_type); |
1075 | SETUP_PORT_ATTRIBUTE(sas_address); | 1359 | SETUP_PHY_ATTRIBUTE(sas_address); |
1076 | SETUP_PORT_ATTRIBUTE(phy_identifier); | 1360 | SETUP_PHY_ATTRIBUTE(phy_identifier); |
1077 | SETUP_PORT_ATTRIBUTE(port_identifier); | 1361 | //SETUP_PHY_ATTRIBUTE(port_identifier); |
1078 | SETUP_PORT_ATTRIBUTE(negotiated_linkrate); | 1362 | SETUP_PHY_ATTRIBUTE(negotiated_linkrate); |
1079 | SETUP_PORT_ATTRIBUTE(minimum_linkrate_hw); | 1363 | SETUP_PHY_ATTRIBUTE(minimum_linkrate_hw); |
1080 | SETUP_PORT_ATTRIBUTE(minimum_linkrate); | 1364 | SETUP_PHY_ATTRIBUTE(minimum_linkrate); |
1081 | SETUP_PORT_ATTRIBUTE(maximum_linkrate_hw); | 1365 | SETUP_PHY_ATTRIBUTE(maximum_linkrate_hw); |
1082 | SETUP_PORT_ATTRIBUTE(maximum_linkrate); | 1366 | SETUP_PHY_ATTRIBUTE(maximum_linkrate); |
1083 | 1367 | ||
1084 | SETUP_PORT_ATTRIBUTE(invalid_dword_count); | 1368 | SETUP_PHY_ATTRIBUTE(invalid_dword_count); |
1085 | SETUP_PORT_ATTRIBUTE(running_disparity_error_count); | 1369 | SETUP_PHY_ATTRIBUTE(running_disparity_error_count); |
1086 | SETUP_PORT_ATTRIBUTE(loss_of_dword_sync_count); | 1370 | SETUP_PHY_ATTRIBUTE(loss_of_dword_sync_count); |
1087 | SETUP_PORT_ATTRIBUTE(phy_reset_problem_count); | 1371 | SETUP_PHY_ATTRIBUTE(phy_reset_problem_count); |
1088 | SETUP_OPTIONAL_PORT_ATTRIBUTE_WRONLY(link_reset, phy_reset); | 1372 | SETUP_OPTIONAL_PHY_ATTRIBUTE_WRONLY(link_reset, phy_reset); |
1089 | SETUP_OPTIONAL_PORT_ATTRIBUTE_WRONLY(hard_reset, phy_reset); | 1373 | SETUP_OPTIONAL_PHY_ATTRIBUTE_WRONLY(hard_reset, phy_reset); |
1090 | i->phy_attrs[count] = NULL; | 1374 | i->phy_attrs[count] = NULL; |
1091 | 1375 | ||
1092 | count = 0; | 1376 | count = 0; |
1377 | SETUP_PORT_ATTRIBUTE(num_phys); | ||
1378 | i->port_attrs[count] = NULL; | ||
1379 | |||
1380 | count = 0; | ||
1093 | SETUP_RPORT_ATTRIBUTE(rphy_initiator_port_protocols); | 1381 | SETUP_RPORT_ATTRIBUTE(rphy_initiator_port_protocols); |
1094 | SETUP_RPORT_ATTRIBUTE(rphy_target_port_protocols); | 1382 | SETUP_RPORT_ATTRIBUTE(rphy_target_port_protocols); |
1095 | SETUP_RPORT_ATTRIBUTE(rphy_device_type); | 1383 | SETUP_RPORT_ATTRIBUTE(rphy_device_type); |
@@ -1131,6 +1419,7 @@ void sas_release_transport(struct scsi_transport_template *t) | |||
1131 | 1419 | ||
1132 | transport_container_unregister(&i->t.host_attrs); | 1420 | transport_container_unregister(&i->t.host_attrs); |
1133 | transport_container_unregister(&i->phy_attr_cont); | 1421 | transport_container_unregister(&i->phy_attr_cont); |
1422 | transport_container_unregister(&i->port_attr_cont); | ||
1134 | transport_container_unregister(&i->rphy_attr_cont); | 1423 | transport_container_unregister(&i->rphy_attr_cont); |
1135 | transport_container_unregister(&i->end_dev_attr_cont); | 1424 | transport_container_unregister(&i->end_dev_attr_cont); |
1136 | transport_container_unregister(&i->expander_attr_cont); | 1425 | transport_container_unregister(&i->expander_attr_cont); |
@@ -1149,9 +1438,12 @@ static __init int sas_transport_init(void) | |||
1149 | error = transport_class_register(&sas_phy_class); | 1438 | error = transport_class_register(&sas_phy_class); |
1150 | if (error) | 1439 | if (error) |
1151 | goto out_unregister_transport; | 1440 | goto out_unregister_transport; |
1152 | error = transport_class_register(&sas_rphy_class); | 1441 | error = transport_class_register(&sas_port_class); |
1153 | if (error) | 1442 | if (error) |
1154 | goto out_unregister_phy; | 1443 | goto out_unregister_phy; |
1444 | error = transport_class_register(&sas_rphy_class); | ||
1445 | if (error) | ||
1446 | goto out_unregister_port; | ||
1155 | error = transport_class_register(&sas_end_dev_class); | 1447 | error = transport_class_register(&sas_end_dev_class); |
1156 | if (error) | 1448 | if (error) |
1157 | goto out_unregister_rphy; | 1449 | goto out_unregister_rphy; |
@@ -1165,6 +1457,8 @@ static __init int sas_transport_init(void) | |||
1165 | transport_class_unregister(&sas_end_dev_class); | 1457 | transport_class_unregister(&sas_end_dev_class); |
1166 | out_unregister_rphy: | 1458 | out_unregister_rphy: |
1167 | transport_class_unregister(&sas_rphy_class); | 1459 | transport_class_unregister(&sas_rphy_class); |
1460 | out_unregister_port: | ||
1461 | transport_class_unregister(&sas_port_class); | ||
1168 | out_unregister_phy: | 1462 | out_unregister_phy: |
1169 | transport_class_unregister(&sas_phy_class); | 1463 | transport_class_unregister(&sas_phy_class); |
1170 | out_unregister_transport: | 1464 | out_unregister_transport: |
@@ -1178,6 +1472,7 @@ static void __exit sas_transport_exit(void) | |||
1178 | { | 1472 | { |
1179 | transport_class_unregister(&sas_host_class); | 1473 | transport_class_unregister(&sas_host_class); |
1180 | transport_class_unregister(&sas_phy_class); | 1474 | transport_class_unregister(&sas_phy_class); |
1475 | transport_class_unregister(&sas_port_class); | ||
1181 | transport_class_unregister(&sas_rphy_class); | 1476 | transport_class_unregister(&sas_rphy_class); |
1182 | transport_class_unregister(&sas_end_dev_class); | 1477 | transport_class_unregister(&sas_end_dev_class); |
1183 | transport_class_unregister(&sas_expander_class); | 1478 | transport_class_unregister(&sas_expander_class); |
diff --git a/drivers/scsi/scsicam.c b/drivers/scsi/scsicam.c index b78354fc4b17..cd68a66c7bb3 100644 --- a/drivers/scsi/scsicam.c +++ b/drivers/scsi/scsicam.c | |||
@@ -57,6 +57,7 @@ EXPORT_SYMBOL(scsi_bios_ptable); | |||
57 | int scsicam_bios_param(struct block_device *bdev, sector_t capacity, int *ip) | 57 | int scsicam_bios_param(struct block_device *bdev, sector_t capacity, int *ip) |
58 | { | 58 | { |
59 | unsigned char *p; | 59 | unsigned char *p; |
60 | u64 capacity64 = capacity; /* Suppress gcc warning */ | ||
60 | int ret; | 61 | int ret; |
61 | 62 | ||
62 | p = scsi_bios_ptable(bdev); | 63 | p = scsi_bios_ptable(bdev); |
@@ -68,7 +69,7 @@ int scsicam_bios_param(struct block_device *bdev, sector_t capacity, int *ip) | |||
68 | (unsigned int *)ip + 0, (unsigned int *)ip + 1); | 69 | (unsigned int *)ip + 0, (unsigned int *)ip + 1); |
69 | kfree(p); | 70 | kfree(p); |
70 | 71 | ||
71 | if (ret == -1) { | 72 | if (ret == -1 && capacity64 < (1ULL << 32)) { |
72 | /* pick some standard mapping with at most 1024 cylinders, | 73 | /* pick some standard mapping with at most 1024 cylinders, |
73 | and at most 62 sectors per track - this works up to | 74 | and at most 62 sectors per track - this works up to |
74 | 7905 MB */ | 75 | 7905 MB */ |
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index ea38757d12e5..3225d31449e1 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c | |||
@@ -207,6 +207,23 @@ static ssize_t sd_store_cache_type(struct class_device *cdev, const char *buf, | |||
207 | return count; | 207 | return count; |
208 | } | 208 | } |
209 | 209 | ||
210 | static ssize_t sd_store_allow_restart(struct class_device *cdev, const char *buf, | ||
211 | size_t count) | ||
212 | { | ||
213 | struct scsi_disk *sdkp = to_scsi_disk(cdev); | ||
214 | struct scsi_device *sdp = sdkp->device; | ||
215 | |||
216 | if (!capable(CAP_SYS_ADMIN)) | ||
217 | return -EACCES; | ||
218 | |||
219 | if (sdp->type != TYPE_DISK) | ||
220 | return -EINVAL; | ||
221 | |||
222 | sdp->allow_restart = simple_strtoul(buf, NULL, 10); | ||
223 | |||
224 | return count; | ||
225 | } | ||
226 | |||
210 | static ssize_t sd_show_cache_type(struct class_device *cdev, char *buf) | 227 | static ssize_t sd_show_cache_type(struct class_device *cdev, char *buf) |
211 | { | 228 | { |
212 | struct scsi_disk *sdkp = to_scsi_disk(cdev); | 229 | struct scsi_disk *sdkp = to_scsi_disk(cdev); |
@@ -222,10 +239,19 @@ static ssize_t sd_show_fua(struct class_device *cdev, char *buf) | |||
222 | return snprintf(buf, 20, "%u\n", sdkp->DPOFUA); | 239 | return snprintf(buf, 20, "%u\n", sdkp->DPOFUA); |
223 | } | 240 | } |
224 | 241 | ||
242 | static ssize_t sd_show_allow_restart(struct class_device *cdev, char *buf) | ||
243 | { | ||
244 | struct scsi_disk *sdkp = to_scsi_disk(cdev); | ||
245 | |||
246 | return snprintf(buf, 40, "%d\n", sdkp->device->allow_restart); | ||
247 | } | ||
248 | |||
225 | static struct class_device_attribute sd_disk_attrs[] = { | 249 | static struct class_device_attribute sd_disk_attrs[] = { |
226 | __ATTR(cache_type, S_IRUGO|S_IWUSR, sd_show_cache_type, | 250 | __ATTR(cache_type, S_IRUGO|S_IWUSR, sd_show_cache_type, |
227 | sd_store_cache_type), | 251 | sd_store_cache_type), |
228 | __ATTR(FUA, S_IRUGO, sd_show_fua, NULL), | 252 | __ATTR(FUA, S_IRUGO, sd_show_fua, NULL), |
253 | __ATTR(allow_restart, S_IRUGO|S_IWUSR, sd_show_allow_restart, | ||
254 | sd_store_allow_restart), | ||
229 | __ATTR_NULL, | 255 | __ATTR_NULL, |
230 | }; | 256 | }; |
231 | 257 | ||
@@ -890,11 +916,10 @@ static struct block_device_operations sd_fops = { | |||
890 | static void sd_rw_intr(struct scsi_cmnd * SCpnt) | 916 | static void sd_rw_intr(struct scsi_cmnd * SCpnt) |
891 | { | 917 | { |
892 | int result = SCpnt->result; | 918 | int result = SCpnt->result; |
893 | int this_count = SCpnt->request_bufflen; | 919 | unsigned int xfer_size = SCpnt->request_bufflen; |
894 | int good_bytes = (result == 0 ? this_count : 0); | 920 | unsigned int good_bytes = result ? 0 : xfer_size; |
895 | sector_t block_sectors = 1; | 921 | u64 start_lba = SCpnt->request->sector; |
896 | u64 first_err_block; | 922 | u64 bad_lba; |
897 | sector_t error_sector; | ||
898 | struct scsi_sense_hdr sshdr; | 923 | struct scsi_sense_hdr sshdr; |
899 | int sense_valid = 0; | 924 | int sense_valid = 0; |
900 | int sense_deferred = 0; | 925 | int sense_deferred = 0; |
@@ -905,7 +930,6 @@ static void sd_rw_intr(struct scsi_cmnd * SCpnt) | |||
905 | if (sense_valid) | 930 | if (sense_valid) |
906 | sense_deferred = scsi_sense_is_deferred(&sshdr); | 931 | sense_deferred = scsi_sense_is_deferred(&sshdr); |
907 | } | 932 | } |
908 | |||
909 | #ifdef CONFIG_SCSI_LOGGING | 933 | #ifdef CONFIG_SCSI_LOGGING |
910 | SCSI_LOG_HLCOMPLETE(1, printk("sd_rw_intr: %s: res=0x%x\n", | 934 | SCSI_LOG_HLCOMPLETE(1, printk("sd_rw_intr: %s: res=0x%x\n", |
911 | SCpnt->request->rq_disk->disk_name, result)); | 935 | SCpnt->request->rq_disk->disk_name, result)); |
@@ -915,89 +939,72 @@ static void sd_rw_intr(struct scsi_cmnd * SCpnt) | |||
915 | sshdr.sense_key, sshdr.asc, sshdr.ascq)); | 939 | sshdr.sense_key, sshdr.asc, sshdr.ascq)); |
916 | } | 940 | } |
917 | #endif | 941 | #endif |
918 | /* | 942 | if (driver_byte(result) != DRIVER_SENSE && |
919 | Handle MEDIUM ERRORs that indicate partial success. Since this is a | 943 | (!sense_valid || sense_deferred)) |
920 | relatively rare error condition, no care is taken to avoid | 944 | goto out; |
921 | unnecessary additional work such as memcpy's that could be avoided. | ||
922 | */ | ||
923 | if (driver_byte(result) != 0 && | ||
924 | sense_valid && !sense_deferred) { | ||
925 | switch (sshdr.sense_key) { | ||
926 | case MEDIUM_ERROR: | ||
927 | if (!blk_fs_request(SCpnt->request)) | ||
928 | break; | ||
929 | info_valid = scsi_get_sense_info_fld( | ||
930 | SCpnt->sense_buffer, SCSI_SENSE_BUFFERSIZE, | ||
931 | &first_err_block); | ||
932 | /* | ||
933 | * May want to warn and skip if following cast results | ||
934 | * in actual truncation (if sector_t < 64 bits) | ||
935 | */ | ||
936 | error_sector = (sector_t)first_err_block; | ||
937 | if (SCpnt->request->bio != NULL) | ||
938 | block_sectors = bio_sectors(SCpnt->request->bio); | ||
939 | switch (SCpnt->device->sector_size) { | ||
940 | case 1024: | ||
941 | error_sector <<= 1; | ||
942 | if (block_sectors < 2) | ||
943 | block_sectors = 2; | ||
944 | break; | ||
945 | case 2048: | ||
946 | error_sector <<= 2; | ||
947 | if (block_sectors < 4) | ||
948 | block_sectors = 4; | ||
949 | break; | ||
950 | case 4096: | ||
951 | error_sector <<=3; | ||
952 | if (block_sectors < 8) | ||
953 | block_sectors = 8; | ||
954 | break; | ||
955 | case 256: | ||
956 | error_sector >>= 1; | ||
957 | break; | ||
958 | default: | ||
959 | break; | ||
960 | } | ||
961 | 945 | ||
962 | error_sector &= ~(block_sectors - 1); | 946 | switch (sshdr.sense_key) { |
963 | good_bytes = (error_sector - SCpnt->request->sector) << 9; | 947 | case HARDWARE_ERROR: |
964 | if (good_bytes < 0 || good_bytes >= this_count) | 948 | case MEDIUM_ERROR: |
965 | good_bytes = 0; | 949 | if (!blk_fs_request(SCpnt->request)) |
950 | goto out; | ||
951 | info_valid = scsi_get_sense_info_fld(SCpnt->sense_buffer, | ||
952 | SCSI_SENSE_BUFFERSIZE, | ||
953 | &bad_lba); | ||
954 | if (!info_valid) | ||
955 | goto out; | ||
956 | if (xfer_size <= SCpnt->device->sector_size) | ||
957 | goto out; | ||
958 | switch (SCpnt->device->sector_size) { | ||
959 | case 256: | ||
960 | start_lba <<= 1; | ||
966 | break; | 961 | break; |
967 | 962 | case 512: | |
968 | case RECOVERED_ERROR: /* an error occurred, but it recovered */ | ||
969 | case NO_SENSE: /* LLDD got sense data */ | ||
970 | /* | ||
971 | * Inform the user, but make sure that it's not treated | ||
972 | * as a hard error. | ||
973 | */ | ||
974 | scsi_print_sense("sd", SCpnt); | ||
975 | SCpnt->result = 0; | ||
976 | memset(SCpnt->sense_buffer, 0, SCSI_SENSE_BUFFERSIZE); | ||
977 | good_bytes = this_count; | ||
978 | break; | 963 | break; |
979 | 964 | case 1024: | |
980 | case ILLEGAL_REQUEST: | 965 | start_lba >>= 1; |
981 | if (SCpnt->device->use_10_for_rw && | 966 | break; |
982 | (SCpnt->cmnd[0] == READ_10 || | 967 | case 2048: |
983 | SCpnt->cmnd[0] == WRITE_10)) | 968 | start_lba >>= 2; |
984 | SCpnt->device->use_10_for_rw = 0; | 969 | break; |
985 | if (SCpnt->device->use_10_for_ms && | 970 | case 4096: |
986 | (SCpnt->cmnd[0] == MODE_SENSE_10 || | 971 | start_lba >>= 3; |
987 | SCpnt->cmnd[0] == MODE_SELECT_10)) | ||
988 | SCpnt->device->use_10_for_ms = 0; | ||
989 | break; | 972 | break; |
990 | |||
991 | default: | 973 | default: |
974 | /* Print something here with limiting frequency. */ | ||
975 | goto out; | ||
992 | break; | 976 | break; |
993 | } | 977 | } |
978 | /* This computation should always be done in terms of | ||
979 | * the resolution of the device's medium. | ||
980 | */ | ||
981 | good_bytes = (bad_lba - start_lba)*SCpnt->device->sector_size; | ||
982 | break; | ||
983 | case RECOVERED_ERROR: | ||
984 | case NO_SENSE: | ||
985 | /* Inform the user, but make sure that it's not treated | ||
986 | * as a hard error. | ||
987 | */ | ||
988 | scsi_print_sense("sd", SCpnt); | ||
989 | SCpnt->result = 0; | ||
990 | memset(SCpnt->sense_buffer, 0, SCSI_SENSE_BUFFERSIZE); | ||
991 | good_bytes = xfer_size; | ||
992 | break; | ||
993 | case ILLEGAL_REQUEST: | ||
994 | if (SCpnt->device->use_10_for_rw && | ||
995 | (SCpnt->cmnd[0] == READ_10 || | ||
996 | SCpnt->cmnd[0] == WRITE_10)) | ||
997 | SCpnt->device->use_10_for_rw = 0; | ||
998 | if (SCpnt->device->use_10_for_ms && | ||
999 | (SCpnt->cmnd[0] == MODE_SENSE_10 || | ||
1000 | SCpnt->cmnd[0] == MODE_SELECT_10)) | ||
1001 | SCpnt->device->use_10_for_ms = 0; | ||
1002 | break; | ||
1003 | default: | ||
1004 | break; | ||
994 | } | 1005 | } |
995 | /* | 1006 | out: |
996 | * This calls the generic completion function, now that we know | 1007 | scsi_io_completion(SCpnt, good_bytes); |
997 | * how many actual sectors finished, and how many sectors we need | ||
998 | * to say have failed. | ||
999 | */ | ||
1000 | scsi_io_completion(SCpnt, good_bytes, block_sectors << 9); | ||
1001 | } | 1008 | } |
1002 | 1009 | ||
1003 | static int media_not_present(struct scsi_disk *sdkp, | 1010 | static int media_not_present(struct scsi_disk *sdkp, |
diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c index 4e607d3065bc..65eef33846bb 100644 --- a/drivers/scsi/sg.c +++ b/drivers/scsi/sg.c | |||
@@ -1401,6 +1401,7 @@ sg_add(struct class_device *cl_dev, struct class_interface *cl_intf) | |||
1401 | Sg_device *sdp = NULL; | 1401 | Sg_device *sdp = NULL; |
1402 | struct cdev * cdev = NULL; | 1402 | struct cdev * cdev = NULL; |
1403 | int error, k; | 1403 | int error, k; |
1404 | unsigned long iflags; | ||
1404 | 1405 | ||
1405 | disk = alloc_disk(1); | 1406 | disk = alloc_disk(1); |
1406 | if (!disk) { | 1407 | if (!disk) { |
@@ -1428,7 +1429,7 @@ sg_add(struct class_device *cl_dev, struct class_interface *cl_intf) | |||
1428 | 1429 | ||
1429 | error = cdev_add(cdev, MKDEV(SCSI_GENERIC_MAJOR, k), 1); | 1430 | error = cdev_add(cdev, MKDEV(SCSI_GENERIC_MAJOR, k), 1); |
1430 | if (error) | 1431 | if (error) |
1431 | goto out; | 1432 | goto cdev_add_err; |
1432 | 1433 | ||
1433 | sdp->cdev = cdev; | 1434 | sdp->cdev = cdev; |
1434 | if (sg_sysfs_valid) { | 1435 | if (sg_sysfs_valid) { |
@@ -1455,6 +1456,13 @@ sg_add(struct class_device *cl_dev, struct class_interface *cl_intf) | |||
1455 | 1456 | ||
1456 | return 0; | 1457 | return 0; |
1457 | 1458 | ||
1459 | cdev_add_err: | ||
1460 | write_lock_irqsave(&sg_dev_arr_lock, iflags); | ||
1461 | kfree(sg_dev_arr[k]); | ||
1462 | sg_dev_arr[k] = NULL; | ||
1463 | sg_nr_dev--; | ||
1464 | write_unlock_irqrestore(&sg_dev_arr_lock, iflags); | ||
1465 | |||
1458 | out: | 1466 | out: |
1459 | put_disk(disk); | 1467 | put_disk(disk); |
1460 | if (cdev) | 1468 | if (cdev) |
diff --git a/drivers/scsi/sr.c b/drivers/scsi/sr.c index ebf6579ed698..fd94408577e5 100644 --- a/drivers/scsi/sr.c +++ b/drivers/scsi/sr.c | |||
@@ -292,7 +292,7 @@ static void rw_intr(struct scsi_cmnd * SCpnt) | |||
292 | * how many actual sectors finished, and how many sectors we need | 292 | * how many actual sectors finished, and how many sectors we need |
293 | * to say have failed. | 293 | * to say have failed. |
294 | */ | 294 | */ |
295 | scsi_io_completion(SCpnt, good_bytes, block_sectors << 9); | 295 | scsi_io_completion(SCpnt, good_bytes); |
296 | } | 296 | } |
297 | 297 | ||
298 | static int sr_init_command(struct scsi_cmnd * SCpnt) | 298 | static int sr_init_command(struct scsi_cmnd * SCpnt) |
diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c index b5218fc0ac86..756ceb93ddc8 100644 --- a/drivers/scsi/st.c +++ b/drivers/scsi/st.c | |||
@@ -3599,7 +3599,6 @@ static struct st_buffer * | |||
3599 | tb->use_sg = max_sg; | 3599 | tb->use_sg = max_sg; |
3600 | tb->frp = (struct st_buf_fragment *)(&(tb->sg[0]) + max_sg); | 3600 | tb->frp = (struct st_buf_fragment *)(&(tb->sg[0]) + max_sg); |
3601 | 3601 | ||
3602 | tb->in_use = 1; | ||
3603 | tb->dma = need_dma; | 3602 | tb->dma = need_dma; |
3604 | tb->buffer_size = got; | 3603 | tb->buffer_size = got; |
3605 | 3604 | ||
diff --git a/drivers/scsi/st.h b/drivers/scsi/st.h index 411209048d74..05a5cae126ec 100644 --- a/drivers/scsi/st.h +++ b/drivers/scsi/st.h | |||
@@ -31,7 +31,6 @@ struct st_request { | |||
31 | 31 | ||
32 | /* The tape buffer descriptor. */ | 32 | /* The tape buffer descriptor. */ |
33 | struct st_buffer { | 33 | struct st_buffer { |
34 | unsigned char in_use; | ||
35 | unsigned char dma; /* DMA-able buffer */ | 34 | unsigned char dma; /* DMA-able buffer */ |
36 | unsigned char do_dio; /* direct i/o set up? */ | 35 | unsigned char do_dio; /* direct i/o set up? */ |
37 | int buffer_size; | 36 | int buffer_size; |
diff --git a/drivers/serial/8250_pci.c b/drivers/serial/8250_pci.c index 864ef859be56..a1d322f8a16c 100644 --- a/drivers/serial/8250_pci.c +++ b/drivers/serial/8250_pci.c | |||
@@ -134,7 +134,7 @@ afavlab_setup(struct serial_private *priv, struct pciserial_board *board, | |||
134 | * and Keystone have one Diva chip with 3 UARTs. Some later machines have | 134 | * and Keystone have one Diva chip with 3 UARTs. Some later machines have |
135 | * one Diva chip, but it has been expanded to 5 UARTs. | 135 | * one Diva chip, but it has been expanded to 5 UARTs. |
136 | */ | 136 | */ |
137 | static int __devinit pci_hp_diva_init(struct pci_dev *dev) | 137 | static int pci_hp_diva_init(struct pci_dev *dev) |
138 | { | 138 | { |
139 | int rc = 0; | 139 | int rc = 0; |
140 | 140 | ||
@@ -194,7 +194,7 @@ pci_hp_diva_setup(struct serial_private *priv, struct pciserial_board *board, | |||
194 | /* | 194 | /* |
195 | * Added for EKF Intel i960 serial boards | 195 | * Added for EKF Intel i960 serial boards |
196 | */ | 196 | */ |
197 | static int __devinit pci_inteli960ni_init(struct pci_dev *dev) | 197 | static int pci_inteli960ni_init(struct pci_dev *dev) |
198 | { | 198 | { |
199 | unsigned long oldval; | 199 | unsigned long oldval; |
200 | 200 | ||
@@ -216,7 +216,7 @@ static int __devinit pci_inteli960ni_init(struct pci_dev *dev) | |||
216 | * seems to be mainly needed on card using the PLX which also use I/O | 216 | * seems to be mainly needed on card using the PLX which also use I/O |
217 | * mapped memory. | 217 | * mapped memory. |
218 | */ | 218 | */ |
219 | static int __devinit pci_plx9050_init(struct pci_dev *dev) | 219 | static int pci_plx9050_init(struct pci_dev *dev) |
220 | { | 220 | { |
221 | u8 irq_config; | 221 | u8 irq_config; |
222 | void __iomem *p; | 222 | void __iomem *p; |
@@ -314,7 +314,7 @@ sbs_setup(struct serial_private *priv, struct pciserial_board *board, | |||
314 | /* global control register offset for SBS PMC-OctalPro */ | 314 | /* global control register offset for SBS PMC-OctalPro */ |
315 | #define OCT_REG_CR_OFF 0x500 | 315 | #define OCT_REG_CR_OFF 0x500 |
316 | 316 | ||
317 | static int __devinit sbs_init(struct pci_dev *dev) | 317 | static int sbs_init(struct pci_dev *dev) |
318 | { | 318 | { |
319 | u8 __iomem *p; | 319 | u8 __iomem *p; |
320 | 320 | ||
@@ -493,7 +493,7 @@ static const struct timedia_struct { | |||
493 | { 0, NULL } | 493 | { 0, NULL } |
494 | }; | 494 | }; |
495 | 495 | ||
496 | static int __devinit pci_timedia_init(struct pci_dev *dev) | 496 | static int pci_timedia_init(struct pci_dev *dev) |
497 | { | 497 | { |
498 | unsigned short *ids; | 498 | unsigned short *ids; |
499 | int i, j; | 499 | int i, j; |
@@ -566,13 +566,13 @@ titan_400l_800l_setup(struct serial_private *priv, | |||
566 | return setup_port(priv, port, bar, offset, board->reg_shift); | 566 | return setup_port(priv, port, bar, offset, board->reg_shift); |
567 | } | 567 | } |
568 | 568 | ||
569 | static int __devinit pci_xircom_init(struct pci_dev *dev) | 569 | static int pci_xircom_init(struct pci_dev *dev) |
570 | { | 570 | { |
571 | msleep(100); | 571 | msleep(100); |
572 | return 0; | 572 | return 0; |
573 | } | 573 | } |
574 | 574 | ||
575 | static int __devinit pci_netmos_init(struct pci_dev *dev) | 575 | static int pci_netmos_init(struct pci_dev *dev) |
576 | { | 576 | { |
577 | /* subdevice 0x00PS means <P> parallel, <S> serial */ | 577 | /* subdevice 0x00PS means <P> parallel, <S> serial */ |
578 | unsigned int num_serial = dev->subsystem_device & 0xf; | 578 | unsigned int num_serial = dev->subsystem_device & 0xf; |
@@ -622,7 +622,7 @@ pci_default_setup(struct serial_private *priv, struct pciserial_board *board, | |||
622 | */ | 622 | */ |
623 | static struct pci_serial_quirk pci_serial_quirks[] = { | 623 | static struct pci_serial_quirk pci_serial_quirks[] = { |
624 | /* | 624 | /* |
625 | * AFAVLAB cards. | 625 | * AFAVLAB cards - these may be called via parport_serial |
626 | * It is not clear whether this applies to all products. | 626 | * It is not clear whether this applies to all products. |
627 | */ | 627 | */ |
628 | { | 628 | { |
@@ -754,7 +754,7 @@ static struct pci_serial_quirk pci_serial_quirks[] = { | |||
754 | .exit = __devexit_p(sbs_exit), | 754 | .exit = __devexit_p(sbs_exit), |
755 | }, | 755 | }, |
756 | /* | 756 | /* |
757 | * SIIG cards. | 757 | * SIIG cards - these may be called via parport_serial |
758 | */ | 758 | */ |
759 | { | 759 | { |
760 | .vendor = PCI_VENDOR_ID_SIIG, | 760 | .vendor = PCI_VENDOR_ID_SIIG, |
@@ -811,7 +811,7 @@ static struct pci_serial_quirk pci_serial_quirks[] = { | |||
811 | .setup = pci_default_setup, | 811 | .setup = pci_default_setup, |
812 | }, | 812 | }, |
813 | /* | 813 | /* |
814 | * Netmos cards | 814 | * Netmos cards - these may be called via parport_serial |
815 | */ | 815 | */ |
816 | { | 816 | { |
817 | .vendor = PCI_VENDOR_ID_NETMOS, | 817 | .vendor = PCI_VENDOR_ID_NETMOS, |
diff --git a/drivers/serial/8250_pnp.c b/drivers/serial/8250_pnp.c index 739bc84f91e9..632f62d6ec7e 100644 --- a/drivers/serial/8250_pnp.c +++ b/drivers/serial/8250_pnp.c | |||
@@ -431,6 +431,8 @@ serial_pnp_probe(struct pnp_dev *dev, const struct pnp_device_id *dev_id) | |||
431 | #endif | 431 | #endif |
432 | 432 | ||
433 | port.flags |= UPF_SKIP_TEST | UPF_BOOT_AUTOCONF; | 433 | port.flags |= UPF_SKIP_TEST | UPF_BOOT_AUTOCONF; |
434 | if (pnp_irq_flags(dev, 0) & IORESOURCE_IRQ_SHAREABLE) | ||
435 | port.flags |= UPF_SHARE_IRQ; | ||
434 | port.uartclk = 1843200; | 436 | port.uartclk = 1843200; |
435 | port.dev = &dev->dev; | 437 | port.dev = &dev->dev; |
436 | 438 | ||
diff --git a/drivers/serial/mpc52xx_uart.c b/drivers/serial/mpc52xx_uart.c index 48eb22d3a63e..7708e5dd3656 100644 --- a/drivers/serial/mpc52xx_uart.c +++ b/drivers/serial/mpc52xx_uart.c | |||
@@ -726,8 +726,7 @@ mpc52xx_uart_probe(struct platform_device *dev) | |||
726 | 726 | ||
727 | spin_lock_init(&port->lock); | 727 | spin_lock_init(&port->lock); |
728 | port->uartclk = __res.bi_ipbfreq / 2; /* Look at CTLR doc */ | 728 | port->uartclk = __res.bi_ipbfreq / 2; /* Look at CTLR doc */ |
729 | port->fifosize = 255; /* Should be 512 ! But it can't be */ | 729 | port->fifosize = 512; |
730 | /* stored in a unsigned char */ | ||
731 | port->iotype = UPIO_MEM; | 730 | port->iotype = UPIO_MEM; |
732 | port->flags = UPF_BOOT_AUTOCONF | | 731 | port->flags = UPF_BOOT_AUTOCONF | |
733 | ( uart_console(port) ? 0 : UPF_IOREMAP ); | 732 | ( uart_console(port) ? 0 : UPF_IOREMAP ); |
diff --git a/drivers/serial/pmac_zilog.c b/drivers/serial/pmac_zilog.c index 459c0231aef3..bfd2a22759eb 100644 --- a/drivers/serial/pmac_zilog.c +++ b/drivers/serial/pmac_zilog.c | |||
@@ -1443,8 +1443,8 @@ static int __init pmz_init_port(struct uart_pmac_port *uap) | |||
1443 | uap->flags &= ~PMACZILOG_FLAG_HAS_DMA; | 1443 | uap->flags &= ~PMACZILOG_FLAG_HAS_DMA; |
1444 | goto no_dma; | 1444 | goto no_dma; |
1445 | } | 1445 | } |
1446 | uap->tx_dma_irq = np->intrs[1].line; | 1446 | uap->tx_dma_irq = irq_of_parse_and_map(np, 1); |
1447 | uap->rx_dma_irq = np->intrs[2].line; | 1447 | uap->rx_dma_irq = irq_of_parse_and_map(np, 2); |
1448 | } | 1448 | } |
1449 | no_dma: | 1449 | no_dma: |
1450 | 1450 | ||
@@ -1491,7 +1491,7 @@ no_dma: | |||
1491 | * Init remaining bits of "port" structure | 1491 | * Init remaining bits of "port" structure |
1492 | */ | 1492 | */ |
1493 | uap->port.iotype = UPIO_MEM; | 1493 | uap->port.iotype = UPIO_MEM; |
1494 | uap->port.irq = np->intrs[0].line; | 1494 | uap->port.irq = irq_of_parse_and_map(np, 0); |
1495 | uap->port.uartclk = ZS_CLOCK; | 1495 | uap->port.uartclk = ZS_CLOCK; |
1496 | uap->port.fifosize = 1; | 1496 | uap->port.fifosize = 1; |
1497 | uap->port.ops = &pmz_pops; | 1497 | uap->port.ops = &pmz_pops; |
diff --git a/drivers/serial/serial_core.c b/drivers/serial/serial_core.c index c54af8774393..d5f636fbf29a 100644 --- a/drivers/serial/serial_core.c +++ b/drivers/serial/serial_core.c | |||
@@ -49,6 +49,12 @@ | |||
49 | */ | 49 | */ |
50 | static DEFINE_MUTEX(port_mutex); | 50 | static DEFINE_MUTEX(port_mutex); |
51 | 51 | ||
52 | /* | ||
53 | * lockdep: port->lock is initialized in two places, but we | ||
54 | * want only one lock-class: | ||
55 | */ | ||
56 | static struct lock_class_key port_lock_key; | ||
57 | |||
52 | #define HIGH_BITS_OFFSET ((sizeof(long)-sizeof(int))*8) | 58 | #define HIGH_BITS_OFFSET ((sizeof(long)-sizeof(int))*8) |
53 | 59 | ||
54 | #define uart_users(state) ((state)->count + ((state)->info ? (state)->info->blocked_open : 0)) | 60 | #define uart_users(state) ((state)->count + ((state)->info ? (state)->info->blocked_open : 0)) |
@@ -690,7 +696,8 @@ static int uart_set_info(struct uart_state *state, | |||
690 | (new_serial.baud_base != port->uartclk / 16) || | 696 | (new_serial.baud_base != port->uartclk / 16) || |
691 | (close_delay != state->close_delay) || | 697 | (close_delay != state->close_delay) || |
692 | (closing_wait != state->closing_wait) || | 698 | (closing_wait != state->closing_wait) || |
693 | (new_serial.xmit_fifo_size != port->fifosize) || | 699 | (new_serial.xmit_fifo_size && |
700 | new_serial.xmit_fifo_size != port->fifosize) || | ||
694 | (((new_flags ^ old_flags) & ~UPF_USR_MASK) != 0)) | 701 | (((new_flags ^ old_flags) & ~UPF_USR_MASK) != 0)) |
695 | goto exit; | 702 | goto exit; |
696 | port->flags = ((port->flags & ~UPF_USR_MASK) | | 703 | port->flags = ((port->flags & ~UPF_USR_MASK) | |
@@ -795,7 +802,8 @@ static int uart_set_info(struct uart_state *state, | |||
795 | port->custom_divisor = new_serial.custom_divisor; | 802 | port->custom_divisor = new_serial.custom_divisor; |
796 | state->close_delay = close_delay; | 803 | state->close_delay = close_delay; |
797 | state->closing_wait = closing_wait; | 804 | state->closing_wait = closing_wait; |
798 | port->fifosize = new_serial.xmit_fifo_size; | 805 | if (new_serial.xmit_fifo_size) |
806 | port->fifosize = new_serial.xmit_fifo_size; | ||
799 | if (state->info->tty) | 807 | if (state->info->tty) |
800 | state->info->tty->low_latency = | 808 | state->info->tty->low_latency = |
801 | (port->flags & UPF_LOW_LATENCY) ? 1 : 0; | 809 | (port->flags & UPF_LOW_LATENCY) ? 1 : 0; |
@@ -1865,6 +1873,7 @@ uart_set_options(struct uart_port *port, struct console *co, | |||
1865 | * early. | 1873 | * early. |
1866 | */ | 1874 | */ |
1867 | spin_lock_init(&port->lock); | 1875 | spin_lock_init(&port->lock); |
1876 | lockdep_set_class(&port->lock, &port_lock_key); | ||
1868 | 1877 | ||
1869 | memset(&termios, 0, sizeof(struct termios)); | 1878 | memset(&termios, 0, sizeof(struct termios)); |
1870 | 1879 | ||
@@ -2247,8 +2256,10 @@ int uart_add_one_port(struct uart_driver *drv, struct uart_port *port) | |||
2247 | * If this port is a console, then the spinlock is already | 2256 | * If this port is a console, then the spinlock is already |
2248 | * initialised. | 2257 | * initialised. |
2249 | */ | 2258 | */ |
2250 | if (!(uart_console(port) && (port->cons->flags & CON_ENABLED))) | 2259 | if (!(uart_console(port) && (port->cons->flags & CON_ENABLED))) { |
2251 | spin_lock_init(&port->lock); | 2260 | spin_lock_init(&port->lock); |
2261 | lockdep_set_class(&port->lock, &port_lock_key); | ||
2262 | } | ||
2252 | 2263 | ||
2253 | uart_configure_port(drv, state, port); | 2264 | uart_configure_port(drv, state, port); |
2254 | 2265 | ||
diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index ed1cdf6ac8f3..146298ad7371 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c | |||
@@ -510,7 +510,7 @@ static void spi_complete(void *arg) | |||
510 | */ | 510 | */ |
511 | int spi_sync(struct spi_device *spi, struct spi_message *message) | 511 | int spi_sync(struct spi_device *spi, struct spi_message *message) |
512 | { | 512 | { |
513 | DECLARE_COMPLETION(done); | 513 | DECLARE_COMPLETION_ONSTACK(done); |
514 | int status; | 514 | int status; |
515 | 515 | ||
516 | message->complete = spi_complete; | 516 | message->complete = spi_complete; |
diff --git a/drivers/usb/core/inode.c b/drivers/usb/core/inode.c index e47e3a8ed6e4..f48c3dbc367a 100644 --- a/drivers/usb/core/inode.c +++ b/drivers/usb/core/inode.c | |||
@@ -200,7 +200,7 @@ static void update_sb(struct super_block *sb) | |||
200 | if (!root) | 200 | if (!root) |
201 | return; | 201 | return; |
202 | 202 | ||
203 | mutex_lock(&root->d_inode->i_mutex); | 203 | mutex_lock_nested(&root->d_inode->i_mutex, I_MUTEX_PARENT); |
204 | 204 | ||
205 | list_for_each_entry(bus, &root->d_subdirs, d_u.d_child) { | 205 | list_for_each_entry(bus, &root->d_subdirs, d_u.d_child) { |
206 | if (bus->d_inode) { | 206 | if (bus->d_inode) { |
@@ -527,7 +527,7 @@ static void fs_remove_file (struct dentry *dentry) | |||
527 | if (!parent || !parent->d_inode) | 527 | if (!parent || !parent->d_inode) |
528 | return; | 528 | return; |
529 | 529 | ||
530 | mutex_lock(&parent->d_inode->i_mutex); | 530 | mutex_lock_nested(&parent->d_inode->i_mutex, I_MUTEX_PARENT); |
531 | if (usbfs_positive(dentry)) { | 531 | if (usbfs_positive(dentry)) { |
532 | if (dentry->d_inode) { | 532 | if (dentry->d_inode) { |
533 | if (S_ISDIR(dentry->d_inode->i_mode)) | 533 | if (S_ISDIR(dentry->d_inode->i_mode)) |
diff --git a/drivers/usb/gadget/lh7a40x_udc.c b/drivers/usb/gadget/lh7a40x_udc.c index bb22b7e82877..36db72579377 100644 --- a/drivers/usb/gadget/lh7a40x_udc.c +++ b/drivers/usb/gadget/lh7a40x_udc.c | |||
@@ -2143,7 +2143,7 @@ static int lh7a40x_udc_remove(struct platform_device *pdev) | |||
2143 | 2143 | ||
2144 | static struct platform_driver udc_driver = { | 2144 | static struct platform_driver udc_driver = { |
2145 | .probe = lh7a40x_udc_probe, | 2145 | .probe = lh7a40x_udc_probe, |
2146 | .remove = lh7a40x_udc_remove | 2146 | .remove = lh7a40x_udc_remove, |
2147 | /* FIXME power management support */ | 2147 | /* FIXME power management support */ |
2148 | /* .suspend = ... disable UDC */ | 2148 | /* .suspend = ... disable UDC */ |
2149 | /* .resume = ... re-enable UDC */ | 2149 | /* .resume = ... re-enable UDC */ |
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig index 17de4c84db69..3badb48d662b 100644 --- a/drivers/video/Kconfig +++ b/drivers/video/Kconfig | |||
@@ -1557,6 +1557,21 @@ config FB_S3C2410_DEBUG | |||
1557 | Turn on debugging messages. Note that you can set/unset at run time | 1557 | Turn on debugging messages. Note that you can set/unset at run time |
1558 | through sysfs | 1558 | through sysfs |
1559 | 1559 | ||
1560 | config FB_PNX4008_DUM | ||
1561 | tristate "Display Update Module support on Philips PNX4008 board" | ||
1562 | depends on FB && ARCH_PNX4008 | ||
1563 | ---help--- | ||
1564 | Say Y here to enable support for PNX4008 Display Update Module (DUM) | ||
1565 | |||
1566 | config FB_PNX4008_DUM_RGB | ||
1567 | tristate "RGB Framebuffer support on Philips PNX4008 board" | ||
1568 | depends on FB_PNX4008_DUM | ||
1569 | select FB_CFB_FILLRECT | ||
1570 | select FB_CFB_COPYAREA | ||
1571 | select FB_CFB_IMAGEBLIT | ||
1572 | ---help--- | ||
1573 | Say Y here to enable support for PNX4008 RGB Framebuffer | ||
1574 | |||
1560 | config FB_VIRTUAL | 1575 | config FB_VIRTUAL |
1561 | tristate "Virtual Frame Buffer support (ONLY FOR TESTING!)" | 1576 | tristate "Virtual Frame Buffer support (ONLY FOR TESTING!)" |
1562 | depends on FB | 1577 | depends on FB |
diff --git a/drivers/video/Makefile b/drivers/video/Makefile index c335e9bc3b20..6283d015f8f5 100644 --- a/drivers/video/Makefile +++ b/drivers/video/Makefile | |||
@@ -94,6 +94,8 @@ obj-$(CONFIG_FB_TX3912) += tx3912fb.o | |||
94 | obj-$(CONFIG_FB_S1D13XXX) += s1d13xxxfb.o | 94 | obj-$(CONFIG_FB_S1D13XXX) += s1d13xxxfb.o |
95 | obj-$(CONFIG_FB_IMX) += imxfb.o | 95 | obj-$(CONFIG_FB_IMX) += imxfb.o |
96 | obj-$(CONFIG_FB_S3C2410) += s3c2410fb.o | 96 | obj-$(CONFIG_FB_S3C2410) += s3c2410fb.o |
97 | obj-$(CONFIG_FB_PNX4008_DUM) += pnx4008/ | ||
98 | obj-$(CONFIG_FB_PNX4008_DUM_RGB) += pnx4008/ | ||
97 | 99 | ||
98 | # Platform or fallback drivers go here | 100 | # Platform or fallback drivers go here |
99 | obj-$(CONFIG_FB_VESA) += vesafb.o | 101 | obj-$(CONFIG_FB_VESA) += vesafb.o |
diff --git a/drivers/video/offb.c b/drivers/video/offb.c index bfeb11bd4712..71ce1fa45cf4 100644 --- a/drivers/video/offb.c +++ b/drivers/video/offb.c | |||
@@ -97,14 +97,43 @@ static int offb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, | |||
97 | u_int transp, struct fb_info *info) | 97 | u_int transp, struct fb_info *info) |
98 | { | 98 | { |
99 | struct offb_par *par = (struct offb_par *) info->par; | 99 | struct offb_par *par = (struct offb_par *) info->par; |
100 | int i, depth; | ||
101 | u32 *pal = info->pseudo_palette; | ||
100 | 102 | ||
101 | if (!par->cmap_adr || regno > 255) | 103 | depth = info->var.bits_per_pixel; |
104 | if (depth == 16) | ||
105 | depth = (info->var.green.length == 5) ? 15 : 16; | ||
106 | |||
107 | if (regno > 255 || | ||
108 | (depth == 16 && regno > 63) || | ||
109 | (depth == 15 && regno > 31)) | ||
102 | return 1; | 110 | return 1; |
103 | 111 | ||
112 | if (regno < 16) { | ||
113 | switch (depth) { | ||
114 | case 15: | ||
115 | pal[regno] = (regno << 10) | (regno << 5) | regno; | ||
116 | break; | ||
117 | case 16: | ||
118 | pal[regno] = (regno << 11) | (regno << 5) | regno; | ||
119 | break; | ||
120 | case 24: | ||
121 | pal[regno] = (regno << 16) | (regno << 8) | regno; | ||
122 | break; | ||
123 | case 32: | ||
124 | i = (regno << 8) | regno; | ||
125 | pal[regno] = (i << 16) | i; | ||
126 | break; | ||
127 | } | ||
128 | } | ||
129 | |||
104 | red >>= 8; | 130 | red >>= 8; |
105 | green >>= 8; | 131 | green >>= 8; |
106 | blue >>= 8; | 132 | blue >>= 8; |
107 | 133 | ||
134 | if (!par->cmap_adr) | ||
135 | return 0; | ||
136 | |||
108 | switch (par->cmap_type) { | 137 | switch (par->cmap_type) { |
109 | case cmap_m64: | 138 | case cmap_m64: |
110 | writeb(regno, par->cmap_adr); | 139 | writeb(regno, par->cmap_adr); |
@@ -141,20 +170,6 @@ static int offb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, | |||
141 | break; | 170 | break; |
142 | } | 171 | } |
143 | 172 | ||
144 | if (regno < 16) | ||
145 | switch (info->var.bits_per_pixel) { | ||
146 | case 16: | ||
147 | ((u16 *) (info->pseudo_palette))[regno] = | ||
148 | (regno << 10) | (regno << 5) | regno; | ||
149 | break; | ||
150 | case 32: | ||
151 | { | ||
152 | int i = (regno << 8) | regno; | ||
153 | ((u32 *) (info->pseudo_palette))[regno] = | ||
154 | (i << 16) | i; | ||
155 | break; | ||
156 | } | ||
157 | } | ||
158 | return 0; | 173 | return 0; |
159 | } | 174 | } |
160 | 175 | ||
@@ -223,81 +238,9 @@ int __init offb_init(void) | |||
223 | { | 238 | { |
224 | struct device_node *dp = NULL, *boot_disp = NULL; | 239 | struct device_node *dp = NULL, *boot_disp = NULL; |
225 | 240 | ||
226 | #if defined(CONFIG_BOOTX_TEXT) && defined(CONFIG_PPC32) | ||
227 | struct device_node *macos_display = NULL; | ||
228 | #endif | ||
229 | if (fb_get_options("offb", NULL)) | 241 | if (fb_get_options("offb", NULL)) |
230 | return -ENODEV; | 242 | return -ENODEV; |
231 | 243 | ||
232 | #if defined(CONFIG_BOOTX_TEXT) && defined(CONFIG_PPC32) | ||
233 | /* If we're booted from BootX... */ | ||
234 | if (boot_infos != 0) { | ||
235 | unsigned long addr = | ||
236 | (unsigned long) boot_infos->dispDeviceBase; | ||
237 | u32 *addrp; | ||
238 | u64 daddr, dsize; | ||
239 | unsigned int flags; | ||
240 | |||
241 | /* find the device node corresponding to the macos display */ | ||
242 | while ((dp = of_find_node_by_type(dp, "display"))) { | ||
243 | int i; | ||
244 | |||
245 | /* | ||
246 | * Look for an AAPL,address property first. | ||
247 | */ | ||
248 | unsigned int na; | ||
249 | unsigned int *ap = | ||
250 | (unsigned int *)get_property(dp, "AAPL,address", | ||
251 | &na); | ||
252 | if (ap != 0) { | ||
253 | for (na /= sizeof(unsigned int); na > 0; | ||
254 | --na, ++ap) | ||
255 | if (*ap <= addr && | ||
256 | addr < *ap + 0x1000000) { | ||
257 | macos_display = dp; | ||
258 | goto foundit; | ||
259 | } | ||
260 | } | ||
261 | |||
262 | /* | ||
263 | * See if the display address is in one of the address | ||
264 | * ranges for this display. | ||
265 | */ | ||
266 | i = 0; | ||
267 | for (;;) { | ||
268 | addrp = of_get_address(dp, i++, &dsize, &flags); | ||
269 | if (addrp == NULL) | ||
270 | break; | ||
271 | if (!(flags & IORESOURCE_MEM)) | ||
272 | continue; | ||
273 | daddr = of_translate_address(dp, addrp); | ||
274 | if (daddr == OF_BAD_ADDR) | ||
275 | continue; | ||
276 | if (daddr <= addr && addr < (daddr + dsize)) { | ||
277 | macos_display = dp; | ||
278 | goto foundit; | ||
279 | } | ||
280 | } | ||
281 | foundit: | ||
282 | if (macos_display) { | ||
283 | printk(KERN_INFO "MacOS display is %s\n", | ||
284 | dp->full_name); | ||
285 | break; | ||
286 | } | ||
287 | } | ||
288 | |||
289 | /* initialize it */ | ||
290 | offb_init_fb(macos_display ? macos_display-> | ||
291 | name : "MacOS display", | ||
292 | macos_display ? macos_display-> | ||
293 | full_name : "MacOS display", | ||
294 | boot_infos->dispDeviceRect[2], | ||
295 | boot_infos->dispDeviceRect[3], | ||
296 | boot_infos->dispDeviceDepth, | ||
297 | boot_infos->dispDeviceRowBytes, addr, NULL); | ||
298 | } | ||
299 | #endif /* defined(CONFIG_BOOTX_TEXT) && defined(CONFIG_PPC32) */ | ||
300 | |||
301 | for (dp = NULL; (dp = of_find_node_by_type(dp, "display"));) { | 244 | for (dp = NULL; (dp = of_find_node_by_type(dp, "display"));) { |
302 | if (get_property(dp, "linux,opened", NULL) && | 245 | if (get_property(dp, "linux,opened", NULL) && |
303 | get_property(dp, "linux,boot-display", NULL)) { | 246 | get_property(dp, "linux,boot-display", NULL)) { |
@@ -317,94 +260,93 @@ int __init offb_init(void) | |||
317 | 260 | ||
318 | static void __init offb_init_nodriver(struct device_node *dp) | 261 | static void __init offb_init_nodriver(struct device_node *dp) |
319 | { | 262 | { |
320 | int *pp, i; | ||
321 | unsigned int len; | 263 | unsigned int len; |
322 | int width = 640, height = 480, depth = 8, pitch; | 264 | int i, width = 640, height = 480, depth = 8, pitch = 640; |
323 | unsigned int flags, rsize, *up; | 265 | unsigned int flags, rsize, addr_prop = 0; |
324 | u64 address = OF_BAD_ADDR; | 266 | unsigned long max_size = 0; |
325 | u32 *addrp; | 267 | u64 rstart, address = OF_BAD_ADDR; |
268 | u32 *pp, *addrp, *up; | ||
326 | u64 asize; | 269 | u64 asize; |
327 | 270 | ||
328 | if ((pp = (int *) get_property(dp, "depth", &len)) != NULL | 271 | pp = (u32 *)get_property(dp, "linux,bootx-depth", &len); |
329 | && len == sizeof(int)) | 272 | if (pp == NULL) |
273 | pp = (u32 *)get_property(dp, "depth", &len); | ||
274 | if (pp && len == sizeof(u32)) | ||
330 | depth = *pp; | 275 | depth = *pp; |
331 | if ((pp = (int *) get_property(dp, "width", &len)) != NULL | 276 | |
332 | && len == sizeof(int)) | 277 | pp = (u32 *)get_property(dp, "linux,bootx-width", &len); |
278 | if (pp == NULL) | ||
279 | pp = (u32 *)get_property(dp, "width", &len); | ||
280 | if (pp && len == sizeof(u32)) | ||
333 | width = *pp; | 281 | width = *pp; |
334 | if ((pp = (int *) get_property(dp, "height", &len)) != NULL | 282 | |
335 | && len == sizeof(int)) | 283 | pp = (u32 *)get_property(dp, "linux,bootx-height", &len); |
284 | if (pp == NULL) | ||
285 | pp = (u32 *)get_property(dp, "height", &len); | ||
286 | if (pp && len == sizeof(u32)) | ||
336 | height = *pp; | 287 | height = *pp; |
337 | if ((pp = (int *) get_property(dp, "linebytes", &len)) != NULL | 288 | |
338 | && len == sizeof(int)) { | 289 | pp = (u32 *)get_property(dp, "linux,bootx-linebytes", &len); |
290 | if (pp == NULL) | ||
291 | pp = (u32 *)get_property(dp, "linebytes", &len); | ||
292 | if (pp && len == sizeof(u32)) | ||
339 | pitch = *pp; | 293 | pitch = *pp; |
340 | if (pitch == 1) | 294 | else |
341 | pitch = 0x1000; | 295 | pitch = width * ((depth + 7) / 8); |
342 | } else | 296 | |
343 | pitch = width; | 297 | rsize = (unsigned long)pitch * (unsigned long)height; |
344 | 298 | ||
345 | rsize = (unsigned long)pitch * (unsigned long)height * | 299 | /* Ok, now we try to figure out the address of the framebuffer. |
346 | (unsigned long)(depth / 8); | 300 | * |
347 | 301 | * Unfortunately, Open Firmware doesn't provide a standard way to do | |
348 | /* Try to match device to a PCI device in order to get a properly | 302 | * so. All we can do is a dodgy heuristic that happens to work in |
349 | * translated address rather then trying to decode the open firmware | 303 | * practice. On most machines, the "address" property contains what |
350 | * stuff in various incorrect ways | 304 | * we need, though not on Matrox cards found in IBM machines. What I've |
351 | */ | 305 | * found that appears to give good results is to go through the PCI |
352 | #ifdef CONFIG_PCI | 306 | * ranges and pick one that is both big enough and if possible encloses |
353 | /* First try to locate the PCI device if any */ | 307 | * the "address" property. If none match, we pick the biggest |
354 | { | 308 | */ |
355 | struct pci_dev *pdev = NULL; | 309 | up = (u32 *)get_property(dp, "linux,bootx-addr", &len); |
356 | 310 | if (up == NULL) | |
357 | for_each_pci_dev(pdev) { | 311 | up = (u32 *)get_property(dp, "address", &len); |
358 | if (dp == pci_device_to_OF_node(pdev)) | 312 | if (up && len == sizeof(u32)) |
359 | break; | 313 | addr_prop = *up; |
360 | } | 314 | |
361 | if (pdev) { | 315 | for (i = 0; (addrp = of_get_address(dp, i, &asize, &flags)) |
362 | for (i = 0; i < 6 && address == OF_BAD_ADDR; i++) { | 316 | != NULL; i++) { |
363 | if ((pci_resource_flags(pdev, i) & | 317 | int match_addrp = 0; |
364 | IORESOURCE_MEM) && | 318 | |
365 | (pci_resource_len(pdev, i) >= rsize)) | 319 | if (!(flags & IORESOURCE_MEM)) |
366 | address = pci_resource_start(pdev, i); | 320 | continue; |
367 | } | 321 | if (asize < rsize) |
368 | pci_dev_put(pdev); | 322 | continue; |
369 | } | 323 | rstart = of_translate_address(dp, addrp); |
370 | } | 324 | if (rstart == OF_BAD_ADDR) |
371 | #endif /* CONFIG_PCI */ | 325 | continue; |
372 | 326 | if (addr_prop && (rstart <= addr_prop) && | |
373 | /* This one is dodgy, we may drop it ... */ | 327 | ((rstart + asize) >= (addr_prop + rsize))) |
374 | if (address == OF_BAD_ADDR && | 328 | match_addrp = 1; |
375 | (up = (unsigned *) get_property(dp, "address", &len)) != NULL && | 329 | if (match_addrp) { |
376 | len == sizeof(unsigned int)) | 330 | address = addr_prop; |
377 | address = (u64) * up; | 331 | break; |
378 | |||
379 | if (address == OF_BAD_ADDR) { | ||
380 | for (i = 0; (addrp = of_get_address(dp, i, &asize, &flags)) | ||
381 | != NULL; i++) { | ||
382 | if (!(flags & IORESOURCE_MEM)) | ||
383 | continue; | ||
384 | if (asize >= pitch * height * depth / 8) | ||
385 | break; | ||
386 | } | ||
387 | if (addrp == NULL) { | ||
388 | printk(KERN_ERR | ||
389 | "no framebuffer address found for %s\n", | ||
390 | dp->full_name); | ||
391 | return; | ||
392 | } | ||
393 | address = of_translate_address(dp, addrp); | ||
394 | if (address == OF_BAD_ADDR) { | ||
395 | printk(KERN_ERR | ||
396 | "can't translate framebuffer address for %s\n", | ||
397 | dp->full_name); | ||
398 | return; | ||
399 | } | 332 | } |
333 | if (rsize > max_size) { | ||
334 | max_size = rsize; | ||
335 | address = OF_BAD_ADDR; | ||
336 | } | ||
400 | 337 | ||
338 | if (address == OF_BAD_ADDR) | ||
339 | address = rstart; | ||
340 | } | ||
341 | if (address == OF_BAD_ADDR && addr_prop) | ||
342 | address = (u64)addr_prop; | ||
343 | if (address != OF_BAD_ADDR) { | ||
401 | /* kludge for valkyrie */ | 344 | /* kludge for valkyrie */ |
402 | if (strcmp(dp->name, "valkyrie") == 0) | 345 | if (strcmp(dp->name, "valkyrie") == 0) |
403 | address += 0x1000; | 346 | address += 0x1000; |
347 | offb_init_fb(dp->name, dp->full_name, width, height, depth, | ||
348 | pitch, address, dp); | ||
404 | } | 349 | } |
405 | offb_init_fb(dp->name, dp->full_name, width, height, depth, | ||
406 | pitch, address, dp); | ||
407 | |||
408 | } | 350 | } |
409 | 351 | ||
410 | static void __init offb_init_fb(const char *name, const char *full_name, | 352 | static void __init offb_init_fb(const char *name, const char *full_name, |
@@ -412,7 +354,7 @@ static void __init offb_init_fb(const char *name, const char *full_name, | |||
412 | int pitch, unsigned long address, | 354 | int pitch, unsigned long address, |
413 | struct device_node *dp) | 355 | struct device_node *dp) |
414 | { | 356 | { |
415 | unsigned long res_size = pitch * height * depth / 8; | 357 | unsigned long res_size = pitch * height * (depth + 7) / 8; |
416 | struct offb_par *par = &default_par; | 358 | struct offb_par *par = &default_par; |
417 | unsigned long res_start = address; | 359 | unsigned long res_start = address; |
418 | struct fb_fix_screeninfo *fix; | 360 | struct fb_fix_screeninfo *fix; |
@@ -426,7 +368,7 @@ static void __init offb_init_fb(const char *name, const char *full_name, | |||
426 | printk(KERN_INFO | 368 | printk(KERN_INFO |
427 | "Using unsupported %dx%d %s at %lx, depth=%d, pitch=%d\n", | 369 | "Using unsupported %dx%d %s at %lx, depth=%d, pitch=%d\n", |
428 | width, height, name, address, depth, pitch); | 370 | width, height, name, address, depth, pitch); |
429 | if (depth != 8 && depth != 16 && depth != 32) { | 371 | if (depth != 8 && depth != 15 && depth != 16 && depth != 32) { |
430 | printk(KERN_ERR "%s: can't use depth = %d\n", full_name, | 372 | printk(KERN_ERR "%s: can't use depth = %d\n", full_name, |
431 | depth); | 373 | depth); |
432 | release_mem_region(res_start, res_size); | 374 | release_mem_region(res_start, res_size); |
@@ -502,7 +444,6 @@ static void __init offb_init_fb(const char *name, const char *full_name, | |||
502 | : */ FB_VISUAL_TRUECOLOR; | 444 | : */ FB_VISUAL_TRUECOLOR; |
503 | 445 | ||
504 | var->xoffset = var->yoffset = 0; | 446 | var->xoffset = var->yoffset = 0; |
505 | var->bits_per_pixel = depth; | ||
506 | switch (depth) { | 447 | switch (depth) { |
507 | case 8: | 448 | case 8: |
508 | var->bits_per_pixel = 8; | 449 | var->bits_per_pixel = 8; |
@@ -515,7 +456,7 @@ static void __init offb_init_fb(const char *name, const char *full_name, | |||
515 | var->transp.offset = 0; | 456 | var->transp.offset = 0; |
516 | var->transp.length = 0; | 457 | var->transp.length = 0; |
517 | break; | 458 | break; |
518 | case 16: /* RGB 555 */ | 459 | case 15: /* RGB 555 */ |
519 | var->bits_per_pixel = 16; | 460 | var->bits_per_pixel = 16; |
520 | var->red.offset = 10; | 461 | var->red.offset = 10; |
521 | var->red.length = 5; | 462 | var->red.length = 5; |
@@ -526,6 +467,17 @@ static void __init offb_init_fb(const char *name, const char *full_name, | |||
526 | var->transp.offset = 0; | 467 | var->transp.offset = 0; |
527 | var->transp.length = 0; | 468 | var->transp.length = 0; |
528 | break; | 469 | break; |
470 | case 16: /* RGB 565 */ | ||
471 | var->bits_per_pixel = 16; | ||
472 | var->red.offset = 11; | ||
473 | var->red.length = 5; | ||
474 | var->green.offset = 5; | ||
475 | var->green.length = 6; | ||
476 | var->blue.offset = 0; | ||
477 | var->blue.length = 5; | ||
478 | var->transp.offset = 0; | ||
479 | var->transp.length = 0; | ||
480 | break; | ||
529 | case 32: /* RGB 888 */ | 481 | case 32: /* RGB 888 */ |
530 | var->bits_per_pixel = 32; | 482 | var->bits_per_pixel = 32; |
531 | var->red.offset = 16; | 483 | var->red.offset = 16; |
diff --git a/drivers/video/pnx4008/Makefile b/drivers/video/pnx4008/Makefile new file mode 100644 index 000000000000..636aaccf01fd --- /dev/null +++ b/drivers/video/pnx4008/Makefile | |||
@@ -0,0 +1,7 @@ | |||
1 | # | ||
2 | # Makefile for the new PNX4008 framebuffer device driver | ||
3 | # | ||
4 | |||
5 | obj-$(CONFIG_FB_PNX4008_DUM) += sdum.o | ||
6 | obj-$(CONFIG_FB_PNX4008_DUM_RGB) += pnxrgbfb.o | ||
7 | |||
diff --git a/drivers/video/pnx4008/dum.h b/drivers/video/pnx4008/dum.h new file mode 100644 index 000000000000..d80a614d89ed --- /dev/null +++ b/drivers/video/pnx4008/dum.h | |||
@@ -0,0 +1,211 @@ | |||
1 | /* | ||
2 | * linux/drivers/video/pnx4008/dum.h | ||
3 | * | ||
4 | * Internal header for SDUM | ||
5 | * | ||
6 | * 2005 (c) Koninklijke Philips N.V. This file is licensed under | ||
7 | * the terms of the GNU General Public License version 2. This program | ||
8 | * is licensed "as is" without any warranty of any kind, whether express | ||
9 | * or implied. | ||
10 | */ | ||
11 | |||
12 | #ifndef __PNX008_DUM_H__ | ||
13 | #define __PNX008_DUM_H__ | ||
14 | |||
15 | #include <asm/arch/platform.h> | ||
16 | |||
17 | #define PNX4008_DUMCONF_VA_BASE IO_ADDRESS(PNX4008_DUMCONF_BASE) | ||
18 | #define PNX4008_DUM_MAIN_VA_BASE IO_ADDRESS(PNX4008_DUM_MAINCFG_BASE) | ||
19 | |||
20 | /* DUM CFG ADDRESSES */ | ||
21 | #define DUM_CH_BASE_ADR (PNX4008_DUMCONF_VA_BASE + 0x00) | ||
22 | #define DUM_CH_MIN_ADR (PNX4008_DUMCONF_VA_BASE + 0x00) | ||
23 | #define DUM_CH_MAX_ADR (PNX4008_DUMCONF_VA_BASE + 0x04) | ||
24 | #define DUM_CH_CONF_ADR (PNX4008_DUMCONF_VA_BASE + 0x08) | ||
25 | #define DUM_CH_STAT_ADR (PNX4008_DUMCONF_VA_BASE + 0x0C) | ||
26 | #define DUM_CH_CTRL_ADR (PNX4008_DUMCONF_VA_BASE + 0x10) | ||
27 | |||
28 | #define CH_MARG (0x100 / sizeof(u32)) | ||
29 | #define DUM_CH_MIN(i) (*((volatile u32 *)DUM_CH_MIN_ADR + (i) * CH_MARG)) | ||
30 | #define DUM_CH_MAX(i) (*((volatile u32 *)DUM_CH_MAX_ADR + (i) * CH_MARG)) | ||
31 | #define DUM_CH_CONF(i) (*((volatile u32 *)DUM_CH_CONF_ADR + (i) * CH_MARG)) | ||
32 | #define DUM_CH_STAT(i) (*((volatile u32 *)DUM_CH_STAT_ADR + (i) * CH_MARG)) | ||
33 | #define DUM_CH_CTRL(i) (*((volatile u32 *)DUM_CH_CTRL_ADR + (i) * CH_MARG)) | ||
34 | |||
35 | #define DUM_CONF_ADR (PNX4008_DUM_MAIN_VA_BASE + 0x00) | ||
36 | #define DUM_CTRL_ADR (PNX4008_DUM_MAIN_VA_BASE + 0x04) | ||
37 | #define DUM_STAT_ADR (PNX4008_DUM_MAIN_VA_BASE + 0x08) | ||
38 | #define DUM_DECODE_ADR (PNX4008_DUM_MAIN_VA_BASE + 0x0C) | ||
39 | #define DUM_COM_BASE_ADR (PNX4008_DUM_MAIN_VA_BASE + 0x10) | ||
40 | #define DUM_SYNC_C_ADR (PNX4008_DUM_MAIN_VA_BASE + 0x14) | ||
41 | #define DUM_CLK_DIV_ADR (PNX4008_DUM_MAIN_VA_BASE + 0x18) | ||
42 | #define DUM_DIRTY_LOW_ADR (PNX4008_DUM_MAIN_VA_BASE + 0x20) | ||
43 | #define DUM_DIRTY_HIGH_ADR (PNX4008_DUM_MAIN_VA_BASE + 0x24) | ||
44 | #define DUM_FORMAT_ADR (PNX4008_DUM_MAIN_VA_BASE + 0x28) | ||
45 | #define DUM_WTCFG1_ADR (PNX4008_DUM_MAIN_VA_BASE + 0x30) | ||
46 | #define DUM_RTCFG1_ADR (PNX4008_DUM_MAIN_VA_BASE + 0x34) | ||
47 | #define DUM_WTCFG2_ADR (PNX4008_DUM_MAIN_VA_BASE + 0x38) | ||
48 | #define DUM_RTCFG2_ADR (PNX4008_DUM_MAIN_VA_BASE + 0x3C) | ||
49 | #define DUM_TCFG_ADR (PNX4008_DUM_MAIN_VA_BASE + 0x40) | ||
50 | #define DUM_OUTP_FORMAT1_ADR (PNX4008_DUM_MAIN_VA_BASE + 0x44) | ||
51 | #define DUM_OUTP_FORMAT2_ADR (PNX4008_DUM_MAIN_VA_BASE + 0x48) | ||
52 | #define DUM_SYNC_MODE_ADR (PNX4008_DUM_MAIN_VA_BASE + 0x4C) | ||
53 | #define DUM_SYNC_OUT_C_ADR (PNX4008_DUM_MAIN_VA_BASE + 0x50) | ||
54 | |||
55 | #define DUM_CONF (*(volatile u32 *)(DUM_CONF_ADR)) | ||
56 | #define DUM_CTRL (*(volatile u32 *)(DUM_CTRL_ADR)) | ||
57 | #define DUM_STAT (*(volatile u32 *)(DUM_STAT_ADR)) | ||
58 | #define DUM_DECODE (*(volatile u32 *)(DUM_DECODE_ADR)) | ||
59 | #define DUM_COM_BASE (*(volatile u32 *)(DUM_COM_BASE_ADR)) | ||
60 | #define DUM_SYNC_C (*(volatile u32 *)(DUM_SYNC_C_ADR)) | ||
61 | #define DUM_CLK_DIV (*(volatile u32 *)(DUM_CLK_DIV_ADR)) | ||
62 | #define DUM_DIRTY_LOW (*(volatile u32 *)(DUM_DIRTY_LOW_ADR)) | ||
63 | #define DUM_DIRTY_HIGH (*(volatile u32 *)(DUM_DIRTY_HIGH_ADR)) | ||
64 | #define DUM_FORMAT (*(volatile u32 *)(DUM_FORMAT_ADR)) | ||
65 | #define DUM_WTCFG1 (*(volatile u32 *)(DUM_WTCFG1_ADR)) | ||
66 | #define DUM_RTCFG1 (*(volatile u32 *)(DUM_RTCFG1_ADR)) | ||
67 | #define DUM_WTCFG2 (*(volatile u32 *)(DUM_WTCFG2_ADR)) | ||
68 | #define DUM_RTCFG2 (*(volatile u32 *)(DUM_RTCFG2_ADR)) | ||
69 | #define DUM_TCFG (*(volatile u32 *)(DUM_TCFG_ADR)) | ||
70 | #define DUM_OUTP_FORMAT1 (*(volatile u32 *)(DUM_OUTP_FORMAT1_ADR)) | ||
71 | #define DUM_OUTP_FORMAT2 (*(volatile u32 *)(DUM_OUTP_FORMAT2_ADR)) | ||
72 | #define DUM_SYNC_MODE (*(volatile u32 *)(DUM_SYNC_MODE_ADR)) | ||
73 | #define DUM_SYNC_OUT_C (*(volatile u32 *)(DUM_SYNC_OUT_C_ADR)) | ||
74 | |||
75 | /* DUM SLAVE ADDRESSES */ | ||
76 | #define DUM_SLAVE_WRITE_ADR (PNX4008_DUM_MAINCFG_BASE + 0x0000000) | ||
77 | #define DUM_SLAVE_READ1_I_ADR (PNX4008_DUM_MAINCFG_BASE + 0x1000000) | ||
78 | #define DUM_SLAVE_READ1_R_ADR (PNX4008_DUM_MAINCFG_BASE + 0x1000004) | ||
79 | #define DUM_SLAVE_READ2_I_ADR (PNX4008_DUM_MAINCFG_BASE + 0x1000008) | ||
80 | #define DUM_SLAVE_READ2_R_ADR (PNX4008_DUM_MAINCFG_BASE + 0x100000C) | ||
81 | |||
82 | #define DUM_SLAVE_WRITE_W ((volatile u32 *)(DUM_SLAVE_WRITE_ADR)) | ||
83 | #define DUM_SLAVE_WRITE_HW ((volatile u16 *)(DUM_SLAVE_WRITE_ADR)) | ||
84 | #define DUM_SLAVE_READ1_I ((volatile u8 *)(DUM_SLAVE_READ1_I_ADR)) | ||
85 | #define DUM_SLAVE_READ1_R ((volatile u16 *)(DUM_SLAVE_READ1_R_ADR)) | ||
86 | #define DUM_SLAVE_READ2_I ((volatile u8 *)(DUM_SLAVE_READ2_I_ADR)) | ||
87 | #define DUM_SLAVE_READ2_R ((volatile u16 *)(DUM_SLAVE_READ2_R_ADR)) | ||
88 | |||
89 | /* Sony display register addresses */ | ||
90 | #define DISP_0_REG (0x00) | ||
91 | #define DISP_1_REG (0x01) | ||
92 | #define DISP_CAL_REG (0x20) | ||
93 | #define DISP_ID_REG (0x2A) | ||
94 | #define DISP_XMIN_L_REG (0x30) | ||
95 | #define DISP_XMIN_H_REG (0x31) | ||
96 | #define DISP_YMIN_REG (0x32) | ||
97 | #define DISP_XMAX_L_REG (0x34) | ||
98 | #define DISP_XMAX_H_REG (0x35) | ||
99 | #define DISP_YMAX_REG (0x36) | ||
100 | #define DISP_SYNC_EN_REG (0x38) | ||
101 | #define DISP_SYNC_RISE_L_REG (0x3C) | ||
102 | #define DISP_SYNC_RISE_H_REG (0x3D) | ||
103 | #define DISP_SYNC_FALL_L_REG (0x3E) | ||
104 | #define DISP_SYNC_FALL_H_REG (0x3F) | ||
105 | #define DISP_PIXEL_REG (0x0B) | ||
106 | #define DISP_DUMMY1_REG (0x28) | ||
107 | #define DISP_DUMMY2_REG (0x29) | ||
108 | #define DISP_TIMING_REG (0x98) | ||
109 | #define DISP_DUMP_REG (0x99) | ||
110 | |||
111 | /* Sony display constants */ | ||
112 | #define SONY_ID1 (0x22) | ||
113 | #define SONY_ID2 (0x23) | ||
114 | |||
115 | /* Philips display register addresses */ | ||
116 | #define PH_DISP_ORIENT_REG (0x003) | ||
117 | #define PH_DISP_YPOINT_REG (0x200) | ||
118 | #define PH_DISP_XPOINT_REG (0x201) | ||
119 | #define PH_DISP_PIXEL_REG (0x202) | ||
120 | #define PH_DISP_YMIN_REG (0x406) | ||
121 | #define PH_DISP_YMAX_REG (0x407) | ||
122 | #define PH_DISP_XMIN_REG (0x408) | ||
123 | #define PH_DISP_XMAX_REG (0x409) | ||
124 | |||
125 | /* Misc constants */ | ||
126 | #define NO_VALID_DISPLAY_FOUND (0) | ||
127 | #define DISPLAY2_IS_NOT_CONNECTED (0) | ||
128 | |||
129 | /* register values */ | ||
130 | #define V_BAC_ENABLE (BIT(0)) | ||
131 | #define V_BAC_DISABLE_IDLE (BIT(1)) | ||
132 | #define V_BAC_DISABLE_TRIG (BIT(2)) | ||
133 | #define V_DUM_RESET (BIT(3)) | ||
134 | #define V_MUX_RESET (BIT(4)) | ||
135 | #define BAC_ENABLED (BIT(0)) | ||
136 | #define BAC_DISABLED 0 | ||
137 | |||
138 | /* Sony LCD commands */ | ||
139 | #define V_LCD_STANDBY_OFF ((BIT(25)) | (0 << 16) | DISP_0_REG) | ||
140 | #define V_LCD_USE_9BIT_BUS ((BIT(25)) | (2 << 16) | DISP_1_REG) | ||
141 | #define V_LCD_SYNC_RISE_L ((BIT(25)) | (0 << 16) | DISP_SYNC_RISE_L_REG) | ||
142 | #define V_LCD_SYNC_RISE_H ((BIT(25)) | (0 << 16) | DISP_SYNC_RISE_H_REG) | ||
143 | #define V_LCD_SYNC_FALL_L ((BIT(25)) | (160 << 16) | DISP_SYNC_FALL_L_REG) | ||
144 | #define V_LCD_SYNC_FALL_H ((BIT(25)) | (0 << 16) | DISP_SYNC_FALL_H_REG) | ||
145 | #define V_LCD_SYNC_ENABLE ((BIT(25)) | (128 << 16) | DISP_SYNC_EN_REG) | ||
146 | #define V_LCD_DISPLAY_ON ((BIT(25)) | (64 << 16) | DISP_0_REG) | ||
147 | |||
148 | enum { | ||
149 | PAD_NONE, | ||
150 | PAD_512, | ||
151 | PAD_1024 | ||
152 | }; | ||
153 | |||
154 | enum { | ||
155 | RGB888, | ||
156 | RGB666, | ||
157 | RGB565, | ||
158 | BGR565, | ||
159 | ARGB1555, | ||
160 | ABGR1555, | ||
161 | ARGB4444, | ||
162 | ABGR4444 | ||
163 | }; | ||
164 | |||
165 | struct dum_setup { | ||
166 | int sync_neg_edge; | ||
167 | int round_robin; | ||
168 | int mux_int; | ||
169 | int synced_dirty_flag_int; | ||
170 | int dirty_flag_int; | ||
171 | int error_int; | ||
172 | int pf_empty_int; | ||
173 | int sf_empty_int; | ||
174 | int bac_dis_int; | ||
175 | u32 dirty_base_adr; | ||
176 | u32 command_base_adr; | ||
177 | u32 sync_clk_div; | ||
178 | int sync_output; | ||
179 | u32 sync_restart_val; | ||
180 | u32 set_sync_high; | ||
181 | u32 set_sync_low; | ||
182 | }; | ||
183 | |||
184 | struct dum_ch_setup { | ||
185 | int disp_no; | ||
186 | u32 xmin; | ||
187 | u32 ymin; | ||
188 | u32 xmax; | ||
189 | u32 ymax; | ||
190 | int xmirror; | ||
191 | int ymirror; | ||
192 | int rotate; | ||
193 | u32 minadr; | ||
194 | u32 maxadr; | ||
195 | u32 dirtybuffer; | ||
196 | int pad; | ||
197 | int format; | ||
198 | int hwdirty; | ||
199 | int slave_trans; | ||
200 | }; | ||
201 | |||
202 | struct disp_window { | ||
203 | u32 xmin_l; | ||
204 | u32 xmin_h; | ||
205 | u32 ymin; | ||
206 | u32 xmax_l; | ||
207 | u32 xmax_h; | ||
208 | u32 ymax; | ||
209 | }; | ||
210 | |||
211 | #endif /* #ifndef __PNX008_DUM_H__ */ | ||
diff --git a/drivers/video/pnx4008/fbcommon.h b/drivers/video/pnx4008/fbcommon.h new file mode 100644 index 000000000000..4ebc87dafafb --- /dev/null +++ b/drivers/video/pnx4008/fbcommon.h | |||
@@ -0,0 +1,43 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2005 Philips Semiconductors | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License as published by | ||
6 | * the Free Software Foundation; either version 2, or (at your option) | ||
7 | * any later version. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License | ||
15 | * along with this program; see the file COPYING. If not, write to | ||
16 | * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, | ||
17 | * Boston, MA 02111-1307, USA, or http://www.gnu.org/licenses/gpl.html | ||
18 | */ | ||
19 | |||
20 | #define QCIF_W (176) | ||
21 | #define QCIF_H (144) | ||
22 | |||
23 | #define CIF_W (352) | ||
24 | #define CIF_H (288) | ||
25 | |||
26 | #define LCD_X_RES 208 | ||
27 | #define LCD_Y_RES 320 | ||
28 | #define LCD_X_PAD 256 | ||
29 | #define LCD_BBP 4 /* Bytes Per Pixel */ | ||
30 | |||
31 | #define DISP_MAX_X_SIZE (320) | ||
32 | #define DISP_MAX_Y_SIZE (208) | ||
33 | |||
34 | #define RETURNVAL_BASE (0x400) | ||
35 | |||
36 | enum fb_ioctl_returntype { | ||
37 | ENORESOURCESLEFT = RETURNVAL_BASE, | ||
38 | ERESOURCESNOTFREED, | ||
39 | EPROCNOTOWNER, | ||
40 | EFBNOTOWNER, | ||
41 | ECOPYFAILED, | ||
42 | EIOREMAPFAILED, | ||
43 | }; | ||
diff --git a/drivers/video/pnx4008/pnxrgbfb.c b/drivers/video/pnx4008/pnxrgbfb.c new file mode 100644 index 000000000000..7d9453c91a42 --- /dev/null +++ b/drivers/video/pnx4008/pnxrgbfb.c | |||
@@ -0,0 +1,213 @@ | |||
1 | /* | ||
2 | * drivers/video/pnx4008/pnxrgbfb.c | ||
3 | * | ||
4 | * PNX4008's framebuffer support | ||
5 | * | ||
6 | * Author: Grigory Tolstolytkin <gtolstolytkin@ru.mvista.com> | ||
7 | * Based on Philips Semiconductors's code | ||
8 | * | ||
9 | * Copyrght (c) 2005 MontaVista Software, Inc. | ||
10 | * Copyright (c) 2005 Philips Semiconductors | ||
11 | * This file is licensed under the terms of the GNU General Public License | ||
12 | * version 2. This program is licensed "as is" without any warranty of any | ||
13 | * kind, whether express or implied. | ||
14 | */ | ||
15 | |||
16 | #include <linux/module.h> | ||
17 | #include <linux/kernel.h> | ||
18 | #include <linux/errno.h> | ||
19 | #include <linux/string.h> | ||
20 | #include <linux/mm.h> | ||
21 | #include <linux/slab.h> | ||
22 | #include <linux/vmalloc.h> | ||
23 | #include <linux/delay.h> | ||
24 | #include <linux/interrupt.h> | ||
25 | #include <linux/fb.h> | ||
26 | #include <linux/init.h> | ||
27 | #include <linux/platform_device.h> | ||
28 | |||
29 | #include <asm/uaccess.h> | ||
30 | #include "sdum.h" | ||
31 | #include "fbcommon.h" | ||
32 | |||
33 | static u32 colreg[16]; | ||
34 | |||
35 | static struct fb_var_screeninfo rgbfb_var __initdata = { | ||
36 | .xres = LCD_X_RES, | ||
37 | .yres = LCD_Y_RES, | ||
38 | .xres_virtual = LCD_X_RES, | ||
39 | .yres_virtual = LCD_Y_RES, | ||
40 | .bits_per_pixel = 32, | ||
41 | .red.offset = 16, | ||
42 | .red.length = 8, | ||
43 | .green.offset = 8, | ||
44 | .green.length = 8, | ||
45 | .blue.offset = 0, | ||
46 | .blue.length = 8, | ||
47 | .left_margin = 0, | ||
48 | .right_margin = 0, | ||
49 | .upper_margin = 0, | ||
50 | .lower_margin = 0, | ||
51 | .vmode = FB_VMODE_NONINTERLACED, | ||
52 | }; | ||
53 | static struct fb_fix_screeninfo rgbfb_fix __initdata = { | ||
54 | .id = "RGBFB", | ||
55 | .line_length = LCD_X_RES * LCD_BBP, | ||
56 | .type = FB_TYPE_PACKED_PIXELS, | ||
57 | .visual = FB_VISUAL_TRUECOLOR, | ||
58 | .xpanstep = 0, | ||
59 | .ypanstep = 0, | ||
60 | .ywrapstep = 0, | ||
61 | .accel = FB_ACCEL_NONE, | ||
62 | }; | ||
63 | |||
64 | static int channel_owned; | ||
65 | |||
66 | static int no_cursor(struct fb_info *info, struct fb_cursor *cursor) | ||
67 | { | ||
68 | return 0; | ||
69 | } | ||
70 | |||
71 | static int rgbfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, | ||
72 | u_int transp, struct fb_info *info) | ||
73 | { | ||
74 | if (regno > 15) | ||
75 | return 1; | ||
76 | |||
77 | colreg[regno] = ((red & 0xff00) << 8) | (green & 0xff00) | | ||
78 | ((blue & 0xff00) >> 8); | ||
79 | return 0; | ||
80 | } | ||
81 | |||
82 | static int rgbfb_mmap(struct fb_info *info, struct vm_area_struct *vma) | ||
83 | { | ||
84 | return pnx4008_sdum_mmap(info, vma, NULL); | ||
85 | } | ||
86 | |||
87 | static struct fb_ops rgbfb_ops = { | ||
88 | .fb_mmap = rgbfb_mmap, | ||
89 | .fb_setcolreg = rgbfb_setcolreg, | ||
90 | .fb_fillrect = cfb_fillrect, | ||
91 | .fb_copyarea = cfb_copyarea, | ||
92 | .fb_imageblit = cfb_imageblit, | ||
93 | }; | ||
94 | |||
95 | static int rgbfb_remove(struct platform_device *pdev) | ||
96 | { | ||
97 | struct fb_info *info = platform_get_drvdata(pdev); | ||
98 | |||
99 | if (info) { | ||
100 | unregister_framebuffer(info); | ||
101 | fb_dealloc_cmap(&info->cmap); | ||
102 | framebuffer_release(info); | ||
103 | platform_set_drvdata(pdev, NULL); | ||
104 | kfree(info); | ||
105 | } | ||
106 | |||
107 | pnx4008_free_dum_channel(channel_owned, pdev->id); | ||
108 | pnx4008_set_dum_exit_notification(pdev->id); | ||
109 | |||
110 | return 0; | ||
111 | } | ||
112 | |||
113 | static int __devinit rgbfb_probe(struct platform_device *pdev) | ||
114 | { | ||
115 | struct fb_info *info; | ||
116 | struct dumchannel_uf chan_uf; | ||
117 | int ret; | ||
118 | char *option; | ||
119 | |||
120 | info = framebuffer_alloc(sizeof(u32) * 16, &pdev->dev); | ||
121 | if (!info) { | ||
122 | ret = -ENOMEM; | ||
123 | goto err; | ||
124 | } | ||
125 | |||
126 | pnx4008_get_fb_addresses(FB_TYPE_RGB, (void **)&info->screen_base, | ||
127 | (dma_addr_t *) &rgbfb_fix.smem_start, | ||
128 | &rgbfb_fix.smem_len); | ||
129 | |||
130 | if ((ret = pnx4008_alloc_dum_channel(pdev->id)) < 0) | ||
131 | goto err0; | ||
132 | else { | ||
133 | channel_owned = ret; | ||
134 | chan_uf.channelnr = channel_owned; | ||
135 | chan_uf.dirty = (u32 *) NULL; | ||
136 | chan_uf.source = (u32 *) rgbfb_fix.smem_start; | ||
137 | chan_uf.x_offset = 0; | ||
138 | chan_uf.y_offset = 0; | ||
139 | chan_uf.width = LCD_X_RES; | ||
140 | chan_uf.height = LCD_Y_RES; | ||
141 | |||
142 | if ((ret = pnx4008_put_dum_channel_uf(chan_uf, pdev->id))< 0) | ||
143 | goto err1; | ||
144 | |||
145 | if ((ret = | ||
146 | pnx4008_set_dum_channel_sync(channel_owned, CONF_SYNC_ON, | ||
147 | pdev->id)) < 0) | ||
148 | goto err1; | ||
149 | |||
150 | if ((ret = | ||
151 | pnx4008_set_dum_channel_dirty_detect(channel_owned, | ||
152 | CONF_DIRTYDETECTION_ON, | ||
153 | pdev->id)) < 0) | ||
154 | goto err1; | ||
155 | } | ||
156 | |||
157 | if (!fb_get_options("pnxrgbfb", &option) && !strcmp(option, "nocursor")) | ||
158 | rgbfb_ops.fb_cursor = no_cursor; | ||
159 | |||
160 | info->node = -1; | ||
161 | info->flags = FBINFO_FLAG_DEFAULT; | ||
162 | info->fbops = &rgbfb_ops; | ||
163 | info->fix = rgbfb_fix; | ||
164 | info->var = rgbfb_var; | ||
165 | info->screen_size = rgbfb_fix.smem_len; | ||
166 | info->pseudo_palette = info->par; | ||
167 | info->par = NULL; | ||
168 | |||
169 | ret = fb_alloc_cmap(&info->cmap, 256, 0); | ||
170 | if (ret < 0) | ||
171 | goto err2; | ||
172 | |||
173 | ret = register_framebuffer(info); | ||
174 | if (ret < 0) | ||
175 | goto err3; | ||
176 | platform_set_drvdata(pdev, info); | ||
177 | |||
178 | return 0; | ||
179 | |||
180 | err3: | ||
181 | fb_dealloc_cmap(&info->cmap); | ||
182 | err2: | ||
183 | framebuffer_release(info); | ||
184 | err1: | ||
185 | pnx4008_free_dum_channel(channel_owned, pdev->id); | ||
186 | err0: | ||
187 | kfree(info); | ||
188 | err: | ||
189 | return ret; | ||
190 | } | ||
191 | |||
192 | static struct platform_driver rgbfb_driver = { | ||
193 | .driver = { | ||
194 | .name = "rgbfb", | ||
195 | }, | ||
196 | .probe = rgbfb_probe, | ||
197 | .remove = rgbfb_remove, | ||
198 | }; | ||
199 | |||
200 | static int __init rgbfb_init(void) | ||
201 | { | ||
202 | return platform_driver_register(&rgbfb_driver); | ||
203 | } | ||
204 | |||
205 | static void __exit rgbfb_exit(void) | ||
206 | { | ||
207 | platform_driver_unregister(&rgbfb_driver); | ||
208 | } | ||
209 | |||
210 | module_init(rgbfb_init); | ||
211 | module_exit(rgbfb_exit); | ||
212 | |||
213 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/video/pnx4008/sdum.c b/drivers/video/pnx4008/sdum.c new file mode 100644 index 000000000000..51f0ecc2a511 --- /dev/null +++ b/drivers/video/pnx4008/sdum.c | |||
@@ -0,0 +1,872 @@ | |||
1 | /* | ||
2 | * drivers/video/pnx4008/sdum.c | ||
3 | * | ||
4 | * Display Update Master support | ||
5 | * | ||
6 | * Authors: Grigory Tolstolytkin <gtolstolytkin@ru.mvista.com> | ||
7 | * Vitaly Wool <vitalywool@gmail.com> | ||
8 | * Based on Philips Semiconductors's code | ||
9 | * | ||
10 | * Copyrght (c) 2005-2006 MontaVista Software, Inc. | ||
11 | * Copyright (c) 2005 Philips Semiconductors | ||
12 | * This file is licensed under the terms of the GNU General Public License | ||
13 | * version 2. This program is licensed "as is" without any warranty of any | ||
14 | * kind, whether express or implied. | ||
15 | */ | ||
16 | |||
17 | #include <linux/module.h> | ||
18 | #include <linux/kernel.h> | ||
19 | #include <linux/errno.h> | ||
20 | #include <linux/string.h> | ||
21 | #include <linux/mm.h> | ||
22 | #include <linux/tty.h> | ||
23 | #include <linux/slab.h> | ||
24 | #include <linux/vmalloc.h> | ||
25 | #include <linux/delay.h> | ||
26 | #include <linux/interrupt.h> | ||
27 | #include <linux/platform_device.h> | ||
28 | #include <linux/fb.h> | ||
29 | #include <linux/init.h> | ||
30 | #include <linux/dma-mapping.h> | ||
31 | #include <linux/clk.h> | ||
32 | #include <asm/uaccess.h> | ||
33 | #include <asm/arch/gpio.h> | ||
34 | |||
35 | #include "sdum.h" | ||
36 | #include "fbcommon.h" | ||
37 | #include "dum.h" | ||
38 | |||
39 | /* Framebuffers we have */ | ||
40 | |||
41 | static struct pnx4008_fb_addr { | ||
42 | int fb_type; | ||
43 | long addr_offset; | ||
44 | long fb_length; | ||
45 | } fb_addr[] = { | ||
46 | [0] = { | ||
47 | FB_TYPE_YUV, 0, 0xB0000 | ||
48 | }, | ||
49 | [1] = { | ||
50 | FB_TYPE_RGB, 0xB0000, 0x50000 | ||
51 | }, | ||
52 | }; | ||
53 | |||
54 | static struct dum_data { | ||
55 | u32 lcd_phys_start; | ||
56 | u32 lcd_virt_start; | ||
57 | u32 slave_phys_base; | ||
58 | u32 *slave_virt_base; | ||
59 | int fb_owning_channel[MAX_DUM_CHANNELS]; | ||
60 | struct dumchannel_uf chan_uf_store[MAX_DUM_CHANNELS]; | ||
61 | } dum_data; | ||
62 | |||
63 | /* Different local helper functions */ | ||
64 | |||
65 | static u32 nof_pixels_dx(struct dum_ch_setup *ch_setup) | ||
66 | { | ||
67 | return (ch_setup->xmax - ch_setup->xmin + 1); | ||
68 | } | ||
69 | |||
70 | static u32 nof_pixels_dy(struct dum_ch_setup *ch_setup) | ||
71 | { | ||
72 | return (ch_setup->ymax - ch_setup->ymin + 1); | ||
73 | } | ||
74 | |||
75 | static u32 nof_pixels_dxy(struct dum_ch_setup *ch_setup) | ||
76 | { | ||
77 | return (nof_pixels_dx(ch_setup) * nof_pixels_dy(ch_setup)); | ||
78 | } | ||
79 | |||
80 | static u32 nof_bytes(struct dum_ch_setup *ch_setup) | ||
81 | { | ||
82 | u32 r = nof_pixels_dxy(ch_setup); | ||
83 | switch (ch_setup->format) { | ||
84 | case RGB888: | ||
85 | case RGB666: | ||
86 | r *= 4; | ||
87 | break; | ||
88 | |||
89 | default: | ||
90 | r *= 2; | ||
91 | break; | ||
92 | } | ||
93 | return r; | ||
94 | } | ||
95 | |||
96 | static u32 build_command(int disp_no, u32 reg, u32 val) | ||
97 | { | ||
98 | return ((disp_no << 26) | BIT(25) | (val << 16) | (disp_no << 10) | | ||
99 | (reg << 0)); | ||
100 | } | ||
101 | |||
102 | static u32 build_double_index(int disp_no, u32 val) | ||
103 | { | ||
104 | return ((disp_no << 26) | (val << 16) | (disp_no << 10) | (val << 0)); | ||
105 | } | ||
106 | |||
107 | static void build_disp_window(struct dum_ch_setup * ch_setup, struct disp_window * dw) | ||
108 | { | ||
109 | dw->ymin = ch_setup->ymin; | ||
110 | dw->ymax = ch_setup->ymax; | ||
111 | dw->xmin_l = ch_setup->xmin & 0xFF; | ||
112 | dw->xmin_h = (ch_setup->xmin & BIT(8)) >> 8; | ||
113 | dw->xmax_l = ch_setup->xmax & 0xFF; | ||
114 | dw->xmax_h = (ch_setup->xmax & BIT(8)) >> 8; | ||
115 | } | ||
116 | |||
117 | static int put_channel(struct dumchannel chan) | ||
118 | { | ||
119 | int i = chan.channelnr; | ||
120 | |||
121 | if (i < 0 || i > MAX_DUM_CHANNELS) | ||
122 | return -EINVAL; | ||
123 | else { | ||
124 | DUM_CH_MIN(i) = chan.dum_ch_min; | ||
125 | DUM_CH_MAX(i) = chan.dum_ch_max; | ||
126 | DUM_CH_CONF(i) = chan.dum_ch_conf; | ||
127 | DUM_CH_CTRL(i) = chan.dum_ch_ctrl; | ||
128 | } | ||
129 | |||
130 | return 0; | ||
131 | } | ||
132 | |||
133 | static void clear_channel(int channr) | ||
134 | { | ||
135 | struct dumchannel chan; | ||
136 | |||
137 | chan.channelnr = channr; | ||
138 | chan.dum_ch_min = 0; | ||
139 | chan.dum_ch_max = 0; | ||
140 | chan.dum_ch_conf = 0; | ||
141 | chan.dum_ch_ctrl = 0; | ||
142 | |||
143 | put_channel(chan); | ||
144 | } | ||
145 | |||
146 | static int put_cmd_string(struct cmdstring cmds) | ||
147 | { | ||
148 | u16 *cmd_str_virtaddr; | ||
149 | u32 *cmd_ptr0_virtaddr; | ||
150 | u32 cmd_str_physaddr; | ||
151 | |||
152 | int i = cmds.channelnr; | ||
153 | |||
154 | if (i < 0 || i > MAX_DUM_CHANNELS) | ||
155 | return -EINVAL; | ||
156 | else if ((cmd_ptr0_virtaddr = | ||
157 | (int *)ioremap_nocache(DUM_COM_BASE, | ||
158 | sizeof(int) * MAX_DUM_CHANNELS)) == | ||
159 | NULL) | ||
160 | return -EIOREMAPFAILED; | ||
161 | else { | ||
162 | cmd_str_physaddr = ioread32(&cmd_ptr0_virtaddr[cmds.channelnr]); | ||
163 | if ((cmd_str_virtaddr = | ||
164 | (u16 *) ioremap_nocache(cmd_str_physaddr, | ||
165 | sizeof(cmds))) == NULL) { | ||
166 | iounmap(cmd_ptr0_virtaddr); | ||
167 | return -EIOREMAPFAILED; | ||
168 | } else { | ||
169 | int t; | ||
170 | for (t = 0; t < 8; t++) | ||
171 | iowrite16(*((u16 *)&cmds.prestringlen + t), | ||
172 | cmd_str_virtaddr + t); | ||
173 | |||
174 | for (t = 0; t < cmds.prestringlen / 2; t++) | ||
175 | iowrite16(*((u16 *)&cmds.precmd + t), | ||
176 | cmd_str_virtaddr + t + 8); | ||
177 | |||
178 | for (t = 0; t < cmds.poststringlen / 2; t++) | ||
179 | iowrite16(*((u16 *)&cmds.postcmd + t), | ||
180 | cmd_str_virtaddr + t + 8 + | ||
181 | cmds.prestringlen / 2); | ||
182 | |||
183 | iounmap(cmd_ptr0_virtaddr); | ||
184 | iounmap(cmd_str_virtaddr); | ||
185 | } | ||
186 | } | ||
187 | |||
188 | return 0; | ||
189 | } | ||
190 | |||
191 | static u32 dum_ch_setup(int ch_no, struct dum_ch_setup * ch_setup) | ||
192 | { | ||
193 | struct cmdstring cmds_c; | ||
194 | struct cmdstring *cmds = &cmds_c; | ||
195 | struct disp_window dw; | ||
196 | int standard; | ||
197 | u32 orientation = 0; | ||
198 | struct dumchannel chan = { 0 }; | ||
199 | int ret; | ||
200 | |||
201 | if ((ch_setup->xmirror) || (ch_setup->ymirror) || (ch_setup->rotate)) { | ||
202 | standard = 0; | ||
203 | |||
204 | orientation = BIT(1); /* always set 9-bit-bus */ | ||
205 | if (ch_setup->xmirror) | ||
206 | orientation |= BIT(4); | ||
207 | if (ch_setup->ymirror) | ||
208 | orientation |= BIT(3); | ||
209 | if (ch_setup->rotate) | ||
210 | orientation |= BIT(0); | ||
211 | } else | ||
212 | standard = 1; | ||
213 | |||
214 | cmds->channelnr = ch_no; | ||
215 | |||
216 | /* build command string header */ | ||
217 | if (standard) { | ||
218 | cmds->prestringlen = 32; | ||
219 | cmds->poststringlen = 0; | ||
220 | } else { | ||
221 | cmds->prestringlen = 48; | ||
222 | cmds->poststringlen = 16; | ||
223 | } | ||
224 | |||
225 | cmds->format = | ||
226 | (u16) ((ch_setup->disp_no << 4) | (BIT(3)) | (ch_setup->format)); | ||
227 | cmds->reserved = 0x0; | ||
228 | cmds->startaddr_low = (ch_setup->minadr & 0xFFFF); | ||
229 | cmds->startaddr_high = (ch_setup->minadr >> 16); | ||
230 | |||
231 | if ((ch_setup->minadr == 0) && (ch_setup->maxadr == 0) | ||
232 | && (ch_setup->xmin == 0) | ||
233 | && (ch_setup->ymin == 0) && (ch_setup->xmax == 0) | ||
234 | && (ch_setup->ymax == 0)) { | ||
235 | cmds->pixdatlen_low = 0; | ||
236 | cmds->pixdatlen_high = 0; | ||
237 | } else { | ||
238 | u32 nbytes = nof_bytes(ch_setup); | ||
239 | cmds->pixdatlen_low = (nbytes & 0xFFFF); | ||
240 | cmds->pixdatlen_high = (nbytes >> 16); | ||
241 | } | ||
242 | |||
243 | if (ch_setup->slave_trans) | ||
244 | cmds->pixdatlen_high |= BIT(15); | ||
245 | |||
246 | /* build pre-string */ | ||
247 | build_disp_window(ch_setup, &dw); | ||
248 | |||
249 | if (standard) { | ||
250 | cmds->precmd[0] = | ||
251 | build_command(ch_setup->disp_no, DISP_XMIN_L_REG, 0x99); | ||
252 | cmds->precmd[1] = | ||
253 | build_command(ch_setup->disp_no, DISP_XMIN_L_REG, | ||
254 | dw.xmin_l); | ||
255 | cmds->precmd[2] = | ||
256 | build_command(ch_setup->disp_no, DISP_XMIN_H_REG, | ||
257 | dw.xmin_h); | ||
258 | cmds->precmd[3] = | ||
259 | build_command(ch_setup->disp_no, DISP_YMIN_REG, dw.ymin); | ||
260 | cmds->precmd[4] = | ||
261 | build_command(ch_setup->disp_no, DISP_XMAX_L_REG, | ||
262 | dw.xmax_l); | ||
263 | cmds->precmd[5] = | ||
264 | build_command(ch_setup->disp_no, DISP_XMAX_H_REG, | ||
265 | dw.xmax_h); | ||
266 | cmds->precmd[6] = | ||
267 | build_command(ch_setup->disp_no, DISP_YMAX_REG, dw.ymax); | ||
268 | cmds->precmd[7] = | ||
269 | build_double_index(ch_setup->disp_no, DISP_PIXEL_REG); | ||
270 | } else { | ||
271 | if (dw.xmin_l == ch_no) | ||
272 | cmds->precmd[0] = | ||
273 | build_command(ch_setup->disp_no, DISP_XMIN_L_REG, | ||
274 | 0x99); | ||
275 | else | ||
276 | cmds->precmd[0] = | ||
277 | build_command(ch_setup->disp_no, DISP_XMIN_L_REG, | ||
278 | ch_no); | ||
279 | |||
280 | cmds->precmd[1] = | ||
281 | build_command(ch_setup->disp_no, DISP_XMIN_L_REG, | ||
282 | dw.xmin_l); | ||
283 | cmds->precmd[2] = | ||
284 | build_command(ch_setup->disp_no, DISP_XMIN_H_REG, | ||
285 | dw.xmin_h); | ||
286 | cmds->precmd[3] = | ||
287 | build_command(ch_setup->disp_no, DISP_YMIN_REG, dw.ymin); | ||
288 | cmds->precmd[4] = | ||
289 | build_command(ch_setup->disp_no, DISP_XMAX_L_REG, | ||
290 | dw.xmax_l); | ||
291 | cmds->precmd[5] = | ||
292 | build_command(ch_setup->disp_no, DISP_XMAX_H_REG, | ||
293 | dw.xmax_h); | ||
294 | cmds->precmd[6] = | ||
295 | build_command(ch_setup->disp_no, DISP_YMAX_REG, dw.ymax); | ||
296 | cmds->precmd[7] = | ||
297 | build_command(ch_setup->disp_no, DISP_1_REG, orientation); | ||
298 | cmds->precmd[8] = | ||
299 | build_double_index(ch_setup->disp_no, DISP_PIXEL_REG); | ||
300 | cmds->precmd[9] = | ||
301 | build_double_index(ch_setup->disp_no, DISP_PIXEL_REG); | ||
302 | cmds->precmd[0xA] = | ||
303 | build_double_index(ch_setup->disp_no, DISP_PIXEL_REG); | ||
304 | cmds->precmd[0xB] = | ||
305 | build_double_index(ch_setup->disp_no, DISP_PIXEL_REG); | ||
306 | cmds->postcmd[0] = | ||
307 | build_command(ch_setup->disp_no, DISP_1_REG, BIT(1)); | ||
308 | cmds->postcmd[1] = | ||
309 | build_command(ch_setup->disp_no, DISP_DUMMY1_REG, 1); | ||
310 | cmds->postcmd[2] = | ||
311 | build_command(ch_setup->disp_no, DISP_DUMMY1_REG, 2); | ||
312 | cmds->postcmd[3] = | ||
313 | build_command(ch_setup->disp_no, DISP_DUMMY1_REG, 3); | ||
314 | } | ||
315 | |||
316 | if ((ret = put_cmd_string(cmds_c)) != 0) { | ||
317 | return ret; | ||
318 | } | ||
319 | |||
320 | chan.channelnr = cmds->channelnr; | ||
321 | chan.dum_ch_min = ch_setup->dirtybuffer + ch_setup->minadr; | ||
322 | chan.dum_ch_max = ch_setup->dirtybuffer + ch_setup->maxadr; | ||
323 | chan.dum_ch_conf = 0x002; | ||
324 | chan.dum_ch_ctrl = 0x04; | ||
325 | |||
326 | put_channel(chan); | ||
327 | |||
328 | return 0; | ||
329 | } | ||
330 | |||
331 | static u32 display_open(int ch_no, int auto_update, u32 * dirty_buffer, | ||
332 | u32 * frame_buffer, u32 xpos, u32 ypos, u32 w, u32 h) | ||
333 | { | ||
334 | |||
335 | struct dum_ch_setup k; | ||
336 | int ret; | ||
337 | |||
338 | /* keep width & height within display area */ | ||
339 | if ((xpos + w) > DISP_MAX_X_SIZE) | ||
340 | w = DISP_MAX_X_SIZE - xpos; | ||
341 | |||
342 | if ((ypos + h) > DISP_MAX_Y_SIZE) | ||
343 | h = DISP_MAX_Y_SIZE - ypos; | ||
344 | |||
345 | /* assume 1 display only */ | ||
346 | k.disp_no = 0; | ||
347 | k.xmin = xpos; | ||
348 | k.ymin = ypos; | ||
349 | k.xmax = xpos + (w - 1); | ||
350 | k.ymax = ypos + (h - 1); | ||
351 | |||
352 | /* adjust min and max values if necessary */ | ||
353 | if (k.xmin > DISP_MAX_X_SIZE - 1) | ||
354 | k.xmin = DISP_MAX_X_SIZE - 1; | ||
355 | if (k.ymin > DISP_MAX_Y_SIZE - 1) | ||
356 | k.ymin = DISP_MAX_Y_SIZE - 1; | ||
357 | |||
358 | if (k.xmax > DISP_MAX_X_SIZE - 1) | ||
359 | k.xmax = DISP_MAX_X_SIZE - 1; | ||
360 | if (k.ymax > DISP_MAX_Y_SIZE - 1) | ||
361 | k.ymax = DISP_MAX_Y_SIZE - 1; | ||
362 | |||
363 | k.xmirror = 0; | ||
364 | k.ymirror = 0; | ||
365 | k.rotate = 0; | ||
366 | k.minadr = (u32) frame_buffer; | ||
367 | k.maxadr = (u32) frame_buffer + (((w - 1) << 10) | ((h << 2) - 2)); | ||
368 | k.pad = PAD_1024; | ||
369 | k.dirtybuffer = (u32) dirty_buffer; | ||
370 | k.format = RGB888; | ||
371 | k.hwdirty = 0; | ||
372 | k.slave_trans = 0; | ||
373 | |||
374 | ret = dum_ch_setup(ch_no, &k); | ||
375 | |||
376 | return ret; | ||
377 | } | ||
378 | |||
379 | static void lcd_reset(void) | ||
380 | { | ||
381 | u32 *dum_pio_base = (u32 *)IO_ADDRESS(PNX4008_PIO_BASE); | ||
382 | |||
383 | udelay(1); | ||
384 | iowrite32(BIT(19), &dum_pio_base[2]); | ||
385 | udelay(1); | ||
386 | iowrite32(BIT(19), &dum_pio_base[1]); | ||
387 | udelay(1); | ||
388 | } | ||
389 | |||
390 | static int dum_init(struct platform_device *pdev) | ||
391 | { | ||
392 | struct clk *clk; | ||
393 | |||
394 | /* enable DUM clock */ | ||
395 | clk = clk_get(&pdev->dev, "dum_ck"); | ||
396 | if (IS_ERR(clk)) { | ||
397 | printk(KERN_ERR "pnx4008_dum: Unable to access DUM clock\n"); | ||
398 | return PTR_ERR(clk); | ||
399 | } | ||
400 | |||
401 | clk_set_rate(clk, 1); | ||
402 | clk_put(clk); | ||
403 | |||
404 | DUM_CTRL = V_DUM_RESET; | ||
405 | |||
406 | /* set priority to "round-robin". All other params to "false" */ | ||
407 | DUM_CONF = BIT(9); | ||
408 | |||
409 | /* Display 1 */ | ||
410 | DUM_WTCFG1 = PNX4008_DUM_WT_CFG; | ||
411 | DUM_RTCFG1 = PNX4008_DUM_RT_CFG; | ||
412 | DUM_TCFG = PNX4008_DUM_T_CFG; | ||
413 | |||
414 | return 0; | ||
415 | } | ||
416 | |||
417 | static void dum_chan_init(void) | ||
418 | { | ||
419 | int i = 0, ch = 0; | ||
420 | u32 *cmdptrs; | ||
421 | u32 *cmdstrings; | ||
422 | |||
423 | DUM_COM_BASE = | ||
424 | CMDSTRING_BASEADDR + BYTES_PER_CMDSTRING * NR_OF_CMDSTRINGS; | ||
425 | |||
426 | if ((cmdptrs = | ||
427 | (u32 *) ioremap_nocache(DUM_COM_BASE, | ||
428 | sizeof(u32) * NR_OF_CMDSTRINGS)) == NULL) | ||
429 | return; | ||
430 | |||
431 | for (ch = 0; ch < NR_OF_CMDSTRINGS; ch++) | ||
432 | iowrite32(CMDSTRING_BASEADDR + BYTES_PER_CMDSTRING * ch, | ||
433 | cmdptrs + ch); | ||
434 | |||
435 | for (ch = 0; ch < MAX_DUM_CHANNELS; ch++) | ||
436 | clear_channel(ch); | ||
437 | |||
438 | /* Clear the cmdstrings */ | ||
439 | cmdstrings = | ||
440 | (u32 *)ioremap_nocache(*cmdptrs, | ||
441 | BYTES_PER_CMDSTRING * NR_OF_CMDSTRINGS); | ||
442 | |||
443 | if (!cmdstrings) | ||
444 | goto out; | ||
445 | |||
446 | for (i = 0; i < NR_OF_CMDSTRINGS * BYTES_PER_CMDSTRING / sizeof(u32); | ||
447 | i++) | ||
448 | iowrite32(0, cmdstrings + i); | ||
449 | |||
450 | iounmap((u32 *)cmdstrings); | ||
451 | |||
452 | out: | ||
453 | iounmap((u32 *)cmdptrs); | ||
454 | } | ||
455 | |||
456 | static void lcd_init(void) | ||
457 | { | ||
458 | lcd_reset(); | ||
459 | |||
460 | DUM_OUTP_FORMAT1 = 0; /* RGB666 */ | ||
461 | |||
462 | udelay(1); | ||
463 | iowrite32(V_LCD_STANDBY_OFF, dum_data.slave_virt_base); | ||
464 | udelay(1); | ||
465 | iowrite32(V_LCD_USE_9BIT_BUS, dum_data.slave_virt_base); | ||
466 | udelay(1); | ||
467 | iowrite32(V_LCD_SYNC_RISE_L, dum_data.slave_virt_base); | ||
468 | udelay(1); | ||
469 | iowrite32(V_LCD_SYNC_RISE_H, dum_data.slave_virt_base); | ||
470 | udelay(1); | ||
471 | iowrite32(V_LCD_SYNC_FALL_L, dum_data.slave_virt_base); | ||
472 | udelay(1); | ||
473 | iowrite32(V_LCD_SYNC_FALL_H, dum_data.slave_virt_base); | ||
474 | udelay(1); | ||
475 | iowrite32(V_LCD_SYNC_ENABLE, dum_data.slave_virt_base); | ||
476 | udelay(1); | ||
477 | iowrite32(V_LCD_DISPLAY_ON, dum_data.slave_virt_base); | ||
478 | udelay(1); | ||
479 | } | ||
480 | |||
481 | /* Interface exported to framebuffer drivers */ | ||
482 | |||
483 | int pnx4008_get_fb_addresses(int fb_type, void **virt_addr, | ||
484 | dma_addr_t *phys_addr, int *fb_length) | ||
485 | { | ||
486 | int i; | ||
487 | int ret = -1; | ||
488 | for (i = 0; i < ARRAY_SIZE(fb_addr); i++) | ||
489 | if (fb_addr[i].fb_type == fb_type) { | ||
490 | *virt_addr = (void *)(dum_data.lcd_virt_start + | ||
491 | fb_addr[i].addr_offset); | ||
492 | *phys_addr = | ||
493 | dum_data.lcd_phys_start + fb_addr[i].addr_offset; | ||
494 | *fb_length = fb_addr[i].fb_length; | ||
495 | ret = 0; | ||
496 | break; | ||
497 | } | ||
498 | |||
499 | return ret; | ||
500 | } | ||
501 | |||
502 | EXPORT_SYMBOL(pnx4008_get_fb_addresses); | ||
503 | |||
504 | int pnx4008_alloc_dum_channel(int dev_id) | ||
505 | { | ||
506 | int i = 0; | ||
507 | |||
508 | while ((i < MAX_DUM_CHANNELS) && (dum_data.fb_owning_channel[i] != -1)) | ||
509 | i++; | ||
510 | |||
511 | if (i == MAX_DUM_CHANNELS) | ||
512 | return -ENORESOURCESLEFT; | ||
513 | else { | ||
514 | dum_data.fb_owning_channel[i] = dev_id; | ||
515 | return i; | ||
516 | } | ||
517 | } | ||
518 | |||
519 | EXPORT_SYMBOL(pnx4008_alloc_dum_channel); | ||
520 | |||
521 | int pnx4008_free_dum_channel(int channr, int dev_id) | ||
522 | { | ||
523 | if (channr < 0 || channr > MAX_DUM_CHANNELS) | ||
524 | return -EINVAL; | ||
525 | else if (dum_data.fb_owning_channel[channr] != dev_id) | ||
526 | return -EFBNOTOWNER; | ||
527 | else { | ||
528 | clear_channel(channr); | ||
529 | dum_data.fb_owning_channel[channr] = -1; | ||
530 | } | ||
531 | |||
532 | return 0; | ||
533 | } | ||
534 | |||
535 | EXPORT_SYMBOL(pnx4008_free_dum_channel); | ||
536 | |||
537 | int pnx4008_put_dum_channel_uf(struct dumchannel_uf chan_uf, int dev_id) | ||
538 | { | ||
539 | int i = chan_uf.channelnr; | ||
540 | int ret; | ||
541 | |||
542 | if (i < 0 || i > MAX_DUM_CHANNELS) | ||
543 | return -EINVAL; | ||
544 | else if (dum_data.fb_owning_channel[i] != dev_id) | ||
545 | return -EFBNOTOWNER; | ||
546 | else if ((ret = | ||
547 | display_open(chan_uf.channelnr, 0, chan_uf.dirty, | ||
548 | chan_uf.source, chan_uf.y_offset, | ||
549 | chan_uf.x_offset, chan_uf.height, | ||
550 | chan_uf.width)) != 0) | ||
551 | return ret; | ||
552 | else { | ||
553 | dum_data.chan_uf_store[i].dirty = chan_uf.dirty; | ||
554 | dum_data.chan_uf_store[i].source = chan_uf.source; | ||
555 | dum_data.chan_uf_store[i].x_offset = chan_uf.x_offset; | ||
556 | dum_data.chan_uf_store[i].y_offset = chan_uf.y_offset; | ||
557 | dum_data.chan_uf_store[i].width = chan_uf.width; | ||
558 | dum_data.chan_uf_store[i].height = chan_uf.height; | ||
559 | } | ||
560 | |||
561 | return 0; | ||
562 | } | ||
563 | |||
564 | EXPORT_SYMBOL(pnx4008_put_dum_channel_uf); | ||
565 | |||
566 | int pnx4008_set_dum_channel_sync(int channr, int val, int dev_id) | ||
567 | { | ||
568 | if (channr < 0 || channr > MAX_DUM_CHANNELS) | ||
569 | return -EINVAL; | ||
570 | else if (dum_data.fb_owning_channel[channr] != dev_id) | ||
571 | return -EFBNOTOWNER; | ||
572 | else { | ||
573 | if (val == CONF_SYNC_ON) { | ||
574 | DUM_CH_CONF(channr) |= CONF_SYNCENABLE; | ||
575 | DUM_CH_CONF(channr) |= DUM_CHANNEL_CFG_SYNC_MASK | | ||
576 | DUM_CHANNEL_CFG_SYNC_MASK_SET; | ||
577 | } else if (val == CONF_SYNC_OFF) | ||
578 | DUM_CH_CONF(channr) &= ~CONF_SYNCENABLE; | ||
579 | else | ||
580 | return -EINVAL; | ||
581 | } | ||
582 | |||
583 | return 0; | ||
584 | } | ||
585 | |||
586 | EXPORT_SYMBOL(pnx4008_set_dum_channel_sync); | ||
587 | |||
588 | int pnx4008_set_dum_channel_dirty_detect(int channr, int val, int dev_id) | ||
589 | { | ||
590 | if (channr < 0 || channr > MAX_DUM_CHANNELS) | ||
591 | return -EINVAL; | ||
592 | else if (dum_data.fb_owning_channel[channr] != dev_id) | ||
593 | return -EFBNOTOWNER; | ||
594 | else { | ||
595 | if (val == CONF_DIRTYDETECTION_ON) | ||
596 | DUM_CH_CONF(channr) |= CONF_DIRTYENABLE; | ||
597 | else if (val == CONF_DIRTYDETECTION_OFF) | ||
598 | DUM_CH_CONF(channr) &= ~CONF_DIRTYENABLE; | ||
599 | else | ||
600 | return -EINVAL; | ||
601 | } | ||
602 | |||
603 | return 0; | ||
604 | } | ||
605 | |||
606 | EXPORT_SYMBOL(pnx4008_set_dum_channel_dirty_detect); | ||
607 | |||
608 | #if 0 /* Functions not used currently, but likely to be used in future */ | ||
609 | |||
610 | static int get_channel(struct dumchannel *p_chan) | ||
611 | { | ||
612 | int i = p_chan->channelnr; | ||
613 | |||
614 | if (i < 0 || i > MAX_DUM_CHANNELS) | ||
615 | return -EINVAL; | ||
616 | else { | ||
617 | p_chan->dum_ch_min = DUM_CH_MIN(i); | ||
618 | p_chan->dum_ch_max = DUM_CH_MAX(i); | ||
619 | p_chan->dum_ch_conf = DUM_CH_CONF(i); | ||
620 | p_chan->dum_ch_stat = DUM_CH_STAT(i); | ||
621 | p_chan->dum_ch_ctrl = 0; /* WriteOnly control register */ | ||
622 | } | ||
623 | |||
624 | return 0; | ||
625 | } | ||
626 | |||
627 | int pnx4008_get_dum_channel_uf(struct dumchannel_uf *p_chan_uf, int dev_id) | ||
628 | { | ||
629 | int i = p_chan_uf->channelnr; | ||
630 | |||
631 | if (i < 0 || i > MAX_DUM_CHANNELS) | ||
632 | return -EINVAL; | ||
633 | else if (dum_data.fb_owning_channel[i] != dev_id) | ||
634 | return -EFBNOTOWNER; | ||
635 | else { | ||
636 | p_chan_uf->dirty = dum_data.chan_uf_store[i].dirty; | ||
637 | p_chan_uf->source = dum_data.chan_uf_store[i].source; | ||
638 | p_chan_uf->x_offset = dum_data.chan_uf_store[i].x_offset; | ||
639 | p_chan_uf->y_offset = dum_data.chan_uf_store[i].y_offset; | ||
640 | p_chan_uf->width = dum_data.chan_uf_store[i].width; | ||
641 | p_chan_uf->height = dum_data.chan_uf_store[i].height; | ||
642 | } | ||
643 | |||
644 | return 0; | ||
645 | } | ||
646 | |||
647 | EXPORT_SYMBOL(pnx4008_get_dum_channel_uf); | ||
648 | |||
649 | int pnx4008_get_dum_channel_config(int channr, int dev_id) | ||
650 | { | ||
651 | int ret; | ||
652 | struct dumchannel chan; | ||
653 | |||
654 | if (channr < 0 || channr > MAX_DUM_CHANNELS) | ||
655 | return -EINVAL; | ||
656 | else if (dum_data.fb_owning_channel[channr] != dev_id) | ||
657 | return -EFBNOTOWNER; | ||
658 | else { | ||
659 | chan.channelnr = channr; | ||
660 | if ((ret = get_channel(&chan)) != 0) | ||
661 | return ret; | ||
662 | } | ||
663 | |||
664 | return (chan.dum_ch_conf & DUM_CHANNEL_CFG_MASK); | ||
665 | } | ||
666 | |||
667 | EXPORT_SYMBOL(pnx4008_get_dum_channel_config); | ||
668 | |||
669 | int pnx4008_force_update_dum_channel(int channr, int dev_id) | ||
670 | { | ||
671 | if (channr < 0 || channr > MAX_DUM_CHANNELS) | ||
672 | return -EINVAL; | ||
673 | |||
674 | else if (dum_data.fb_owning_channel[channr] != dev_id) | ||
675 | return -EFBNOTOWNER; | ||
676 | else | ||
677 | DUM_CH_CTRL(channr) = CTRL_SETDIRTY; | ||
678 | |||
679 | return 0; | ||
680 | } | ||
681 | |||
682 | EXPORT_SYMBOL(pnx4008_force_update_dum_channel); | ||
683 | |||
684 | #endif | ||
685 | |||
686 | int pnx4008_sdum_mmap(struct fb_info *info, struct vm_area_struct *vma, | ||
687 | struct device *dev) | ||
688 | { | ||
689 | unsigned long off = vma->vm_pgoff << PAGE_SHIFT; | ||
690 | |||
691 | if (off < info->fix.smem_len) { | ||
692 | vma->vm_pgoff += 1; | ||
693 | return dma_mmap_writecombine(dev, vma, | ||
694 | (void *)dum_data.lcd_virt_start, | ||
695 | dum_data.lcd_phys_start, | ||
696 | FB_DMA_SIZE); | ||
697 | } | ||
698 | return -EINVAL; | ||
699 | } | ||
700 | |||
701 | EXPORT_SYMBOL(pnx4008_sdum_mmap); | ||
702 | |||
703 | int pnx4008_set_dum_exit_notification(int dev_id) | ||
704 | { | ||
705 | int i; | ||
706 | |||
707 | for (i = 0; i < MAX_DUM_CHANNELS; i++) | ||
708 | if (dum_data.fb_owning_channel[i] == dev_id) | ||
709 | return -ERESOURCESNOTFREED; | ||
710 | |||
711 | return 0; | ||
712 | } | ||
713 | |||
714 | EXPORT_SYMBOL(pnx4008_set_dum_exit_notification); | ||
715 | |||
716 | /* Platform device driver for DUM */ | ||
717 | |||
718 | static int sdum_suspend(struct platform_device *pdev, pm_message_t state) | ||
719 | { | ||
720 | int retval = 0; | ||
721 | struct clk *clk; | ||
722 | |||
723 | clk = clk_get(0, "dum_ck"); | ||
724 | if (!IS_ERR(clk)) { | ||
725 | clk_set_rate(clk, 0); | ||
726 | clk_put(clk); | ||
727 | } else | ||
728 | retval = PTR_ERR(clk); | ||
729 | |||
730 | /* disable BAC */ | ||
731 | DUM_CTRL = V_BAC_DISABLE_IDLE; | ||
732 | |||
733 | /* LCD standby & turn off display */ | ||
734 | lcd_reset(); | ||
735 | |||
736 | return retval; | ||
737 | } | ||
738 | |||
739 | static int sdum_resume(struct platform_device *pdev) | ||
740 | { | ||
741 | int retval = 0; | ||
742 | struct clk *clk; | ||
743 | |||
744 | clk = clk_get(0, "dum_ck"); | ||
745 | if (!IS_ERR(clk)) { | ||
746 | clk_set_rate(clk, 1); | ||
747 | clk_put(clk); | ||
748 | } else | ||
749 | retval = PTR_ERR(clk); | ||
750 | |||
751 | /* wait for BAC disable */ | ||
752 | DUM_CTRL = V_BAC_DISABLE_TRIG; | ||
753 | |||
754 | while (DUM_CTRL & BAC_ENABLED) | ||
755 | udelay(10); | ||
756 | |||
757 | /* re-init LCD */ | ||
758 | lcd_init(); | ||
759 | |||
760 | /* enable BAC and reset MUX */ | ||
761 | DUM_CTRL = V_BAC_ENABLE; | ||
762 | udelay(1); | ||
763 | DUM_CTRL = V_MUX_RESET; | ||
764 | return 0; | ||
765 | } | ||
766 | |||
767 | static int __devinit sdum_probe(struct platform_device *pdev) | ||
768 | { | ||
769 | int ret = 0, i = 0; | ||
770 | |||
771 | /* map frame buffer */ | ||
772 | dum_data.lcd_virt_start = (u32) dma_alloc_writecombine(&pdev->dev, | ||
773 | FB_DMA_SIZE, | ||
774 | &dum_data.lcd_phys_start, | ||
775 | GFP_KERNEL); | ||
776 | |||
777 | if (!dum_data.lcd_virt_start) { | ||
778 | ret = -ENOMEM; | ||
779 | goto out_3; | ||
780 | } | ||
781 | |||
782 | /* map slave registers */ | ||
783 | dum_data.slave_phys_base = PNX4008_DUM_SLAVE_BASE; | ||
784 | dum_data.slave_virt_base = | ||
785 | (u32 *) ioremap_nocache(dum_data.slave_phys_base, sizeof(u32)); | ||
786 | |||
787 | if (dum_data.slave_virt_base == NULL) { | ||
788 | ret = -ENOMEM; | ||
789 | goto out_2; | ||
790 | } | ||
791 | |||
792 | /* initialize DUM and LCD display */ | ||
793 | ret = dum_init(pdev); | ||
794 | if (ret) | ||
795 | goto out_1; | ||
796 | |||
797 | dum_chan_init(); | ||
798 | lcd_init(); | ||
799 | |||
800 | DUM_CTRL = V_BAC_ENABLE; | ||
801 | udelay(1); | ||
802 | DUM_CTRL = V_MUX_RESET; | ||
803 | |||
804 | /* set decode address and sync clock divider */ | ||
805 | DUM_DECODE = dum_data.lcd_phys_start & DUM_DECODE_MASK; | ||
806 | DUM_CLK_DIV = PNX4008_DUM_CLK_DIV; | ||
807 | |||
808 | for (i = 0; i < MAX_DUM_CHANNELS; i++) | ||
809 | dum_data.fb_owning_channel[i] = -1; | ||
810 | |||
811 | /*setup wakeup interrupt */ | ||
812 | start_int_set_rising_edge(SE_DISP_SYNC_INT); | ||
813 | start_int_ack(SE_DISP_SYNC_INT); | ||
814 | start_int_umask(SE_DISP_SYNC_INT); | ||
815 | |||
816 | return 0; | ||
817 | |||
818 | out_1: | ||
819 | iounmap((void *)dum_data.slave_virt_base); | ||
820 | out_2: | ||
821 | dma_free_writecombine(&pdev->dev, FB_DMA_SIZE, | ||
822 | (void *)dum_data.lcd_virt_start, | ||
823 | dum_data.lcd_phys_start); | ||
824 | out_3: | ||
825 | return ret; | ||
826 | } | ||
827 | |||
828 | static int sdum_remove(struct platform_device *pdev) | ||
829 | { | ||
830 | struct clk *clk; | ||
831 | |||
832 | start_int_mask(SE_DISP_SYNC_INT); | ||
833 | |||
834 | clk = clk_get(0, "dum_ck"); | ||
835 | if (!IS_ERR(clk)) { | ||
836 | clk_set_rate(clk, 0); | ||
837 | clk_put(clk); | ||
838 | } | ||
839 | |||
840 | iounmap((void *)dum_data.slave_virt_base); | ||
841 | |||
842 | dma_free_writecombine(&pdev->dev, FB_DMA_SIZE, | ||
843 | (void *)dum_data.lcd_virt_start, | ||
844 | dum_data.lcd_phys_start); | ||
845 | |||
846 | return 0; | ||
847 | } | ||
848 | |||
849 | static struct platform_driver sdum_driver = { | ||
850 | .driver = { | ||
851 | .name = "sdum", | ||
852 | }, | ||
853 | .probe = sdum_probe, | ||
854 | .remove = sdum_remove, | ||
855 | .suspend = sdum_suspend, | ||
856 | .resume = sdum_resume, | ||
857 | }; | ||
858 | |||
859 | int __init sdum_init(void) | ||
860 | { | ||
861 | return platform_driver_register(&sdum_driver); | ||
862 | } | ||
863 | |||
864 | static void __exit sdum_exit(void) | ||
865 | { | ||
866 | platform_driver_unregister(&sdum_driver); | ||
867 | }; | ||
868 | |||
869 | module_init(sdum_init); | ||
870 | module_exit(sdum_exit); | ||
871 | |||
872 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/video/pnx4008/sdum.h b/drivers/video/pnx4008/sdum.h new file mode 100644 index 000000000000..e8c5dcdd8813 --- /dev/null +++ b/drivers/video/pnx4008/sdum.h | |||
@@ -0,0 +1,139 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2005 Philips Semiconductors | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License as published by | ||
6 | * the Free Software Foundation; either version 2, or (at your option) | ||
7 | * any later version. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License | ||
15 | * along with this program; see the file COPYING. If not, write to | ||
16 | * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, | ||
17 | * Boston, MA 02111-1307, USA, or http://www.gnu.org/licenses/gpl.html | ||
18 | */ | ||
19 | |||
20 | #define MAX_DUM_CHANNELS 64 | ||
21 | |||
22 | #define RGB_MEM_WINDOW(x) (0x10000000 + (x)*0x00100000) | ||
23 | |||
24 | #define QCIF_OFFSET(x) (((x) == 0) ? 0x00000: ((x) == 1) ? 0x30000: -1) | ||
25 | #define CIF_OFFSET(x) (((x) == 0) ? 0x00000: ((x) == 1) ? 0x60000: -1) | ||
26 | |||
27 | #define CTRL_SETDIRTY (0x00000001) | ||
28 | #define CONF_DIRTYENABLE (0x00000020) | ||
29 | #define CONF_SYNCENABLE (0x00000004) | ||
30 | |||
31 | #define DIRTY_ENABLED(conf) ((conf) & 0x0020) | ||
32 | #define SYNC_ENABLED(conf) ((conf) & 0x0004) | ||
33 | |||
34 | /* Display 1 & 2 Write Timing Configuration */ | ||
35 | #define PNX4008_DUM_WT_CFG 0x00372000 | ||
36 | |||
37 | /* Display 1 & 2 Read Timing Configuration */ | ||
38 | #define PNX4008_DUM_RT_CFG 0x00003A47 | ||
39 | |||
40 | /* DUM Transit State Timing Configuration */ | ||
41 | #define PNX4008_DUM_T_CFG 0x1D /* 29 HCLK cycles */ | ||
42 | |||
43 | /* DUM Sync count clock divider */ | ||
44 | #define PNX4008_DUM_CLK_DIV 0x02DD | ||
45 | |||
46 | /* Memory size for framebuffer, allocated through dma_alloc_writecombine(). | ||
47 | * Must be PAGE aligned | ||
48 | */ | ||
49 | #define FB_DMA_SIZE (PAGE_ALIGN(SZ_1M + PAGE_SIZE)) | ||
50 | |||
51 | #define OFFSET_RGBBUFFER (0xB0000) | ||
52 | #define OFFSET_YUVBUFFER (0x00000) | ||
53 | |||
54 | #define YUVBUFFER (lcd_video_start + OFFSET_YUVBUFFER) | ||
55 | #define RGBBUFFER (lcd_video_start + OFFSET_RGBBUFFER) | ||
56 | |||
57 | #define CMDSTRING_BASEADDR (0x00C000) /* iram */ | ||
58 | #define BYTES_PER_CMDSTRING (0x80) | ||
59 | #define NR_OF_CMDSTRINGS (64) | ||
60 | |||
61 | #define MAX_NR_PRESTRINGS (0x40) | ||
62 | #define MAX_NR_POSTSTRINGS (0x40) | ||
63 | |||
64 | /* various mask definitions */ | ||
65 | #define DUM_CLK_ENABLE 0x01 | ||
66 | #define DUM_CLK_DISABLE 0 | ||
67 | #define DUM_DECODE_MASK 0x1FFFFFFF | ||
68 | #define DUM_CHANNEL_CFG_MASK 0x01FF | ||
69 | #define DUM_CHANNEL_CFG_SYNC_MASK 0xFFFE00FF | ||
70 | #define DUM_CHANNEL_CFG_SYNC_MASK_SET 0x0CA00 | ||
71 | |||
72 | #define SDUM_RETURNVAL_BASE (0x500) | ||
73 | |||
74 | #define CONF_SYNC_OFF (0x602) | ||
75 | #define CONF_SYNC_ON (0x603) | ||
76 | |||
77 | #define CONF_DIRTYDETECTION_OFF (0x600) | ||
78 | #define CONF_DIRTYDETECTION_ON (0x601) | ||
79 | |||
80 | /* Set the corresponding bit. */ | ||
81 | #define BIT(n) (0x1U << (n)) | ||
82 | |||
83 | struct dumchannel_uf { | ||
84 | int channelnr; | ||
85 | u32 *dirty; | ||
86 | u32 *source; | ||
87 | u32 x_offset; | ||
88 | u32 y_offset; | ||
89 | u32 width; | ||
90 | u32 height; | ||
91 | }; | ||
92 | |||
93 | enum { | ||
94 | FB_TYPE_YUV, | ||
95 | FB_TYPE_RGB | ||
96 | }; | ||
97 | |||
98 | struct cmdstring { | ||
99 | int channelnr; | ||
100 | uint16_t prestringlen; | ||
101 | uint16_t poststringlen; | ||
102 | uint16_t format; | ||
103 | uint16_t reserved; | ||
104 | uint16_t startaddr_low; | ||
105 | uint16_t startaddr_high; | ||
106 | uint16_t pixdatlen_low; | ||
107 | uint16_t pixdatlen_high; | ||
108 | u32 precmd[MAX_NR_PRESTRINGS]; | ||
109 | u32 postcmd[MAX_NR_POSTSTRINGS]; | ||
110 | |||
111 | }; | ||
112 | |||
113 | struct dumchannel { | ||
114 | int channelnr; | ||
115 | int dum_ch_min; | ||
116 | int dum_ch_max; | ||
117 | int dum_ch_conf; | ||
118 | int dum_ch_stat; | ||
119 | int dum_ch_ctrl; | ||
120 | }; | ||
121 | |||
122 | int pnx4008_alloc_dum_channel(int dev_id); | ||
123 | int pnx4008_free_dum_channel(int channr, int dev_id); | ||
124 | |||
125 | int pnx4008_get_dum_channel_uf(struct dumchannel_uf *pChan_uf, int dev_id); | ||
126 | int pnx4008_put_dum_channel_uf(struct dumchannel_uf chan_uf, int dev_id); | ||
127 | |||
128 | int pnx4008_set_dum_channel_sync(int channr, int val, int dev_id); | ||
129 | int pnx4008_set_dum_channel_dirty_detect(int channr, int val, int dev_id); | ||
130 | |||
131 | int pnx4008_force_dum_update_channel(int channr, int dev_id); | ||
132 | |||
133 | int pnx4008_get_dum_channel_config(int channr, int dev_id); | ||
134 | |||
135 | int pnx4008_sdum_mmap(struct fb_info *info, struct vm_area_struct *vma, struct device *dev); | ||
136 | int pnx4008_set_dum_exit_notification(int dev_id); | ||
137 | |||
138 | int pnx4008_get_fb_addresses(int fb_type, void **virt_addr, | ||
139 | dma_addr_t * phys_addr, int *fb_length); | ||