[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: Markus Lidel <Markus.Lidel@shadowconnect.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
This commit is contained in:
Markus Lidel 2005-06-23 22:02:14 -07:00 committed by Linus Torvalds
parent 61fbfa8129
commit f88e119c4b
10 changed files with 359 additions and 339 deletions

View file

@ -282,8 +282,7 @@ int i2o_device_parse_lct(struct i2o_controller *c)
down(&c->lct_lock);
if (c->lct)
kfree(c->lct);
kfree(c->lct);
lct = c->dlct.virt;
@ -447,8 +446,8 @@ static struct class_interface i2o_device_class_interface = {
* ResultCount, ErrorInfoSize, BlockStatus and BlockSize.
*/
int i2o_parm_issue(struct i2o_device *i2o_dev, int cmd, void *oplist,
int oplen, void *reslist, int reslen)
static int i2o_parm_issue(struct i2o_device *i2o_dev, int cmd, void *oplist,
int oplen, void *reslist, int reslen)
{
struct i2o_message __iomem *msg;
u32 m;
@ -540,7 +539,7 @@ int i2o_parm_field_get(struct i2o_device *i2o_dev, int group, int field,
opblk[4] = -1;
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 */

View file

@ -18,7 +18,7 @@
#include <linux/rwsem.h>
#include <linux/i2o.h>
#define OSM_NAME "core"
#define OSM_NAME "i2o"
/* max_drivers - Maximum I2O drivers (OSMs) which could be registered */
unsigned int i2o_max_drivers = I2O_MAX_DRIVERS;
@ -78,17 +78,16 @@ int i2o_driver_register(struct i2o_driver *drv)
int rc = 0;
unsigned long flags;
pr_debug("i2o: Register driver %s\n", drv->name);
osm_debug("Register driver %s\n", drv->name);
if (drv->event) {
drv->event_queue = create_workqueue(drv->name);
if (!drv->event_queue) {
printk(KERN_ERR "i2o: Could not initialize event queue "
"for driver %s\n", drv->name);
osm_err("Could not initialize event queue for driver "
"%s\n", drv->name);
return -EFAULT;
}
pr_debug("i2o: Event queue initialized for driver %s\n",
drv->name);
osm_debug("Event queue initialized for driver %s\n", drv->name);
} else
drv->event_queue = NULL;
@ -99,8 +98,8 @@ int i2o_driver_register(struct i2o_driver *drv)
for (i = 0; i2o_drivers[i]; i++)
if (i >= i2o_max_drivers) {
printk(KERN_ERR "i2o: too many drivers registered, "
"increase max_drivers\n");
osm_err("too many drivers registered, increase "
"max_drivers\n");
spin_unlock_irqrestore(&i2o_drivers_lock, flags);
return -EFAULT;
}
@ -110,8 +109,7 @@ int i2o_driver_register(struct i2o_driver *drv)
spin_unlock_irqrestore(&i2o_drivers_lock, flags);
pr_debug("i2o: driver %s gets context id %d\n", drv->name,
drv->context);
osm_debug("driver %s gets context id %d\n", drv->name, drv->context);
list_for_each_entry(c, &i2o_controllers, list) {
struct i2o_device *i2o_dev;
@ -141,7 +139,7 @@ void i2o_driver_unregister(struct i2o_driver *drv)
struct i2o_controller *c;
unsigned long flags;
pr_debug("i2o: unregister driver %s\n", drv->name);
osm_debug("unregister driver %s\n", drv->name);
driver_unregister(&drv->driver);
@ -161,7 +159,7 @@ void i2o_driver_unregister(struct i2o_driver *drv)
if (drv->event_queue) {
destroy_workqueue(drv->event_queue);
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)
* on success and if the message should be flushed afterwords. Returns
* negative error code on failure (the message will be flushed too).
*/
int i2o_driver_dispatch(struct i2o_controller *c, u32 m,
struct i2o_message __iomem *msg)
int i2o_driver_dispatch(struct i2o_controller *c, u32 m)
{
struct i2o_driver *drv;
struct i2o_message __iomem *msg = i2o_msg_out_to_virt(c, m);
u32 context = readl(&msg->u.s.icntxt);
if (unlikely(context >= i2o_max_drivers)) {
printk(KERN_WARNING "%s: Spurious reply to unknown driver "
"%d\n", c->name, readl(&msg->u.s.icntxt));
osm_warn("%s: Spurious reply to unknown driver %d\n", c->name,
context);
return -EIO;
}
@ -195,7 +193,8 @@ int i2o_driver_dispatch(struct i2o_controller *c, u32 m,
spin_unlock(&i2o_drivers_lock);
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;
}
@ -207,6 +206,9 @@ int i2o_driver_dispatch(struct i2o_controller *c, u32 m,
osm_debug("event received from device %d\n", tid);
if (!drv->event)
return -EIO;
/* cut of header from message size (in 32-bit words) */
size = (readl(&msg->u.head[0]) >> 16) - 5;
@ -231,8 +233,8 @@ int i2o_driver_dispatch(struct i2o_controller *c, u32 m,
}
if (unlikely(!drv->reply)) {
pr_debug("%s: Reply to driver %s, but no reply function"
" defined!\n", c->name, drv->name);
osm_debug("%s: Reply to driver %s, but no reply function"
" defined!\n", c->name, drv->name);
return -EIO;
}
@ -333,11 +335,11 @@ int __init i2o_driver_init(void)
if ((i2o_max_drivers < 2) || (i2o_max_drivers > 64) ||
((i2o_max_drivers ^ (i2o_max_drivers - 1)) !=
(2 * i2o_max_drivers - 1))) {
printk(KERN_WARNING "i2o: max_drivers set to %d, but must be "
">=2 and <= 64 and a power of 2\n", i2o_max_drivers);
osm_warn("max_drivers set to %d, but must be >=2 and <= 64 and "
"a power of 2\n", 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 =
kmalloc(i2o_max_drivers * sizeof(*i2o_drivers), GFP_KERNEL);

View file

@ -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
* 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
timeout, struct i2o_dma *dma)
@ -116,7 +117,7 @@ int i2o_msg_post_wait_mem(struct i2o_controller *c, u32 m, unsigned long
DECLARE_WAIT_QUEUE_HEAD(wq);
struct i2o_exec_wait *wait;
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;
wait = i2o_exec_wait_alloc();
@ -161,8 +162,7 @@ int i2o_msg_post_wait_mem(struct i2o_controller *c, u32 m, unsigned long
barrier();
if (wait->complete) {
if (readl(&wait->msg->body[0]) >> 24)
rc = readl(&wait->msg->body[0]) & 0xff;
rc = readl(&wait->msg->body[0]) >> 24;
i2o_flush_reply(c, wait->m);
i2o_exec_wait_free(wait);
} else {
@ -187,6 +187,7 @@ int i2o_msg_post_wait_mem(struct i2o_controller *c, u32 m, unsigned long
* @c: I2O controller which answers
* @m: message id
* @msg: pointer to the I2O reply message
* @context: transaction context of request
*
* 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
@ -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.
*/
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;
static spinlock_t lock = SPIN_LOCK_UNLOCKED;
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
@ -251,7 +250,7 @@ static int i2o_msg_post_wait_complete(struct i2o_controller *c, u32 m,
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);
return -1;
@ -321,29 +320,35 @@ static void i2o_exec_lct_modified(struct i2o_controller *c)
* code on failure and if the reply should be flushed.
*/
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
struct i2o_message __iomem *pmsg; /* preserved message */
u32 context;
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;
pm = le32_to_cpu(msg->body[3]);
pm = readl(&msg->body[3]);
pmsg = i2o_msg_in_to_virt(c, pm);
i2o_report_status(KERN_INFO, "i2o_core", msg);
/* Release the preserved msg by resubmitting it as a NOP */
context = readl(&pmsg->u.s.tcntxt);
/* Release the preserved msg */
i2o_msg_nop(c, pm);
} else
context = readl(&msg->u.s.tcntxt);
/* If reply to i2o_post_wait failed, return causes a timeout */
return -1;
}
if (context & 0x80000000)
return i2o_msg_post_wait_complete(c, m, msg, context);
if (le32_to_cpu(msg->u.s.tcntxt) & 0x80000000)
return i2o_msg_post_wait_complete(c, m, msg);
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;
pr_debug("%s: LCT notify received\n", c->name);

View file

@ -104,7 +104,8 @@ static int i2o_block_remove(struct device *dev)
struct i2o_device *i2o_dev = to_i2o_device(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);
@ -399,6 +400,49 @@ static void i2o_block_delayed_request_fn(void *delayed_request)
kfree(dreq);
};
/**
* i2o_block_end_request - Post-processing of completed commands
* @req: request which should be completed
* @uptodate: 1 for success, 0 for I/O error, < 0 for specific error
* @nr_bytes: number of bytes to complete
*
* Mark the request as complete. The lock must not be held when entering.
*
*/
static void i2o_block_end_request(struct request *req, int uptodate,
int nr_bytes)
{
struct i2o_block_request *ireq = req->special;
struct i2o_block_device *dev = ireq->i2o_blk_dev;
request_queue_t *q = dev->gd->queue;
unsigned long flags;
if (end_that_request_chunk(req, uptodate, nr_bytes)) {
int leftover = (req->hard_nr_sectors << 9);
if (blk_pc_request(req))
leftover = req->data_len;
if (end_io_error(uptodate))
end_that_request_chunk(req, 0, leftover);
}
add_disk_randomness(req->rq_disk);
spin_lock_irqsave(q->queue_lock, flags);
end_that_request_last(req);
dev->open_queue_depth--;
list_del(&ireq->queue);
blk_start_queue(q);
spin_unlock_irqrestore(q->queue_lock, flags);
i2o_block_sglist_free(ireq);
i2o_block_request_free(ireq);
};
/**
* i2o_block_reply - Block OSM reply handler.
* @c: I2O controller from which the message arrives
@ -411,60 +455,8 @@ static void i2o_block_delayed_request_fn(void *delayed_request)
static int i2o_block_reply(struct i2o_controller *c, u32 m,
struct i2o_message *msg)
{
struct i2o_block_request *ireq;
struct request *req;
struct i2o_block_device *dev;
struct request_queue *q;
u8 st;
unsigned long flags;
/* FAILed message */
if (unlikely(le32_to_cpu(msg->u.head[0]) & (1 << 13))) {
struct i2o_message *pmsg;
u32 pm;
/*
* FAILed message from controller
* 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 (unlikely(!req)) {
osm_err("NULL reply received!\n");
return -1;
}
ireq = req->special;
dev = ireq->i2o_blk_dev;
q = dev->gd->queue;
req->errors++;
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);
dev->open_queue_depth--;
list_del(&ireq->queue);
blk_start_queue(q);
spin_unlock_irqrestore(q->queue_lock, flags);
/* Now flush the message by making it a NOP */
i2o_msg_nop(c, pm);
return -1;
}
int uptodate = 1;
req = i2o_cntxt_list_get(c, le32_to_cpu(msg->u.s.tcntxt));
if (unlikely(!req)) {
@ -472,61 +464,13 @@ static int i2o_block_reply(struct i2o_controller *c, u32 m,
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
* request in the context.
*/
st = le32_to_cpu(msg->body[0]) >> 24;
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;
if ((le32_to_cpu(msg->body[0]) >> 24) != 0) {
u32 status = le32_to_cpu(msg->body[0]);
/*
* Device not ready means two things. One is that the
* the thing went offline (but not a removal media)
@ -539,40 +483,23 @@ static int i2o_block_reply(struct i2o_controller *c, u32 m,
* Don't stick a supertrak100 into cache aggressive modes
*/
osm_err("block-osm: /dev/%s error: %s", dev->gd->disk_name,
bsa_errors[le32_to_cpu(msg->body[0]) & 0xffff]);
if (le32_to_cpu(msg->body[0]) & 0x00ff0000)
printk(KERN_ERR " - DDM attempted %d retries",
(le32_to_cpu(msg->body[0]) >> 16) & 0x00ff);
printk(KERN_ERR ".\n");
osm_err("%03x error status: %02x, detailed status: %04x\n",
(le32_to_cpu(msg->u.head[1]) >> 12 & 0xfff),
status >> 24, status & 0xffff);
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);
uptodate = 0;
}
end_that_request_last(req);
dev->open_queue_depth--;
list_del(&ireq->queue);
blk_start_queue(q);
spin_unlock_irqrestore(q->queue_lock, flags);
i2o_block_sglist_free(ireq);
i2o_block_request_free(ireq);
} else
osm_err("still remaining chunks\n");
i2o_block_end_request(req, uptodate, le32_to_cpu(msg->body[1]));
return 1;
};
static void i2o_block_event(struct i2o_event *evt)
{
osm_info("block-osm: event received\n");
osm_info("event received\n");
kfree(evt);
};
@ -875,9 +802,7 @@ static int i2o_block_transfer(struct request *req)
sg++;
}
writel(I2O_MESSAGE_SIZE
(((unsigned long)mptr -
(unsigned long)&msg->u.head[0]) >> 2) | SGL_OFFSET_8,
writel(I2O_MESSAGE_SIZE(mptr - &msg->u.head[0]) | SGL_OFFSET_8,
&msg->u.head[0]);
list_add_tail(&ireq->queue, &dev->open_queue);
@ -1048,7 +973,6 @@ static int i2o_block_probe(struct device *dev)
int rc;
u64 size;
u32 blocksize;
u16 power;
u32 flags, status;
int segments;
@ -1058,8 +982,6 @@ static int i2o_block_probe(struct device *dev)
return -ENODEV;
}
osm_info("New device detected (TID: %03x)\n", i2o_dev->lct_data.tid);
if (i2o_device_claim(i2o_dev)) {
osm_warn("Unable to claim device. Installation aborted\n");
rc = -EFAULT;
@ -1111,15 +1033,21 @@ static int i2o_block_probe(struct device *dev)
* Ask for the current media data. If that isn't supported
* then we ask for the device capacity data
*/
if (i2o_parm_field_get(i2o_dev, 0x0004, 1, &blocksize, 4) != 0
|| i2o_parm_field_get(i2o_dev, 0x0004, 0, &size, 8) != 0) {
i2o_parm_field_get(i2o_dev, 0x0000, 3, &blocksize, 4);
i2o_parm_field_get(i2o_dev, 0x0000, 4, &size, 8);
}
osm_debug("blocksize = %d\n", blocksize);
if (!i2o_parm_field_get(i2o_dev, 0x0004, 0, &size, 8))
if (!i2o_parm_field_get(i2o_dev, 0x0000, 4, &size, 8)) {
osm_warn("could not get size of %s\n", gd->disk_name);
size = 0;
}
if (i2o_parm_field_get(i2o_dev, 0x0000, 2, &power, 2))
power = 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;
}
if (!i2o_parm_field_get(i2o_dev, 0x0000, 2, &i2o_blk_dev->power, 2))
i2o_blk_dev->power = 0;
i2o_parm_field_get(i2o_dev, 0x0000, 5, &flags, 4);
i2o_parm_field_get(i2o_dev, 0x0000, 6, &status, 4);
@ -1131,6 +1059,9 @@ static int i2o_block_probe(struct device *dev)
unit++;
osm_info("device added (TID: %03x): %s\n", i2o_dev->lct_data.tid,
i2o_blk_dev->gd->disk_name);
return 0;
claim_release:

View file

@ -74,7 +74,7 @@ struct i2o_block_device {
int rcache; /* read cache flags */
int wcache; /* write cache flags */
int flags;
int power; /* power state */
u16 power; /* power state */
int media_change_flag; /* media changed flag */
};

View file

@ -80,13 +80,123 @@ struct i2o_cfg_info {
static struct i2o_cfg_info *open_files = NULL;
static ulong i2o_cfg_info_id = 0;
/*
* Each of these describes an i2o message handler. They are
* multiplexed by the i2o_core code
/**
* i2o_config_read_hrt - Returns the HRT of the controller
* @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 = {
.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)

View file

@ -40,6 +40,7 @@
* Fix the resource management problems.
*/
#define DEBUG 1
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/types.h>
@ -179,6 +180,8 @@ static int i2o_scsi_remove(struct device *dev)
struct i2o_scsi_host *i2o_shost;
struct scsi_device *scsi_dev;
osm_info("device removed (TID: %03x)\n", i2o_dev->lct_data.tid);
i2o_shost = i2o_scsi_get_host(c);
shost_for_each_device(scsi_dev, i2o_shost->scsi_host)
@ -262,8 +265,8 @@ static int i2o_scsi_probe(struct device *dev)
return -EFAULT;
}
osm_debug("added new SCSI device %03x (cannel: %d, id: %d, lun: %d)\n",
i2o_dev->lct_data.tid, channel, id, (unsigned int)lun);
osm_info("device added (TID: %03x) channel: %d, id: %d, lun: %d\n",
i2o_dev->lct_data.tid, channel, id, (unsigned int)lun);
return 0;
};
@ -439,8 +442,6 @@ static int i2o_scsi_reply(struct i2o_controller *c, u32 m,
cmd->result = DID_OK << 16 | ds;
cmd->scsi_done(cmd);
dev = &c->pdev->dev;
if (cmd->use_sg)
dma_unmap_sg(dev, (struct scatterlist *)cmd->buffer,
@ -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),
cmd->request_bufflen, cmd->sc_data_direction);
cmd->scsi_done(cmd);
return 1;
};
@ -502,7 +505,7 @@ static void i2o_scsi_notify_controller_remove(struct i2o_controller *c)
scsi_remove_host(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 */
@ -545,7 +548,7 @@ static int i2o_scsi_queuecommand(struct scsi_cmnd *SCpnt,
u32 scsi_flags, sg_flags;
u32 __iomem *mptr;
u32 __iomem *lenptr;
u32 len, reqlen;
u32 len;
int i;
/*
@ -580,12 +583,12 @@ static int i2o_scsi_queuecommand(struct scsi_cmnd *SCpnt,
if (m == I2O_QUEUE_EMPTY)
return SCSI_MLQUEUE_HOST_BUSY;
mptr = &msg->body[0];
/*
* Put together a scsi execscb message
*/
len = SCpnt->request_bufflen;
switch (SCpnt->sc_data_direction) {
case PCI_DMA_NONE:
scsi_flags = 0x00000000; // DATA NO XFER
@ -637,17 +640,13 @@ static int i2o_scsi_queuecommand(struct scsi_cmnd *SCpnt,
*/
/* Direction, disconnect ok, tag, CDBLen */
writel(scsi_flags | 0x20200000 | SCpnt->cmd_len, &msg->body[0]);
mptr = &msg->body[1];
writel(scsi_flags | 0x20200000 | SCpnt->cmd_len, mptr ++);
/* Write SCSI command into the message - always 16 byte block */
memcpy_toio(mptr, SCpnt->cmnd, 16);
mptr += 4;
lenptr = mptr++; /* Remember me - fill in when we know */
reqlen = 12; // SINGLE SGE
/* Now fill in the SGList and command */
if (SCpnt->use_sg) {
struct scatterlist *sg;
@ -671,7 +670,6 @@ static int i2o_scsi_queuecommand(struct scsi_cmnd *SCpnt,
sg++;
}
reqlen = mptr - &msg->u.head[0];
writel(len, lenptr);
} else {
len = SCpnt->request_bufflen;
@ -691,12 +689,11 @@ static int i2o_scsi_queuecommand(struct scsi_cmnd *SCpnt,
sg_flags |= 0xC0000000;
writel(sg_flags | SCpnt->request_bufflen, mptr++);
writel(dma_addr, mptr++);
} else
reqlen = 9;
}
}
/* 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 */
i2o_msg_post(c, m);

View file

@ -68,7 +68,7 @@ extern void i2o_device_exit(void);
*/
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(I2O_CMD_UTIL_NOP << 24 | HOST_TID << 12 | ADAPTER_TID,
@ -452,8 +452,6 @@ static int i2o_iop_clear(struct i2o_controller *c)
/* Enable all IOPs */
i2o_iop_enable_all();
i2o_status_get(c);
return rc;
}
@ -591,12 +589,11 @@ static int i2o_iop_init_outbound_queue(struct i2o_controller *c)
if (m == I2O_QUEUE_EMPTY)
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,
&msg->u.head[1]);
writel(i2o_exec_driver.context, &msg->u.s.icntxt);
writel(0x0106, &msg->u.s.tcntxt); /* FIXME: why 0x0106, maybe in
Spec? */
writel(0x00000000, &msg->u.s.tcntxt);
writel(PAGE_SIZE, &msg->body[0]);
writel(MSG_FRAME_SIZE << 16 | 0x80, &msg->body[1]); /* Outbound msg frame
size in words and Initcode */
@ -891,8 +888,12 @@ void i2o_iop_remove(struct i2o_controller *c)
list_for_each_entry_safe(dev, tmp, &c->devices, list)
i2o_device_remove(dev);
device_del(&c->device);
/* Ask the IOP to switch to RESET state */
i2o_iop_reset(c);
put_device(&c->device);
}
/**
@ -971,8 +972,10 @@ static int i2o_systab_build(void)
systab->iops[count].frame_size = sb->inbound_frame_size;
systab->iops[count].last_changed = change_ind;
systab->iops[count].iop_capabilities = sb->iop_capabilities;
systab->iops[count].inbound_low = i2o_ptr_low(c->post_port);
systab->iops[count].inbound_high = i2o_ptr_high(c->post_port);
systab->iops[count].inbound_low =
i2o_dma_low(c->base.phys + I2O_IN_PORT);
systab->iops[count].inbound_high =
i2o_dma_high(c->base.phys + I2O_IN_PORT);
count++;
}
@ -1109,6 +1112,30 @@ static int i2o_hrt_get(struct i2o_controller *c)
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
*
@ -1137,6 +1164,10 @@ struct i2o_controller *i2o_iop_alloc(void)
c->unit = 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
spin_lock_init(&c->context_list_lock);
atomic_set(&c->context_list_counter, 0);
@ -1146,15 +1177,6 @@ struct i2o_controller *i2o_iop_alloc(void)
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
* @c: controller
@ -1168,6 +1190,11 @@ int i2o_iop_add(struct i2o_controller *c)
{
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: This may take a few minutes if there are many "
"devices\n", c->name);
@ -1175,30 +1202,23 @@ int i2o_iop_add(struct i2o_controller *c)
if ((rc = i2o_iop_activate(c))) {
printk(KERN_ERR "%s: could not activate controller\n",
c->name);
i2o_iop_reset(c);
return rc;
goto iop_reset;
}
pr_debug("%s: building sys table...\n", c->name);
if ((rc = i2o_systab_build())) {
i2o_iop_reset(c);
return rc;
}
if ((rc = i2o_systab_build()))
goto iop_reset;
pr_debug("%s: online controller...\n", c->name);
if ((rc = i2o_iop_online(c))) {
i2o_iop_reset(c);
return rc;
}
if ((rc = i2o_iop_online(c)))
goto iop_reset;
pr_debug("%s: getting LCT...\n", c->name);
if ((rc = i2o_exec_lct_get(c))) {
i2o_iop_reset(c);
return rc;
}
if ((rc = i2o_exec_lct_get(c)))
goto iop_reset;
list_add(&c->list, &i2o_controllers);
@ -1207,6 +1227,11 @@ int i2o_iop_add(struct i2o_controller *c)
printk(KERN_INFO "%s: Controller added\n", c->name);
return 0;
iop_reset:
i2o_iop_reset(c);
return rc;
};
/**

View file

@ -38,8 +38,7 @@ extern void i2o_iop_free(struct i2o_controller *);
extern int i2o_iop_add(struct i2o_controller *);
extern void i2o_iop_remove(struct i2o_controller *);
extern int i2o_driver_dispatch(struct i2o_controller *, u32,
struct i2o_message *);
extern int i2o_driver_dispatch(struct i2o_controller *, u32);
/* PCI device id table for all I2O controllers */
static struct pci_device_id __devinitdata i2o_pci_ids[] = {
@ -89,8 +88,7 @@ static void i2o_pci_free(struct i2o_controller *c)
i2o_dma_free(dev, &c->out_queue);
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->hrt);
i2o_dma_free(dev, &c->status);
@ -187,9 +185,9 @@ static int __devinit i2o_pci_alloc(struct i2o_controller *c)
} else
c->in_queue = c->base;
c->irq_mask = c->base.virt + 0x34;
c->post_port = c->base.virt + 0x40;
c->reply_port = c->base.virt + 0x44;
c->irq_mask = c->base.virt + I2O_IRQ_MASK;
c->in_port = c->base.virt + I2O_IN_PORT;
c->out_port = c->base.virt + I2O_OUT_PORT;
if (i2o_dma_alloc(dev, &c->status, 8, GFP_KERNEL)) {
i2o_pci_free(c);
@ -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 device *dev = &c->pdev->dev;
struct i2o_message *m;
u32 mv;
u32 mv = readl(c->out_port);
/*
* Old 960 steppings had a bug in the I2O unit that caused
* the queue to appear empty when it wasn't.
*/
mv = I2O_REPLY_READ32(c);
if (mv == I2O_QUEUE_EMPTY) {
mv = I2O_REPLY_READ32(c);
if (unlikely(mv == I2O_QUEUE_EMPTY)) {
mv = readl(c->out_port);
if (unlikely(mv == I2O_QUEUE_EMPTY))
return IRQ_NONE;
} else
else
pr_debug("%s: 960 bug detected\n", c->name);
}
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 */
if (i2o_driver_dispatch(c, mv, m))
if (i2o_driver_dispatch(c, mv))
/* flush it if result != 0 */
i2o_flush_reply(c, mv);
/*
* That 960 bug again...
*/
mv = I2O_REPLY_READ32(c);
mv = readl(c->out_port);
if (mv == I2O_QUEUE_EMPTY)
mv = I2O_REPLY_READ32(c);
mv = readl(c->out_port);
}
return IRQ_HANDLED;
}
@ -294,7 +277,9 @@ static int i2o_pci_irq_enable(struct i2o_controller *c)
struct pci_dev *pdev = c->pdev;
int rc;
I2O_IRQ_WRITE32(c, 0xffffffff);
wmb();
writel(0xffffffff, c->irq_mask);
wmb();
if (pdev->irq) {
rc = request_irq(pdev->irq, i2o_pci_interrupt, SA_SHIRQ,
@ -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);
@ -321,7 +307,9 @@ static int i2o_pci_irq_enable(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)
free_irq(c->pdev->irq, c);
@ -379,7 +367,7 @@ static int __devinit i2o_pci_probe(struct pci_dev *pdev,
pci_name(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... */
if (pdev->vendor == PCI_VENDOR_ID_NCR && pdev->device == 0x0630) {
@ -428,6 +416,8 @@ static int __devinit i2o_pci_probe(struct pci_dev *pdev,
if (i960)
pci_write_config_word(i960, 0x42, 0x03ff);
get_device(&c->device);
return 0;
uninstall:
@ -438,6 +428,7 @@ static int __devinit i2o_pci_probe(struct pci_dev *pdev,
free_controller:
i2o_iop_free(c);
put_device(c->device.parent);
disable:
pci_disable_device(pdev);
@ -461,15 +452,17 @@ static void __devexit i2o_pci_remove(struct pci_dev *pdev)
i2o_pci_irq_disable(c);
i2o_pci_free(c);
pci_disable_device(pdev);
printk(KERN_INFO "%s: Controller removed.\n", c->name);
i2o_iop_free(c);
pci_disable_device(pdev);
put_device(c->device.parent);
put_device(&c->device);
};
/* PCI driver for I2O controller */
static struct pci_driver i2o_pci_driver = {
.name = "I2O controller",
.name = "PCI_I2O",
.id_table = i2o_pci_ids,
.probe = i2o_pci_probe,
.remove = __devexit_p(i2o_pci_remove),

View file

@ -153,12 +153,10 @@ struct i2o_controller {
unsigned int promise:1; /* Promise controller */
struct list_head devices; /* list of I2O devices */
struct notifier_block *event_notifer; /* Events */
atomic_t users;
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 */
/* Dynamic LCT related data */
@ -182,9 +180,6 @@ struct i2o_controller {
struct resource io_resource; /* I/O 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 i2o_device *exec; /* Executive */
#if BITS_PER_LONG == 64
@ -380,49 +375,10 @@ extern int i2o_device_claim_release(struct i2o_device *);
/* Exec OSM functions */
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_device(dev) container_of(dev, struct i2o_device, 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();
};
#define to_i2o_controller(dev) container_of(dev, struct i2o_controller, device)
/**
* 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)
static inline u32 i2o_msg_get(struct i2o_controller *c,
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;
rmb();
}
return m;
};
@ -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)
{
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,
* 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
* 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)
{
I2O_REPLY_WRITE32(c, m);
writel(m, c->out_port);
};
/**
@ -505,8 +462,9 @@ static inline void i2o_flush_reply(struct i2o_controller *c, u32 m)
* work for sender side messages as they are ioremap objects
* provided by the I2O controller.
*/
static inline struct i2o_message *i2o_msg_out_to_virt(struct i2o_controller *c,
u32 m)
static inline struct i2o_message __iomem *i2o_msg_out_to_virt(struct
i2o_controller *c,
u32 m)
{
BUG_ON(m < c->out_queue.phys
|| m >= c->out_queue.phys + c->out_queue.len);
@ -917,7 +875,7 @@ extern void i2o_debug_state(struct i2o_controller *c);
#define I2OVER15 0x0001
#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 SGL_OFFSET_0 I2OVERSION