[PATCH] I2O: second code cleanup of sparse warnings and unneeded syncronization
authorMarkus Lidel <Markus.Lidel@shadowconnect.com>
Fri, 24 Jun 2005 05:02:21 +0000 (22:02 -0700)
committerLinus Torvalds <torvalds@ppc970.osdl.org>
Fri, 24 Jun 2005 07:05:29 +0000 (00:05 -0700)
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>
12 files changed:
drivers/message/i2o/core.h [new file with mode: 0644]
drivers/message/i2o/debug.c
drivers/message/i2o/device.c
drivers/message/i2o/driver.c
drivers/message/i2o/exec-osm.c
drivers/message/i2o/i2o_block.c
drivers/message/i2o/i2o_config.c
drivers/message/i2o/i2o_scsi.c
drivers/message/i2o/iop.c
drivers/message/i2o/pci.c
include/linux/i2o-dev.h
include/linux/i2o.h

diff --git a/drivers/message/i2o/core.h b/drivers/message/i2o/core.h
new file mode 100644 (file)
index 0000000..49851cc
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ *     I2O core internal declarations
+ *
+ *     Copyright (C) 2005      Markus Lidel <Markus.Lidel@shadowconnect.com>
+ *
+ *     This program is free software; you can redistribute it and/or modify it
+ *     under the terms of the GNU General Public License as published by the
+ *     Free Software Foundation; either version 2 of the License, or (at your
+ *     option) any later version.
+ *
+ *     Fixes/additions:
+ *             Markus Lidel <Markus.Lidel@shadowconnect.com>
+ *                     initial version.
+ */
+
+/* Exec-OSM */
+extern struct bus_type i2o_bus_type;
+
+extern struct i2o_driver i2o_exec_driver;
+extern int i2o_exec_lct_get(struct i2o_controller *);
+
+extern int __init i2o_exec_init(void);
+extern void __exit i2o_exec_exit(void);
+
+/* driver */
+extern int i2o_driver_dispatch(struct i2o_controller *, u32);
+
+extern int __init i2o_driver_init(void);
+extern void __exit i2o_driver_exit(void);
+
+/* PCI */
+extern int __init i2o_pci_init(void);
+extern void __exit i2o_pci_exit(void);
+
+/* device */
+extern void i2o_device_remove(struct i2o_device *);
+extern int i2o_device_parse_lct(struct i2o_controller *);
+
+extern int i2o_device_init(void);
+extern void i2o_device_exit(void);
+
+/* IOP */
+extern struct i2o_controller *i2o_iop_alloc(void);
+extern void i2o_iop_free(struct i2o_controller *);
+
+extern int i2o_iop_add(struct i2o_controller *);
+extern void i2o_iop_remove(struct i2o_controller *);
+
+/* control registers relative to c->base */
+#define I2O_IRQ_STATUS 0x30
+#define I2O_IRQ_MASK   0x34
+#define I2O_IN_PORT    0x40
+#define I2O_OUT_PORT   0x44
+
+#define I2O_IRQ_OUTBOUND_POST  0x00000008
index 2a5d478..018ca88 100644 (file)
@@ -4,8 +4,6 @@
 #include <linux/pci.h>
 #include <linux/i2o.h>
 
-extern struct i2o_driver **i2o_drivers;
-extern unsigned int i2o_max_drivers;
 static void i2o_report_util_cmd(u8 cmd);
 static void i2o_report_exec_cmd(u8 cmd);
 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,
        u8 cmd = (msg[1] >> 24) & 0xFF;
        u8 req_status = (msg[4] >> 24) & 0xFF;
        u16 detailed_status = msg[4] & 0xFFFF;
-       //struct i2o_driver *h = i2o_drivers[msg[2] & (i2o_max_drivers-1)];
 
        if (cmd == I2O_CMD_UTIL_EVT_REGISTER)
                return;         // No status in this reply
index f1b7eb6..0ee342e 100644 (file)
@@ -16,9 +16,7 @@
 #include <linux/module.h>
 #include <linux/i2o.h>
 #include <linux/delay.h>
-
-/* Exec OSM functions */
-extern struct bus_type i2o_bus_type;
+#include "core.h"
 
 /**
  *     i2o_device_issue_claim - claim or release a device
@@ -293,12 +291,12 @@ int i2o_device_parse_lct(struct i2o_controller *c)
        }
 
        if (lct->table_size * 4 > c->dlct.len) {
-               memcpy_fromio(c->lct, c->dlct.virt, c->dlct.len);
+               memcpy(c->lct, c->dlct.virt, c->dlct.len);
                up(&c->lct_lock);
                return -EAGAIN;
        }
 
-       memcpy_fromio(c->lct, c->dlct.virt, lct->table_size * 4);
+       memcpy(c->lct, c->dlct.virt, lct->table_size * 4);
 
        lct = c->lct;
 
@@ -353,7 +351,7 @@ static ssize_t i2o_device_class_show_class_id(struct class_device *cd,
 {
        struct i2o_device *dev = to_i2o_device(cd->dev);
 
-       sprintf(buf, "%03x\n", dev->lct_data.class_id);
+       sprintf(buf, "0x%03x\n", dev->lct_data.class_id);
        return strlen(buf) + 1;
 };
 
@@ -368,7 +366,7 @@ static ssize_t i2o_device_class_show_tid(struct class_device *cd, char *buf)
 {
        struct i2o_device *dev = to_i2o_device(cd->dev);
 
-       sprintf(buf, "%03x\n", dev->lct_data.tid);
+       sprintf(buf, "0x%03x\n", dev->lct_data.tid);
        return strlen(buf) + 1;
 };
 
@@ -490,7 +488,7 @@ static int i2o_parm_issue(struct i2o_device *i2o_dev, int cmd, void *oplist,
        if (rc == -ETIMEDOUT)
                return rc;
 
-       memcpy_fromio(reslist, res.virt, res.len);
+       memcpy(reslist, res.virt, res.len);
        i2o_dma_free(dev, &res);
 
        /* Query failed */
@@ -532,17 +530,23 @@ int i2o_parm_field_get(struct i2o_device *i2o_dev, int group, int field,
                       void *buf, int buflen)
 {
        u16 opblk[] = { 1, 0, I2O_PARAMS_FIELD_GET, group, 1, field };
-       u8 resblk[8 + buflen];  /* 8 bytes for header */
+       u8 *resblk;             /* 8 bytes for header */
        int size;
 
        if (field == -1)        /* whole group */
                opblk[4] = -1;
 
+       resblk = kmalloc(buflen + 8, GFP_KERNEL | GFP_ATOMIC);
+       if (!resblk)
+               return -ENOMEM;
+
        size = i2o_parm_issue(i2o_dev, I2O_CMD_UTIL_PARAMS_GET, opblk,
                              sizeof(opblk), resblk, buflen + 8);
 
        memcpy(buf, resblk + 8, buflen);        /* cut off header */
 
+       kfree(resblk);
+
        if (size > buflen)
                return buflen;
 
index 393be8e..c32f9db 100644 (file)
 #include <linux/module.h>
 #include <linux/rwsem.h>
 #include <linux/i2o.h>
+#include "core.h"
 
 #define OSM_NAME       "i2o"
 
 /* max_drivers - Maximum I2O drivers (OSMs) which could be registered */
-unsigned int i2o_max_drivers = I2O_MAX_DRIVERS;
+static unsigned int i2o_max_drivers = I2O_MAX_DRIVERS;
 module_param_named(max_drivers, i2o_max_drivers, uint, 0);
 MODULE_PARM_DESC(max_drivers, "maximum number of OSM's to support");
 
@@ -179,15 +180,10 @@ void i2o_driver_unregister(struct i2o_driver *drv)
 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;
+       struct i2o_message *msg = i2o_msg_out_to_virt(c, m);
+       u32 context = le32_to_cpu(msg->u.s.icntxt);
        unsigned long flags;
 
-       if(unlikely(!msg))
-               return -EIO;
-
-       context = readl(&msg->u.s.icntxt);
-
        if (unlikely(context >= i2o_max_drivers)) {
                osm_warn("%s: Spurious reply to unknown driver %d\n", c->name,
                         context);
@@ -204,11 +200,11 @@ int i2o_driver_dispatch(struct i2o_controller *c, u32 m)
                return -EIO;
        }
 
-       if ((readl(&msg->u.head[1]) >> 24) == I2O_CMD_UTIL_EVT_REGISTER) {
+       if ((le32_to_cpu(msg->u.head[1]) >> 24) == I2O_CMD_UTIL_EVT_REGISTER) {
                struct i2o_device *dev, *tmp;
                struct i2o_event *evt;
                u16 size;
-               u16 tid = readl(&msg->u.head[1]) & 0xfff;
+               u16 tid = le32_to_cpu(msg->u.head[1]) & 0xfff;
 
                osm_debug("event received from device %d\n", tid);
 
@@ -216,16 +212,16 @@ int i2o_driver_dispatch(struct i2o_controller *c, u32 m)
                        return -EIO;
 
                /* cut of header from message size (in 32-bit words) */
-               size = (readl(&msg->u.head[0]) >> 16) - 5;
+               size = (le32_to_cpu(msg->u.head[0]) >> 16) - 5;
 
                evt = kmalloc(size * 4 + sizeof(*evt), GFP_ATOMIC | __GFP_ZERO);
                if (!evt)
                        return -ENOMEM;
 
                evt->size = size;
-               evt->tcntxt = readl(&msg->u.s.tcntxt);
-               evt->event_indicator = readl(&msg->body[0]);
-               memcpy_fromio(&evt->tcntxt, &msg->u.s.tcntxt, size * 4);
+               evt->tcntxt = le32_to_cpu(msg->u.s.tcntxt);
+               evt->event_indicator = le32_to_cpu(msg->body[0]);
+               memcpy(&evt->tcntxt, &msg->u.s.tcntxt, size * 4);
 
                list_for_each_entry_safe(dev, tmp, &c->devices, list)
                    if (dev->lct_data.tid == tid) {
index 0160221..ffe0cec 100644 (file)
@@ -30,6 +30,7 @@
 #include <linux/module.h>
 #include <linux/i2o.h>
 #include <linux/delay.h>
+#include "core.h"
 
 #define OSM_NAME "exec-osm"
 
@@ -37,9 +38,6 @@ struct i2o_driver i2o_exec_driver;
 
 static int i2o_exec_lct_notify(struct i2o_controller *c, u32 change_ind);
 
-/* Module internal functions from other sources */
-extern int i2o_device_parse_lct(struct i2o_controller *);
-
 /* global wait list for POST WAIT */
 static LIST_HEAD(i2o_exec_wait_list);
 
@@ -50,7 +48,7 @@ struct i2o_exec_wait {
        u32 tcntxt;             /* transaction context from reply */
        int complete;           /* 1 if reply received otherwise 0 */
        u32 m;                  /* message id */
-       struct i2o_message __iomem *msg;        /* pointer to the reply message */
+       struct i2o_message *msg;        /* pointer to the reply message */
        struct list_head list;  /* node in global wait list */
 };
 
@@ -162,7 +160,7 @@ int i2o_msg_post_wait_mem(struct i2o_controller *c, u32 m, unsigned long
        barrier();
 
        if (wait->complete) {
-               rc = readl(&wait->msg->body[0]) >> 24;
+               rc = le32_to_cpu(wait->msg->body[0]) >> 24;
                i2o_flush_reply(c, wait->m);
                i2o_exec_wait_free(wait);
        } else {
@@ -202,8 +200,7 @@ 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,
-                                     u32 context)
+                                     struct i2o_message *msg, u32 context)
 {
        struct i2o_exec_wait *wait, *tmp;
        unsigned long flags;
@@ -378,11 +375,11 @@ 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 __iomem *msg)
+                         struct i2o_message *msg)
 {
        u32 context;
 
-       if (readl(&msg->u.head[0]) & MSG_FAIL) {
+       if (le32_to_cpu(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.
@@ -390,7 +387,7 @@ static int i2o_exec_reply(struct i2o_controller *c, u32 m,
                struct i2o_message __iomem *pmsg;
                u32 pm;
 
-               pm = readl(&msg->body[3]);
+               pm = le32_to_cpu(msg->body[3]);
 
                pmsg = i2o_msg_in_to_virt(c, pm);
 
@@ -401,12 +398,12 @@ static int i2o_exec_reply(struct i2o_controller *c, u32 m,
                /* Release the preserved msg */
                i2o_msg_nop(c, pm);
        } else
-               context = readl(&msg->u.s.tcntxt);
+               context = le32_to_cpu(msg->u.s.tcntxt);
 
        if (context & 0x80000000)
                return i2o_msg_post_wait_complete(c, m, msg, context);
 
-       if ((readl(&msg->u.head[1]) >> 24) == I2O_CMD_LCT_NOTIFY) {
+       if ((le32_to_cpu(msg->u.head[1]) >> 24) == I2O_CMD_LCT_NOTIFY) {
                struct work_struct *work;
 
                pr_debug("%s: LCT notify received\n", c->name);
@@ -442,9 +439,9 @@ static int i2o_exec_reply(struct i2o_controller *c, u32 m,
  */
 static void i2o_exec_event(struct i2o_event *evt)
 {
-       if(likely(evt->i2o_dev))
-               osm_info("Event received from device: %d\n",
-                        evt->i2o_dev->lct_data.tid);
+       if (likely(evt->i2o_dev))
+               osm_debug("Event received from device: %d\n",
+                         evt->i2o_dev->lct_data.tid);
        kfree(evt);
 };
 
index 1dd2b9d..28b3918 100644 (file)
@@ -62,7 +62,7 @@
 #include "i2o_block.h"
 
 #define OSM_NAME       "block-osm"
-#define OSM_VERSION    "$Rev$"
+#define OSM_VERSION    "1.287"
 #define OSM_DESCRIPTION        "I2O Block Device OSM"
 
 static struct i2o_driver i2o_block_driver;
@@ -537,7 +537,7 @@ static int i2o_block_reply(struct i2o_controller *c, u32 m,
 
 static void i2o_block_event(struct i2o_event *evt)
 {
-       osm_info("event received\n");
+       osm_debug("event received\n");
        kfree(evt);
 };
 
index 7636833..8160a1f 100644 (file)
@@ -36,6 +36,8 @@
 
 #include <asm/uaccess.h>
 
+#define SG_TABLESIZE           30
+
 extern int i2o_parm_issue(struct i2o_device *, int, void *, int, void *, int);
 
 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
                goto sg_list_cleanup;
 
        if (sg_offset) {
-               u32 msg[MSG_FRAME_SIZE];
+               u32 msg[I2O_OUTBOUND_MSG_FRAME_SIZE];
                /* Copy back the Scatter Gather buffers back to user space */
                u32 j;
                // TODO 64bit fix
@@ -671,7 +673,7 @@ static int i2o_cfg_passthru32(struct file *file, unsigned cmnd, unsigned long ar
                int sg_size;
 
                // re-acquire the original message to handle correctly the sg copy operation
-               memset(&msg, 0, MSG_FRAME_SIZE * 4);
+               memset(&msg, 0, I2O_OUTBOUND_MSG_FRAME_SIZE * 4);
                // get user msg size in u32s
                if (get_user(size, &user_msg[0])) {
                        rcode = -EFAULT;
@@ -902,7 +904,7 @@ static int i2o_cfg_passthru(unsigned long arg)
                int sg_size;
 
                // re-acquire the original message to handle correctly the sg copy operation
-               memset(&msg, 0, MSG_FRAME_SIZE * 4);
+               memset(&msg, 0, I2O_OUTBOUND_MSG_FRAME_SIZE * 4);
                // get user msg size in u32s
                if (get_user(size, &user_msg[0])) {
                        rcode = -EFAULT;
index fef53b5..9f1744c 100644 (file)
@@ -40,7 +40,6 @@
  *     Fix the resource management problems.
  */
 
-#define DEBUG 1
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/types.h>
@@ -338,162 +337,89 @@ static int i2o_scsi_reply(struct i2o_controller *c, u32 m,
                          struct i2o_message *msg)
 {
        struct scsi_cmnd *cmd;
+       u32 error;
        struct device *dev;
-       u8 as, ds, st;
 
        cmd = i2o_cntxt_list_get(c, le32_to_cpu(msg->u.s.tcntxt));
-
-       if (msg->u.head[0] & (1 << 13)) {
-               struct i2o_message __iomem *pmsg;       /* preserved message */
-               u32 pm;
-               int err = DID_ERROR;
-
-               pm = le32_to_cpu(msg->body[3]);
-
-               pmsg = i2o_msg_in_to_virt(c, pm);
-
-               osm_err("IOP fail.\n");
-               osm_err("From %d To %d Cmd %d.\n",
-                       (msg->u.head[1] >> 12) & 0xFFF,
-                       msg->u.head[1] & 0xFFF, msg->u.head[1] >> 24);
-               osm_err("Failure Code %d.\n", msg->body[0] >> 24);
-               if (msg->body[0] & (1 << 16))
-                       osm_err("Format error.\n");
-               if (msg->body[0] & (1 << 17))
-                       osm_err("Path error.\n");
-               if (msg->body[0] & (1 << 18))
-                       osm_err("Path State.\n");
-               if (msg->body[0] & (1 << 18))
-               {
-                       osm_err("Congestion.\n");
-                       err = DID_BUS_BUSY;
-               }
-
-               osm_debug("Failing message is %p.\n", pmsg);
-
-               cmd = i2o_cntxt_list_get(c, readl(&pmsg->u.s.tcntxt));
-               if (!cmd)
-                       return 1;
-
-               cmd->result = err << 16;
-               cmd->scsi_done(cmd);
-
-               /* Now flush the message by making it a NOP */
-               i2o_msg_nop(c, pm);
-
-               return 1;
+       if (unlikely(!cmd)) {
+               osm_err("NULL reply received!\n");
+               return -1;
        }
 
        /*
         *      Low byte is device status, next is adapter status,
         *      (then one byte reserved), then request status.
         */
-       ds = (u8) le32_to_cpu(msg->body[0]);
-       as = (u8) (le32_to_cpu(msg->body[0]) >> 8);
-       st = (u8) (le32_to_cpu(msg->body[0]) >> 24);
+       error = le32_to_cpu(msg->body[0]);
 
+       osm_debug("Completed %ld\n", cmd->serial_number);
+
+       cmd->result = error & 0xff;
        /*
-        *      Is this a control request coming back - eg an abort ?
+        * if DeviceStatus is not SCSI_SUCCESS copy over the sense data and let
+        * the SCSI layer handle the error
         */
+       if (cmd->result)
+               memcpy(cmd->sense_buffer, &msg->body[3],
+                      min(sizeof(cmd->sense_buffer), (size_t) 40));
 
-       if (!cmd) {
-               if (st)
-                       osm_warn("SCSI abort: %08X", le32_to_cpu(msg->body[0]));
-               osm_info("SCSI abort completed.\n");
-               return -EFAULT;
-       }
+       /* only output error code if AdapterStatus is not HBA_SUCCESS */
+       if ((error >> 8) & 0xff)
+               osm_err("SCSI error %08x\n", error);
 
-       osm_debug("Completed %ld\n", cmd->serial_number);
+       dev = &c->pdev->dev;
+       if (cmd->use_sg)
+               dma_unmap_sg(dev, cmd->request_buffer, cmd->use_sg,
+                            cmd->sc_data_direction);
+       else if (cmd->SCp.dma_handle)
+               dma_unmap_single(dev, cmd->SCp.dma_handle, cmd->request_bufflen,
+                                cmd->sc_data_direction);
 
-       if (st) {
-               u32 count, error;
-               /* An error has occurred */
-
-               switch (st) {
-               case 0x06:
-                       count = le32_to_cpu(msg->body[1]);
-                       if (count < cmd->underflow) {
-                               int i;
-
-                               osm_err("SCSI underflow 0x%08X 0x%08X\n", count,
-                                       cmd->underflow);
-                               osm_debug("Cmd: ");
-                               for (i = 0; i < 15; i++)
-                                       pr_debug("%02X ", cmd->cmnd[i]);
-                               pr_debug(".\n");
-                               cmd->result = (DID_ERROR << 16);
-                       }
-                       break;
+       cmd->scsi_done(cmd);
 
-               default:
-                       error = le32_to_cpu(msg->body[0]);
-
-                       osm_err("SCSI error %08x\n", error);
-
-                       if ((error & 0xff) == 0x02 /*CHECK_CONDITION */ ) {
-                               int i;
-                               u32 len = sizeof(cmd->sense_buffer);
-                               len = (len > 40) ? 40 : len;
-                               // Copy over the sense data
-                               memcpy(cmd->sense_buffer, (void *)&msg->body[3],
-                                      len);
-                               for (i = 0; i <= len; i++)
-                                       osm_info("%02x\n",
-                                                cmd->sense_buffer[i]);
-                               if (cmd->sense_buffer[0] == 0x70
-                                   && cmd->sense_buffer[2] == DATA_PROTECT) {
-                                       /* This is to handle an array failed */
-                                       cmd->result = (DID_TIME_OUT << 16);
-                                       printk(KERN_WARNING "%s: SCSI Data "
-                                              "Protect-Device (%d,%d,%d) "
-                                              "hba_status=0x%x, dev_status="
-                                              "0x%x, cmd=0x%x\n", c->name,
-                                              (u32) cmd->device->channel,
-                                              (u32) cmd->device->id,
-                                              (u32) cmd->device->lun,
-                                              (error >> 8) & 0xff,
-                                              error & 0xff, cmd->cmnd[0]);
-                               } else
-                                       cmd->result = (DID_ERROR << 16);
-
-                               break;
-                       }
-
-                       switch (as) {
-                       case 0x0E:
-                               /* SCSI Reset */
-                               cmd->result = DID_RESET << 16;
-                               break;
-
-                       case 0x0F:
-                               cmd->result = DID_PARITY << 16;
-                               break;
-
-                       default:
-                               cmd->result = DID_ERROR << 16;
-                               break;
-                       }
+       return 1;
+};
 
-                       break;
-               }
+/**
+ *     i2o_scsi_notify_device_add - Retrieve notifications of added devices
+ *     @i2o_dev: the I2O device which was added
+ *
+ *     If a I2O device is added we catch the notification, because I2O classes
+ *     other then SCSI peripheral will not be received through
+ *     i2o_scsi_probe().
+ */
+static void i2o_scsi_notify_device_add(struct i2o_device *i2o_dev)
+{
+       switch (i2o_dev->lct_data.class_id) {
+       case I2O_CLASS_EXECUTIVE:
+       case I2O_CLASS_RANDOM_BLOCK_STORAGE:
+               i2o_scsi_probe(&i2o_dev->device);
+               break;
 
-               cmd->scsi_done(cmd);
-               return 1;
+       default:
+               break;
        }
+};
 
-       cmd->result = DID_OK << 16 | ds;
-
-       dev = &c->pdev->dev;
-       if (cmd->use_sg)
-               dma_unmap_sg(dev, (struct scatterlist *)cmd->buffer,
-                            cmd->use_sg, cmd->sc_data_direction);
-       else if (cmd->request_bufflen)
-               dma_unmap_single(dev, (dma_addr_t) ((long)cmd->SCp.ptr),
-                                cmd->request_bufflen, cmd->sc_data_direction);
-
-       cmd->scsi_done(cmd);
+/**
+ *     i2o_scsi_notify_device_remove - Retrieve notifications of removed
+ *                                     devices
+ *     @i2o_dev: the I2O device which was removed
+ *
+ *     If a I2O device is removed, we catch the notification to remove the
+ *     corresponding SCSI device.
+ */
+static void i2o_scsi_notify_device_remove(struct i2o_device *i2o_dev)
+{
+       switch (i2o_dev->lct_data.class_id) {
+       case I2O_CLASS_EXECUTIVE:
+       case I2O_CLASS_RANDOM_BLOCK_STORAGE:
+               i2o_scsi_remove(&i2o_dev->device);
+               break;
 
-       return 1;
+       default:
+               break;
+       }
 };
 
 /**
@@ -554,6 +480,8 @@ static struct i2o_driver i2o_scsi_driver = {
        .name = OSM_NAME,
        .reply = i2o_scsi_reply,
        .classes = i2o_scsi_class_id,
+       .notify_device_add = i2o_scsi_notify_device_add,
+       .notify_device_remove = i2o_scsi_notify_device_remove,
        .notify_controller_add = i2o_scsi_notify_controller_add,
        .notify_controller_remove = i2o_scsi_notify_controller_remove,
        .driver = {
@@ -712,7 +640,7 @@ static int i2o_scsi_queuecommand(struct scsi_cmnd *SCpnt,
         */
 
        /* Attach tags to the devices */
-       /*
+       /* FIXME: implement
           if(SCpnt->device->tagged_supported) {
           if(SCpnt->tag == HEAD_OF_QUEUE_TAG)
           scsi_flags |= 0x01000000;
index 4031205..c32022b 100644 (file)
 #include <linux/module.h>
 #include <linux/i2o.h>
 #include <linux/delay.h>
+#include "core.h"
 
-#define OSM_VERSION    "$Rev$"
+#define OSM_NAME       "i2o"
+#define OSM_VERSION    "1.288"
 #define OSM_DESCRIPTION        "I2O subsystem"
 
 /* global I2O controller list */
@@ -43,20 +45,6 @@ static struct i2o_dma i2o_systab;
 
 static int i2o_hrt_get(struct i2o_controller *c);
 
-/* Module internal functions from other sources */
-extern struct i2o_driver i2o_exec_driver;
-extern int i2o_exec_lct_get(struct i2o_controller *);
-extern void i2o_device_remove(struct i2o_device *);
-
-extern int __init i2o_driver_init(void);
-extern void __exit i2o_driver_exit(void);
-extern int __init i2o_exec_init(void);
-extern void __exit i2o_exec_exit(void);
-extern int __init i2o_pci_init(void);
-extern void __exit i2o_pci_exit(void);
-extern int i2o_device_init(void);
-extern void i2o_device_exit(void);
-
 /**
  *     i2o_msg_nop - Returns a message which is not used
  *     @c: I2O controller from which the message was created
@@ -92,16 +80,16 @@ void i2o_msg_nop(struct i2o_controller *c, u32 m)
  *     address from the read port (see the i2o spec). If no message is
  *     available returns I2O_QUEUE_EMPTY and msg is leaved untouched.
  */
-u32 i2o_msg_get_wait(struct i2o_controller *c, struct i2o_message __iomem **msg,
-                    int wait)
+u32 i2o_msg_get_wait(struct i2o_controller *c,
+                    struct i2o_message __iomem ** msg, int wait)
 {
        unsigned long timeout = jiffies + wait * HZ;
        u32 m;
 
        while ((m = i2o_msg_get(c, msg)) == I2O_QUEUE_EMPTY) {
                if (time_after(jiffies, timeout)) {
-                       pr_debug("%s: Timeout waiting for message frame.\n",
-                                c->name);
+                       osm_debug("%s: Timeout waiting for message frame.\n",
+                                 c->name);
                        return I2O_QUEUE_EMPTY;
                }
                set_current_state(TASK_UNINTERRUPTIBLE);
@@ -466,7 +454,7 @@ static int i2o_iop_clear(struct i2o_controller *c)
  */
 static int i2o_iop_init_outbound_queue(struct i2o_controller *c)
 {
-       u8 *status = c->status.virt;
+       volatile u8 *status = c->status.virt;
        u32 m;
        struct i2o_message __iomem *msg;
        ulong timeout;
@@ -474,21 +462,20 @@ static int i2o_iop_init_outbound_queue(struct i2o_controller *c)
 
        osm_debug("%s: Initializing Outbound Queue...\n", c->name);
 
-       memset(status, 0, 4);
+       memset(c->status.virt, 0, 4);
 
        m = i2o_msg_get_wait(c, &msg, I2O_TIMEOUT_MESSAGE_GET);
        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]);
        /* Outbound msg frame size in words and Initcode */
-       writel(MSG_FRAME_SIZE << 16 | 0x80, &msg->body[1]);
+       writel(I2O_OUTBOUND_MSG_FRAME_SIZE << 16 | 0x80, &msg->body[1]);
        writel(0xd0000004, &msg->body[2]);
        writel(i2o_dma_low(c->status.phys), &msg->body[3]);
        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)
                }
                set_current_state(TASK_UNINTERRUPTIBLE);
                schedule_timeout(1);
-
-               rmb();
        }
 
        m = c->out_queue.phys;
 
        /* Post frames */
-       for (i = 0; i < NMBR_MSG_FRAMES; i++) {
+       for (i = 0; i < I2O_MAX_OUTBOUND_MSG_FRAMES; i++) {
                i2o_flush_reply(c, m);
                udelay(1);      /* Promise */
-               m += MSG_FRAME_SIZE * 4;
+               m += I2O_OUTBOUND_MSG_FRAME_SIZE * sizeof(u32);
        }
 
        return 0;
@@ -530,20 +515,20 @@ static int i2o_iop_init_outbound_queue(struct i2o_controller *c)
  */
 static int i2o_iop_reset(struct i2o_controller *c)
 {
-       u8 *status = c->status.virt;
+       volatile u8 *status = c->status.virt;
        struct i2o_message __iomem *msg;
        u32 m;
        unsigned long timeout;
        i2o_status_block *sb = c->status_block.virt;
        int rc = 0;
 
-       pr_debug("%s: Resetting controller\n", c->name);
+       osm_debug("%s: Resetting controller\n", c->name);
 
        m = i2o_msg_get_wait(c, &msg, I2O_TIMEOUT_MESSAGE_GET);
        if (m == I2O_QUEUE_EMPTY)
                return -ETIMEDOUT;
 
-       memset(status, 0, 8);
+       memset(c->status_block.virt, 0, 8);
 
        /* Quiesce all IOPs first */
        i2o_iop_quiesce_all();
@@ -568,8 +553,6 @@ static int i2o_iop_reset(struct i2o_controller *c)
 
                set_current_state(TASK_UNINTERRUPTIBLE);
                schedule_timeout(1);
-
-               rmb();
        }
 
        switch (*status) {
@@ -984,11 +967,11 @@ int i2o_status_get(struct i2o_controller *c)
 {
        struct i2o_message __iomem *msg;
        u32 m;
-       u8 *status_block;
+       volatile u8 *status_block;
        unsigned long timeout;
 
        status_block = (u8 *) c->status_block.virt;
-       memset(status_block, 0, sizeof(i2o_status_block));
+       memset(c->status_block.virt, 0, sizeof(i2o_status_block));
 
        m = i2o_msg_get_wait(c, &msg, I2O_TIMEOUT_MESSAGE_GET);
        if (m == I2O_QUEUE_EMPTY)
@@ -1017,8 +1000,6 @@ int i2o_status_get(struct i2o_controller *c)
 
                set_current_state(TASK_UNINTERRUPTIBLE);
                schedule_timeout(1);
-
-               rmb();
        }
 
 #ifdef DEBUG
@@ -1107,6 +1088,11 @@ static void i2o_iop_release(struct device *dev)
        i2o_iop_free(c);
 };
 
+/* I2O controller class */
+static struct class i2o_controller_class = {
+       .name = "i2o_controller",
+};
+
 /**
  *     i2o_iop_alloc - Allocate and initialize a i2o_controller struct
  *
@@ -1136,8 +1122,14 @@ struct i2o_controller *i2o_iop_alloc(void)
        sprintf(c->name, "iop%d", c->unit);
 
        device_initialize(&c->device);
+       class_device_initialize(&c->classdev);
+
        c->device.release = &i2o_iop_release;
+       c->classdev.class = &i2o_controller_class;
+       c->classdev.dev = &c->device;
+
        snprintf(c->device.bus_id, BUS_ID_SIZE, "iop%d", c->unit);
+       snprintf(c->classdev.class_id, BUS_ID_SIZE, "iop%d", c->unit);
 
 #if BITS_PER_LONG == 64
        spin_lock_init(&c->context_list_lock);
@@ -1161,45 +1153,55 @@ 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);
+       if ((rc = device_add(&c->device))) {
+               osm_err("%s: could not add 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);
+       if ((rc = class_device_add(&c->classdev))) {
+               osm_err("%s: could not add controller class\n", c->name);
+               goto device_del;
+       }
+
+       osm_info("%s: Activating I2O controller...\n", c->name);
+       osm_info("%s: This may take a few minutes if there are many devices\n",
+                c->name);
 
        if ((rc = i2o_iop_activate(c))) {
-               printk(KERN_ERR "%s: could not activate controller\n",
-                      c->name);
-               goto iop_reset;
+               osm_err("%s: could not activate controller\n", c->name);
+               goto class_del;
        }
 
-       pr_debug("%s: building sys table...\n", c->name);
+       osm_debug("%s: building sys table...\n", c->name);
 
        if ((rc = i2o_systab_build()))
-               goto iop_reset;
+               goto class_del;
 
-       pr_debug("%s: online controller...\n", c->name);
+       osm_debug("%s: online controller...\n", c->name);
 
        if ((rc = i2o_iop_online(c)))
-               goto iop_reset;
+               goto class_del;
 
-       pr_debug("%s: getting LCT...\n", c->name);
+       osm_debug("%s: getting LCT...\n", c->name);
 
        if ((rc = i2o_exec_lct_get(c)))
-               goto iop_reset;
+               goto class_del;
 
        list_add(&c->list, &i2o_controllers);
 
        i2o_driver_notify_controller_add_all(c);
 
-       printk(KERN_INFO "%s: Controller added\n", c->name);
+       osm_info("%s: Controller added\n", c->name);
 
        return 0;
 
-iop_reset:
+      class_del:
+       class_device_del(&c->classdev);
+
+      device_del:
+       device_del(&c->device);
+
+      iop_reset:
        i2o_iop_reset(c);
 
        return rc;
@@ -1260,16 +1262,18 @@ static int __init i2o_iop_init(void)
        if (rc)
                goto exit;
 
-       rc = i2o_driver_init();
-       if (rc)
+       if ((rc = class_register(&i2o_controller_class))) {
+               osm_err("can't register class i2o_controller\n");
                goto device_exit;
+       }
 
-       rc = i2o_exec_init();
-       if (rc)
+       if ((rc = i2o_driver_init()))
+               goto class_exit;
+
+       if ((rc = i2o_exec_init()))
                goto driver_exit;
 
-       rc = i2o_pci_init();
-       if (rc < 0)
+       if ((rc = i2o_pci_init()))
                goto exec_exit;
 
        return 0;
@@ -1280,6 +1284,9 @@ static int __init i2o_iop_init(void)
       driver_exit:
        i2o_driver_exit();
 
+      class_exit:
+       class_unregister(&i2o_controller_class);
+
       device_exit:
        i2o_device_exit();
 
@@ -1297,6 +1304,7 @@ static void __exit i2o_iop_exit(void)
        i2o_pci_exit();
        i2o_exec_exit();
        i2o_driver_exit();
+       class_unregister(&i2o_controller_class);
        i2o_device_exit();
 };
 
index 964fe48..442e345 100644 (file)
 #include <linux/pci.h>
 #include <linux/interrupt.h>
 #include <linux/i2o.h>
-
-/* Module internal functions from other sources */
-extern struct i2o_controller *i2o_iop_alloc(void);
-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);
+#include "core.h"
 
 /* PCI device id table for all I2O controllers */
 static struct pci_device_id __devinitdata i2o_pci_ids[] = {
@@ -248,9 +240,7 @@ static int i2o_pci_irq_enable(struct i2o_controller *c)
        struct pci_dev *pdev = c->pdev;
        int rc;
 
-       wmb();
        writel(0xffffffff, c->irq_mask);
-       wmb();
 
        if (pdev->irq) {
                rc = request_irq(pdev->irq, i2o_pci_interrupt, SA_SHIRQ,
@@ -263,7 +253,6 @@ static int i2o_pci_irq_enable(struct i2o_controller *c)
        }
 
        writel(0x00000000, c->irq_mask);
-       wmb();
 
        printk(KERN_INFO "%s: Installed at IRQ %d\n", c->name, pdev->irq);
 
@@ -278,9 +267,7 @@ static int i2o_pci_irq_enable(struct i2o_controller *c)
  */
 static void i2o_pci_irq_disable(struct i2o_controller *c)
 {
-       wmb();
        writel(0xffffffff, c->irq_mask);
-       wmb();
 
        if (c->pdev->irq > 0)
                free_irq(c->pdev->irq, c);
@@ -406,11 +393,11 @@ static int __devinit i2o_pci_probe(struct pci_dev *pdev,
        if ((rc = i2o_iop_add(c)))
                goto uninstall;
 
+       get_device(&c->device);
+
        if (i960)
                pci_write_config_word(i960, 0x42, 0x03ff);
 
-       get_device(&c->device);
-
        return 0;
 
       uninstall:
@@ -478,6 +465,4 @@ void __exit i2o_pci_exit(void)
 {
        pci_unregister_driver(&i2o_pci_driver);
 };
-
-EXPORT_SYMBOL(i2o_dma_realloc);
 MODULE_DEVICE_TABLE(pci, i2o_pci_ids);
index d4a08d2..36fd18c 100644 (file)
@@ -33,18 +33,6 @@ typedef unsigned int u32;
 #endif                         /* __KERNEL__ */
 
 /*
- *     Software module types
- */
-#define I2O_SOFTWARE_MODULE_IRTOS              0x11
-#define I2O_SOFTWARE_MODULE_IOP_PRIVATE                0x22
-#define I2O_SOFTWARE_MODULE_IOP_CONFIG         0x23
-
-/*
- *     Vendors
- */
-#define I2O_VENDOR_DPT                         0x001b
-
-/*
  * I2O Control IOCTLs and structures
  */
 #define I2O_MAGIC_NUMBER       'i'
@@ -414,6 +402,17 @@ typedef struct _i2o_status_block {
 #define ADAPTER_STATE_FAILED                   0x10
 #define ADAPTER_STATE_FAULTED                  0x11
 
+/*
+ *     Software module types
+ */
+#define I2O_SOFTWARE_MODULE_IRTOS              0x11
+#define I2O_SOFTWARE_MODULE_IOP_PRIVATE                0x22
+#define I2O_SOFTWARE_MODULE_IOP_CONFIG         0x23
+
+/*
+ *     Vendors
+ */
+#define I2O_VENDOR_DPT                         0x001b
 
 /*
  * DPT / Adaptec specific values for i2o_sg_io_hdr flags.
index 2039a87..be937d0 100644 (file)
@@ -119,12 +119,21 @@ struct i2o_driver {
 };
 
 /*
- *     Contains all information which are necessary for DMA operations
+ *     Contains DMA mapped address information
  */
 struct i2o_dma {
        void *virt;
        dma_addr_t phys;
-       u32 len;
+       size_t len;
+};
+
+/*
+ *     Contains IO mapped address information
+ */
+struct i2o_io {
+       void __iomem *virt;
+       unsigned long phys;
+       unsigned long len;
 };
 
 /*
@@ -173,8 +182,8 @@ struct i2o_controller {
        struct semaphore lct_lock;      /* Lock for LCT updates */
        struct i2o_dma status_block;    /* IOP status block */
 
-       struct i2o_dma base;    /* controller messaging unit */
-       struct i2o_dma in_queue;        /* inbound message queue Host->IOP */
+       struct i2o_io base;     /* controller messaging unit */
+       struct i2o_io in_queue; /* inbound message queue Host->IOP */
        struct i2o_dma out_queue;       /* outbound message queue IOP->Host */
 
        unsigned int battery:1;         /* Has a battery backup */
@@ -185,6 +194,7 @@ struct i2o_controller {
        struct resource mem_resource;   /* Mem resource allocated to the IOP */
 
        struct device device;
+       struct class_device classdev;   /* I2O controller class */
        struct i2o_device *exec;        /* Executive */
 #if BITS_PER_LONG == 64
        spinlock_t context_list_lock;   /* lock for context_list */
@@ -235,9 +245,10 @@ struct i2o_sys_tbl {
 extern struct list_head i2o_controllers;
 
 /* Message functions */
-static inline u32 i2o_msg_get(struct i2o_controller *, struct i2o_message __iomem **);
-extern u32 i2o_msg_get_wait(struct i2o_controller *, struct i2o_message __iomem **,
-                           int);
+static inline u32 i2o_msg_get(struct i2o_controller *,
+                             struct i2o_message __iomem **);
+extern u32 i2o_msg_get_wait(struct i2o_controller *,
+                           struct i2o_message __iomem **, int);
 static inline void i2o_msg_post(struct i2o_controller *, u32);
 static inline int i2o_msg_post_wait(struct i2o_controller *, u32,
                                    unsigned long);
@@ -638,14 +649,12 @@ extern int i2o_exec_lct_get(struct i2o_controller *);
  *     available returns I2O_QUEUE_EMPTY and msg is leaved untouched.
  */
 static inline u32 i2o_msg_get(struct i2o_controller *c,
-                             struct i2o_message __iomem **msg)
+                             struct i2o_message __iomem ** msg)
 {
        u32 m = readl(c->in_port);
 
-       if (m != I2O_QUEUE_EMPTY) {
+       if (m != I2O_QUEUE_EMPTY)
                *msg = c->in_queue.virt + m;
-               rmb();
-       }
 
        return m;
 };
@@ -659,7 +668,6 @@ static inline u32 i2o_msg_get(struct i2o_controller *c,
  */
 static inline void i2o_msg_post(struct i2o_controller *c, u32 m)
 {
-       wmb();
        writel(m, c->in_port);
 };
 
@@ -706,14 +714,11 @@ 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 __iomem *i2o_msg_out_to_virt(struct
-                                                             i2o_controller *c,
-                                                             u32 m)
+static inline struct i2o_message *i2o_msg_out_to_virt(struct i2o_controller *c,
+                                                     u32 m)
 {
-       if (unlikely
-           (m < c->out_queue.phys
-            || m >= c->out_queue.phys + c->out_queue.len))
-               return NULL;
+       BUG_ON(m < c->out_queue.phys
+              || m >= c->out_queue.phys + c->out_queue.len);
 
        return c->out_queue.virt + (m - c->out_queue.phys);
 };
@@ -729,69 +734,13 @@ static inline struct i2o_message __iomem *i2o_msg_out_to_virt(struct
  *     work for receive side messages as they are kmalloc objects
  *     in a different pool.
  */
-static inline struct i2o_message __iomem *i2o_msg_in_to_virt(struct i2o_controller *c,
-                                                    u32 m)
+static inline struct i2o_message __iomem *i2o_msg_in_to_virt(struct
+                                                            i2o_controller *c,
+                                                            u32 m)
 {
        return c->in_queue.virt + m;
 };
 
-/**
- *     i2o_dma_alloc - Allocate DMA memory
- *     @dev: struct device pointer to the PCI device of the I2O controller
- *     @addr: i2o_dma struct which should get the DMA buffer
- *     @len: length of the new DMA memory
- *     @gfp_mask: GFP mask
- *
- *     Allocate a coherent DMA memory and write the pointers into addr.
- *
- *     Returns 0 on success or -ENOMEM on failure.
- */
-static inline int i2o_dma_alloc(struct device *dev, struct i2o_dma *addr,
-                               size_t len, unsigned int gfp_mask)
-{
-       struct pci_dev *pdev = to_pci_dev(dev);
-       int dma_64 = 0;
-
-       if ((sizeof(dma_addr_t) > 4) && (pdev->dma_mask == DMA_64BIT_MASK)) {
-                       dma_64 = 1;
-                       if(pci_set_dma_mask(pdev, DMA_32BIT_MASK))
-                               return -ENOMEM;
-       }
-
-       addr->virt = dma_alloc_coherent(dev, len, &addr->phys, gfp_mask);
-
-       if ((sizeof(dma_addr_t) > 4) && dma_64)
-               if(pci_set_dma_mask(pdev, DMA_64BIT_MASK))
-                       printk(KERN_WARNING "i2o: unable to set 64-bit DMA");
-
-       if (!addr->virt)
-               return -ENOMEM;
-
-       memset(addr->virt, 0, len);
-       addr->len = len;
-
-       return 0;
-};
-
-/**
- *     i2o_dma_free - Free DMA memory
- *     @dev: struct device pointer to the PCI device of the I2O controller
- *     @addr: i2o_dma struct which contains the DMA buffer
- *
- *     Free a coherent DMA memory and set virtual address of addr to NULL.
- */
-static inline void i2o_dma_free(struct device *dev, struct i2o_dma *addr)
-{
-       if (addr->virt) {
-               if (addr->phys)
-                       dma_free_coherent(dev, addr->len, addr->virt,
-                                         addr->phys);
-               else
-                       kfree(addr->virt);
-               addr->virt = NULL;
-       }
-};
-
 /*
  *     Endian handling wrapped into the macro - keeps the core code
  *     cleaner.
@@ -1141,16 +1090,13 @@ extern void i2o_debug_state(struct i2o_controller *c);
 #define ELEVEN_WORD_MSG_SIZE   0x000B0000
 #define I2O_MESSAGE_SIZE(x)    ((x)<<16)
 
-/* Special TID Assignments */
-
+/* special TID assignments */
 #define ADAPTER_TID            0
 #define HOST_TID               1
 
-#define MSG_FRAME_SIZE         128     /* i2o_scsi assumes >= 32 */
-#define SG_TABLESIZE           30
-#define NMBR_MSG_FRAMES                128
-
-#define MSG_POOL_SIZE          (MSG_FRAME_SIZE*NMBR_MSG_FRAMES*sizeof(u32))
+/* outbound queue defines */
+#define I2O_MAX_OUTBOUND_MSG_FRAMES    128
+#define I2O_OUTBOUND_MSG_FRAME_SIZE    128     /* in 32-bit words */
 
 #define I2O_POST_WAIT_OK       0
 #define I2O_POST_WAIT_TIMEOUT  -ETIMEDOUT