Commit f88e119c authored by Markus Lidel's avatar Markus Lidel Committed by Linus Torvalds

[PATCH] I2O: first code cleanup of spare warnings and unused functions

Changes:

 - Removed unnecessary checking of NULL before calling kfree()
 - Make some functions static
 - Changed pr_debug() into osm_debug()
 - Use i2o_msg_in_to_virt() for getting a pointer to the message frame
 - Cleaned up some comments
 - Changed some le32_to_cpu() into readl() where necessary
 - Make error messages of OSM's look the same
 - Cleaned up error handling in i2o_block_end_request()
 - Removed unused error handling of failed messages in Block-OSM, which
   are not allowed by the I2O spec
 - Corrected the blocksize detection in i2o_block
 - Added hrt and lct sysfs-attribute to controller
 - Call done() function in SCSI-OSM after freeing DMA buffers
 - Removed unneeded variable for message size calculation in
   i2o_scsi_queuecommand()
 - Make some changes to remove sparse warnings
 - Reordered some functions
 - Cleaned up controller initialization
 - Replaced some magic numbers by defines
 - Removed unnecessary dma_sync_single_for_cpu() call on coherent DMA
 - Removed some unused fields in i2o_controller and removed some unused
   functions
Signed-off-by: default avatarMarkus Lidel <Markus.Lidel@shadowconnect.com>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 61fbfa81
...@@ -282,7 +282,6 @@ int i2o_device_parse_lct(struct i2o_controller *c) ...@@ -282,7 +282,6 @@ int i2o_device_parse_lct(struct i2o_controller *c)
down(&c->lct_lock); down(&c->lct_lock);
if (c->lct)
kfree(c->lct); kfree(c->lct);
lct = c->dlct.virt; lct = c->dlct.virt;
...@@ -447,7 +446,7 @@ static struct class_interface i2o_device_class_interface = { ...@@ -447,7 +446,7 @@ static struct class_interface i2o_device_class_interface = {
* ResultCount, ErrorInfoSize, BlockStatus and BlockSize. * ResultCount, ErrorInfoSize, BlockStatus and BlockSize.
*/ */
int i2o_parm_issue(struct i2o_device *i2o_dev, int cmd, void *oplist, static int i2o_parm_issue(struct i2o_device *i2o_dev, int cmd, void *oplist,
int oplen, void *reslist, int reslen) int oplen, void *reslist, int reslen)
{ {
struct i2o_message __iomem *msg; struct i2o_message __iomem *msg;
...@@ -540,7 +539,7 @@ int i2o_parm_field_get(struct i2o_device *i2o_dev, int group, int field, ...@@ -540,7 +539,7 @@ int i2o_parm_field_get(struct i2o_device *i2o_dev, int group, int field,
opblk[4] = -1; opblk[4] = -1;
size = i2o_parm_issue(i2o_dev, I2O_CMD_UTIL_PARAMS_GET, opblk, size = i2o_parm_issue(i2o_dev, I2O_CMD_UTIL_PARAMS_GET, opblk,
sizeof(opblk), resblk, sizeof(resblk)); sizeof(opblk), resblk, buflen + 8);
memcpy(buf, resblk + 8, buflen); /* cut off header */ memcpy(buf, resblk + 8, buflen); /* cut off header */
......
...@@ -18,7 +18,7 @@ ...@@ -18,7 +18,7 @@
#include <linux/rwsem.h> #include <linux/rwsem.h>
#include <linux/i2o.h> #include <linux/i2o.h>
#define OSM_NAME "core" #define OSM_NAME "i2o"
/* max_drivers - Maximum I2O drivers (OSMs) which could be registered */ /* max_drivers - Maximum I2O drivers (OSMs) which could be registered */
unsigned int i2o_max_drivers = I2O_MAX_DRIVERS; unsigned int i2o_max_drivers = I2O_MAX_DRIVERS;
...@@ -78,17 +78,16 @@ int i2o_driver_register(struct i2o_driver *drv) ...@@ -78,17 +78,16 @@ int i2o_driver_register(struct i2o_driver *drv)
int rc = 0; int rc = 0;
unsigned long flags; unsigned long flags;
pr_debug("i2o: Register driver %s\n", drv->name); osm_debug("Register driver %s\n", drv->name);
if (drv->event) { if (drv->event) {
drv->event_queue = create_workqueue(drv->name); drv->event_queue = create_workqueue(drv->name);
if (!drv->event_queue) { if (!drv->event_queue) {
printk(KERN_ERR "i2o: Could not initialize event queue " osm_err("Could not initialize event queue for driver "
"for driver %s\n", drv->name); "%s\n", drv->name);
return -EFAULT; return -EFAULT;
} }
pr_debug("i2o: Event queue initialized for driver %s\n", osm_debug("Event queue initialized for driver %s\n", drv->name);
drv->name);
} else } else
drv->event_queue = NULL; drv->event_queue = NULL;
...@@ -99,8 +98,8 @@ int i2o_driver_register(struct i2o_driver *drv) ...@@ -99,8 +98,8 @@ int i2o_driver_register(struct i2o_driver *drv)
for (i = 0; i2o_drivers[i]; i++) for (i = 0; i2o_drivers[i]; i++)
if (i >= i2o_max_drivers) { if (i >= i2o_max_drivers) {
printk(KERN_ERR "i2o: too many drivers registered, " osm_err("too many drivers registered, increase "
"increase max_drivers\n"); "max_drivers\n");
spin_unlock_irqrestore(&i2o_drivers_lock, flags); spin_unlock_irqrestore(&i2o_drivers_lock, flags);
return -EFAULT; return -EFAULT;
} }
...@@ -110,8 +109,7 @@ int i2o_driver_register(struct i2o_driver *drv) ...@@ -110,8 +109,7 @@ int i2o_driver_register(struct i2o_driver *drv)
spin_unlock_irqrestore(&i2o_drivers_lock, flags); spin_unlock_irqrestore(&i2o_drivers_lock, flags);
pr_debug("i2o: driver %s gets context id %d\n", drv->name, osm_debug("driver %s gets context id %d\n", drv->name, drv->context);
drv->context);
list_for_each_entry(c, &i2o_controllers, list) { list_for_each_entry(c, &i2o_controllers, list) {
struct i2o_device *i2o_dev; struct i2o_device *i2o_dev;
...@@ -141,7 +139,7 @@ void i2o_driver_unregister(struct i2o_driver *drv) ...@@ -141,7 +139,7 @@ void i2o_driver_unregister(struct i2o_driver *drv)
struct i2o_controller *c; struct i2o_controller *c;
unsigned long flags; unsigned long flags;
pr_debug("i2o: unregister driver %s\n", drv->name); osm_debug("unregister driver %s\n", drv->name);
driver_unregister(&drv->driver); driver_unregister(&drv->driver);
...@@ -161,7 +159,7 @@ void i2o_driver_unregister(struct i2o_driver *drv) ...@@ -161,7 +159,7 @@ void i2o_driver_unregister(struct i2o_driver *drv)
if (drv->event_queue) { if (drv->event_queue) {
destroy_workqueue(drv->event_queue); destroy_workqueue(drv->event_queue);
drv->event_queue = NULL; drv->event_queue = NULL;
pr_debug("i2o: event queue removed for %s\n", drv->name); osm_debug("event queue removed for %s\n", drv->name);
} }
}; };
...@@ -178,15 +176,15 @@ void i2o_driver_unregister(struct i2o_driver *drv) ...@@ -178,15 +176,15 @@ void i2o_driver_unregister(struct i2o_driver *drv)
* on success and if the message should be flushed afterwords. Returns * on success and if the message should be flushed afterwords. Returns
* negative error code on failure (the message will be flushed too). * negative error code on failure (the message will be flushed too).
*/ */
int i2o_driver_dispatch(struct i2o_controller *c, u32 m, int i2o_driver_dispatch(struct i2o_controller *c, u32 m)
struct i2o_message __iomem *msg)
{ {
struct i2o_driver *drv; struct i2o_driver *drv;
struct i2o_message __iomem *msg = i2o_msg_out_to_virt(c, m);
u32 context = readl(&msg->u.s.icntxt); u32 context = readl(&msg->u.s.icntxt);
if (unlikely(context >= i2o_max_drivers)) { if (unlikely(context >= i2o_max_drivers)) {
printk(KERN_WARNING "%s: Spurious reply to unknown driver " osm_warn("%s: Spurious reply to unknown driver %d\n", c->name,
"%d\n", c->name, readl(&msg->u.s.icntxt)); context);
return -EIO; return -EIO;
} }
...@@ -195,7 +193,8 @@ int i2o_driver_dispatch(struct i2o_controller *c, u32 m, ...@@ -195,7 +193,8 @@ int i2o_driver_dispatch(struct i2o_controller *c, u32 m,
spin_unlock(&i2o_drivers_lock); spin_unlock(&i2o_drivers_lock);
if (unlikely(!drv)) { if (unlikely(!drv)) {
osm_warn("Spurious reply to unknown driver %d\n", context); osm_warn("%s: Spurious reply to unknown driver %d\n", c->name,
context);
return -EIO; return -EIO;
} }
...@@ -207,6 +206,9 @@ int i2o_driver_dispatch(struct i2o_controller *c, u32 m, ...@@ -207,6 +206,9 @@ int i2o_driver_dispatch(struct i2o_controller *c, u32 m,
osm_debug("event received from device %d\n", tid); osm_debug("event received from device %d\n", tid);
if (!drv->event)
return -EIO;
/* cut of header from message size (in 32-bit words) */ /* cut of header from message size (in 32-bit words) */
size = (readl(&msg->u.head[0]) >> 16) - 5; size = (readl(&msg->u.head[0]) >> 16) - 5;
...@@ -231,7 +233,7 @@ int i2o_driver_dispatch(struct i2o_controller *c, u32 m, ...@@ -231,7 +233,7 @@ int i2o_driver_dispatch(struct i2o_controller *c, u32 m,
} }
if (unlikely(!drv->reply)) { if (unlikely(!drv->reply)) {
pr_debug("%s: Reply to driver %s, but no reply function" osm_debug("%s: Reply to driver %s, but no reply function"
" defined!\n", c->name, drv->name); " defined!\n", c->name, drv->name);
return -EIO; return -EIO;
} }
...@@ -333,11 +335,11 @@ int __init i2o_driver_init(void) ...@@ -333,11 +335,11 @@ int __init i2o_driver_init(void)
if ((i2o_max_drivers < 2) || (i2o_max_drivers > 64) || if ((i2o_max_drivers < 2) || (i2o_max_drivers > 64) ||
((i2o_max_drivers ^ (i2o_max_drivers - 1)) != ((i2o_max_drivers ^ (i2o_max_drivers - 1)) !=
(2 * i2o_max_drivers - 1))) { (2 * i2o_max_drivers - 1))) {
printk(KERN_WARNING "i2o: max_drivers set to %d, but must be " osm_warn("max_drivers set to %d, but must be >=2 and <= 64 and "
">=2 and <= 64 and a power of 2\n", i2o_max_drivers); "a power of 2\n", i2o_max_drivers);
i2o_max_drivers = I2O_MAX_DRIVERS; i2o_max_drivers = I2O_MAX_DRIVERS;
} }
printk(KERN_INFO "i2o: max drivers = %d\n", i2o_max_drivers); osm_info("max drivers = %d\n", i2o_max_drivers);
i2o_drivers = i2o_drivers =
kmalloc(i2o_max_drivers * sizeof(*i2o_drivers), GFP_KERNEL); kmalloc(i2o_max_drivers * sizeof(*i2o_drivers), GFP_KERNEL);
......
...@@ -108,7 +108,8 @@ static void i2o_exec_wait_free(struct i2o_exec_wait *wait) ...@@ -108,7 +108,8 @@ static void i2o_exec_wait_free(struct i2o_exec_wait *wait)
* buffer must not be freed. Instead the event completion will free them * buffer must not be freed. Instead the event completion will free them
* for you. In all other cases the buffer are your problem. * for you. In all other cases the buffer are your problem.
* *
* Returns 0 on success or negative error code on failure. * Returns 0 on success, negative error code on timeout or positive error
* code from reply.
*/ */
int i2o_msg_post_wait_mem(struct i2o_controller *c, u32 m, unsigned long int i2o_msg_post_wait_mem(struct i2o_controller *c, u32 m, unsigned long
timeout, struct i2o_dma *dma) timeout, struct i2o_dma *dma)
...@@ -116,7 +117,7 @@ int i2o_msg_post_wait_mem(struct i2o_controller *c, u32 m, unsigned long ...@@ -116,7 +117,7 @@ int i2o_msg_post_wait_mem(struct i2o_controller *c, u32 m, unsigned long
DECLARE_WAIT_QUEUE_HEAD(wq); DECLARE_WAIT_QUEUE_HEAD(wq);
struct i2o_exec_wait *wait; struct i2o_exec_wait *wait;
static u32 tcntxt = 0x80000000; static u32 tcntxt = 0x80000000;
struct i2o_message __iomem *msg = c->in_queue.virt + m; struct i2o_message __iomem *msg = i2o_msg_in_to_virt(c, m);
int rc = 0; int rc = 0;
wait = i2o_exec_wait_alloc(); wait = i2o_exec_wait_alloc();
...@@ -161,8 +162,7 @@ int i2o_msg_post_wait_mem(struct i2o_controller *c, u32 m, unsigned long ...@@ -161,8 +162,7 @@ int i2o_msg_post_wait_mem(struct i2o_controller *c, u32 m, unsigned long
barrier(); barrier();
if (wait->complete) { if (wait->complete) {
if (readl(&wait->msg->body[0]) >> 24) rc = readl(&wait->msg->body[0]) >> 24;
rc = readl(&wait->msg->body[0]) & 0xff;
i2o_flush_reply(c, wait->m); i2o_flush_reply(c, wait->m);
i2o_exec_wait_free(wait); i2o_exec_wait_free(wait);
} else { } else {
...@@ -187,6 +187,7 @@ int i2o_msg_post_wait_mem(struct i2o_controller *c, u32 m, unsigned long ...@@ -187,6 +187,7 @@ int i2o_msg_post_wait_mem(struct i2o_controller *c, u32 m, unsigned long
* @c: I2O controller which answers * @c: I2O controller which answers
* @m: message id * @m: message id
* @msg: pointer to the I2O reply message * @msg: pointer to the I2O reply message
* @context: transaction context of request
* *
* This function is called in interrupt context only. If the reply reached * This function is called in interrupt context only. If the reply reached
* before the timeout, the i2o_exec_wait struct is filled with the message * before the timeout, the i2o_exec_wait struct is filled with the message
...@@ -201,14 +202,12 @@ int i2o_msg_post_wait_mem(struct i2o_controller *c, u32 m, unsigned long ...@@ -201,14 +202,12 @@ int i2o_msg_post_wait_mem(struct i2o_controller *c, u32 m, unsigned long
* message must also be given back to the controller. * message must also be given back to the controller.
*/ */
static int i2o_msg_post_wait_complete(struct i2o_controller *c, u32 m, static int i2o_msg_post_wait_complete(struct i2o_controller *c, u32 m,
struct i2o_message __iomem *msg) struct i2o_message __iomem *msg,
u32 context)
{ {
struct i2o_exec_wait *wait, *tmp; struct i2o_exec_wait *wait, *tmp;
static spinlock_t lock = SPIN_LOCK_UNLOCKED; static spinlock_t lock = SPIN_LOCK_UNLOCKED;
int rc = 1; int rc = 1;
u32 context;
context = readl(&msg->u.s.tcntxt);
/* /*
* We need to search through the i2o_exec_wait_list to see if the given * We need to search through the i2o_exec_wait_list to see if the given
...@@ -251,7 +250,7 @@ static int i2o_msg_post_wait_complete(struct i2o_controller *c, u32 m, ...@@ -251,7 +250,7 @@ static int i2o_msg_post_wait_complete(struct i2o_controller *c, u32 m,
spin_unlock(&lock); spin_unlock(&lock);
pr_debug("%s: Bogus reply in POST WAIT (tr-context: %08x)!\n", c->name, osm_warn("%s: Bogus reply in POST WAIT (tr-context: %08x)!\n", c->name,
context); context);
return -1; return -1;
...@@ -321,29 +320,35 @@ static void i2o_exec_lct_modified(struct i2o_controller *c) ...@@ -321,29 +320,35 @@ static void i2o_exec_lct_modified(struct i2o_controller *c)
* code on failure and if the reply should be flushed. * code on failure and if the reply should be flushed.
*/ */
static int i2o_exec_reply(struct i2o_controller *c, u32 m, static int i2o_exec_reply(struct i2o_controller *c, u32 m,
struct i2o_message *msg) struct i2o_message __iomem *msg)
{ {
if (le32_to_cpu(msg->u.head[0]) & MSG_FAIL) { // Fail bit is set u32 context;
struct i2o_message __iomem *pmsg; /* preserved message */
if (readl(&msg->u.head[0]) & MSG_FAIL) {
/*
* If Fail bit is set we must take the transaction context of
* the preserved message to find the right request again.
*/
struct i2o_message __iomem *pmsg;
u32 pm; u32 pm;
pm = le32_to_cpu(msg->body[3]); pm = readl(&msg->body[3]);
pmsg = i2o_msg_in_to_virt(c, pm); pmsg = i2o_msg_in_to_virt(c, pm);
i2o_report_status(KERN_INFO, "i2o_core", msg); i2o_report_status(KERN_INFO, "i2o_core", msg);
/* Release the preserved msg by resubmitting it as a NOP */ context = readl(&pmsg->u.s.tcntxt);
i2o_msg_nop(c, pm);
/* If reply to i2o_post_wait failed, return causes a timeout */ /* Release the preserved msg */
return -1; i2o_msg_nop(c, pm);
} } else
context = readl(&msg->u.s.tcntxt);
if (le32_to_cpu(msg->u.s.tcntxt) & 0x80000000) if (context & 0x80000000)
return i2o_msg_post_wait_complete(c, m, msg); return i2o_msg_post_wait_complete(c, m, msg, context);
if ((le32_to_cpu(msg->u.head[1]) >> 24) == I2O_CMD_LCT_NOTIFY) { if ((readl(&msg->u.head[1]) >> 24) == I2O_CMD_LCT_NOTIFY) {
struct work_struct *work; struct work_struct *work;
pr_debug("%s: LCT notify received\n", c->name); pr_debug("%s: LCT notify received\n", c->name);
......
...@@ -104,7 +104,8 @@ static int i2o_block_remove(struct device *dev) ...@@ -104,7 +104,8 @@ static int i2o_block_remove(struct device *dev)
struct i2o_device *i2o_dev = to_i2o_device(dev); struct i2o_device *i2o_dev = to_i2o_device(dev);
struct i2o_block_device *i2o_blk_dev = dev_get_drvdata(dev); struct i2o_block_device *i2o_blk_dev = dev_get_drvdata(dev);
osm_info("Device removed %s\n", i2o_blk_dev->gd->disk_name); osm_info("device removed (TID: %03x): %s\n", i2o_dev->lct_data.tid,
i2o_blk_dev->gd->disk_name);
i2o_event_register(i2o_dev, &i2o_block_driver, 0, 0); i2o_event_register(i2o_dev, &i2o_block_driver, 0, 0);
...@@ -400,71 +401,62 @@ static void i2o_block_delayed_request_fn(void *delayed_request) ...@@ -400,71 +401,62 @@ static void i2o_block_delayed_request_fn(void *delayed_request)
}; };
/** /**
* i2o_block_reply - Block OSM reply handler. * i2o_block_end_request - Post-processing of completed commands
* @c: I2O controller from which the message arrives * @req: request which should be completed
* @m: message id of reply * @uptodate: 1 for success, 0 for I/O error, < 0 for specific error
* qmsg: the actuall I2O message reply * @nr_bytes: number of bytes to complete
* *
* This function gets all the message replies. * Mark the request as complete. The lock must not be held when entering.
* *
*/ */
static int i2o_block_reply(struct i2o_controller *c, u32 m, static void i2o_block_end_request(struct request *req, int uptodate,
struct i2o_message *msg) int nr_bytes)
{ {
struct i2o_block_request *ireq; struct i2o_block_request *ireq = req->special;
struct request *req; struct i2o_block_device *dev = ireq->i2o_blk_dev;
struct i2o_block_device *dev; request_queue_t *q = dev->gd->queue;
struct request_queue *q;
u8 st;
unsigned long flags; unsigned long flags;
/* FAILed message */ if (end_that_request_chunk(req, uptodate, nr_bytes)) {
if (unlikely(le32_to_cpu(msg->u.head[0]) & (1 << 13))) { int leftover = (req->hard_nr_sectors << 9);
struct i2o_message *pmsg;
u32 pm;
/* if (blk_pc_request(req))
* FAILed message from controller leftover = req->data_len;
* We increment the error count and abort it
*
* In theory this will never happen. The I2O block class
* specification states that block devices never return
* FAILs but instead use the REQ status field...but
* better be on the safe side since no one really follows
* the spec to the book :)
*/
pm = le32_to_cpu(msg->body[3]);
pmsg = i2o_msg_in_to_virt(c, pm);
req = i2o_cntxt_list_get(c, le32_to_cpu(pmsg->u.s.tcntxt)); if (end_io_error(uptodate))
if (unlikely(!req)) { end_that_request_chunk(req, 0, leftover);
osm_err("NULL reply received!\n");
return -1;
} }
ireq = req->special; add_disk_randomness(req->rq_disk);
dev = ireq->i2o_blk_dev;
q = dev->gd->queue;
req->errors++;
spin_lock_irqsave(q->queue_lock, flags); spin_lock_irqsave(q->queue_lock, flags);
while (end_that_request_chunk(req, !req->errors,
le32_to_cpu(pmsg->body[1]))) ;
end_that_request_last(req); end_that_request_last(req);
dev->open_queue_depth--; dev->open_queue_depth--;
list_del(&ireq->queue); list_del(&ireq->queue);
blk_start_queue(q); blk_start_queue(q);
spin_unlock_irqrestore(q->queue_lock, flags); spin_unlock_irqrestore(q->queue_lock, flags);
/* Now flush the message by making it a NOP */ i2o_block_sglist_free(ireq);
i2o_msg_nop(c, pm); i2o_block_request_free(ireq);
};
return -1; /**
} * i2o_block_reply - Block OSM reply handler.
* @c: I2O controller from which the message arrives
* @m: message id of reply
* qmsg: the actuall I2O message reply
*
* This function gets all the message replies.
*
*/
static int i2o_block_reply(struct i2o_controller *c, u32 m,
struct i2o_message *msg)
{
struct request *req;
int uptodate = 1;
req = i2o_cntxt_list_get(c, le32_to_cpu(msg->u.s.tcntxt)); req = i2o_cntxt_list_get(c, le32_to_cpu(msg->u.s.tcntxt));
if (unlikely(!req)) { if (unlikely(!req)) {
...@@ -472,61 +464,13 @@ static int i2o_block_reply(struct i2o_controller *c, u32 m, ...@@ -472,61 +464,13 @@ static int i2o_block_reply(struct i2o_controller *c, u32 m,
return -1; return -1;
} }
ireq = req->special;
dev = ireq->i2o_blk_dev;
q = dev->gd->queue;
if (unlikely(!dev->i2o_dev)) {
/*
* This is HACK, but Intel Integrated RAID allows user
* to delete a volume that is claimed, locked, and in use
* by the OS. We have to check for a reply from a
* non-existent device and flag it as an error or the system
* goes kaput...
*/
req->errors++;
osm_warn("Data transfer to deleted device!\n");
spin_lock_irqsave(q->queue_lock, flags);
while (end_that_request_chunk
(req, !req->errors, le32_to_cpu(msg->body[1]))) ;
end_that_request_last(req);
dev->open_queue_depth--;
list_del(&ireq->queue);
blk_start_queue(q);
spin_unlock_irqrestore(q->queue_lock, flags);
return -1;
}
/* /*
* Lets see what is cooking. We stuffed the * Lets see what is cooking. We stuffed the
* request in the context. * request in the context.
*/ */
st = le32_to_cpu(msg->body[0]) >> 24; if ((le32_to_cpu(msg->body[0]) >> 24) != 0) {
u32 status = le32_to_cpu(msg->body[0]);
if (st != 0) {
int err;
char *bsa_errors[] = {
"Success",
"Media Error",
"Failure communicating to device",
"Device Failure",
"Device is not ready",
"Media not present",
"Media is locked by another user",
"Media has failed",
"Failure communicating to device",
"Device bus failure",
"Device is locked by another user",
"Device is write protected",
"Device has reset",
"Volume has changed, waiting for acknowledgement"
};
err = le32_to_cpu(msg->body[0]) & 0xffff;
/* /*
* Device not ready means two things. One is that the * Device not ready means two things. One is that the
* the thing went offline (but not a removal media) * the thing went offline (but not a removal media)
...@@ -539,40 +483,23 @@ static int i2o_block_reply(struct i2o_controller *c, u32 m, ...@@ -539,40 +483,23 @@ static int i2o_block_reply(struct i2o_controller *c, u32 m,
* Don't stick a supertrak100 into cache aggressive modes * Don't stick a supertrak100 into cache aggressive modes
*/ */
osm_err("block-osm: /dev/%s error: %s", dev->gd->disk_name, osm_err("%03x error status: %02x, detailed status: %04x\n",
bsa_errors[le32_to_cpu(msg->body[0]) & 0xffff]); (le32_to_cpu(msg->u.head[1]) >> 12 & 0xfff),
if (le32_to_cpu(msg->body[0]) & 0x00ff0000) status >> 24, status & 0xffff);
printk(KERN_ERR " - DDM attempted %d retries",
(le32_to_cpu(msg->body[0]) >> 16) & 0x00ff);
printk(KERN_ERR ".\n");
req->errors++;
} else
req->errors = 0;
if (!end_that_request_chunk
(req, !req->errors, le32_to_cpu(msg->body[1]))) {
add_disk_randomness(req->rq_disk);
spin_lock_irqsave(q->queue_lock, flags);
end_that_request_last(req);
dev->open_queue_depth--; req->errors++;
list_del(&ireq->queue);
blk_start_queue(q);
spin_unlock_irqrestore(q->queue_lock, flags); uptodate = 0;
}
i2o_block_sglist_free(ireq); i2o_block_end_request(req, uptodate, le32_to_cpu(msg->body[1]));
i2o_block_request_free(ireq);
} else
osm_err("still remaining chunks\n");
return 1; return 1;
}; };
static void i2o_block_event(struct i2o_event *evt) static void i2o_block_event(struct i2o_event *evt)
{ {
osm_info("block-osm: event received\n"); osm_info("event received\n");
kfree(evt); kfree(evt);
}; };
...@@ -875,9 +802,7 @@ static int i2o_block_transfer(struct request *req) ...@@ -875,9 +802,7 @@ static int i2o_block_transfer(struct request *req)
sg++; sg++;
} }
writel(I2O_MESSAGE_SIZE writel(I2O_MESSAGE_SIZE(mptr - &msg->u.head[0]) | SGL_OFFSET_8,
(((unsigned long)mptr -
(unsigned long)&msg->u.head[0]) >> 2) | SGL_OFFSET_8,
&msg->u.head[0]); &msg->u.head[0]);
list_add_tail(&ireq->queue, &dev->open_queue); list_add_tail(&ireq->queue, &dev->open_queue);
...@@ -1048,7 +973,6 @@ static int i2o_block_probe(struct device *dev) ...@@ -1048,7 +973,6 @@ static int i2o_block_probe(struct device *dev)
int rc; int rc;
u64 size; u64 size;
u32 blocksize; u32 blocksize;
u16 power;
u32 flags, status; u32 flags, status;
int segments; int segments;
...@@ -1058,8 +982,6 @@ static int i2o_block_probe(struct device *dev) ...@@ -1058,8 +982,6 @@ static int i2o_block_probe(struct device *dev)
return -ENODEV; return -ENODEV;
} }
osm_info("New device detected (TID: %03x)\n", i2o_dev->lct_data.tid);
if (i2o_device_claim(i2o_dev)) { if (i2o_device_claim(i2o_dev)) {
osm_warn("Unable to claim device. Installation aborted\n"); osm_warn("Unable to claim device. Installation aborted\n");
rc = -EFAULT; rc = -EFAULT;
...@@ -1111,15 +1033,21 @@ static int i2o_block_probe(struct device *dev) ...@@ -1111,15 +1033,21 @@ static int i2o_block_probe(struct device *dev)
* Ask for the current media data. If that isn't supported * Ask for the current media data. If that isn't supported
* then we ask for the device capacity data * then we ask for the device capacity data
*/ */
if (i2o_parm_field_get(i2o_dev, 0x0004, 1, &blocksize, 4) != 0 if (!i2o_parm_field_get(i2o_dev, 0x0004, 0, &size, 8))
|| i2o_parm_field_get(i2o_dev, 0x0004, 0, &size, 8) != 0) { if (!i2o_parm_field_get(i2o_dev, 0x0000, 4, &size, 8)) {
i2o_parm_field_get(i2o_dev, 0x0000, 3, &blocksize, 4); osm_warn("could not get size of %s\n", gd->disk_name);
i2o_parm_field_get(i2o_dev, 0x0000, 4, &size, 8); size = 0;
}
if (!i2o_parm_field_get(i2o_dev, 0x0004, 1, &blocksize, 4))
if (!i2o_parm_field_get(i2o_dev, 0x0000, 3, &blocksize, 4)) {
osm_warn("unable to get blocksize of %s\n",
gd->disk_name);
blocksize = 0;
} }
osm_debug("blocksize = %d\n", blocksize);
if (i2o_parm_field_get(i2o_dev, 0x0000, 2, &power, 2)) if (!i2o_parm_field_get(i2o_dev, 0x0000, 2, &i2o_blk_dev->power, 2))
power = 0; i2o_blk_dev->power = 0;
i2o_parm_field_get(i2o_dev, 0x0000, 5, &flags, 4); i2o_parm_field_get(i2o_dev, 0x0000, 5, &flags, 4);
i2o_parm_field_get(i2o_dev, 0x0000, 6, &status, 4); i2o_parm_field_get(i2o_dev, 0x0000, 6, &status, 4);
...@@ -1131,6 +1059,9 @@ static int i2o_block_probe(struct device *dev) ...@@ -1131,6 +1059,9 @@ static int i2o_block_probe(struct device *dev)
unit++; unit++;
osm_info("device added (TID: %03x): %s\n", i2o_dev->lct_data.tid,
i2o_blk_dev->gd->disk_name);
return 0; return 0;
claim_release: claim_release:
......
...@@ -74,7 +74,7 @@ struct i2o_block_device { ...@@ -74,7 +74,7 @@ struct i2o_block_device {
int rcache; /* read cache flags */ int rcache; /* read cache flags */
int wcache; /* write cache flags */ int wcache; /* write cache flags */
int flags; int flags;
int power; /* power state */ u16 power; /* power state */
int media_change_flag; /* media changed flag */ int media_change_flag; /* media changed flag */
}; };
......
...@@ -80,13 +80,123 @@ struct i2o_cfg_info { ...@@ -80,13 +80,123 @@ struct i2o_cfg_info {
static struct i2o_cfg_info *open_files = NULL; static struct i2o_cfg_info *open_files = NULL;
static ulong i2o_cfg_info_id = 0; static ulong i2o_cfg_info_id = 0;
/* /**
* Each of these describes an i2o message handler. They are * i2o_config_read_hrt - Returns the HRT of the controller
* multiplexed by the i2o_core code * @kob: kernel object handle
* @buf: buffer into which the HRT should be copied
* @off: file offset
* @count: number of bytes to read
*
* Put @count bytes starting at @off into @buf from the HRT of the I2O
* controller corresponding to @kobj.
*
* Returns number of bytes copied into buffer.
*/
static ssize_t i2o_config_read_hrt(struct kobject *kobj, char *buf,
loff_t offset, size_t count)
{
struct i2o_controller *c = to_i2o_controller(container_of(kobj,
struct device,
kobj));
i2o_hrt *hrt = c->hrt.virt;
u32 size = (hrt->num_entries * hrt->entry_len + 2) * 4;
if(offset > size)
return 0;
if(offset + count > size)
count = size - offset;
memcpy(buf, (u8 *) hrt + offset, count);
return count;
};
/**
* i2o_config_read_lct - Returns the LCT of the controller
* @kob: kernel object handle
* @buf: buffer into which the LCT should be copied
* @off: file offset
* @count: number of bytes to read
*
* Put @count bytes starting at @off into @buf from the LCT of the I2O
* controller corresponding to @kobj.
*
* Returns number of bytes copied into buffer.
*/
static ssize_t i2o_config_read_lct(struct kobject *kobj, char *buf,
loff_t offset, size_t count)
{
struct i2o_controller *c = to_i2o_controller(container_of(kobj,
struct device,
kobj));
u32 size = c->lct->table_size * 4;
if(offset > size)
return 0;
if(offset + count > size)
count = size - offset;
memcpy(buf, (u8 *) c->lct + offset, count);
return count;
};
/* attribute for HRT in sysfs */
static struct bin_attribute i2o_config_hrt_attr = {
.attr = {
.name = "hrt",
.mode = S_IRUGO,
.owner = THIS_MODULE
},
.size = 0,
.read = i2o_config_read_hrt
};
/* attribute for LCT in sysfs */
static struct bin_attribute i2o_config_lct_attr = {
.attr = {
.name = "lct",
.mode = S_IRUGO,
.owner = THIS_MODULE
},
.size = 0,
.read = i2o_config_read_lct
};
/**
* i2o_config_notify_controller_add - Notify of added controller
* @c: the controller which was added
*
* If a I2O controller is added, we catch the notification to add sysfs
* entries.
*/ */
static void i2o_config_notify_controller_add(struct i2o_controller *c)
{
sysfs_create_bin_file(&(c->device.kobj), &i2o_config_hrt_attr);
sysfs_create_bin_file(&(c->device.kobj), &i2o_config_lct_attr);
};
/**
* i2o_config_notify_controller_remove - Notify of removed controller
* @c: the controller which was removed
*
* If a I2O controller is removed, we catch the notification to remove the
* sysfs entries.
*/
static void i2o_config_notify_controller_remove(struct i2o_controller *c)
{
sysfs_remove_bin_file(&c->device.kobj, &i2o_config_lct_attr);
sysfs_remove_bin_file(&c->device.kobj, &i2o_config_hrt_attr);
};
/* Config OSM driver struct */
static struct i2o_driver i2o_config_driver = { static struct i2o_driver i2o_config_driver = {
.name = OSM_NAME .name = OSM_NAME,
.notify_controller_add = i2o_config_notify_controller_add,
.notify_controller_remove = i2o_config_notify_controller_remove
}; };
static int i2o_cfg_getiops(unsigned long arg) static int i2o_cfg_getiops(unsigned long arg)
......
...@@ -40,6 +40,7 @@ ...@@ -40,6 +40,7 @@
* Fix the resource management problems. * Fix the resource management problems.
*/ */
#define DEBUG 1
#include <linux/module.h> #include <linux/module.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/types.h> #include <linux/types.h>
...@@ -179,6 +180,8 @@ static int i2o_scsi_remove(struct device *dev) ...@@ -179,6 +180,8 @@ static int i2o_scsi_remove(struct device *dev)
struct i2o_scsi_host *i2o_shost; struct i2o_scsi_host *i2o_shost;
struct scsi_device *scsi_dev; struct scsi_device *scsi_dev;
osm_info("device removed (TID: %03x)\n", i2o_dev->lct_data.tid);
i2o_shost = i2o_scsi_get_host(c); i2o_shost = i2o_scsi_get_host(c);
shost_for_each_device(scsi_dev, i2o_shost->scsi_host) shost_for_each_device(scsi_dev, i2o_shost->scsi_host)
...@@ -262,7 +265,7 @@ static int i2o_scsi_probe(struct device *dev) ...@@ -262,7 +265,7 @@ static int i2o_scsi_probe(struct device *dev)
return -EFAULT; return -EFAULT;
} }
osm_debug("added new SCSI device %03x (cannel: %d, id: %d, lun: %d)\n", osm_info("device added (TID: %03x) channel: %d, id: %d, lun: %d\n",
i2o_dev->lct_data.tid, channel, id, (unsigned int)lun); i2o_dev->lct_data.tid, channel, id, (unsigned int)lun);
return 0; return 0;
...@@ -439,8 +442,6 @@ static int i2o_scsi_reply(struct i2o_controller *c, u32 m, ...@@ -439,8 +442,6 @@ static int i2o_scsi_reply(struct i2o_controller *c, u32 m,
cmd->result = DID_OK << 16 | ds; cmd->result = DID_OK << 16 | ds;
cmd->scsi_done(cmd);
dev = &c->pdev->dev; dev = &c->pdev->dev;
if (cmd->use_sg) if (cmd->use_sg)
dma_unmap_sg(dev, (struct scatterlist *)cmd->buffer, dma_unmap_sg(dev, (struct scatterlist *)cmd->buffer,
...@@ -449,6 +450,8 @@ static int i2o_scsi_reply(struct i2o_controller *c, u32 m, ...@@ -449,6 +450,8 @@ static int i2o_scsi_reply(struct i2o_controller *c, u32 m,
dma_unmap_single(dev, (dma_addr_t) ((long)cmd->SCp.ptr), dma_unmap_single(dev, (dma_addr_t) ((long)cmd->SCp.ptr),
cmd->request_bufflen, cmd->sc_data_direction); cmd->request_bufflen, cmd->sc_data_direction);
cmd->scsi_done(cmd);
return 1; return 1;
}; };
...@@ -502,7 +505,7 @@ static void i2o_scsi_notify_controller_remove(struct i2o_controller *c) ...@@ -502,7 +505,7 @@ static void i2o_scsi_notify_controller_remove(struct i2o_controller *c)
scsi_remove_host(i2o_shost->scsi_host); scsi_remove_host(i2o_shost->scsi_host);
scsi_host_put(i2o_shost->scsi_host); scsi_host_put(i2o_shost->scsi_host);
pr_info("I2O SCSI host removed\n"); osm_debug("I2O SCSI host removed\n");
}; };
/* SCSI OSM driver struct */ /* SCSI OSM driver struct */
...@@ -545,7 +548,7 @@ static int i2o_scsi_queuecommand(struct scsi_cmnd *SCpnt, ...@@ -545,7 +548,7 @@ static int i2o_scsi_queuecommand(struct scsi_cmnd *SCpnt,
u32 scsi_flags, sg_flags; u32 scsi_flags, sg_flags;
u32 __iomem *mptr; u32 __iomem *mptr;
u32 __iomem *lenptr; u32 __iomem *lenptr;
u32 len, reqlen; u32 len;
int i; int i;
/* /*
...@@ -580,12 +583,12 @@ static int i2o_scsi_queuecommand(struct scsi_cmnd *SCpnt, ...@@ -580,12 +583,12 @@ static int i2o_scsi_queuecommand(struct scsi_cmnd *SCpnt,
if (m == I2O_QUEUE_EMPTY) if (m == I2O_QUEUE_EMPTY)
return SCSI_MLQUEUE_HOST_BUSY; return SCSI_MLQUEUE_HOST_BUSY;
mptr = &msg->body[0];
/* /*
* Put together a scsi execscb message * Put together a scsi execscb message
*/ */
len = SCpnt->request_bufflen;
switch (SCpnt->sc_data_direction) { switch (SCpnt->sc_data_direction) {
case PCI_DMA_NONE: case PCI_DMA_NONE:
scsi_flags = 0x00000000; // DATA NO XFER scsi_flags = 0x00000000; // DATA NO XFER
...@@ -637,17 +640,13 @@ static int i2o_scsi_queuecommand(struct scsi_cmnd *SCpnt, ...@@ -637,17 +640,13 @@ static int i2o_scsi_queuecommand(struct scsi_cmnd *SCpnt,
*/ */
/* Direction, disconnect ok, tag, CDBLen */ /* Direction, disconnect ok, tag, CDBLen */
writel(scsi_flags | 0x20200000 | SCpnt->cmd_len, &msg->body[0]); writel(scsi_flags | 0x20200000 | SCpnt->cmd_len, mptr ++);
mptr = &msg->body[1];
/* Write SCSI command into the message - always 16 byte block */ /* Write SCSI command into the message - always 16 byte block */
memcpy_toio(mptr, SCpnt->cmnd, 16); memcpy_toio(mptr, SCpnt->cmnd, 16);
mptr += 4; mptr += 4;
lenptr = mptr++; /* Remember me - fill in when we know */ lenptr = mptr++; /* Remember me - fill in when we know */
reqlen = 12; // SINGLE SGE
/* Now fill in the SGList and command */ /* Now fill in the SGList and command */
if (SCpnt->use_sg) { if (SCpnt->use_sg) {
struct scatterlist *sg; struct scatterlist *sg;
...@@ -671,7 +670,6 @@ static int i2o_scsi_queuecommand(struct scsi_cmnd *SCpnt, ...@@ -671,7 +670,6 @@ static int i2o_scsi_queuecommand(struct scsi_cmnd *SCpnt,
sg++; sg++;
} }
reqlen = mptr - &msg->u.head[0];
writel(len, lenptr); writel(len, lenptr);
} else { } else {
len = SCpnt->request_bufflen; len = SCpnt->request_bufflen;
...@@ -691,12 +689,11 @@ static int i2o_scsi_queuecommand(struct scsi_cmnd *SCpnt, ...@@ -691,12 +689,11 @@ static int i2o_scsi_queuecommand(struct scsi_cmnd *SCpnt,
sg_flags |= 0xC0000000; sg_flags |= 0xC0000000;
writel(sg_flags | SCpnt->request_bufflen, mptr++); writel(sg_flags | SCpnt->request_bufflen, mptr++);
writel(dma_addr, mptr++); writel(dma_addr, mptr++);
} else }
reqlen = 9;
} }
/* Stick the headers on */ /* Stick the headers on */
writel(reqlen << 16 | SGL_OFFSET_10, &msg->u.head[0]); writel((mptr - &msg->u.head[0]) << 16 | SGL_OFFSET_10, &msg->u.head[0]);
/* Queue the message */ /* Queue the message */
i2o_msg_post(c, m); i2o_msg_post(c, m);
......
...@@ -68,7 +68,7 @@ extern void i2o_device_exit(void); ...@@ -68,7 +68,7 @@ extern void i2o_device_exit(void);
*/ */
void i2o_msg_nop(struct i2o_controller *c, u32 m) void i2o_msg_nop(struct i2o_controller *c, u32 m)
{ {
struct i2o_message __iomem *msg = c->in_queue.virt + m; struct i2o_message __iomem *msg = i2o_msg_in_to_virt(c, m);
writel(THREE_WORD_MSG_SIZE | SGL_OFFSET_0, &msg->u.head[0]); writel(THREE_WORD_MSG_SIZE | SGL_OFFSET_0, &msg->u.head[0]);
writel(I2O_CMD_UTIL_NOP << 24 | HOST_TID << 12 | ADAPTER_TID, writel(I2O_CMD_UTIL_NOP << 24 | HOST_TID << 12 | ADAPTER_TID,
...@@ -452,8 +452,6 @@ static int i2o_iop_clear(struct i2o_controller *c) ...@@ -452,8 +452,6 @@ static int i2o_iop_clear(struct i2o_controller *c)
/* Enable all IOPs */ /* Enable all IOPs */
i2o_iop_enable_all(); i2o_iop_enable_all();
i2o_status_get(c);
return rc; return rc;
} }
...@@ -591,12 +589,11 @@ static int i2o_iop_init_outbound_queue(struct i2o_controller *c) ...@@ -591,12 +589,11 @@ static int i2o_iop_init_outbound_queue(struct i2o_controller *c)
if (m == I2O_QUEUE_EMPTY) if (m == I2O_QUEUE_EMPTY)
return -ETIMEDOUT; return -ETIMEDOUT;
writel(EIGHT_WORD_MSG_SIZE | TRL_OFFSET_6, &msg->u.head[0]); writel(EIGHT_WORD_MSG_SIZE | SGL_OFFSET_6, &msg->u.head[0]);
writel(I2O_CMD_OUTBOUND_INIT << 24 | HOST_TID << 12 | ADAPTER_TID, writel(I2O_CMD_OUTBOUND_INIT << 24 | HOST_TID << 12 | ADAPTER_TID,
&msg->u.head[1]); &msg->u.head[1]);
writel(i2o_exec_driver.context, &msg->u.s.icntxt); writel(i2o_exec_driver.context, &msg->u.s.icntxt);
writel(0x0106, &msg->u.s.tcntxt); /* FIXME: why 0x0106, maybe in writel(0x00000000, &msg->u.s.tcntxt);
Spec? */
writel(PAGE_SIZE, &msg->body[0]); writel(PAGE_SIZE, &msg->body[0]);
writel(MSG_FRAME_SIZE << 16 | 0x80, &msg->body[1]); /* Outbound msg frame writel(MSG_FRAME_SIZE << 16 | 0x80, &msg->body[1]); /* Outbound msg frame
size in words and Initcode */ size in words and Initcode */
...@@ -891,8 +888,12 @@ void i2o_iop_remove(struct i2o_controller *c) ...@@ -891,8 +888,12 @@ void i2o_iop_remove(struct i2o_controller *c)
list_for_each_entry_safe(dev, tmp, &c->devices, list) list_for_each_entry_safe(dev, tmp, &c->devices, list)
i2o_device_remove(dev); i2o_device_remove(dev);
device_del(&c->device);
/* Ask the IOP to switch to RESET state */ /* Ask the IOP to switch to RESET state */
i2o_iop_reset(c); i2o_iop_reset(c);
put_device(&c->device);
} }
/** /**
...@@ -971,8 +972,10 @@ static int i2o_systab_build(void) ...@@ -971,8 +972,10 @@ static int i2o_systab_build(void)
systab->iops[count].frame_size = sb->inbound_frame_size; systab->iops[count].frame_size = sb->inbound_frame_size;
systab->iops[count].last_changed = change_ind; systab->iops[count].last_changed = change_ind;
systab->iops[count].iop_capabilities = sb->iop_capabilities; systab->iops[count].iop_capabilities = sb->iop_capabilities;
systab->iops[count].inbound_low = i2o_ptr_low(c->post_port); systab->iops[count].inbound_low =
systab->iops[count].inbound_high = i2o_ptr_high(c->post_port); i2o_dma_low(c->base.phys + I2O_IN_PORT);
systab->iops[count].inbound_high =
i2o_dma_high(c->base.phys + I2O_IN_PORT);
count++; count++;
} }
...@@ -1109,6 +1112,30 @@ static int i2o_hrt_get(struct i2o_controller *c) ...@@ -1109,6 +1112,30 @@ static int i2o_hrt_get(struct i2o_controller *c)
return -EBUSY; return -EBUSY;
} }
/**
* i2o_iop_free - Free the i2o_controller struct
* @c: I2O controller to free
*/
void i2o_iop_free(struct i2o_controller *c)
{
kfree(c);
};
/**
* i2o_iop_release - release the memory for a I2O controller
* @dev: I2O controller which should be released
*
* Release the allocated memory. This function is called if refcount of
* device reaches 0 automatically.
*/
static void i2o_iop_release(struct device *dev)
{
struct i2o_controller *c = to_i2o_controller(dev);
i2o_iop_free(c);
};
/** /**
* i2o_iop_alloc - Allocate and initialize a i2o_controller struct * i2o_iop_alloc - Allocate and initialize a i2o_controller struct
* *
...@@ -1137,6 +1164,10 @@ struct i2o_controller *i2o_iop_alloc(void) ...@@ -1137,6 +1164,10 @@ struct i2o_controller *i2o_iop_alloc(void)
c->unit = unit++; c->unit = unit++;
sprintf(c->name, "iop%d", c->unit); sprintf(c->name, "iop%d", c->unit);
device_initialize(&c->device);
c->device.release = &i2o_iop_release;
snprintf(c->device.bus_id, BUS_ID_SIZE, "iop%d", c->unit);
#if BITS_PER_LONG == 64 #if BITS_PER_LONG == 64
spin_lock_init(&c->context_list_lock); spin_lock_init(&c->context_list_lock);
atomic_set(&c->context_list_counter, 0); atomic_set(&c->context_list_counter, 0);
...@@ -1146,15 +1177,6 @@ struct i2o_controller *i2o_iop_alloc(void) ...@@ -1146,15 +1177,6 @@ struct i2o_controller *i2o_iop_alloc(void)
return c; return c;
}; };
/**
* i2o_iop_free - Free the i2o_controller struct
* @c: I2O controller to free
*/
void i2o_iop_free(struct i2o_controller *c)
{
kfree(c);
};
/** /**
* i2o_iop_add - Initialize the I2O controller and add him to the I2O core * i2o_iop_add - Initialize the I2O controller and add him to the I2O core
* @c: controller * @c: controller
...@@ -1168,6 +1190,11 @@ int i2o_iop_add(struct i2o_controller *c) ...@@ -1168,6 +1190,11 @@ int i2o_iop_add(struct i2o_controller *c)
{ {
int rc; int rc;
if((rc = device_add(&c->device))) {
printk(KERN_ERR "%s: could not register controller\n", c->name);
goto iop_reset;
}
printk(KERN_INFO "%s: Activating I2O controller...\n", c->name); printk(KERN_INFO "%s: Activating I2O controller...\n", c->name);
printk(KERN_INFO "%s: This may take a few minutes if there are many " printk(KERN_INFO "%s: This may take a few minutes if there are many "
"devices\n", c->name); "devices\n", c->name);
...@@ -1175,30 +1202,23 @@ int i2o_iop_add(struct i2o_controller *c) ...@@ -1175,30 +1202,23 @@ int i2o_iop_add(struct i2o_controller *c)
if ((rc = i2o_iop_activate(c))) { if ((rc = i2o_iop_activate(c))) {
printk(KERN_ERR "%s: could not activate controller\n", printk(KERN_ERR "%s: could not activate controller\n",
c->name); c->name);
i2o_iop_reset(c); goto iop_reset;
return rc;
} }
pr_debug("%s: building sys table...\n", c->name); pr_debug("%s: building sys table...\n", c->name);
if ((rc = i2o_systab_build())) { if ((rc = i2o_systab_build()))
i2o_iop_reset(c); goto iop_reset;
return rc;
}
pr_debug("%s: online controller...\n", c->name); pr_debug("%s: online controller...\n", c->name);
if ((rc = i2o_iop_online(c))) { if ((rc = i2o_iop_online(c)))
i2o_iop_reset(c); goto iop_reset;
return rc;
}
pr_debug("%s: getting LCT...\n", c->name); pr_debug("%s: getting LCT...\n", c->name);
if ((rc = i2o_exec_lct_get(c))) { if ((rc = i2o_exec_lct_get(c)))
i2o_iop_reset(c); goto iop_reset;
return rc;
}
list_add(&c->list, &i2o_controllers); list_add(&c->list, &i2o_controllers);
...@@ -1207,6 +1227,11 @@ int i2o_iop_add(struct i2o_controller *c) ...@@ -1207,6 +1227,11 @@ int i2o_iop_add(struct i2o_controller *c)
printk(KERN_INFO "%s: Controller added\n", c->name); printk(KERN_INFO "%s: Controller added\n", c->name);
return 0; return 0;
iop_reset:
i2o_iop_reset(c);
return rc;
}; };
/** /**
......
...@@ -38,8 +38,7 @@ extern void i2o_iop_free(struct i2o_controller *); ...@@ -38,8 +38,7 @@ extern void i2o_iop_free(struct i2o_controller *);
extern int i2o_iop_add(struct i2o_controller *); extern int i2o_iop_add(struct i2o_controller *);
extern void i2o_iop_remove(struct i2o_controller *); extern void i2o_iop_remove(struct i2o_controller *);
extern int i2o_driver_dispatch(struct i2o_controller *, u32, extern int i2o_driver_dispatch(struct i2o_controller *, u32);
struct i2o_message *);
/* PCI device id table for all I2O controllers */ /* PCI device id table for all I2O controllers */
static struct pci_device_id __devinitdata i2o_pci_ids[] = { static struct pci_device_id __devinitdata i2o_pci_ids[] = {
...@@ -89,7 +88,6 @@ static void i2o_pci_free(struct i2o_controller *c) ...@@ -89,7 +88,6 @@ static void i2o_pci_free(struct i2o_controller *c)
i2o_dma_free(dev, &c->out_queue); i2o_dma_free(dev, &c->out_queue);
i2o_dma_free(dev, &c->status_block); i2o_dma_free(dev, &c->status_block);
if (c->lct)
kfree(c->lct); kfree(c->lct);
i2o_dma_free(dev, &c->dlct); i2o_dma_free(dev, &c->dlct);
i2o_dma_free(dev, &c->hrt); i2o_dma_free(dev, &c->hrt);
...@@ -187,9 +185,9 @@ static int __devinit i2o_pci_alloc(struct i2o_controller *c) ...@@ -187,9 +185,9 @@ static int __devinit i2o_pci_alloc(struct i2o_controller *c)
} else } else
c->in_queue = c->base; c->in_queue = c->base;
c->irq_mask = c->base.virt + 0x34; c->irq_mask = c->base.virt + I2O_IRQ_MASK;
c->post_port = c->base.virt + 0x40; c->in_port = c->base.virt + I2O_IN_PORT;
c->reply_port = c->base.virt + 0x44; c->out_port = c->base.virt + I2O_OUT_PORT;
if (i2o_dma_alloc(dev, &c->status, 8, GFP_KERNEL)) { if (i2o_dma_alloc(dev, &c->status, 8, GFP_KERNEL)) {
i2o_pci_free(c); i2o_pci_free(c);
...@@ -235,49 +233,34 @@ static irqreturn_t i2o_pci_interrupt(int irq, void *dev_id, struct pt_regs *r) ...@@ -235,49 +233,34 @@ static irqreturn_t i2o_pci_interrupt(int irq, void *dev_id, struct pt_regs *r)
{ {
struct i2o_controller *c = dev_id; struct i2o_controller *c = dev_id;
struct device *dev = &c->pdev->dev; struct device *dev = &c->pdev->dev;
struct i2o_message *m; u32 mv = readl(c->out_port);
u32 mv;
/* /*
* Old 960 steppings had a bug in the I2O unit that caused * Old 960 steppings had a bug in the I2O unit that caused
* the queue to appear empty when it wasn't. * the queue to appear empty when it wasn't.
*/ */
mv = I2O_REPLY_READ32(c);
if (mv == I2O_QUEUE_EMPTY) { if (mv == I2O_QUEUE_EMPTY) {
mv = I2O_REPLY_READ32(c); mv = readl(c->out_port);
if (unlikely(mv == I2O_QUEUE_EMPTY)) { if (unlikely(mv == I2O_QUEUE_EMPTY))
return IRQ_NONE; return IRQ_NONE;
} else else
pr_debug("%s: 960 bug detected\n", c->name); pr_debug("%s: 960 bug detected\n", c->name);
} }
while (mv != I2O_QUEUE_EMPTY) { while (mv != I2O_QUEUE_EMPTY) {
/*
* Map the message from the page frame map to kernel virtual.
* Because bus_to_virt is deprecated, we have calculate the
* location by ourself!
*/
m = i2o_msg_out_to_virt(c, mv);
/*
* Ensure this message is seen coherently but cachably by
* the processor
*/
dma_sync_single_for_cpu(dev, mv, MSG_FRAME_SIZE * 4,
PCI_DMA_FROMDEVICE);
/* dispatch it */ /* dispatch it */
if (i2o_driver_dispatch(c, mv, m)) if (i2o_driver_dispatch(c, mv))
/* flush it if result != 0 */ /* flush it if result != 0 */
i2o_flush_reply(c, mv); i2o_flush_reply(c, mv);
/* /*
* That 960 bug again... * That 960 bug again...
*/ */
mv = I2O_REPLY_READ32(c); mv = readl(c->out_port);
if (mv == I2O_QUEUE_EMPTY) if (mv == I2O_QUEUE_EMPTY)
mv = I2O_REPLY_READ32(c); mv = readl(c->out_port);
} }
return IRQ_HANDLED; return IRQ_HANDLED;
} }
...@@ -294,7 +277,9 @@ static int i2o_pci_irq_enable(struct i2o_controller *c) ...@@ -294,7 +277,9 @@ static int i2o_pci_irq_enable(struct i2o_controller *c)
struct pci_dev *pdev = c->pdev; struct pci_dev *pdev = c->pdev;
int rc; int rc;
I2O_IRQ_WRITE32(c, 0xffffffff); wmb();
writel(0xffffffff, c->irq_mask);
wmb();
if (pdev->irq) { if (pdev->irq) {
rc = request_irq(pdev->irq, i2o_pci_interrupt, SA_SHIRQ, rc = request_irq(pdev->irq, i2o_pci_interrupt, SA_SHIRQ,
...@@ -306,7 +291,8 @@ static int i2o_pci_irq_enable(struct i2o_controller *c) ...@@ -306,7 +291,8 @@ static int i2o_pci_irq_enable(struct i2o_controller *c)
} }
} }
I2O_IRQ_WRITE32(c, 0x00000000); writel(0x00000000, c->irq_mask);
wmb();
printk(KERN_INFO "%s: Installed at IRQ %d\n", c->name, pdev->irq); printk(KERN_INFO "%s: Installed at IRQ %d\n", c->name, pdev->irq);
...@@ -321,7 +307,9 @@ static int i2o_pci_irq_enable(struct i2o_controller *c) ...@@ -321,7 +307,9 @@ static int i2o_pci_irq_enable(struct i2o_controller *c)
*/ */
static void i2o_pci_irq_disable(struct i2o_controller *c) static void i2o_pci_irq_disable(struct i2o_controller *c)
{ {
I2O_IRQ_WRITE32(c, 0xffffffff); wmb();
writel(0xffffffff, c->irq_mask);
wmb();
if (c->pdev->irq > 0) if (c->pdev->irq > 0)
free_irq(c->pdev->irq, c); free_irq(c->pdev->irq, c);
...@@ -379,7 +367,7 @@ static int __devinit i2o_pci_probe(struct pci_dev *pdev, ...@@ -379,7 +367,7 @@ static int __devinit i2o_pci_probe(struct pci_dev *pdev,
pci_name(pdev)); pci_name(pdev));
c->pdev = pdev; c->pdev = pdev;
c->device = pdev->dev; c->device.parent = get_device(&pdev->dev);
/* Cards that fall apart if you hit them with large I/O loads... */ /* Cards that fall apart if you hit them with large I/O loads... */
if (pdev->vendor == PCI_VENDOR_ID_NCR && pdev->device == 0x0630) { if (pdev->vendor == PCI_VENDOR_ID_NCR && pdev->device == 0x0630) {
...@@ -428,6 +416,8 @@ static int __devinit i2o_pci_probe(struct pci_dev *pdev, ...@@ -428,6 +416,8 @@ static int __devinit i2o_pci_probe(struct pci_dev *pdev,
if (i960) if (i960)
pci_write_config_word(i960, 0x42, 0x03ff); pci_write_config_word(i960, 0x42, 0x03ff);
get_device(&c->device);
return 0; return 0;
uninstall: uninstall:
...@@ -438,6 +428,7 @@ static int __devinit i2o_pci_probe(struct pci_dev *pdev, ...@@ -438,6 +428,7 @@ static int __devinit i2o_pci_probe(struct pci_dev *pdev,
free_controller: free_controller:
i2o_iop_free(c); i2o_iop_free(c);
put_device(c->device.parent);
disable: disable:
pci_disable_device(pdev); pci_disable_device(pdev);
...@@ -461,15 +452,17 @@ static void __devexit i2o_pci_remove(struct pci_dev *pdev) ...@@ -461,15 +452,17 @@ static void __devexit i2o_pci_remove(struct pci_dev *pdev)
i2o_pci_irq_disable(c); i2o_pci_irq_disable(c);
i2o_pci_free(c); i2o_pci_free(c);
pci_disable_device(pdev);
printk(KERN_INFO "%s: Controller removed.\n", c->name); printk(KERN_INFO "%s: Controller removed.\n", c->name);
i2o_iop_free(c); put_device(c->device.parent);
pci_disable_device(pdev); put_device(&c->device);
}; };
/* PCI driver for I2O controller */ /* PCI driver for I2O controller */
static struct pci_driver i2o_pci_driver = { static struct pci_driver i2o_pci_driver = {
.name = "I2O controller", .name = "PCI_I2O",
.id_table = i2o_pci_ids, .id_table = i2o_pci_ids,
.probe = i2o_pci_probe, .probe = i2o_pci_probe,
.remove = __devexit_p(i2o_pci_remove), .remove = __devexit_p(i2o_pci_remove),
......
...@@ -153,12 +153,10 @@ struct i2o_controller { ...@@ -153,12 +153,10 @@ struct i2o_controller {
unsigned int promise:1; /* Promise controller */ unsigned int promise:1; /* Promise controller */
struct list_head devices; /* list of I2O devices */ struct list_head devices; /* list of I2O devices */
struct notifier_block *event_notifer; /* Events */
atomic_t users;
struct list_head list; /* Controller list */ struct list_head list; /* Controller list */
void __iomem *post_port; /* Inbout port address */
void __iomem *reply_port; /* Outbound port address */ void __iomem *in_port; /* Inbout port address */
void __iomem *out_port; /* Outbound port address */
void __iomem *irq_mask; /* Interrupt register address */ void __iomem *irq_mask; /* Interrupt register address */
/* Dynamic LCT related data */ /* Dynamic LCT related data */
...@@ -182,9 +180,6 @@ struct i2o_controller { ...@@ -182,9 +180,6 @@ struct i2o_controller {
struct resource io_resource; /* I/O resource allocated to the IOP */ struct resource io_resource; /* I/O resource allocated to the IOP */
struct resource mem_resource; /* Mem resource allocated to the IOP */ struct resource mem_resource; /* Mem resource allocated to the IOP */
struct proc_dir_entry *proc_entry; /* /proc dir */
struct list_head bus_list; /* list of busses on IOP */
struct device device; struct device device;
struct i2o_device *exec; /* Executive */ struct i2o_device *exec; /* Executive */
#if BITS_PER_LONG == 64 #if BITS_PER_LONG == 64
...@@ -380,49 +375,10 @@ extern int i2o_device_claim_release(struct i2o_device *); ...@@ -380,49 +375,10 @@ extern int i2o_device_claim_release(struct i2o_device *);
/* Exec OSM functions */ /* Exec OSM functions */
extern int i2o_exec_lct_get(struct i2o_controller *); extern int i2o_exec_lct_get(struct i2o_controller *);
/* device to i2o_device and driver to i2o_driver convertion functions */ /* device / driver conversion functions */
#define to_i2o_driver(drv) container_of(drv,struct i2o_driver, driver) #define to_i2o_driver(drv) container_of(drv,struct i2o_driver, driver)
#define to_i2o_device(dev) container_of(dev, struct i2o_device, device) #define to_i2o_device(dev) container_of(dev, struct i2o_device, device)
#define to_i2o_controller(dev) container_of(dev, struct i2o_controller, device)
/*
* Messenger inlines
*/
static inline u32 I2O_POST_READ32(struct i2o_controller *c)
{
rmb();
return readl(c->post_port);
};
static inline void I2O_POST_WRITE32(struct i2o_controller *c, u32 val)
{
wmb();
writel(val, c->post_port);
};
static inline u32 I2O_REPLY_READ32(struct i2o_controller *c)
{
rmb();
return readl(c->reply_port);
};
static inline void I2O_REPLY_WRITE32(struct i2o_controller *c, u32 val)
{
wmb();
writel(val, c->reply_port);
};
static inline u32 I2O_IRQ_READ32(struct i2o_controller *c)
{
rmb();
return readl(c->irq_mask);
};
static inline void I2O_IRQ_WRITE32(struct i2o_controller *c, u32 val)
{
wmb();
writel(val, c->irq_mask);
wmb();
};
/** /**
* i2o_msg_get - obtain an I2O message from the IOP * i2o_msg_get - obtain an I2O message from the IOP
...@@ -440,10 +396,12 @@ static inline void I2O_IRQ_WRITE32(struct i2o_controller *c, u32 val) ...@@ -440,10 +396,12 @@ static inline void I2O_IRQ_WRITE32(struct i2o_controller *c, u32 val)
static inline u32 i2o_msg_get(struct i2o_controller *c, static inline u32 i2o_msg_get(struct i2o_controller *c,
struct i2o_message __iomem **msg) struct i2o_message __iomem **msg)
{ {
u32 m; u32 m = readl(c->in_port);
if ((m = I2O_POST_READ32(c)) != I2O_QUEUE_EMPTY) if (m != I2O_QUEUE_EMPTY) {
*msg = c->in_queue.virt + m; *msg = c->in_queue.virt + m;
rmb();
}
return m; return m;
}; };
...@@ -457,7 +415,8 @@ static inline u32 i2o_msg_get(struct i2o_controller *c, ...@@ -457,7 +415,8 @@ static inline u32 i2o_msg_get(struct i2o_controller *c,
*/ */
static inline void i2o_msg_post(struct i2o_controller *c, u32 m) static inline void i2o_msg_post(struct i2o_controller *c, u32 m)
{ {
I2O_POST_WRITE32(c, m); wmb();
writel(m, c->in_port);
}; };
/** /**
...@@ -486,12 +445,10 @@ static inline int i2o_msg_post_wait(struct i2o_controller *c, u32 m, ...@@ -486,12 +445,10 @@ static inline int i2o_msg_post_wait(struct i2o_controller *c, u32 m,
* The I2O controller must be informed that the reply message is not needed * The I2O controller must be informed that the reply message is not needed
* anymore. If you forget to flush the reply, the message frame can't be * anymore. If you forget to flush the reply, the message frame can't be
* used by the controller anymore and is therefore lost. * used by the controller anymore and is therefore lost.
*
* FIXME: is there a timeout after which the controller reuse the message?
*/ */
static inline void i2o_flush_reply(struct i2o_controller *c, u32 m) static inline void i2o_flush_reply(struct i2o_controller *c, u32 m)
{ {
I2O_REPLY_WRITE32(c, m); writel(m, c->out_port);
}; };
/** /**
...@@ -505,7 +462,8 @@ static inline void i2o_flush_reply(struct i2o_controller *c, u32 m) ...@@ -505,7 +462,8 @@ static inline void i2o_flush_reply(struct i2o_controller *c, u32 m)
* work for sender side messages as they are ioremap objects * work for sender side messages as they are ioremap objects
* provided by the I2O controller. * provided by the I2O controller.
*/ */
static inline struct i2o_message *i2o_msg_out_to_virt(struct i2o_controller *c, static inline struct i2o_message __iomem *i2o_msg_out_to_virt(struct
i2o_controller *c,
u32 m) u32 m)
{ {
BUG_ON(m < c->out_queue.phys BUG_ON(m < c->out_queue.phys
...@@ -917,7 +875,7 @@ extern void i2o_debug_state(struct i2o_controller *c); ...@@ -917,7 +875,7 @@ extern void i2o_debug_state(struct i2o_controller *c);
#define I2OVER15 0x0001 #define I2OVER15 0x0001
#define I2OVER20 0x0002 #define I2OVER20 0x0002
/* Default is 1.5, FIXME: Need support for both 1.5 and 2.0 */ /* Default is 1.5 */
#define I2OVERSION I2OVER15 #define I2OVERSION I2OVER15
#define SGL_OFFSET_0 I2OVERSION #define SGL_OFFSET_0 I2OVERSION
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment