Merge to Fedora kernel-2.6.18-1.2224_FC5 patched with stable patch-2.6.18.1-vs2.0...
[linux-2.6.git] / drivers / scsi / ibmmca.c
index 917dc2e..2be1dc5 100644 (file)
  
  */
 
-#include <linux/config.h>
-#ifndef LINUX_VERSION_CODE
-#include <linux/version.h>
-#endif
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,45)
-#error "This driver works only with kernel 2.5.45 or higher!"
-#endif
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/types.h>
@@ -36,7 +29,6 @@
 #include <linux/proc_fs.h>
 #include <linux/stat.h>
 #include <linux/mca.h>
-#include <linux/string.h>
 #include <linux/spinlock.h>
 #include <linux/init.h>
 #include <linux/mca-legacy.h>
@@ -292,7 +284,7 @@ struct subsys_list_struct {
 #define INTEGRATED_SCSI          101
 
 /* List of possible IBM-SCSI-adapters */
-struct subsys_list_struct subsys_list[] = {
+static struct subsys_list_struct subsys_list[] = {
        {0x8efc, "IBM SCSI-2 F/W Adapter"},     /* special = 0 */
        {0x8efd, "IBM 7568 Industrial Computer SCSI Adapter w/Cache"},  /* special = 1 */
        {0x8ef8, "IBM Expansion Unit SCSI Controller"}, /* special = 2 */
@@ -451,14 +443,19 @@ static int scsi_id[IM_MAX_HOSTS] = { 7, 7, 7, 7, 7, 7, 7, 7 };
    (that is kernel version 2.1.x) */
 #if defined(MODULE)
 static char *boot_options = NULL;
-MODULE_PARM(boot_options, "s");
-MODULE_PARM(io_port, "1-" __MODULE_STRING(IM_MAX_HOSTS) "i");
-MODULE_PARM(scsi_id, "1-" __MODULE_STRING(IM_MAX_HOSTS) "i");
+module_param(boot_options, charp, 0);
+module_param_array(io_port, int, NULL, 0);
+module_param_array(scsi_id, int, NULL, 0);
+
+#if 0 /* FIXME: No longer exist? --RR */
 MODULE_PARM(display, "1i");
 MODULE_PARM(adisplay, "1i");
 MODULE_PARM(normal, "1i");
 MODULE_PARM(ansi, "1i");
 #endif
+
+MODULE_LICENSE("GPL");
+#endif
 /*counter of concurrent disk read/writes, to turn on/off disk led */
 static int disk_rw_in_progress = 0;
 
@@ -494,7 +491,7 @@ static char *ibmrate(unsigned int, int);
 static int probe_display(int);
 static int probe_bus_mode(int);
 static int device_exists(int, int, int *, int *);
-static struct Scsi_Host *ibmmca_register(Scsi_Host_Template *, int, int, int, char *);
+static struct Scsi_Host *ibmmca_register(struct scsi_host_template *, int, int, int, char *);
 static int option_setup(char *);
 /* local functions needed for proc_info */
 static int ldn_access_load(int, int);
@@ -762,7 +759,7 @@ static int device_inquiry(int host_index, int ldn)
                while (!got_interrupt(host_index))
                        barrier();
 
-               /*if command succesful, break */
+               /*if command successful, break */
                if ((stat_result(host_index) == IM_SCB_CMD_COMPLETED) || (stat_result(host_index) == IM_SCB_CMD_COMPLETED_WITH_RETRIES))
                        return 1;
        }
@@ -887,7 +884,7 @@ static int immediate_assign(int host_index, unsigned int pun, unsigned int lun,
                while (!got_interrupt(host_index))
                        barrier();
 
-               /*if command succesful, break */
+               /*if command successful, break */
                if (stat_result(host_index) == IM_IMMEDIATE_CMD_COMPLETED)
                        return 1;
        }
@@ -923,7 +920,7 @@ static int immediate_feature(int host_index, unsigned int speed, unsigned int ti
                        return 2;
                } else
                        global_command_error_excuse = 0;
-               /*if command succesful, break */
+               /*if command successful, break */
                if (stat_result(host_index) == IM_IMMEDIATE_CMD_COMPLETED)
                        return 1;
        }
@@ -961,7 +958,7 @@ static int immediate_reset(int host_index, unsigned int ldn)
                        /* did not work, finish */
                        return 1;
                }
-               /*if command succesful, break */
+               /*if command successful, break */
                if (stat_result(host_index) == IM_IMMEDIATE_CMD_COMPLETED)
                        return 1;
        }
@@ -1443,7 +1440,7 @@ static int ibmmca_getinfo(char *buf, int slot, void *dev_id)
        struct Scsi_Host *dev = dev_id;
 
        spin_lock_irqsave(dev->host_lock, flags);
-       
+
        shpnt = dev;            /* assign host-structure to local pointer */
        len = 0;                /* set filled text-buffer index to 0 */
        /* get the _special contents of the hostdata structure */
@@ -1458,7 +1455,7 @@ static int ibmmca_getinfo(char *buf, int slot, void *dev_id)
                /* if the integrated subsystem has been found automatically: */
                len += sprintf(buf + len,
                               "Adapter category: integrated\n" "Chip revision level: %d\n" "Chip status: %s\n" "8 kByte NVRAM status: %s\n", ((pos[2] & 0xf0) >> 4), (pos[2] & 1) ? "enabled" : "disabled", (pos[2] & 2) ? "locked" : "accessible");
-       } else if ((speciale >= 0) && (speciale < (sizeof(subsys_list) / sizeof(struct subsys_list_struct)))) {
+       } else if ((speciale >= 0) && (speciale < ARRAY_SIZE(subsys_list))) {
                /* if the subsystem is a slot adapter */
                len += sprintf(buf + len, "Adapter category: slot-card\n" "ROM Segment Address: ");
                if ((pos[2] & 0xf0) == 0xf0)
@@ -1479,16 +1476,16 @@ static int ibmmca_getinfo(char *buf, int slot, void *dev_id)
        while (len % sizeof(int) != (sizeof(int) - 1))
                len += sprintf(buf + len, " ");
        len += sprintf(buf + len, "\n");
-       
+
        spin_unlock_irqrestore(shpnt->host_lock, flags);
-       
+
        return len;
 }
 
-int ibmmca_detect(Scsi_Host_Template * scsi_template)
+int ibmmca_detect(struct scsi_host_template * scsi_template)
 {
        struct Scsi_Host *shpnt;
-       int port, id, i, j, k, list_size, slot;
+       int port, id, i, j, k, slot;
        int devices_on_irq_11 = 0;
        int devices_on_irq_14 = 0;
        int IRQ14_registered = 0;
@@ -1513,7 +1510,7 @@ int ibmmca_detect(Scsi_Host_Template * scsi_template)
 #endif
 
        /* get interrupt request level */
-       if (request_irq(IM_IRQ, interrupt_handler, SA_SHIRQ, "ibmmcascsi", hosts)) {
+       if (request_irq(IM_IRQ, interrupt_handler, IRQF_SHARED, "ibmmcascsi", hosts)) {
                printk(KERN_ERR "IBM MCA SCSI: Unable to get shared IRQ %d.\n", IM_IRQ);
                return 0;
        } else
@@ -1605,8 +1602,7 @@ int ibmmca_detect(Scsi_Host_Template * scsi_template)
        /* now look for other adapters in MCA slots, */
        /* determine the number of known IBM-SCSI-subsystem types */
        /* see the pos[2] dependence to get the adapter port-offset. */
-       list_size = sizeof(subsys_list) / sizeof(struct subsys_list_struct);
-       for (i = 0; i < list_size; i++) {
+       for (i = 0; i < ARRAY_SIZE(subsys_list); i++) {
                /* scan each slot for a fitting adapter id */
                slot = 0;       /* start at slot 0 */
                while ((slot = mca_find_adapter(subsys_list[i].mca_id, slot))
@@ -1639,7 +1635,7 @@ int ibmmca_detect(Scsi_Host_Template * scsi_template)
                                /* IRQ11 is used by SCSI-2 F/W Adapter/A */
                                printk(KERN_DEBUG "IBM MCA SCSI: SCSI-2 F/W adapter needs IRQ 11.\n");
                                /* get interrupt request level */
-                               if (request_irq(IM_IRQ_FW, interrupt_handler, SA_SHIRQ, "ibmmcascsi", hosts)) {
+                               if (request_irq(IM_IRQ_FW, interrupt_handler, IRQF_SHARED, "ibmmcascsi", hosts)) {
                                        printk(KERN_ERR "IBM MCA SCSI: Unable to get shared IRQ %d.\n", IM_IRQ_FW);
                                } else
                                        IRQ11_registered++;
@@ -1671,8 +1667,7 @@ int ibmmca_detect(Scsi_Host_Template * scsi_template)
        /* now check for SCSI-adapters, mapped to the integrated SCSI
         * area. E.g. a W/Cache in MCA-slot 9(!). Do the check correct here,
         * as this is a known effect on some models 95xx. */
-       list_size = sizeof(subsys_list) / sizeof(struct subsys_list_struct);
-       for (i = 0; i < list_size; i++) {
+       for (i = 0; i < ARRAY_SIZE(subsys_list); i++) {
                /* scan each slot for a fitting adapter id */
                slot = mca_find_adapter(subsys_list[i].mca_id, MCA_INTEGSCSI);
                if (slot != MCA_NOTFOUND) {     /* scan through all slots */
@@ -1701,7 +1696,7 @@ int ibmmca_detect(Scsi_Host_Template * scsi_template)
                                /* IRQ11 is used by SCSI-2 F/W Adapter/A */
                                printk(KERN_DEBUG  "IBM MCA SCSI: SCSI-2 F/W adapter needs IRQ 11.\n");
                                /* get interrupt request level */
-                               if (request_irq(IM_IRQ_FW, interrupt_handler, SA_SHIRQ, "ibmmcascsi", hosts))
+                               if (request_irq(IM_IRQ_FW, interrupt_handler, IRQF_SHARED, "ibmmcascsi", hosts))
                                        printk(KERN_ERR "IBM MCA SCSI: Unable to get shared IRQ %d.\n", IM_IRQ_FW);
                                else
                                        IRQ11_registered++;
@@ -1738,7 +1733,7 @@ int ibmmca_detect(Scsi_Host_Template * scsi_template)
        return found;           /* return the number of found SCSI hosts. Should be 1 or 0. */
 }
 
-static struct Scsi_Host *ibmmca_register(Scsi_Host_Template * scsi_template, int port, int id, int adaptertype, char *hostname)
+static struct Scsi_Host *ibmmca_register(struct scsi_host_template * scsi_template, int port, int id, int adaptertype, char *hostname)
 {
        struct Scsi_Host *shpnt;
        int i, j;
@@ -1856,7 +1851,10 @@ static int ibmmca_queuecommand(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *))
                                        next_ldn(host_index) = 7;
                                if (current_ldn == next_ldn(host_index)) {      /* One circle done ? */
                                        /* no non-processing ldn found */
-                                       printk("IBM MCA SCSI: Cannot assign SCSI-device dynamically!\n" "              On ldn 7-14 SCSI-commands everywhere in progress.\n" "              Reporting DID_NO_CONNECT for device (%d,%d).\n", target, cmd->device->lun);
+                                       scmd_printk(KERN_WARNING, cmd,
+       "IBM MCA SCSI: Cannot assign SCSI-device dynamically!\n"
+       "              On ldn 7-14 SCSI-commands everywhere in progress.\n"
+       "              Reporting DID_NO_CONNECT for device.\n");
                                        cmd->result = DID_NO_CONNECT << 16;     /* return no connect */
                                        if (done)
                                                done(cmd);
@@ -2115,7 +2113,7 @@ static int ibmmca_queuecommand(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *))
        return 0;
 }
 
-static int ibmmca_abort(Scsi_Cmnd * cmd)
+static int __ibmmca_abort(Scsi_Cmnd * cmd)
 {
        /* Abort does not work, as the adapter never generates an interrupt on
         * whatever situation is simulated, even when really pending commands
@@ -2222,7 +2220,19 @@ static int ibmmca_abort(Scsi_Cmnd * cmd)
        }
 }
 
-static int ibmmca_host_reset(Scsi_Cmnd * cmd)
+static int ibmmca_abort(Scsi_Cmnd * cmd)
+{
+       struct Scsi_Host *shpnt = cmd->device->host;
+       int rc;
+
+       spin_lock_irq(shpnt->host_lock);
+       rc = __ibmmca_abort(cmd);
+       spin_unlock_irq(shpnt->host_lock);
+
+       return rc;
+}
+
+static int __ibmmca_host_reset(Scsi_Cmnd * cmd)
 {
        struct Scsi_Host *shpnt;
        Scsi_Cmnd *cmd_aid;
@@ -2230,8 +2240,7 @@ static int ibmmca_host_reset(Scsi_Cmnd * cmd)
        int host_index;
        unsigned long imm_command;
 
-       if (cmd == NULL)
-               BUG();
+       BUG_ON(cmd == NULL);
 
        ticks = IM_RESET_DELAY * HZ;
        shpnt = cmd->device->host;
@@ -2309,6 +2318,18 @@ static int ibmmca_host_reset(Scsi_Cmnd * cmd)
        return SUCCESS;
 }
 
+static int ibmmca_host_reset(Scsi_Cmnd * cmd)
+{
+       struct Scsi_Host *shpnt = cmd->device->host;
+       int rc;
+
+       spin_lock_irq(shpnt->host_lock);
+       rc = __ibmmca_host_reset(cmd);
+       spin_unlock_irq(shpnt->host_lock);
+
+       return rc;
+}
+
 static int ibmmca_biosparam(struct scsi_device *sdev, struct block_device *bdev, sector_t capacity, int *info)
 {
        int size = capacity;
@@ -2387,8 +2408,7 @@ static int ibmmca_proc_info(struct Scsi_Host *shpnt, char *buffer, char **start,
        spin_lock_irqsave(hosts[i]->host_lock, flags);  /* Check it */
        host_index = i;
        if (!shpnt) {
-               len += sprintf(buffer + len, "\nIBM MCA SCSI: Can't find adapter for host number %d\n",
-                               shpnt->host_no);
+               len += sprintf(buffer + len, "\nIBM MCA SCSI: Can't find adapter");
                return len;
        }
        max_pun = subsystem_maxid(host_index);
@@ -2464,12 +2484,12 @@ static int option_setup(char *str)
        }
        ints[0] = i - 1;
        internal_ibmmca_scsi_setup(cur, ints);
-       return 0;
+       return 1;
 }
 
 __setup("ibmmcascsi=", option_setup);
 
-static Scsi_Host_Template driver_template = {
+static struct scsi_host_template driver_template = {
           .proc_name      = "ibmmca",
          .proc_info      = ibmmca_proc_info,
           .name           = "IBM SCSI-Subsystem",