diff options
author | Markus Lidel <Markus.Lidel@shadowconnect.com> | 2005-06-24 01:02:21 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-06-24 03:05:29 -0400 |
commit | 9e87545f06930c1d294423a8091d1077e7444a47 (patch) | |
tree | ef05fca1becfa0e1584f234ddf9b1a430b7d018e /drivers | |
parent | b2aaee33fbb354a2f08121aa1c1be55841102761 (diff) |
[PATCH] I2O: second code cleanup of sparse warnings and unneeded syncronization
Changes:
- Added header "core.h" for i2o_core.ko internal definitions
- More sparse fixes
- Changed display of TID's in sysfs attributes from XXX to 0xXXX
- Use the right functions for accessing I/O and normal memory
- Removed error handling of SCSI device errors and let the SCSI layer
take care of it
- Added new device / removed device handling to SCSI-OSM
- Make status access volatile
- Cleaned up activation of I2O controller
- Removed unnecessary wmb() and rmb() calls
- Use own struct i2o_io for I/O memory instead of struct i2o_dma
Signed-off-by: Markus Lidel <Markus.Lidel@shadowconnect.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/message/i2o/core.h | 55 | ||||
-rw-r--r-- | drivers/message/i2o/debug.c | 3 | ||||
-rw-r--r-- | drivers/message/i2o/device.c | 22 | ||||
-rw-r--r-- | drivers/message/i2o/driver.c | 24 | ||||
-rw-r--r-- | drivers/message/i2o/exec-osm.c | 27 | ||||
-rw-r--r-- | drivers/message/i2o/i2o_block.c | 4 | ||||
-rw-r--r-- | drivers/message/i2o/i2o_config.c | 8 | ||||
-rw-r--r-- | drivers/message/i2o/i2o_scsi.c | 202 | ||||
-rw-r--r-- | drivers/message/i2o/iop.c | 128 | ||||
-rw-r--r-- | drivers/message/i2o/pci.c | 21 |
10 files changed, 233 insertions, 261 deletions
diff --git a/drivers/message/i2o/core.h b/drivers/message/i2o/core.h new file mode 100644 index 000000000000..49851cccc48d --- /dev/null +++ b/drivers/message/i2o/core.h | |||
@@ -0,0 +1,55 @@ | |||
1 | /* | ||
2 | * I2O core internal declarations | ||
3 | * | ||
4 | * Copyright (C) 2005 Markus Lidel <Markus.Lidel@shadowconnect.com> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify it | ||
7 | * under the terms of the GNU General Public License as published by the | ||
8 | * Free Software Foundation; either version 2 of the License, or (at your | ||
9 | * option) any later version. | ||
10 | * | ||
11 | * Fixes/additions: | ||
12 | * Markus Lidel <Markus.Lidel@shadowconnect.com> | ||
13 | * initial version. | ||
14 | */ | ||
15 | |||
16 | /* Exec-OSM */ | ||
17 | extern struct bus_type i2o_bus_type; | ||
18 | |||
19 | extern struct i2o_driver i2o_exec_driver; | ||
20 | extern int i2o_exec_lct_get(struct i2o_controller *); | ||
21 | |||
22 | extern int __init i2o_exec_init(void); | ||
23 | extern void __exit i2o_exec_exit(void); | ||
24 | |||
25 | /* driver */ | ||
26 | extern int i2o_driver_dispatch(struct i2o_controller *, u32); | ||
27 | |||
28 | extern int __init i2o_driver_init(void); | ||
29 | extern void __exit i2o_driver_exit(void); | ||
30 | |||
31 | /* PCI */ | ||
32 | extern int __init i2o_pci_init(void); | ||
33 | extern void __exit i2o_pci_exit(void); | ||
34 | |||
35 | /* device */ | ||
36 | extern void i2o_device_remove(struct i2o_device *); | ||
37 | extern int i2o_device_parse_lct(struct i2o_controller *); | ||
38 | |||
39 | extern int i2o_device_init(void); | ||
40 | extern void i2o_device_exit(void); | ||
41 | |||
42 | /* IOP */ | ||
43 | extern struct i2o_controller *i2o_iop_alloc(void); | ||
44 | extern void i2o_iop_free(struct i2o_controller *); | ||
45 | |||
46 | extern int i2o_iop_add(struct i2o_controller *); | ||
47 | extern void i2o_iop_remove(struct i2o_controller *); | ||
48 | |||
49 | /* control registers relative to c->base */ | ||
50 | #define I2O_IRQ_STATUS 0x30 | ||
51 | #define I2O_IRQ_MASK 0x34 | ||
52 | #define I2O_IN_PORT 0x40 | ||
53 | #define I2O_OUT_PORT 0x44 | ||
54 | |||
55 | #define I2O_IRQ_OUTBOUND_POST 0x00000008 | ||
diff --git a/drivers/message/i2o/debug.c b/drivers/message/i2o/debug.c index 2a5d478fc60e..018ca887ca85 100644 --- a/drivers/message/i2o/debug.c +++ b/drivers/message/i2o/debug.c | |||
@@ -4,8 +4,6 @@ | |||
4 | #include <linux/pci.h> | 4 | #include <linux/pci.h> |
5 | #include <linux/i2o.h> | 5 | #include <linux/i2o.h> |
6 | 6 | ||
7 | extern struct i2o_driver **i2o_drivers; | ||
8 | extern unsigned int i2o_max_drivers; | ||
9 | static void i2o_report_util_cmd(u8 cmd); | 7 | static void i2o_report_util_cmd(u8 cmd); |
10 | static void i2o_report_exec_cmd(u8 cmd); | 8 | static void i2o_report_exec_cmd(u8 cmd); |
11 | static void i2o_report_fail_status(u8 req_status, u32 * msg); | 9 | static void i2o_report_fail_status(u8 req_status, u32 * msg); |
@@ -23,7 +21,6 @@ void i2o_report_status(const char *severity, const char *str, | |||
23 | u8 cmd = (msg[1] >> 24) & 0xFF; | 21 | u8 cmd = (msg[1] >> 24) & 0xFF; |
24 | u8 req_status = (msg[4] >> 24) & 0xFF; | 22 | u8 req_status = (msg[4] >> 24) & 0xFF; |
25 | u16 detailed_status = msg[4] & 0xFFFF; | 23 | u16 detailed_status = msg[4] & 0xFFFF; |
26 | //struct i2o_driver *h = i2o_drivers[msg[2] & (i2o_max_drivers-1)]; | ||
27 | 24 | ||
28 | if (cmd == I2O_CMD_UTIL_EVT_REGISTER) | 25 | if (cmd == I2O_CMD_UTIL_EVT_REGISTER) |
29 | return; // No status in this reply | 26 | return; // No status in this reply |
diff --git a/drivers/message/i2o/device.c b/drivers/message/i2o/device.c index f1b7eb63d54b..0ee342ea29bc 100644 --- a/drivers/message/i2o/device.c +++ b/drivers/message/i2o/device.c | |||
@@ -16,9 +16,7 @@ | |||
16 | #include <linux/module.h> | 16 | #include <linux/module.h> |
17 | #include <linux/i2o.h> | 17 | #include <linux/i2o.h> |
18 | #include <linux/delay.h> | 18 | #include <linux/delay.h> |
19 | 19 | #include "core.h" | |
20 | /* Exec OSM functions */ | ||
21 | extern struct bus_type i2o_bus_type; | ||
22 | 20 | ||
23 | /** | 21 | /** |
24 | * i2o_device_issue_claim - claim or release a device | 22 | * i2o_device_issue_claim - claim or release a device |
@@ -293,12 +291,12 @@ int i2o_device_parse_lct(struct i2o_controller *c) | |||
293 | } | 291 | } |
294 | 292 | ||
295 | if (lct->table_size * 4 > c->dlct.len) { | 293 | if (lct->table_size * 4 > c->dlct.len) { |
296 | memcpy_fromio(c->lct, c->dlct.virt, c->dlct.len); | 294 | memcpy(c->lct, c->dlct.virt, c->dlct.len); |
297 | up(&c->lct_lock); | 295 | up(&c->lct_lock); |
298 | return -EAGAIN; | 296 | return -EAGAIN; |
299 | } | 297 | } |
300 | 298 | ||
301 | memcpy_fromio(c->lct, c->dlct.virt, lct->table_size * 4); | 299 | memcpy(c->lct, c->dlct.virt, lct->table_size * 4); |
302 | 300 | ||
303 | lct = c->lct; | 301 | lct = c->lct; |
304 | 302 | ||
@@ -353,7 +351,7 @@ static ssize_t i2o_device_class_show_class_id(struct class_device *cd, | |||
353 | { | 351 | { |
354 | struct i2o_device *dev = to_i2o_device(cd->dev); | 352 | struct i2o_device *dev = to_i2o_device(cd->dev); |
355 | 353 | ||
356 | sprintf(buf, "%03x\n", dev->lct_data.class_id); | 354 | sprintf(buf, "0x%03x\n", dev->lct_data.class_id); |
357 | return strlen(buf) + 1; | 355 | return strlen(buf) + 1; |
358 | }; | 356 | }; |
359 | 357 | ||
@@ -368,7 +366,7 @@ static ssize_t i2o_device_class_show_tid(struct class_device *cd, char *buf) | |||
368 | { | 366 | { |
369 | struct i2o_device *dev = to_i2o_device(cd->dev); | 367 | struct i2o_device *dev = to_i2o_device(cd->dev); |
370 | 368 | ||
371 | sprintf(buf, "%03x\n", dev->lct_data.tid); | 369 | sprintf(buf, "0x%03x\n", dev->lct_data.tid); |
372 | return strlen(buf) + 1; | 370 | return strlen(buf) + 1; |
373 | }; | 371 | }; |
374 | 372 | ||
@@ -490,7 +488,7 @@ static int i2o_parm_issue(struct i2o_device *i2o_dev, int cmd, void *oplist, | |||
490 | if (rc == -ETIMEDOUT) | 488 | if (rc == -ETIMEDOUT) |
491 | return rc; | 489 | return rc; |
492 | 490 | ||
493 | memcpy_fromio(reslist, res.virt, res.len); | 491 | memcpy(reslist, res.virt, res.len); |
494 | i2o_dma_free(dev, &res); | 492 | i2o_dma_free(dev, &res); |
495 | 493 | ||
496 | /* Query failed */ | 494 | /* Query failed */ |
@@ -532,17 +530,23 @@ int i2o_parm_field_get(struct i2o_device *i2o_dev, int group, int field, | |||
532 | void *buf, int buflen) | 530 | void *buf, int buflen) |
533 | { | 531 | { |
534 | u16 opblk[] = { 1, 0, I2O_PARAMS_FIELD_GET, group, 1, field }; | 532 | u16 opblk[] = { 1, 0, I2O_PARAMS_FIELD_GET, group, 1, field }; |
535 | u8 resblk[8 + buflen]; /* 8 bytes for header */ | 533 | u8 *resblk; /* 8 bytes for header */ |
536 | int size; | 534 | int size; |
537 | 535 | ||
538 | if (field == -1) /* whole group */ | 536 | if (field == -1) /* whole group */ |
539 | opblk[4] = -1; | 537 | opblk[4] = -1; |
540 | 538 | ||
539 | resblk = kmalloc(buflen + 8, GFP_KERNEL | GFP_ATOMIC); | ||
540 | if (!resblk) | ||
541 | return -ENOMEM; | ||
542 | |||
541 | size = i2o_parm_issue(i2o_dev, I2O_CMD_UTIL_PARAMS_GET, opblk, | 543 | size = i2o_parm_issue(i2o_dev, I2O_CMD_UTIL_PARAMS_GET, opblk, |
542 | sizeof(opblk), resblk, buflen + 8); | 544 | sizeof(opblk), resblk, buflen + 8); |
543 | 545 | ||
544 | memcpy(buf, resblk + 8, buflen); /* cut off header */ | 546 | memcpy(buf, resblk + 8, buflen); /* cut off header */ |
545 | 547 | ||
548 | kfree(resblk); | ||
549 | |||
546 | if (size > buflen) | 550 | if (size > buflen) |
547 | return buflen; | 551 | return buflen; |
548 | 552 | ||
diff --git a/drivers/message/i2o/driver.c b/drivers/message/i2o/driver.c index 393be8e2914c..c32f9dbc5744 100644 --- a/drivers/message/i2o/driver.c +++ b/drivers/message/i2o/driver.c | |||
@@ -17,11 +17,12 @@ | |||
17 | #include <linux/module.h> | 17 | #include <linux/module.h> |
18 | #include <linux/rwsem.h> | 18 | #include <linux/rwsem.h> |
19 | #include <linux/i2o.h> | 19 | #include <linux/i2o.h> |
20 | #include "core.h" | ||
20 | 21 | ||
21 | #define OSM_NAME "i2o" | 22 | #define OSM_NAME "i2o" |
22 | 23 | ||
23 | /* max_drivers - Maximum I2O drivers (OSMs) which could be registered */ | 24 | /* max_drivers - Maximum I2O drivers (OSMs) which could be registered */ |
24 | unsigned int i2o_max_drivers = I2O_MAX_DRIVERS; | 25 | static unsigned int i2o_max_drivers = I2O_MAX_DRIVERS; |
25 | module_param_named(max_drivers, i2o_max_drivers, uint, 0); | 26 | module_param_named(max_drivers, i2o_max_drivers, uint, 0); |
26 | MODULE_PARM_DESC(max_drivers, "maximum number of OSM's to support"); | 27 | MODULE_PARM_DESC(max_drivers, "maximum number of OSM's to support"); |
27 | 28 | ||
@@ -179,15 +180,10 @@ void i2o_driver_unregister(struct i2o_driver *drv) | |||
179 | int i2o_driver_dispatch(struct i2o_controller *c, u32 m) | 180 | int i2o_driver_dispatch(struct i2o_controller *c, u32 m) |
180 | { | 181 | { |
181 | struct i2o_driver *drv; | 182 | struct i2o_driver *drv; |
182 | struct i2o_message __iomem *msg = i2o_msg_out_to_virt(c, m); | 183 | struct i2o_message *msg = i2o_msg_out_to_virt(c, m); |
183 | u32 context; | 184 | u32 context = le32_to_cpu(msg->u.s.icntxt); |
184 | unsigned long flags; | 185 | unsigned long flags; |
185 | 186 | ||
186 | if(unlikely(!msg)) | ||
187 | return -EIO; | ||
188 | |||
189 | context = readl(&msg->u.s.icntxt); | ||
190 | |||
191 | if (unlikely(context >= i2o_max_drivers)) { | 187 | if (unlikely(context >= i2o_max_drivers)) { |
192 | osm_warn("%s: Spurious reply to unknown driver %d\n", c->name, | 188 | osm_warn("%s: Spurious reply to unknown driver %d\n", c->name, |
193 | context); | 189 | context); |
@@ -204,11 +200,11 @@ int i2o_driver_dispatch(struct i2o_controller *c, u32 m) | |||
204 | return -EIO; | 200 | return -EIO; |
205 | } | 201 | } |
206 | 202 | ||
207 | if ((readl(&msg->u.head[1]) >> 24) == I2O_CMD_UTIL_EVT_REGISTER) { | 203 | if ((le32_to_cpu(msg->u.head[1]) >> 24) == I2O_CMD_UTIL_EVT_REGISTER) { |
208 | struct i2o_device *dev, *tmp; | 204 | struct i2o_device *dev, *tmp; |
209 | struct i2o_event *evt; | 205 | struct i2o_event *evt; |
210 | u16 size; | 206 | u16 size; |
211 | u16 tid = readl(&msg->u.head[1]) & 0xfff; | 207 | u16 tid = le32_to_cpu(msg->u.head[1]) & 0xfff; |
212 | 208 | ||
213 | osm_debug("event received from device %d\n", tid); | 209 | osm_debug("event received from device %d\n", tid); |
214 | 210 | ||
@@ -216,16 +212,16 @@ int i2o_driver_dispatch(struct i2o_controller *c, u32 m) | |||
216 | return -EIO; | 212 | return -EIO; |
217 | 213 | ||
218 | /* cut of header from message size (in 32-bit words) */ | 214 | /* cut of header from message size (in 32-bit words) */ |
219 | size = (readl(&msg->u.head[0]) >> 16) - 5; | 215 | size = (le32_to_cpu(msg->u.head[0]) >> 16) - 5; |
220 | 216 | ||
221 | evt = kmalloc(size * 4 + sizeof(*evt), GFP_ATOMIC | __GFP_ZERO); | 217 | evt = kmalloc(size * 4 + sizeof(*evt), GFP_ATOMIC | __GFP_ZERO); |
222 | if (!evt) | 218 | if (!evt) |
223 | return -ENOMEM; | 219 | return -ENOMEM; |
224 | 220 | ||
225 | evt->size = size; | 221 | evt->size = size; |
226 | evt->tcntxt = readl(&msg->u.s.tcntxt); | 222 | evt->tcntxt = le32_to_cpu(msg->u.s.tcntxt); |
227 | evt->event_indicator = readl(&msg->body[0]); | 223 | evt->event_indicator = le32_to_cpu(msg->body[0]); |
228 | memcpy_fromio(&evt->tcntxt, &msg->u.s.tcntxt, size * 4); | 224 | memcpy(&evt->tcntxt, &msg->u.s.tcntxt, size * 4); |
229 | 225 | ||
230 | list_for_each_entry_safe(dev, tmp, &c->devices, list) | 226 | list_for_each_entry_safe(dev, tmp, &c->devices, list) |
231 | if (dev->lct_data.tid == tid) { | 227 | if (dev->lct_data.tid == tid) { |
diff --git a/drivers/message/i2o/exec-osm.c b/drivers/message/i2o/exec-osm.c index 0160221c802a..ffe0cecfa060 100644 --- a/drivers/message/i2o/exec-osm.c +++ b/drivers/message/i2o/exec-osm.c | |||
@@ -30,6 +30,7 @@ | |||
30 | #include <linux/module.h> | 30 | #include <linux/module.h> |
31 | #include <linux/i2o.h> | 31 | #include <linux/i2o.h> |
32 | #include <linux/delay.h> | 32 | #include <linux/delay.h> |
33 | #include "core.h" | ||
33 | 34 | ||
34 | #define OSM_NAME "exec-osm" | 35 | #define OSM_NAME "exec-osm" |
35 | 36 | ||
@@ -37,9 +38,6 @@ struct i2o_driver i2o_exec_driver; | |||
37 | 38 | ||
38 | static int i2o_exec_lct_notify(struct i2o_controller *c, u32 change_ind); | 39 | static int i2o_exec_lct_notify(struct i2o_controller *c, u32 change_ind); |
39 | 40 | ||
40 | /* Module internal functions from other sources */ | ||
41 | extern int i2o_device_parse_lct(struct i2o_controller *); | ||
42 | |||
43 | /* global wait list for POST WAIT */ | 41 | /* global wait list for POST WAIT */ |
44 | static LIST_HEAD(i2o_exec_wait_list); | 42 | static LIST_HEAD(i2o_exec_wait_list); |
45 | 43 | ||
@@ -50,7 +48,7 @@ struct i2o_exec_wait { | |||
50 | u32 tcntxt; /* transaction context from reply */ | 48 | u32 tcntxt; /* transaction context from reply */ |
51 | int complete; /* 1 if reply received otherwise 0 */ | 49 | int complete; /* 1 if reply received otherwise 0 */ |
52 | u32 m; /* message id */ | 50 | u32 m; /* message id */ |
53 | struct i2o_message __iomem *msg; /* pointer to the reply message */ | 51 | struct i2o_message *msg; /* pointer to the reply message */ |
54 | struct list_head list; /* node in global wait list */ | 52 | struct list_head list; /* node in global wait list */ |
55 | }; | 53 | }; |
56 | 54 | ||
@@ -162,7 +160,7 @@ int i2o_msg_post_wait_mem(struct i2o_controller *c, u32 m, unsigned long | |||
162 | barrier(); | 160 | barrier(); |
163 | 161 | ||
164 | if (wait->complete) { | 162 | if (wait->complete) { |
165 | rc = readl(&wait->msg->body[0]) >> 24; | 163 | rc = le32_to_cpu(wait->msg->body[0]) >> 24; |
166 | i2o_flush_reply(c, wait->m); | 164 | i2o_flush_reply(c, wait->m); |
167 | i2o_exec_wait_free(wait); | 165 | i2o_exec_wait_free(wait); |
168 | } else { | 166 | } else { |
@@ -202,8 +200,7 @@ int i2o_msg_post_wait_mem(struct i2o_controller *c, u32 m, unsigned long | |||
202 | * message must also be given back to the controller. | 200 | * message must also be given back to the controller. |
203 | */ | 201 | */ |
204 | static int i2o_msg_post_wait_complete(struct i2o_controller *c, u32 m, | 202 | static int i2o_msg_post_wait_complete(struct i2o_controller *c, u32 m, |
205 | struct i2o_message __iomem *msg, | 203 | struct i2o_message *msg, u32 context) |
206 | u32 context) | ||
207 | { | 204 | { |
208 | struct i2o_exec_wait *wait, *tmp; | 205 | struct i2o_exec_wait *wait, *tmp; |
209 | unsigned long flags; | 206 | unsigned long flags; |
@@ -378,11 +375,11 @@ static void i2o_exec_lct_modified(struct i2o_controller *c) | |||
378 | * code on failure and if the reply should be flushed. | 375 | * code on failure and if the reply should be flushed. |
379 | */ | 376 | */ |
380 | static int i2o_exec_reply(struct i2o_controller *c, u32 m, | 377 | static int i2o_exec_reply(struct i2o_controller *c, u32 m, |
381 | struct i2o_message __iomem *msg) | 378 | struct i2o_message *msg) |
382 | { | 379 | { |
383 | u32 context; | 380 | u32 context; |
384 | 381 | ||
385 | if (readl(&msg->u.head[0]) & MSG_FAIL) { | 382 | if (le32_to_cpu(msg->u.head[0]) & MSG_FAIL) { |
386 | /* | 383 | /* |
387 | * If Fail bit is set we must take the transaction context of | 384 | * If Fail bit is set we must take the transaction context of |
388 | * the preserved message to find the right request again. | 385 | * the preserved message to find the right request again. |
@@ -390,7 +387,7 @@ static int i2o_exec_reply(struct i2o_controller *c, u32 m, | |||
390 | struct i2o_message __iomem *pmsg; | 387 | struct i2o_message __iomem *pmsg; |
391 | u32 pm; | 388 | u32 pm; |
392 | 389 | ||
393 | pm = readl(&msg->body[3]); | 390 | pm = le32_to_cpu(msg->body[3]); |
394 | 391 | ||
395 | pmsg = i2o_msg_in_to_virt(c, pm); | 392 | pmsg = i2o_msg_in_to_virt(c, pm); |
396 | 393 | ||
@@ -401,12 +398,12 @@ static int i2o_exec_reply(struct i2o_controller *c, u32 m, | |||
401 | /* Release the preserved msg */ | 398 | /* Release the preserved msg */ |
402 | i2o_msg_nop(c, pm); | 399 | i2o_msg_nop(c, pm); |
403 | } else | 400 | } else |
404 | context = readl(&msg->u.s.tcntxt); | 401 | context = le32_to_cpu(msg->u.s.tcntxt); |
405 | 402 | ||
406 | if (context & 0x80000000) | 403 | if (context & 0x80000000) |
407 | return i2o_msg_post_wait_complete(c, m, msg, context); | 404 | return i2o_msg_post_wait_complete(c, m, msg, context); |
408 | 405 | ||
409 | if ((readl(&msg->u.head[1]) >> 24) == I2O_CMD_LCT_NOTIFY) { | 406 | if ((le32_to_cpu(msg->u.head[1]) >> 24) == I2O_CMD_LCT_NOTIFY) { |
410 | struct work_struct *work; | 407 | struct work_struct *work; |
411 | 408 | ||
412 | pr_debug("%s: LCT notify received\n", c->name); | 409 | pr_debug("%s: LCT notify received\n", c->name); |
@@ -442,9 +439,9 @@ static int i2o_exec_reply(struct i2o_controller *c, u32 m, | |||
442 | */ | 439 | */ |
443 | static void i2o_exec_event(struct i2o_event *evt) | 440 | static void i2o_exec_event(struct i2o_event *evt) |
444 | { | 441 | { |
445 | if(likely(evt->i2o_dev)) | 442 | if (likely(evt->i2o_dev)) |
446 | osm_info("Event received from device: %d\n", | 443 | osm_debug("Event received from device: %d\n", |
447 | evt->i2o_dev->lct_data.tid); | 444 | evt->i2o_dev->lct_data.tid); |
448 | kfree(evt); | 445 | kfree(evt); |
449 | }; | 446 | }; |
450 | 447 | ||
diff --git a/drivers/message/i2o/i2o_block.c b/drivers/message/i2o/i2o_block.c index 1dd2b9dad50e..28b3918dbc16 100644 --- a/drivers/message/i2o/i2o_block.c +++ b/drivers/message/i2o/i2o_block.c | |||
@@ -62,7 +62,7 @@ | |||
62 | #include "i2o_block.h" | 62 | #include "i2o_block.h" |
63 | 63 | ||
64 | #define OSM_NAME "block-osm" | 64 | #define OSM_NAME "block-osm" |
65 | #define OSM_VERSION "$Rev$" | 65 | #define OSM_VERSION "1.287" |
66 | #define OSM_DESCRIPTION "I2O Block Device OSM" | 66 | #define OSM_DESCRIPTION "I2O Block Device OSM" |
67 | 67 | ||
68 | static struct i2o_driver i2o_block_driver; | 68 | static struct i2o_driver i2o_block_driver; |
@@ -537,7 +537,7 @@ static int i2o_block_reply(struct i2o_controller *c, u32 m, | |||
537 | 537 | ||
538 | static void i2o_block_event(struct i2o_event *evt) | 538 | static void i2o_block_event(struct i2o_event *evt) |
539 | { | 539 | { |
540 | osm_info("event received\n"); | 540 | osm_debug("event received\n"); |
541 | kfree(evt); | 541 | kfree(evt); |
542 | }; | 542 | }; |
543 | 543 | ||
diff --git a/drivers/message/i2o/i2o_config.c b/drivers/message/i2o/i2o_config.c index 7636833b4623..8160a1f6c73a 100644 --- a/drivers/message/i2o/i2o_config.c +++ b/drivers/message/i2o/i2o_config.c | |||
@@ -36,6 +36,8 @@ | |||
36 | 36 | ||
37 | #include <asm/uaccess.h> | 37 | #include <asm/uaccess.h> |
38 | 38 | ||
39 | #define SG_TABLESIZE 30 | ||
40 | |||
39 | extern int i2o_parm_issue(struct i2o_device *, int, void *, int, void *, int); | 41 | extern int i2o_parm_issue(struct i2o_device *, int, void *, int, void *, int); |
40 | 42 | ||
41 | static int i2o_cfg_ioctl(struct inode *inode, struct file *fp, unsigned int cmd, | 43 | static int i2o_cfg_ioctl(struct inode *inode, struct file *fp, unsigned int cmd, |
@@ -663,7 +665,7 @@ static int i2o_cfg_passthru32(struct file *file, unsigned cmnd, unsigned long ar | |||
663 | goto sg_list_cleanup; | 665 | goto sg_list_cleanup; |
664 | 666 | ||
665 | if (sg_offset) { | 667 | if (sg_offset) { |
666 | u32 msg[MSG_FRAME_SIZE]; | 668 | u32 msg[I2O_OUTBOUND_MSG_FRAME_SIZE]; |
667 | /* Copy back the Scatter Gather buffers back to user space */ | 669 | /* Copy back the Scatter Gather buffers back to user space */ |
668 | u32 j; | 670 | u32 j; |
669 | // TODO 64bit fix | 671 | // TODO 64bit fix |
@@ -671,7 +673,7 @@ static int i2o_cfg_passthru32(struct file *file, unsigned cmnd, unsigned long ar | |||
671 | int sg_size; | 673 | int sg_size; |
672 | 674 | ||
673 | // re-acquire the original message to handle correctly the sg copy operation | 675 | // re-acquire the original message to handle correctly the sg copy operation |
674 | memset(&msg, 0, MSG_FRAME_SIZE * 4); | 676 | memset(&msg, 0, I2O_OUTBOUND_MSG_FRAME_SIZE * 4); |
675 | // get user msg size in u32s | 677 | // get user msg size in u32s |
676 | if (get_user(size, &user_msg[0])) { | 678 | if (get_user(size, &user_msg[0])) { |
677 | rcode = -EFAULT; | 679 | rcode = -EFAULT; |
@@ -902,7 +904,7 @@ static int i2o_cfg_passthru(unsigned long arg) | |||
902 | int sg_size; | 904 | int sg_size; |
903 | 905 | ||
904 | // re-acquire the original message to handle correctly the sg copy operation | 906 | // re-acquire the original message to handle correctly the sg copy operation |
905 | memset(&msg, 0, MSG_FRAME_SIZE * 4); | 907 | memset(&msg, 0, I2O_OUTBOUND_MSG_FRAME_SIZE * 4); |
906 | // get user msg size in u32s | 908 | // get user msg size in u32s |
907 | if (get_user(size, &user_msg[0])) { | 909 | if (get_user(size, &user_msg[0])) { |
908 | rcode = -EFAULT; | 910 | rcode = -EFAULT; |
diff --git a/drivers/message/i2o/i2o_scsi.c b/drivers/message/i2o/i2o_scsi.c index fef53b509a61..9f1744c3933b 100644 --- a/drivers/message/i2o/i2o_scsi.c +++ b/drivers/message/i2o/i2o_scsi.c | |||
@@ -40,7 +40,6 @@ | |||
40 | * Fix the resource management problems. | 40 | * Fix the resource management problems. |
41 | */ | 41 | */ |
42 | 42 | ||
43 | #define DEBUG 1 | ||
44 | #include <linux/module.h> | 43 | #include <linux/module.h> |
45 | #include <linux/kernel.h> | 44 | #include <linux/kernel.h> |
46 | #include <linux/types.h> | 45 | #include <linux/types.h> |
@@ -338,162 +337,89 @@ static int i2o_scsi_reply(struct i2o_controller *c, u32 m, | |||
338 | struct i2o_message *msg) | 337 | struct i2o_message *msg) |
339 | { | 338 | { |
340 | struct scsi_cmnd *cmd; | 339 | struct scsi_cmnd *cmd; |
340 | u32 error; | ||
341 | struct device *dev; | 341 | struct device *dev; |
342 | u8 as, ds, st; | ||
343 | 342 | ||
344 | cmd = i2o_cntxt_list_get(c, le32_to_cpu(msg->u.s.tcntxt)); | 343 | cmd = i2o_cntxt_list_get(c, le32_to_cpu(msg->u.s.tcntxt)); |
345 | 344 | if (unlikely(!cmd)) { | |
346 | if (msg->u.head[0] & (1 << 13)) { | 345 | osm_err("NULL reply received!\n"); |
347 | struct i2o_message __iomem *pmsg; /* preserved message */ | 346 | return -1; |
348 | u32 pm; | ||
349 | int err = DID_ERROR; | ||
350 | |||
351 | pm = le32_to_cpu(msg->body[3]); | ||
352 | |||
353 | pmsg = i2o_msg_in_to_virt(c, pm); | ||
354 | |||
355 | osm_err("IOP fail.\n"); | ||
356 | osm_err("From %d To %d Cmd %d.\n", | ||
357 | (msg->u.head[1] >> 12) & 0xFFF, | ||
358 | msg->u.head[1] & 0xFFF, msg->u.head[1] >> 24); | ||
359 | osm_err("Failure Code %d.\n", msg->body[0] >> 24); | ||
360 | if (msg->body[0] & (1 << 16)) | ||
361 | osm_err("Format error.\n"); | ||
362 | if (msg->body[0] & (1 << 17)) | ||
363 | osm_err("Path error.\n"); | ||
364 | if (msg->body[0] & (1 << 18)) | ||
365 | osm_err("Path State.\n"); | ||
366 | if (msg->body[0] & (1 << 18)) | ||
367 | { | ||
368 | osm_err("Congestion.\n"); | ||
369 | err = DID_BUS_BUSY; | ||
370 | } | ||
371 | |||
372 | osm_debug("Failing message is %p.\n", pmsg); | ||
373 | |||
374 | cmd = i2o_cntxt_list_get(c, readl(&pmsg->u.s.tcntxt)); | ||
375 | if (!cmd) | ||
376 | return 1; | ||
377 | |||
378 | cmd->result = err << 16; | ||
379 | cmd->scsi_done(cmd); | ||
380 | |||
381 | /* Now flush the message by making it a NOP */ | ||
382 | i2o_msg_nop(c, pm); | ||
383 | |||
384 | return 1; | ||
385 | } | 347 | } |
386 | 348 | ||
387 | /* | 349 | /* |
388 | * Low byte is device status, next is adapter status, | 350 | * Low byte is device status, next is adapter status, |
389 | * (then one byte reserved), then request status. | 351 | * (then one byte reserved), then request status. |
390 | */ | 352 | */ |
391 | ds = (u8) le32_to_cpu(msg->body[0]); | 353 | error = le32_to_cpu(msg->body[0]); |
392 | as = (u8) (le32_to_cpu(msg->body[0]) >> 8); | ||
393 | st = (u8) (le32_to_cpu(msg->body[0]) >> 24); | ||
394 | 354 | ||
355 | osm_debug("Completed %ld\n", cmd->serial_number); | ||
356 | |||
357 | cmd->result = error & 0xff; | ||
395 | /* | 358 | /* |
396 | * Is this a control request coming back - eg an abort ? | 359 | * if DeviceStatus is not SCSI_SUCCESS copy over the sense data and let |
360 | * the SCSI layer handle the error | ||
397 | */ | 361 | */ |
362 | if (cmd->result) | ||
363 | memcpy(cmd->sense_buffer, &msg->body[3], | ||
364 | min(sizeof(cmd->sense_buffer), (size_t) 40)); | ||
398 | 365 | ||
399 | if (!cmd) { | 366 | /* only output error code if AdapterStatus is not HBA_SUCCESS */ |
400 | if (st) | 367 | if ((error >> 8) & 0xff) |
401 | osm_warn("SCSI abort: %08X", le32_to_cpu(msg->body[0])); | 368 | osm_err("SCSI error %08x\n", error); |
402 | osm_info("SCSI abort completed.\n"); | ||
403 | return -EFAULT; | ||
404 | } | ||
405 | 369 | ||
406 | osm_debug("Completed %ld\n", cmd->serial_number); | 370 | dev = &c->pdev->dev; |
371 | if (cmd->use_sg) | ||
372 | dma_unmap_sg(dev, cmd->request_buffer, cmd->use_sg, | ||
373 | cmd->sc_data_direction); | ||
374 | else if (cmd->SCp.dma_handle) | ||
375 | dma_unmap_single(dev, cmd->SCp.dma_handle, cmd->request_bufflen, | ||
376 | cmd->sc_data_direction); | ||
407 | 377 | ||
408 | if (st) { | 378 | cmd->scsi_done(cmd); |
409 | u32 count, error; | ||
410 | /* An error has occurred */ | ||
411 | |||
412 | switch (st) { | ||
413 | case 0x06: | ||
414 | count = le32_to_cpu(msg->body[1]); | ||
415 | if (count < cmd->underflow) { | ||
416 | int i; | ||
417 | |||
418 | osm_err("SCSI underflow 0x%08X 0x%08X\n", count, | ||
419 | cmd->underflow); | ||
420 | osm_debug("Cmd: "); | ||
421 | for (i = 0; i < 15; i++) | ||
422 | pr_debug("%02X ", cmd->cmnd[i]); | ||
423 | pr_debug(".\n"); | ||
424 | cmd->result = (DID_ERROR << 16); | ||
425 | } | ||
426 | break; | ||
427 | 379 | ||
428 | default: | 380 | return 1; |
429 | error = le32_to_cpu(msg->body[0]); | 381 | }; |
430 | |||
431 | osm_err("SCSI error %08x\n", error); | ||
432 | |||
433 | if ((error & 0xff) == 0x02 /*CHECK_CONDITION */ ) { | ||
434 | int i; | ||
435 | u32 len = sizeof(cmd->sense_buffer); | ||
436 | len = (len > 40) ? 40 : len; | ||
437 | // Copy over the sense data | ||
438 | memcpy(cmd->sense_buffer, (void *)&msg->body[3], | ||
439 | len); | ||
440 | for (i = 0; i <= len; i++) | ||
441 | osm_info("%02x\n", | ||
442 | cmd->sense_buffer[i]); | ||
443 | if (cmd->sense_buffer[0] == 0x70 | ||
444 | && cmd->sense_buffer[2] == DATA_PROTECT) { | ||
445 | /* This is to handle an array failed */ | ||
446 | cmd->result = (DID_TIME_OUT << 16); | ||
447 | printk(KERN_WARNING "%s: SCSI Data " | ||
448 | "Protect-Device (%d,%d,%d) " | ||
449 | "hba_status=0x%x, dev_status=" | ||
450 | "0x%x, cmd=0x%x\n", c->name, | ||
451 | (u32) cmd->device->channel, | ||
452 | (u32) cmd->device->id, | ||
453 | (u32) cmd->device->lun, | ||
454 | (error >> 8) & 0xff, | ||
455 | error & 0xff, cmd->cmnd[0]); | ||
456 | } else | ||
457 | cmd->result = (DID_ERROR << 16); | ||
458 | |||
459 | break; | ||
460 | } | ||
461 | |||
462 | switch (as) { | ||
463 | case 0x0E: | ||
464 | /* SCSI Reset */ | ||
465 | cmd->result = DID_RESET << 16; | ||
466 | break; | ||
467 | |||
468 | case 0x0F: | ||
469 | cmd->result = DID_PARITY << 16; | ||
470 | break; | ||
471 | |||
472 | default: | ||
473 | cmd->result = DID_ERROR << 16; | ||
474 | break; | ||
475 | } | ||
476 | 382 | ||
477 | break; | 383 | /** |
478 | } | 384 | * i2o_scsi_notify_device_add - Retrieve notifications of added devices |
385 | * @i2o_dev: the I2O device which was added | ||
386 | * | ||
387 | * If a I2O device is added we catch the notification, because I2O classes | ||
388 | * other then SCSI peripheral will not be received through | ||
389 | * i2o_scsi_probe(). | ||
390 | */ | ||
391 | static void i2o_scsi_notify_device_add(struct i2o_device *i2o_dev) | ||
392 | { | ||
393 | switch (i2o_dev->lct_data.class_id) { | ||
394 | case I2O_CLASS_EXECUTIVE: | ||
395 | case I2O_CLASS_RANDOM_BLOCK_STORAGE: | ||
396 | i2o_scsi_probe(&i2o_dev->device); | ||
397 | break; | ||
479 | 398 | ||
480 | cmd->scsi_done(cmd); | 399 | default: |
481 | return 1; | 400 | break; |
482 | } | 401 | } |
402 | }; | ||
483 | 403 | ||
484 | cmd->result = DID_OK << 16 | ds; | 404 | /** |
485 | 405 | * i2o_scsi_notify_device_remove - Retrieve notifications of removed | |
486 | dev = &c->pdev->dev; | 406 | * devices |
487 | if (cmd->use_sg) | 407 | * @i2o_dev: the I2O device which was removed |
488 | dma_unmap_sg(dev, (struct scatterlist *)cmd->buffer, | 408 | * |
489 | cmd->use_sg, cmd->sc_data_direction); | 409 | * If a I2O device is removed, we catch the notification to remove the |
490 | else if (cmd->request_bufflen) | 410 | * corresponding SCSI device. |
491 | dma_unmap_single(dev, (dma_addr_t) ((long)cmd->SCp.ptr), | 411 | */ |
492 | cmd->request_bufflen, cmd->sc_data_direction); | 412 | static void i2o_scsi_notify_device_remove(struct i2o_device *i2o_dev) |
493 | 413 | { | |
494 | cmd->scsi_done(cmd); | 414 | switch (i2o_dev->lct_data.class_id) { |
415 | case I2O_CLASS_EXECUTIVE: | ||
416 | case I2O_CLASS_RANDOM_BLOCK_STORAGE: | ||
417 | i2o_scsi_remove(&i2o_dev->device); | ||
418 | break; | ||
495 | 419 | ||
496 | return 1; | 420 | default: |
421 | break; | ||
422 | } | ||
497 | }; | 423 | }; |
498 | 424 | ||
499 | /** | 425 | /** |
@@ -554,6 +480,8 @@ static struct i2o_driver i2o_scsi_driver = { | |||
554 | .name = OSM_NAME, | 480 | .name = OSM_NAME, |
555 | .reply = i2o_scsi_reply, | 481 | .reply = i2o_scsi_reply, |
556 | .classes = i2o_scsi_class_id, | 482 | .classes = i2o_scsi_class_id, |
483 | .notify_device_add = i2o_scsi_notify_device_add, | ||
484 | .notify_device_remove = i2o_scsi_notify_device_remove, | ||
557 | .notify_controller_add = i2o_scsi_notify_controller_add, | 485 | .notify_controller_add = i2o_scsi_notify_controller_add, |
558 | .notify_controller_remove = i2o_scsi_notify_controller_remove, | 486 | .notify_controller_remove = i2o_scsi_notify_controller_remove, |
559 | .driver = { | 487 | .driver = { |
@@ -712,7 +640,7 @@ static int i2o_scsi_queuecommand(struct scsi_cmnd *SCpnt, | |||
712 | */ | 640 | */ |
713 | 641 | ||
714 | /* Attach tags to the devices */ | 642 | /* Attach tags to the devices */ |
715 | /* | 643 | /* FIXME: implement |
716 | if(SCpnt->device->tagged_supported) { | 644 | if(SCpnt->device->tagged_supported) { |
717 | if(SCpnt->tag == HEAD_OF_QUEUE_TAG) | 645 | if(SCpnt->tag == HEAD_OF_QUEUE_TAG) |
718 | scsi_flags |= 0x01000000; | 646 | scsi_flags |= 0x01000000; |
diff --git a/drivers/message/i2o/iop.c b/drivers/message/i2o/iop.c index 40312053b38d..c32022bc2a21 100644 --- a/drivers/message/i2o/iop.c +++ b/drivers/message/i2o/iop.c | |||
@@ -28,8 +28,10 @@ | |||
28 | #include <linux/module.h> | 28 | #include <linux/module.h> |
29 | #include <linux/i2o.h> | 29 | #include <linux/i2o.h> |
30 | #include <linux/delay.h> | 30 | #include <linux/delay.h> |
31 | #include "core.h" | ||
31 | 32 | ||
32 | #define OSM_VERSION "$Rev$" | 33 | #define OSM_NAME "i2o" |
34 | #define OSM_VERSION "1.288" | ||
33 | #define OSM_DESCRIPTION "I2O subsystem" | 35 | #define OSM_DESCRIPTION "I2O subsystem" |
34 | 36 | ||
35 | /* global I2O controller list */ | 37 | /* global I2O controller list */ |
@@ -43,20 +45,6 @@ static struct i2o_dma i2o_systab; | |||
43 | 45 | ||
44 | static int i2o_hrt_get(struct i2o_controller *c); | 46 | static int i2o_hrt_get(struct i2o_controller *c); |
45 | 47 | ||
46 | /* Module internal functions from other sources */ | ||
47 | extern struct i2o_driver i2o_exec_driver; | ||
48 | extern int i2o_exec_lct_get(struct i2o_controller *); | ||
49 | extern void i2o_device_remove(struct i2o_device *); | ||
50 | |||
51 | extern int __init i2o_driver_init(void); | ||
52 | extern void __exit i2o_driver_exit(void); | ||
53 | extern int __init i2o_exec_init(void); | ||
54 | extern void __exit i2o_exec_exit(void); | ||
55 | extern int __init i2o_pci_init(void); | ||
56 | extern void __exit i2o_pci_exit(void); | ||
57 | extern int i2o_device_init(void); | ||
58 | extern void i2o_device_exit(void); | ||
59 | |||
60 | /** | 48 | /** |
61 | * i2o_msg_nop - Returns a message which is not used | 49 | * i2o_msg_nop - Returns a message which is not used |
62 | * @c: I2O controller from which the message was created | 50 | * @c: I2O controller from which the message was created |
@@ -92,16 +80,16 @@ void i2o_msg_nop(struct i2o_controller *c, u32 m) | |||
92 | * address from the read port (see the i2o spec). If no message is | 80 | * address from the read port (see the i2o spec). If no message is |
93 | * available returns I2O_QUEUE_EMPTY and msg is leaved untouched. | 81 | * available returns I2O_QUEUE_EMPTY and msg is leaved untouched. |
94 | */ | 82 | */ |
95 | u32 i2o_msg_get_wait(struct i2o_controller *c, struct i2o_message __iomem **msg, | 83 | u32 i2o_msg_get_wait(struct i2o_controller *c, |
96 | int wait) | 84 | struct i2o_message __iomem ** msg, int wait) |
97 | { | 85 | { |
98 | unsigned long timeout = jiffies + wait * HZ; | 86 | unsigned long timeout = jiffies + wait * HZ; |
99 | u32 m; | 87 | u32 m; |
100 | 88 | ||
101 | while ((m = i2o_msg_get(c, msg)) == I2O_QUEUE_EMPTY) { | 89 | while ((m = i2o_msg_get(c, msg)) == I2O_QUEUE_EMPTY) { |
102 | if (time_after(jiffies, timeout)) { | 90 | if (time_after(jiffies, timeout)) { |
103 | pr_debug("%s: Timeout waiting for message frame.\n", | 91 | osm_debug("%s: Timeout waiting for message frame.\n", |
104 | c->name); | 92 | c->name); |
105 | return I2O_QUEUE_EMPTY; | 93 | return I2O_QUEUE_EMPTY; |
106 | } | 94 | } |
107 | set_current_state(TASK_UNINTERRUPTIBLE); | 95 | set_current_state(TASK_UNINTERRUPTIBLE); |
@@ -466,7 +454,7 @@ static int i2o_iop_clear(struct i2o_controller *c) | |||
466 | */ | 454 | */ |
467 | static int i2o_iop_init_outbound_queue(struct i2o_controller *c) | 455 | static int i2o_iop_init_outbound_queue(struct i2o_controller *c) |
468 | { | 456 | { |
469 | u8 *status = c->status.virt; | 457 | volatile u8 *status = c->status.virt; |
470 | u32 m; | 458 | u32 m; |
471 | struct i2o_message __iomem *msg; | 459 | struct i2o_message __iomem *msg; |
472 | ulong timeout; | 460 | ulong timeout; |
@@ -474,21 +462,20 @@ static int i2o_iop_init_outbound_queue(struct i2o_controller *c) | |||
474 | 462 | ||
475 | osm_debug("%s: Initializing Outbound Queue...\n", c->name); | 463 | osm_debug("%s: Initializing Outbound Queue...\n", c->name); |
476 | 464 | ||
477 | memset(status, 0, 4); | 465 | memset(c->status.virt, 0, 4); |
478 | 466 | ||
479 | m = i2o_msg_get_wait(c, &msg, I2O_TIMEOUT_MESSAGE_GET); | 467 | m = i2o_msg_get_wait(c, &msg, I2O_TIMEOUT_MESSAGE_GET); |
480 | if (m == I2O_QUEUE_EMPTY) | 468 | if (m == I2O_QUEUE_EMPTY) |
481 | return -ETIMEDOUT; | 469 | return -ETIMEDOUT; |
482 | 470 | ||
483 | writel(EIGHT_WORD_MSG_SIZE | TRL_OFFSET_6, &msg->u.head[0]); | 471 | writel(EIGHT_WORD_MSG_SIZE | SGL_OFFSET_6, &msg->u.head[0]); |
484 | writel(I2O_CMD_OUTBOUND_INIT << 24 | HOST_TID << 12 | ADAPTER_TID, | 472 | writel(I2O_CMD_OUTBOUND_INIT << 24 | HOST_TID << 12 | ADAPTER_TID, |
485 | &msg->u.head[1]); | 473 | &msg->u.head[1]); |
486 | writel(i2o_exec_driver.context, &msg->u.s.icntxt); | 474 | writel(i2o_exec_driver.context, &msg->u.s.icntxt); |
487 | writel(0x0106, &msg->u.s.tcntxt); /* FIXME: why 0x0106, maybe in | 475 | writel(0x00000000, &msg->u.s.tcntxt); |
488 | Spec? */ | ||
489 | writel(PAGE_SIZE, &msg->body[0]); | 476 | writel(PAGE_SIZE, &msg->body[0]); |
490 | /* Outbound msg frame size in words and Initcode */ | 477 | /* Outbound msg frame size in words and Initcode */ |
491 | writel(MSG_FRAME_SIZE << 16 | 0x80, &msg->body[1]); | 478 | writel(I2O_OUTBOUND_MSG_FRAME_SIZE << 16 | 0x80, &msg->body[1]); |
492 | writel(0xd0000004, &msg->body[2]); | 479 | writel(0xd0000004, &msg->body[2]); |
493 | writel(i2o_dma_low(c->status.phys), &msg->body[3]); | 480 | writel(i2o_dma_low(c->status.phys), &msg->body[3]); |
494 | writel(i2o_dma_high(c->status.phys), &msg->body[4]); | 481 | writel(i2o_dma_high(c->status.phys), &msg->body[4]); |
@@ -503,17 +490,15 @@ static int i2o_iop_init_outbound_queue(struct i2o_controller *c) | |||
503 | } | 490 | } |
504 | set_current_state(TASK_UNINTERRUPTIBLE); | 491 | set_current_state(TASK_UNINTERRUPTIBLE); |
505 | schedule_timeout(1); | 492 | schedule_timeout(1); |
506 | |||
507 | rmb(); | ||
508 | } | 493 | } |
509 | 494 | ||
510 | m = c->out_queue.phys; | 495 | m = c->out_queue.phys; |
511 | 496 | ||
512 | /* Post frames */ | 497 | /* Post frames */ |
513 | for (i = 0; i < NMBR_MSG_FRAMES; i++) { | 498 | for (i = 0; i < I2O_MAX_OUTBOUND_MSG_FRAMES; i++) { |
514 | i2o_flush_reply(c, m); | 499 | i2o_flush_reply(c, m); |
515 | udelay(1); /* Promise */ | 500 | udelay(1); /* Promise */ |
516 | m += MSG_FRAME_SIZE * 4; | 501 | m += I2O_OUTBOUND_MSG_FRAME_SIZE * sizeof(u32); |
517 | } | 502 | } |
518 | 503 | ||
519 | return 0; | 504 | return 0; |
@@ -530,20 +515,20 @@ static int i2o_iop_init_outbound_queue(struct i2o_controller *c) | |||
530 | */ | 515 | */ |
531 | static int i2o_iop_reset(struct i2o_controller *c) | 516 | static int i2o_iop_reset(struct i2o_controller *c) |
532 | { | 517 | { |
533 | u8 *status = c->status.virt; | 518 | volatile u8 *status = c->status.virt; |
534 | struct i2o_message __iomem *msg; | 519 | struct i2o_message __iomem *msg; |
535 | u32 m; | 520 | u32 m; |
536 | unsigned long timeout; | 521 | unsigned long timeout; |
537 | i2o_status_block *sb = c->status_block.virt; | 522 | i2o_status_block *sb = c->status_block.virt; |
538 | int rc = 0; | 523 | int rc = 0; |
539 | 524 | ||
540 | pr_debug("%s: Resetting controller\n", c->name); | 525 | osm_debug("%s: Resetting controller\n", c->name); |
541 | 526 | ||
542 | m = i2o_msg_get_wait(c, &msg, I2O_TIMEOUT_MESSAGE_GET); | 527 | m = i2o_msg_get_wait(c, &msg, I2O_TIMEOUT_MESSAGE_GET); |
543 | if (m == I2O_QUEUE_EMPTY) | 528 | if (m == I2O_QUEUE_EMPTY) |
544 | return -ETIMEDOUT; | 529 | return -ETIMEDOUT; |
545 | 530 | ||
546 | memset(status, 0, 8); | 531 | memset(c->status_block.virt, 0, 8); |
547 | 532 | ||
548 | /* Quiesce all IOPs first */ | 533 | /* Quiesce all IOPs first */ |
549 | i2o_iop_quiesce_all(); | 534 | i2o_iop_quiesce_all(); |
@@ -568,8 +553,6 @@ static int i2o_iop_reset(struct i2o_controller *c) | |||
568 | 553 | ||
569 | set_current_state(TASK_UNINTERRUPTIBLE); | 554 | set_current_state(TASK_UNINTERRUPTIBLE); |
570 | schedule_timeout(1); | 555 | schedule_timeout(1); |
571 | |||
572 | rmb(); | ||
573 | } | 556 | } |
574 | 557 | ||
575 | switch (*status) { | 558 | switch (*status) { |
@@ -984,11 +967,11 @@ int i2o_status_get(struct i2o_controller *c) | |||
984 | { | 967 | { |
985 | struct i2o_message __iomem *msg; | 968 | struct i2o_message __iomem *msg; |
986 | u32 m; | 969 | u32 m; |
987 | u8 *status_block; | 970 | volatile u8 *status_block; |
988 | unsigned long timeout; | 971 | unsigned long timeout; |
989 | 972 | ||
990 | status_block = (u8 *) c->status_block.virt; | 973 | status_block = (u8 *) c->status_block.virt; |
991 | memset(status_block, 0, sizeof(i2o_status_block)); | 974 | memset(c->status_block.virt, 0, sizeof(i2o_status_block)); |
992 | 975 | ||
993 | m = i2o_msg_get_wait(c, &msg, I2O_TIMEOUT_MESSAGE_GET); | 976 | m = i2o_msg_get_wait(c, &msg, I2O_TIMEOUT_MESSAGE_GET); |
994 | if (m == I2O_QUEUE_EMPTY) | 977 | if (m == I2O_QUEUE_EMPTY) |
@@ -1017,8 +1000,6 @@ int i2o_status_get(struct i2o_controller *c) | |||
1017 | 1000 | ||
1018 | set_current_state(TASK_UNINTERRUPTIBLE); | 1001 | set_current_state(TASK_UNINTERRUPTIBLE); |
1019 | schedule_timeout(1); | 1002 | schedule_timeout(1); |
1020 | |||
1021 | rmb(); | ||
1022 | } | 1003 | } |
1023 | 1004 | ||
1024 | #ifdef DEBUG | 1005 | #ifdef DEBUG |
@@ -1107,6 +1088,11 @@ static void i2o_iop_release(struct device *dev) | |||
1107 | i2o_iop_free(c); | 1088 | i2o_iop_free(c); |
1108 | }; | 1089 | }; |
1109 | 1090 | ||
1091 | /* I2O controller class */ | ||
1092 | static struct class i2o_controller_class = { | ||
1093 | .name = "i2o_controller", | ||
1094 | }; | ||
1095 | |||
1110 | /** | 1096 | /** |
1111 | * i2o_iop_alloc - Allocate and initialize a i2o_controller struct | 1097 | * i2o_iop_alloc - Allocate and initialize a i2o_controller struct |
1112 | * | 1098 | * |
@@ -1136,8 +1122,14 @@ struct i2o_controller *i2o_iop_alloc(void) | |||
1136 | sprintf(c->name, "iop%d", c->unit); | 1122 | sprintf(c->name, "iop%d", c->unit); |
1137 | 1123 | ||
1138 | device_initialize(&c->device); | 1124 | device_initialize(&c->device); |
1125 | class_device_initialize(&c->classdev); | ||
1126 | |||
1139 | c->device.release = &i2o_iop_release; | 1127 | c->device.release = &i2o_iop_release; |
1128 | c->classdev.class = &i2o_controller_class; | ||
1129 | c->classdev.dev = &c->device; | ||
1130 | |||
1140 | snprintf(c->device.bus_id, BUS_ID_SIZE, "iop%d", c->unit); | 1131 | snprintf(c->device.bus_id, BUS_ID_SIZE, "iop%d", c->unit); |
1132 | snprintf(c->classdev.class_id, BUS_ID_SIZE, "iop%d", c->unit); | ||
1141 | 1133 | ||
1142 | #if BITS_PER_LONG == 64 | 1134 | #if BITS_PER_LONG == 64 |
1143 | spin_lock_init(&c->context_list_lock); | 1135 | spin_lock_init(&c->context_list_lock); |
@@ -1161,45 +1153,55 @@ int i2o_iop_add(struct i2o_controller *c) | |||
1161 | { | 1153 | { |
1162 | int rc; | 1154 | int rc; |
1163 | 1155 | ||
1164 | if((rc = device_add(&c->device))) { | 1156 | if ((rc = device_add(&c->device))) { |
1165 | printk(KERN_ERR "%s: could not register controller\n", c->name); | 1157 | osm_err("%s: could not add controller\n", c->name); |
1166 | goto iop_reset; | 1158 | goto iop_reset; |
1167 | } | 1159 | } |
1168 | 1160 | ||
1169 | printk(KERN_INFO "%s: Activating I2O controller...\n", c->name); | 1161 | if ((rc = class_device_add(&c->classdev))) { |
1170 | printk(KERN_INFO "%s: This may take a few minutes if there are many " | 1162 | osm_err("%s: could not add controller class\n", c->name); |
1171 | "devices\n", c->name); | 1163 | goto device_del; |
1164 | } | ||
1165 | |||
1166 | osm_info("%s: Activating I2O controller...\n", c->name); | ||
1167 | osm_info("%s: This may take a few minutes if there are many devices\n", | ||
1168 | c->name); | ||
1172 | 1169 | ||
1173 | if ((rc = i2o_iop_activate(c))) { | 1170 | if ((rc = i2o_iop_activate(c))) { |
1174 | printk(KERN_ERR "%s: could not activate controller\n", | 1171 | osm_err("%s: could not activate controller\n", c->name); |
1175 | c->name); | 1172 | goto class_del; |
1176 | goto iop_reset; | ||
1177 | } | 1173 | } |
1178 | 1174 | ||
1179 | pr_debug("%s: building sys table...\n", c->name); | 1175 | osm_debug("%s: building sys table...\n", c->name); |
1180 | 1176 | ||
1181 | if ((rc = i2o_systab_build())) | 1177 | if ((rc = i2o_systab_build())) |
1182 | goto iop_reset; | 1178 | goto class_del; |
1183 | 1179 | ||
1184 | pr_debug("%s: online controller...\n", c->name); | 1180 | osm_debug("%s: online controller...\n", c->name); |
1185 | 1181 | ||
1186 | if ((rc = i2o_iop_online(c))) | 1182 | if ((rc = i2o_iop_online(c))) |
1187 | goto iop_reset; | 1183 | goto class_del; |
1188 | 1184 | ||
1189 | pr_debug("%s: getting LCT...\n", c->name); | 1185 | osm_debug("%s: getting LCT...\n", c->name); |
1190 | 1186 | ||
1191 | if ((rc = i2o_exec_lct_get(c))) | 1187 | if ((rc = i2o_exec_lct_get(c))) |
1192 | goto iop_reset; | 1188 | goto class_del; |
1193 | 1189 | ||
1194 | list_add(&c->list, &i2o_controllers); | 1190 | list_add(&c->list, &i2o_controllers); |
1195 | 1191 | ||
1196 | i2o_driver_notify_controller_add_all(c); | 1192 | i2o_driver_notify_controller_add_all(c); |
1197 | 1193 | ||
1198 | printk(KERN_INFO "%s: Controller added\n", c->name); | 1194 | osm_info("%s: Controller added\n", c->name); |
1199 | 1195 | ||
1200 | return 0; | 1196 | return 0; |
1201 | 1197 | ||
1202 | iop_reset: | 1198 | class_del: |
1199 | class_device_del(&c->classdev); | ||
1200 | |||
1201 | device_del: | ||
1202 | device_del(&c->device); | ||
1203 | |||
1204 | iop_reset: | ||
1203 | i2o_iop_reset(c); | 1205 | i2o_iop_reset(c); |
1204 | 1206 | ||
1205 | return rc; | 1207 | return rc; |
@@ -1260,16 +1262,18 @@ static int __init i2o_iop_init(void) | |||
1260 | if (rc) | 1262 | if (rc) |
1261 | goto exit; | 1263 | goto exit; |
1262 | 1264 | ||
1263 | rc = i2o_driver_init(); | 1265 | if ((rc = class_register(&i2o_controller_class))) { |
1264 | if (rc) | 1266 | osm_err("can't register class i2o_controller\n"); |
1265 | goto device_exit; | 1267 | goto device_exit; |
1268 | } | ||
1266 | 1269 | ||
1267 | rc = i2o_exec_init(); | 1270 | if ((rc = i2o_driver_init())) |
1268 | if (rc) | 1271 | goto class_exit; |
1272 | |||
1273 | if ((rc = i2o_exec_init())) | ||
1269 | goto driver_exit; | 1274 | goto driver_exit; |
1270 | 1275 | ||
1271 | rc = i2o_pci_init(); | 1276 | if ((rc = i2o_pci_init())) |
1272 | if (rc < 0) | ||
1273 | goto exec_exit; | 1277 | goto exec_exit; |
1274 | 1278 | ||
1275 | return 0; | 1279 | return 0; |
@@ -1280,6 +1284,9 @@ static int __init i2o_iop_init(void) | |||
1280 | driver_exit: | 1284 | driver_exit: |
1281 | i2o_driver_exit(); | 1285 | i2o_driver_exit(); |
1282 | 1286 | ||
1287 | class_exit: | ||
1288 | class_unregister(&i2o_controller_class); | ||
1289 | |||
1283 | device_exit: | 1290 | device_exit: |
1284 | i2o_device_exit(); | 1291 | i2o_device_exit(); |
1285 | 1292 | ||
@@ -1297,6 +1304,7 @@ static void __exit i2o_iop_exit(void) | |||
1297 | i2o_pci_exit(); | 1304 | i2o_pci_exit(); |
1298 | i2o_exec_exit(); | 1305 | i2o_exec_exit(); |
1299 | i2o_driver_exit(); | 1306 | i2o_driver_exit(); |
1307 | class_unregister(&i2o_controller_class); | ||
1300 | i2o_device_exit(); | 1308 | i2o_device_exit(); |
1301 | }; | 1309 | }; |
1302 | 1310 | ||
diff --git a/drivers/message/i2o/pci.c b/drivers/message/i2o/pci.c index 964fe481849e..442e34506b90 100644 --- a/drivers/message/i2o/pci.c +++ b/drivers/message/i2o/pci.c | |||
@@ -30,15 +30,7 @@ | |||
30 | #include <linux/pci.h> | 30 | #include <linux/pci.h> |
31 | #include <linux/interrupt.h> | 31 | #include <linux/interrupt.h> |
32 | #include <linux/i2o.h> | 32 | #include <linux/i2o.h> |
33 | 33 | #include "core.h" | |
34 | /* Module internal functions from other sources */ | ||
35 | extern struct i2o_controller *i2o_iop_alloc(void); | ||
36 | extern void i2o_iop_free(struct i2o_controller *); | ||
37 | |||
38 | extern int i2o_iop_add(struct i2o_controller *); | ||
39 | extern void i2o_iop_remove(struct i2o_controller *); | ||
40 | |||
41 | extern int i2o_driver_dispatch(struct i2o_controller *, u32); | ||
42 | 34 | ||
43 | /* PCI device id table for all I2O controllers */ | 35 | /* PCI device id table for all I2O controllers */ |
44 | static struct pci_device_id __devinitdata i2o_pci_ids[] = { | 36 | static struct pci_device_id __devinitdata i2o_pci_ids[] = { |
@@ -248,9 +240,7 @@ static int i2o_pci_irq_enable(struct i2o_controller *c) | |||
248 | struct pci_dev *pdev = c->pdev; | 240 | struct pci_dev *pdev = c->pdev; |
249 | int rc; | 241 | int rc; |
250 | 242 | ||
251 | wmb(); | ||
252 | writel(0xffffffff, c->irq_mask); | 243 | writel(0xffffffff, c->irq_mask); |
253 | wmb(); | ||
254 | 244 | ||
255 | if (pdev->irq) { | 245 | if (pdev->irq) { |
256 | rc = request_irq(pdev->irq, i2o_pci_interrupt, SA_SHIRQ, | 246 | rc = request_irq(pdev->irq, i2o_pci_interrupt, SA_SHIRQ, |
@@ -263,7 +253,6 @@ static int i2o_pci_irq_enable(struct i2o_controller *c) | |||
263 | } | 253 | } |
264 | 254 | ||
265 | writel(0x00000000, c->irq_mask); | 255 | writel(0x00000000, c->irq_mask); |
266 | wmb(); | ||
267 | 256 | ||
268 | printk(KERN_INFO "%s: Installed at IRQ %d\n", c->name, pdev->irq); | 257 | printk(KERN_INFO "%s: Installed at IRQ %d\n", c->name, pdev->irq); |
269 | 258 | ||
@@ -278,9 +267,7 @@ static int i2o_pci_irq_enable(struct i2o_controller *c) | |||
278 | */ | 267 | */ |
279 | static void i2o_pci_irq_disable(struct i2o_controller *c) | 268 | static void i2o_pci_irq_disable(struct i2o_controller *c) |
280 | { | 269 | { |
281 | wmb(); | ||
282 | writel(0xffffffff, c->irq_mask); | 270 | writel(0xffffffff, c->irq_mask); |
283 | wmb(); | ||
284 | 271 | ||
285 | if (c->pdev->irq > 0) | 272 | if (c->pdev->irq > 0) |
286 | free_irq(c->pdev->irq, c); | 273 | free_irq(c->pdev->irq, c); |
@@ -406,11 +393,11 @@ static int __devinit i2o_pci_probe(struct pci_dev *pdev, | |||
406 | if ((rc = i2o_iop_add(c))) | 393 | if ((rc = i2o_iop_add(c))) |
407 | goto uninstall; | 394 | goto uninstall; |
408 | 395 | ||
396 | get_device(&c->device); | ||
397 | |||
409 | if (i960) | 398 | if (i960) |
410 | pci_write_config_word(i960, 0x42, 0x03ff); | 399 | pci_write_config_word(i960, 0x42, 0x03ff); |
411 | 400 | ||
412 | get_device(&c->device); | ||
413 | |||
414 | return 0; | 401 | return 0; |
415 | 402 | ||
416 | uninstall: | 403 | uninstall: |
@@ -478,6 +465,4 @@ void __exit i2o_pci_exit(void) | |||
478 | { | 465 | { |
479 | pci_unregister_driver(&i2o_pci_driver); | 466 | pci_unregister_driver(&i2o_pci_driver); |
480 | }; | 467 | }; |
481 | |||
482 | EXPORT_SYMBOL(i2o_dma_realloc); | ||
483 | MODULE_DEVICE_TABLE(pci, i2o_pci_ids); | 468 | MODULE_DEVICE_TABLE(pci, i2o_pci_ids); |