linux 2.6.16.38 w/ vs2.0.3-rc1
[linux-2.6.git] / drivers / scsi / aacraid / linit.c
index e42a479..2716178 100644 (file)
  * Abstract: Linux Driver entry module for Adaptec RAID Array Controller
  */
 
+#define AAC_DRIVER_VERSION             "1.1-4"
+#ifndef AAC_DRIVER_BRANCH
+#define AAC_DRIVER_BRANCH              ""
+#endif
+#define AAC_DRIVER_BUILD_DATE          __DATE__ " " __TIME__
+#define AAC_DRIVERNAME                 "aacraid"
 
 #include <linux/compat.h>
 #include <linux/blkdev.h>
 #include <linux/pci.h>
 #include <linux/slab.h>
 #include <linux/spinlock.h>
-#include <linux/dma-mapping.h>
 #include <linux/syscalls.h>
 #include <linux/delay.h>
 #include <linux/smp_lock.h>
-#include <linux/kthread.h>
 #include <asm/semaphore.h>
 
 #include <scsi/scsi.h>
 
 #include "aacraid.h"
 
-#define AAC_DRIVER_VERSION             "1.1-5"
-#ifndef AAC_DRIVER_BRANCH
-#define AAC_DRIVER_BRANCH              ""
-#endif
-#define AAC_DRIVER_BUILD_DATE          __DATE__ " " __TIME__
-#define AAC_DRIVERNAME                 "aacraid"
-
 #ifdef AAC_DRIVER_BUILD
 #define _str(x) #x
 #define str(x) _str(x)
@@ -74,7 +71,7 @@
 MODULE_AUTHOR("Red Hat Inc and Adaptec");
 MODULE_DESCRIPTION("Dell PERC2, 2/Si, 3/Si, 3/Di, "
                   "Adaptec Advanced Raid Products, "
-                  "HP NetRAID-4M, IBM ServeRAID & ICP SCSI driver");
+                  "and HP NetRAID-4M SCSI driver");
 MODULE_LICENSE("GPL");
 MODULE_VERSION(AAC_DRIVER_FULL_VERSION);
 
@@ -119,7 +116,7 @@ static struct pci_device_id aac_pci_tbl[] = {
        { 0x9005, 0x0286, 0x9005, 0x029f, 0, 0, 26 }, /* ICP9014R0 (Lancer) */
        { 0x9005, 0x0286, 0x9005, 0x02a0, 0, 0, 27 }, /* ICP9047MA (Lancer) */
        { 0x9005, 0x0286, 0x9005, 0x02a1, 0, 0, 28 }, /* ICP9087MA (Lancer) */
-       { 0x9005, 0x0286, 0x9005, 0x02a3, 0, 0, 29 }, /* ICP5445AU (Hurricane44) */
+       { 0x9005, 0x0286, 0x9005, 0x02a3, 0, 0, 29 }, /* ICP5085AU (Hurricane) */
        { 0x9005, 0x0285, 0x9005, 0x02a4, 0, 0, 30 }, /* ICP9085LI (Marauder-X) */
        { 0x9005, 0x0285, 0x9005, 0x02a5, 0, 0, 31 }, /* ICP5085BR (Marauder-E) */
        { 0x9005, 0x0286, 0x9005, 0x02a6, 0, 0, 32 }, /* ICP9067MA (Intruder-6) */
@@ -143,7 +140,7 @@ static struct pci_device_id aac_pci_tbl[] = {
        { 0x9005, 0x0285, 0x9005, 0x0298, 0, 0, 48 }, /* ASR-4000SAS (BlackBird) */
        { 0x9005, 0x0285, 0x9005, 0x0299, 0, 0, 49 }, /* ASR-4800SAS (Marauder-X) */
        { 0x9005, 0x0285, 0x9005, 0x029a, 0, 0, 50 }, /* ASR-4805SAS (Marauder-E) */
-       { 0x9005, 0x0286, 0x9005, 0x02a2, 0, 0, 51 }, /* ASR-3800SAS (Hurricane44) */
+       { 0x9005, 0x0286, 0x9005, 0x02a2, 0, 0, 51 }, /* ASR-4810SAS (Hurricane */
 
        { 0x9005, 0x0285, 0x1028, 0x0287, 0, 0, 52 }, /* Perc 320/DC*/
        { 0x1011, 0x0046, 0x9005, 0x0365, 0, 0, 53 }, /* Adaptec 5400S (Mustang)*/
@@ -195,7 +192,7 @@ static struct aac_driver_ident aac_drivers[] = {
        { aac_rkt_init, "aacraid",  "ICP     ", "ICP9014R0       ", 1 }, /* ICP9014R0 (Lancer) */
        { aac_rkt_init, "aacraid",  "ICP     ", "ICP9047MA       ", 1 }, /* ICP9047MA (Lancer) */
        { aac_rkt_init, "aacraid",  "ICP     ", "ICP9087MA       ", 1 }, /* ICP9087MA (Lancer) */
-       { aac_rkt_init, "aacraid",  "ICP     ", "ICP5445AU       ", 1 }, /* ICP5445AU (Hurricane44) */
+       { aac_rkt_init, "aacraid",  "ICP     ", "ICP5085AU       ", 1 }, /* ICP5085AU (Hurricane) */
        { aac_rx_init, "aacraid",  "ICP     ", "ICP9085LI       ", 1 }, /* ICP9085LI (Marauder-X) */
        { aac_rx_init, "aacraid",  "ICP     ", "ICP5085BR       ", 1 }, /* ICP5085BR (Marauder-E) */
        { aac_rkt_init, "aacraid",  "ICP     ", "ICP9067MA       ", 1 }, /* ICP9067MA (Intruder-6) */
@@ -217,7 +214,7 @@ static struct aac_driver_ident aac_drivers[] = {
        { aac_rx_init, "aacraid",  "ADAPTEC ", "ASR-4000SAS     ", 1 }, /* ASR-4000SAS (BlackBird & AvonPark) */
        { aac_rx_init, "aacraid",  "ADAPTEC ", "ASR-4800SAS     ", 1 }, /* ASR-4800SAS (Marauder-X) */
        { aac_rx_init, "aacraid",  "ADAPTEC ", "ASR-4805SAS     ", 1 }, /* ASR-4805SAS (Marauder-E) */
-       { aac_rkt_init, "aacraid",  "ADAPTEC ", "ASR-3800SAS     ", 1 }, /* ASR-3800SAS (Hurricane44) */
+       { aac_rkt_init, "aacraid",  "ADAPTEC ", "ASR-4810SAS     ", 1 }, /* ASR-4810SAS (Hurricane) */
 
        { aac_rx_init, "percraid", "DELL    ", "PERC 320/DC     ", 2, AAC_QUIRK_31BIT | AAC_QUIRK_34SG }, /* Perc 320/DC*/
        { aac_sa_init, "aacraid",  "ADAPTEC ", "Adaptec 5400S   ", 4, AAC_QUIRK_34SG }, /* Adaptec 5400S (Mustang)*/
@@ -244,7 +241,6 @@ static struct aac_driver_ident aac_drivers[] = {
 static int aac_queuecommand(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
 {
        cmd->scsi_done = done;
-       cmd->SCp.phase = AAC_OWNER_LOWLEVEL;
        return (aac_scsi_cmd(cmd) ? FAILED : 0);
 } 
 
@@ -453,10 +449,15 @@ static int aac_eh_reset(struct scsi_cmnd* cmd)
 
        printk(KERN_ERR "%s: Host adapter reset request. SCSI hang ?\n", 
                                        AAC_DRIVERNAME);
+
+
+       spin_lock_irq(host->host_lock);
+
        aac = (struct aac_dev *)host->hostdata;
        if (aac_adapter_check_health(aac)) {
                printk(KERN_ERR "%s: Host adapter appears dead\n", 
                                AAC_DRIVERNAME);
+               spin_unlock_irq(host->host_lock);
                return -ENODEV;
        }
        /*
@@ -468,8 +469,7 @@ static int aac_eh_reset(struct scsi_cmnd* cmd)
                __shost_for_each_device(dev, host) {
                        spin_lock_irqsave(&dev->list_lock, flags);
                        list_for_each_entry(command, &dev->cmd_list, list) {
-                               if ((command != cmd) &&
-                                   (command->SCp.phase == AAC_OWNER_FIRMWARE)) {
+                               if (command->serial_number) {
                                        active++;
                                        break;
                                }
@@ -482,10 +482,13 @@ static int aac_eh_reset(struct scsi_cmnd* cmd)
                /*
                 * We can exit If all the commands are complete
                 */
+               spin_unlock_irq(host->host_lock);
                if (active == 0)
                        return SUCCESS;
                ssleep(1);
+               spin_lock_irq(host->host_lock);
        }
+       spin_unlock_irq(host->host_lock);
        printk(KERN_ERR "%s: SCSI bus appears hung\n", AAC_DRIVERNAME);
        return -ETIMEDOUT;
 }
@@ -564,12 +567,12 @@ static long aac_compat_do_ioctl(struct aac_dev *dev, unsigned cmd, unsigned long
                
                f = compat_alloc_user_space(sizeof(*f));
                ret = 0;
-               if (clear_user(f, sizeof(*f)))
+               if (clear_user(f, sizeof(*f) != sizeof(*f)))
                        ret = -EFAULT;
                if (copy_in_user(f, (void __user *)arg, sizeof(struct fib_ioctl) - sizeof(u32)))
                        ret = -EFAULT;
                if (!ret)
-                       ret = aac_do_ioctl(dev, cmd, f);
+                       ret = aac_do_ioctl(dev, cmd, (void __user *)arg);
                break;
        }
 
@@ -682,18 +685,6 @@ static ssize_t aac_show_serial_number(struct class_device *class_dev,
        return len;
 }
 
-static ssize_t aac_show_max_channel(struct class_device *class_dev, char *buf)
-{
-       return snprintf(buf, PAGE_SIZE, "%d\n",
-         class_to_shost(class_dev)->max_channel);
-}
-
-static ssize_t aac_show_max_id(struct class_device *class_dev, char *buf)
-{
-       return snprintf(buf, PAGE_SIZE, "%d\n",
-         class_to_shost(class_dev)->max_id);
-}
-
 
 static struct class_device_attribute aac_model = {
        .attr = {
@@ -737,20 +728,6 @@ static struct class_device_attribute aac_serial_number = {
        },
        .show = aac_show_serial_number,
 };
-static struct class_device_attribute aac_max_channel = {
-       .attr = {
-               .name = "max_channel",
-               .mode = S_IRUGO,
-       },
-       .show = aac_show_max_channel,
-};
-static struct class_device_attribute aac_max_id = {
-       .attr = {
-               .name = "max_id",
-               .mode = S_IRUGO,
-       },
-       .show = aac_show_max_id,
-};
 
 static struct class_device_attribute *aac_attrs[] = {
        &aac_model,
@@ -759,8 +736,6 @@ static struct class_device_attribute *aac_attrs[] = {
        &aac_monitor_version,
        &aac_bios_version,
        &aac_serial_number,
-       &aac_max_channel,
-       &aac_max_id,
        NULL
 };
 
@@ -798,7 +773,6 @@ static struct scsi_host_template aac_driver_template = {
        .cmd_per_lun                    = AAC_NUM_IO_FIB, 
 #endif 
        .use_clustering                 = ENABLE_CLUSTERING,
-       .emulated                       = 1,
 };
 
 
@@ -822,19 +796,18 @@ static int __devinit aac_probe_one(struct pci_dev *pdev,
        error = pci_enable_device(pdev);
        if (error)
                goto out;
-       error = -ENODEV;
 
        if (pci_set_dma_mask(pdev, DMA_32BIT_MASK) || 
                        pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK))
-               goto out_disable_pdev;
+               goto out;
        /*
         * If the quirk31 bit is set, the adapter needs adapter
         * to driver communication memory to be allocated below 2gig
         */
        if (aac_drivers[index].quirks & AAC_QUIRK_31BIT) 
-               if (pci_set_dma_mask(pdev, DMA_31BIT_MASK) ||
-                               pci_set_consistent_dma_mask(pdev, DMA_31BIT_MASK))
-                       goto out_disable_pdev;
+               if (pci_set_dma_mask(pdev, 0x7FFFFFFFULL) ||
+                               pci_set_consistent_dma_mask(pdev, 0x7FFFFFFFULL))
+                       goto out;
        
        pci_set_master(pdev);
 
@@ -877,10 +850,10 @@ static int __devinit aac_probe_one(struct pci_dev *pdev,
        /*
         *      Start any kernel threads needed
         */
-       aac->thread = kthread_run(aac_command_thread, aac, AAC_DRIVERNAME);
-       if (IS_ERR(aac->thread)) {
+       aac->thread_pid = kernel_thread((int (*)(void *))aac_command_thread,
+         aac, 0);
+       if (aac->thread_pid < 0) {
                printk(KERN_ERR "aacraid: Unable to create command thread.\n");
-               error = PTR_ERR(aac->thread);
                goto out_deinit;
        }
 
@@ -929,9 +902,9 @@ static int __devinit aac_probe_one(struct pci_dev *pdev,
         * physical channels are address by their actual physical number+1
         */
        if (aac->nondasd_support == 1)
-               shost->max_channel = aac->maximum_num_channels;
+               shost->max_channel = aac->maximum_num_channels + 1;
        else
-               shost->max_channel = 0;
+               shost->max_channel = 1;
 
        aac_get_config_status(aac);
        aac_get_containers(aac);
@@ -961,7 +934,9 @@ static int __devinit aac_probe_one(struct pci_dev *pdev,
        return 0;
 
  out_deinit:
-       kthread_stop(aac->thread);
+       kill_proc(aac->thread_pid, SIGKILL, 0);
+       wait_for_completion(&aac->aif_completion);
+
        aac_send_shutdown(aac);
        aac_adapter_disable_int(aac);
        free_irq(pdev->irq, aac);
@@ -995,7 +970,8 @@ static void __devexit aac_remove_one(struct pci_dev *pdev)
 
        scsi_remove_host(shost);
 
-       kthread_stop(aac->thread);
+       kill_proc(aac->thread_pid, SIGKILL, 0);
+       wait_for_completion(&aac->aif_completion);
 
        aac_send_shutdown(aac);
        aac_adapter_disable_int(aac);
@@ -1045,8 +1021,7 @@ static int __init aac_init(void)
 
 static void __exit aac_exit(void)
 {
-       if (aac_cfg_major > -1)
-               unregister_chrdev(aac_cfg_major, "aac");
+       unregister_chrdev(aac_cfg_major, "aac");
        pci_unregister_driver(&aac_pci_driver);
 }