aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi
diff options
context:
space:
mode:
authorMatthew Wilcox <matthew@wil.cx>2007-10-05 15:55:12 -0400
committerJames Bottomley <jejb@mulgrave.localdomain>2007-10-23 15:23:28 -0400
commit99c9e0a1d6cfe1ba1169a7a81435ee85bc00e4a1 (patch)
treea946e291692f09e3b4ecc71ceb9dd264a9f7acea /drivers/scsi
parent8022fbdacb0e9193a5dfb666479d1fc2ca63ecf1 (diff)
[SCSI] sym53c8xx: Make interrupt handler capable of returning IRQ_NONE
Make sym_interrupt return an irqreturn_t instead of void, and take a Scsi_Host instead of a sym_hcb. Pass the Scsi_Host to the interrupt handler instead of the sym_hcb. Rename the host_data to sym_data. Keep a pci_dev pointer in the sym_data. Rename the Scsi_Host from instance to shost. Signed-off-by: Matthew Wilcox <willy@linux.intel.com> Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
Diffstat (limited to 'drivers/scsi')
-rw-r--r--drivers/scsi/sym53c8xx_2/sym_glue.c107
-rw-r--r--drivers/scsi/sym53c8xx_2/sym_glue.h6
-rw-r--r--drivers/scsi/sym53c8xx_2/sym_hipd.c16
-rw-r--r--drivers/scsi/sym53c8xx_2/sym_hipd.h2
4 files changed, 66 insertions, 65 deletions
diff --git a/drivers/scsi/sym53c8xx_2/sym_glue.c b/drivers/scsi/sym53c8xx_2/sym_glue.c
index 9521f0ea4129..1c18b3b9aa15 100644
--- a/drivers/scsi/sym53c8xx_2/sym_glue.c
+++ b/drivers/scsi/sym53c8xx_2/sym_glue.c
@@ -39,7 +39,6 @@
39 */ 39 */
40#include <linux/ctype.h> 40#include <linux/ctype.h>
41#include <linux/init.h> 41#include <linux/init.h>
42#include <linux/interrupt.h>
43#include <linux/module.h> 42#include <linux/module.h>
44#include <linux/moduleparam.h> 43#include <linux/moduleparam.h>
45#include <linux/spinlock.h> 44#include <linux/spinlock.h>
@@ -549,21 +548,23 @@ static int sym53c8xx_queue_command(struct scsi_cmnd *cmd,
549 */ 548 */
550static irqreturn_t sym53c8xx_intr(int irq, void *dev_id) 549static irqreturn_t sym53c8xx_intr(int irq, void *dev_id)
551{ 550{
552 struct sym_hcb *np = dev_id; 551 struct Scsi_Host *shost = dev_id;
552 struct sym_data *sym_data = shost_priv(shost);
553 irqreturn_t result;
553 554
554 /* Avoid spinloop trying to handle interrupts on frozen device */ 555 /* Avoid spinloop trying to handle interrupts on frozen device */
555 if (pci_channel_offline(np->s.device)) 556 if (pci_channel_offline(sym_data->pdev))
556 return IRQ_NONE; 557 return IRQ_NONE;
557 558
558 if (DEBUG_FLAGS & DEBUG_TINY) printf_debug ("["); 559 if (DEBUG_FLAGS & DEBUG_TINY) printf_debug ("[");
559 560
560 spin_lock(np->s.host->host_lock); 561 spin_lock(shost->host_lock);
561 sym_interrupt(np); 562 result = sym_interrupt(shost);
562 spin_unlock(np->s.host->host_lock); 563 spin_unlock(shost->host_lock);
563 564
564 if (DEBUG_FLAGS & DEBUG_TINY) printf_debug ("]\n"); 565 if (DEBUG_FLAGS & DEBUG_TINY) printf_debug ("]\n");
565 566
566 return IRQ_HANDLED; 567 return result;
567} 568}
568 569
569/* 570/*
@@ -613,22 +614,19 @@ static int sym_eh_handler(int op, char *opname, struct scsi_cmnd *cmd)
613 */ 614 */
614#define WAIT_FOR_PCI_RECOVERY 35 615#define WAIT_FOR_PCI_RECOVERY 35
615 if (pci_channel_offline(pdev)) { 616 if (pci_channel_offline(pdev)) {
616 struct host_data *hostdata = shost_priv(host); 617 struct sym_data *sym_data = shost_priv(host);
617 struct completion *io_reset; 618 struct completion *io_reset;
618 int finished_reset = 0; 619 int finished_reset = 0;
619 init_completion(&eh_done); 620 init_completion(&eh_done);
620 spin_lock_irq(host->host_lock); 621 spin_lock_irq(host->host_lock);
621 /* Make sure we didn't race */ 622 /* Make sure we didn't race */
622 if (pci_channel_offline(pdev)) { 623 if (pci_channel_offline(pdev)) {
623 if (!hostdata->io_reset) 624 if (!sym_data->io_reset)
624 hostdata->io_reset = &eh_done; 625 sym_data->io_reset = &eh_done;
625 io_reset = hostdata->io_reset; 626 io_reset = sym_data->io_reset;
626 } else { 627 } else {
627 io_reset = NULL;
628 }
629
630 if (!pci_channel_offline(pdev))
631 finished_reset = 1; 628 finished_reset = 1;
629 }
632 spin_unlock_irq(host->host_lock); 630 spin_unlock_irq(host->host_lock);
633 if (!finished_reset) 631 if (!finished_reset)
634 finished_reset = wait_for_completion_timeout(io_reset, 632 finished_reset = wait_for_completion_timeout(io_reset,
@@ -1273,9 +1271,9 @@ static void sym_free_resources(struct sym_hcb *np, struct pci_dev *pdev)
1273static struct Scsi_Host * __devinit sym_attach(struct scsi_host_template *tpnt, 1271static struct Scsi_Host * __devinit sym_attach(struct scsi_host_template *tpnt,
1274 int unit, struct sym_device *dev) 1272 int unit, struct sym_device *dev)
1275{ 1273{
1276 struct host_data *host_data; 1274 struct sym_data *sym_data;
1277 struct sym_hcb *np = NULL; 1275 struct sym_hcb *np = NULL;
1278 struct Scsi_Host *instance = NULL; 1276 struct Scsi_Host *shost;
1279 struct pci_dev *pdev = dev->pdev; 1277 struct pci_dev *pdev = dev->pdev;
1280 unsigned long flags; 1278 unsigned long flags;
1281 struct sym_fw *fw; 1279 struct sym_fw *fw;
@@ -1289,15 +1287,12 @@ static struct Scsi_Host * __devinit sym_attach(struct scsi_host_template *tpnt,
1289 */ 1287 */
1290 fw = sym_find_firmware(&dev->chip); 1288 fw = sym_find_firmware(&dev->chip);
1291 if (!fw) 1289 if (!fw)
1292 goto attach_failed; 1290 return NULL;
1293 1291
1294 /* 1292 shost = scsi_host_alloc(tpnt, sizeof(*sym_data));
1295 * Allocate host_data structure 1293 if (!shost)
1296 */ 1294 return NULL;
1297 instance = scsi_host_alloc(tpnt, sizeof(*host_data)); 1295 sym_data = shost_priv(shost);
1298 if (!instance)
1299 goto attach_failed;
1300 host_data = (struct host_data *) instance->hostdata;
1301 1296
1302 /* 1297 /*
1303 * Allocate immediately the host control block, 1298 * Allocate immediately the host control block,
@@ -1310,8 +1305,9 @@ static struct Scsi_Host * __devinit sym_attach(struct scsi_host_template *tpnt,
1310 goto attach_failed; 1305 goto attach_failed;
1311 np->s.device = pdev; 1306 np->s.device = pdev;
1312 np->bus_dmat = &pdev->dev; /* Result in 1 DMA pool per HBA */ 1307 np->bus_dmat = &pdev->dev; /* Result in 1 DMA pool per HBA */
1313 host_data->ncb = np; 1308 sym_data->ncb = np;
1314 np->s.host = instance; 1309 sym_data->pdev = pdev;
1310 np->s.host = shost;
1315 1311
1316 pci_set_drvdata(pdev, np); 1312 pci_set_drvdata(pdev, np);
1317 1313
@@ -1358,7 +1354,7 @@ static struct Scsi_Host * __devinit sym_attach(struct scsi_host_template *tpnt,
1358 if (dev->ram_base) 1354 if (dev->ram_base)
1359 np->ram_ba = (u32)dev->ram_base; 1355 np->ram_ba = (u32)dev->ram_base;
1360 1356
1361 if (sym_hcb_attach(instance, fw, dev->nvram)) 1357 if (sym_hcb_attach(shost, fw, dev->nvram))
1362 goto attach_failed; 1358 goto attach_failed;
1363 1359
1364 /* 1360 /*
@@ -1366,7 +1362,8 @@ static struct Scsi_Host * __devinit sym_attach(struct scsi_host_template *tpnt,
1366 * If we synchonize the C code with SCRIPTS on interrupt, 1362 * If we synchonize the C code with SCRIPTS on interrupt,
1367 * we do not want to share the INTR line at all. 1363 * we do not want to share the INTR line at all.
1368 */ 1364 */
1369 if (request_irq(pdev->irq, sym53c8xx_intr, IRQF_SHARED, NAME53C8XX, np)) { 1365 if (request_irq(pdev->irq, sym53c8xx_intr, IRQF_SHARED, NAME53C8XX,
1366 shost)) {
1370 printf_err("%s: request irq %u failure\n", 1367 printf_err("%s: request irq %u failure\n",
1371 sym_name(np), pdev->irq); 1368 sym_name(np), pdev->irq);
1372 goto attach_failed; 1369 goto attach_failed;
@@ -1376,7 +1373,7 @@ static struct Scsi_Host * __devinit sym_attach(struct scsi_host_template *tpnt,
1376 * After SCSI devices have been opened, we cannot 1373 * After SCSI devices have been opened, we cannot
1377 * reset the bus safely, so we do it here. 1374 * reset the bus safely, so we do it here.
1378 */ 1375 */
1379 spin_lock_irqsave(instance->host_lock, flags); 1376 spin_lock_irqsave(shost->host_lock, flags);
1380 if (sym_reset_scsi_bus(np, 0)) 1377 if (sym_reset_scsi_bus(np, 0))
1381 goto reset_failed; 1378 goto reset_failed;
1382 1379
@@ -1398,37 +1395,37 @@ static struct Scsi_Host * __devinit sym_attach(struct scsi_host_template *tpnt,
1398 * Fill Linux host instance structure 1395 * Fill Linux host instance structure
1399 * and return success. 1396 * and return success.
1400 */ 1397 */
1401 instance->max_channel = 0; 1398 shost->max_channel = 0;
1402 instance->this_id = np->myaddr; 1399 shost->this_id = np->myaddr;
1403 instance->max_id = np->maxwide ? 16 : 8; 1400 shost->max_id = np->maxwide ? 16 : 8;
1404 instance->max_lun = SYM_CONF_MAX_LUN; 1401 shost->max_lun = SYM_CONF_MAX_LUN;
1405 instance->unique_id = pci_resource_start(pdev, 0); 1402 shost->unique_id = pci_resource_start(pdev, 0);
1406 instance->cmd_per_lun = SYM_CONF_MAX_TAG; 1403 shost->cmd_per_lun = SYM_CONF_MAX_TAG;
1407 instance->can_queue = (SYM_CONF_MAX_START-2); 1404 shost->can_queue = (SYM_CONF_MAX_START-2);
1408 instance->sg_tablesize = SYM_CONF_MAX_SG; 1405 shost->sg_tablesize = SYM_CONF_MAX_SG;
1409 instance->max_cmd_len = 16; 1406 shost->max_cmd_len = 16;
1410 BUG_ON(sym2_transport_template == NULL); 1407 BUG_ON(sym2_transport_template == NULL);
1411 instance->transportt = sym2_transport_template; 1408 shost->transportt = sym2_transport_template;
1412 1409
1413 /* 53c896 rev 1 errata: DMA may not cross 16MB boundary */ 1410 /* 53c896 rev 1 errata: DMA may not cross 16MB boundary */
1414 if (pdev->device == PCI_DEVICE_ID_NCR_53C896 && pdev->revision < 2) 1411 if (pdev->device == PCI_DEVICE_ID_NCR_53C896 && pdev->revision < 2)
1415 instance->dma_boundary = 0xFFFFFF; 1412 shost->dma_boundary = 0xFFFFFF;
1416 1413
1417 spin_unlock_irqrestore(instance->host_lock, flags); 1414 spin_unlock_irqrestore(shost->host_lock, flags);
1418 1415
1419 return instance; 1416 return shost;
1420 1417
1421 reset_failed: 1418 reset_failed:
1422 printf_err("%s: FATAL ERROR: CHECK SCSI BUS - CABLES, " 1419 printf_err("%s: FATAL ERROR: CHECK SCSI BUS - CABLES, "
1423 "TERMINATION, DEVICE POWER etc.!\n", sym_name(np)); 1420 "TERMINATION, DEVICE POWER etc.!\n", sym_name(np));
1424 spin_unlock_irqrestore(instance->host_lock, flags); 1421 spin_unlock_irqrestore(shost->host_lock, flags);
1425 attach_failed: 1422 attach_failed:
1426 if (!instance) 1423 if (!shost)
1427 return NULL; 1424 return NULL;
1428 printf_info("%s: giving up ...\n", sym_name(np)); 1425 printf_info("%s: giving up ...\n", sym_name(np));
1429 if (np) 1426 if (np)
1430 sym_free_resources(np, pdev); 1427 sym_free_resources(np, pdev);
1431 scsi_host_put(instance); 1428 scsi_host_put(shost);
1432 1429
1433 return NULL; 1430 return NULL;
1434 } 1431 }
@@ -1702,7 +1699,7 @@ static int __devinit sym2_probe(struct pci_dev *pdev,
1702{ 1699{
1703 struct sym_device sym_dev; 1700 struct sym_device sym_dev;
1704 struct sym_nvram nvram; 1701 struct sym_nvram nvram;
1705 struct Scsi_Host *instance; 1702 struct Scsi_Host *shost;
1706 1703
1707 memset(&sym_dev, 0, sizeof(sym_dev)); 1704 memset(&sym_dev, 0, sizeof(sym_dev));
1708 memset(&nvram, 0, sizeof(nvram)); 1705 memset(&nvram, 0, sizeof(nvram));
@@ -1729,13 +1726,13 @@ static int __devinit sym2_probe(struct pci_dev *pdev,
1729 1726
1730 sym_get_nvram(&sym_dev, &nvram); 1727 sym_get_nvram(&sym_dev, &nvram);
1731 1728
1732 instance = sym_attach(&sym2_template, attach_count, &sym_dev); 1729 shost = sym_attach(&sym2_template, attach_count, &sym_dev);
1733 if (!instance) 1730 if (!shost)
1734 goto free; 1731 goto free;
1735 1732
1736 if (scsi_add_host(instance, &pdev->dev)) 1733 if (scsi_add_host(shost, &pdev->dev))
1737 goto detach; 1734 goto detach;
1738 scsi_scan_host(instance); 1735 scsi_scan_host(shost);
1739 1736
1740 attach_count++; 1737 attach_count++;
1741 1738
@@ -1884,12 +1881,12 @@ static void sym2_io_resume(struct pci_dev *pdev)
1884{ 1881{
1885 struct sym_hcb *np = pci_get_drvdata(pdev); 1882 struct sym_hcb *np = pci_get_drvdata(pdev);
1886 struct Scsi_Host *shost = np->s.host; 1883 struct Scsi_Host *shost = np->s.host;
1887 struct host_data *hostdata = shost_priv(shost); 1884 struct sym_data *sym_data = shost_priv(shost);
1888 1885
1889 spin_lock_irq(shost->host_lock); 1886 spin_lock_irq(shost->host_lock);
1890 if (hostdata->io_reset) 1887 if (sym_data->io_reset)
1891 complete_all(hostdata->io_reset); 1888 complete_all(sym_data->io_reset);
1892 hostdata->io_reset = NULL; 1889 sym_data->io_reset = NULL;
1893 spin_unlock_irq(shost->host_lock); 1890 spin_unlock_irq(shost->host_lock);
1894} 1891}
1895 1892
diff --git a/drivers/scsi/sym53c8xx_2/sym_glue.h b/drivers/scsi/sym53c8xx_2/sym_glue.h
index ab2de1ca9438..98261a5af87d 100644
--- a/drivers/scsi/sym53c8xx_2/sym_glue.h
+++ b/drivers/scsi/sym53c8xx_2/sym_glue.h
@@ -42,6 +42,7 @@
42 42
43#include <linux/completion.h> 43#include <linux/completion.h>
44#include <linux/delay.h> 44#include <linux/delay.h>
45#include <linux/interrupt.h>
45#include <linux/ioport.h> 46#include <linux/ioport.h>
46#include <linux/pci.h> 47#include <linux/pci.h>
47#include <linux/string.h> 48#include <linux/string.h>
@@ -217,14 +218,15 @@ struct sym_device {
217/* 218/*
218 * Driver host data structure. 219 * Driver host data structure.
219 */ 220 */
220struct host_data { 221struct sym_data {
221 struct sym_hcb *ncb; 222 struct sym_hcb *ncb;
222 struct completion *io_reset; /* PCI error handling */ 223 struct completion *io_reset; /* PCI error handling */
224 struct pci_dev *pdev;
223}; 225};
224 226
225static inline struct sym_hcb * sym_get_hcb(struct Scsi_Host *host) 227static inline struct sym_hcb * sym_get_hcb(struct Scsi_Host *host)
226{ 228{
227 return ((struct host_data *)host->hostdata)->ncb; 229 return ((struct sym_data *)host->hostdata)->ncb;
228} 230}
229 231
230#include "sym_fw.h" 232#include "sym_fw.h"
diff --git a/drivers/scsi/sym53c8xx_2/sym_hipd.c b/drivers/scsi/sym53c8xx_2/sym_hipd.c
index 13fd5b2c56fc..5d2079f9e596 100644
--- a/drivers/scsi/sym53c8xx_2/sym_hipd.c
+++ b/drivers/scsi/sym53c8xx_2/sym_hipd.c
@@ -2760,8 +2760,9 @@ reset_all:
2760 * Use at your own decision and risk. 2760 * Use at your own decision and risk.
2761 */ 2761 */
2762 2762
2763void sym_interrupt (struct sym_hcb *np) 2763irqreturn_t sym_interrupt(struct Scsi_Host *shost)
2764{ 2764{
2765 struct sym_hcb *np = sym_get_hcb(shost);
2765 u_char istat, istatc; 2766 u_char istat, istatc;
2766 u_char dstat; 2767 u_char dstat;
2767 u_short sist; 2768 u_short sist;
@@ -2786,7 +2787,7 @@ void sym_interrupt (struct sym_hcb *np)
2786 } 2787 }
2787 2788
2788 if (!(istat & (SIP|DIP))) 2789 if (!(istat & (SIP|DIP)))
2789 return; 2790 return (istat & INTF) ? IRQ_HANDLED : IRQ_NONE;
2790 2791
2791#if 0 /* We should never get this one */ 2792#if 0 /* We should never get this one */
2792 if (istat & CABRT) 2793 if (istat & CABRT)
@@ -2818,7 +2819,7 @@ void sym_interrupt (struct sym_hcb *np)
2818 * never clear. */ 2819 * never clear. */
2819 if (unlikely(sist == 0xffff && dstat == 0xff)) { 2820 if (unlikely(sist == 0xffff && dstat == 0xff)) {
2820 if (pci_channel_offline(np->s.device)) 2821 if (pci_channel_offline(np->s.device))
2821 return; 2822 return IRQ_NONE;
2822 } 2823 }
2823 } while (istatc & (SIP|DIP)); 2824 } while (istatc & (SIP|DIP));
2824 2825
@@ -2856,7 +2857,7 @@ void sym_interrupt (struct sym_hcb *np)
2856 else if (dstat & SIR) sym_int_sir(np); 2857 else if (dstat & SIR) sym_int_sir(np);
2857 else if (dstat & SSI) OUTONB_STD(); 2858 else if (dstat & SSI) OUTONB_STD();
2858 else goto unknown_int; 2859 else goto unknown_int;
2859 return; 2860 return IRQ_HANDLED;
2860 } 2861 }
2861 2862
2862 /* 2863 /*
@@ -2873,7 +2874,7 @@ void sym_interrupt (struct sym_hcb *np)
2873 if (sist & RST) { 2874 if (sist & RST) {
2874 printf("%s: SCSI BUS reset detected.\n", sym_name(np)); 2875 printf("%s: SCSI BUS reset detected.\n", sym_name(np));
2875 sym_start_up (np, 1); 2876 sym_start_up (np, 1);
2876 return; 2877 return IRQ_HANDLED;
2877 } 2878 }
2878 2879
2879 OUTB(np, nc_ctest3, np->rv_ctest3 | CLF); /* clear dma fifo */ 2880 OUTB(np, nc_ctest3, np->rv_ctest3 | CLF); /* clear dma fifo */
@@ -2885,7 +2886,7 @@ void sym_interrupt (struct sym_hcb *np)
2885 else if (sist & STO) sym_int_sto (np); 2886 else if (sist & STO) sym_int_sto (np);
2886 else if (sist & UDC) sym_int_udc (np); 2887 else if (sist & UDC) sym_int_udc (np);
2887 else goto unknown_int; 2888 else goto unknown_int;
2888 return; 2889 return IRQ_HANDLED;
2889 } 2890 }
2890 2891
2891 /* 2892 /*
@@ -2900,7 +2901,7 @@ void sym_interrupt (struct sym_hcb *np)
2900 if ((sist & (GEN|HTH|SGE)) || 2901 if ((sist & (GEN|HTH|SGE)) ||
2901 (dstat & (MDPE|BF|ABRT|IID))) { 2902 (dstat & (MDPE|BF|ABRT|IID))) {
2902 sym_start_reset(np); 2903 sym_start_reset(np);
2903 return; 2904 return IRQ_HANDLED;
2904 } 2905 }
2905 2906
2906unknown_int: 2907unknown_int:
@@ -2911,6 +2912,7 @@ unknown_int:
2911 printf( "%s: unknown interrupt(s) ignored, " 2912 printf( "%s: unknown interrupt(s) ignored, "
2912 "ISTAT=0x%x DSTAT=0x%x SIST=0x%x\n", 2913 "ISTAT=0x%x DSTAT=0x%x SIST=0x%x\n",
2913 sym_name(np), istat, dstat, sist); 2914 sym_name(np), istat, dstat, sist);
2915 return IRQ_NONE;
2914} 2916}
2915 2917
2916/* 2918/*
diff --git a/drivers/scsi/sym53c8xx_2/sym_hipd.h b/drivers/scsi/sym53c8xx_2/sym_hipd.h
index 4354571a63ef..a9c08668b98c 100644
--- a/drivers/scsi/sym53c8xx_2/sym_hipd.h
+++ b/drivers/scsi/sym53c8xx_2/sym_hipd.h
@@ -1056,7 +1056,7 @@ void sym_start_next_ccbs(struct sym_hcb *np, struct sym_lcb *lp, int maxn);
1056void sym_put_start_queue(struct sym_hcb *np, struct sym_ccb *cp); 1056void sym_put_start_queue(struct sym_hcb *np, struct sym_ccb *cp);
1057#endif 1057#endif
1058void sym_start_up(struct sym_hcb *np, int reason); 1058void sym_start_up(struct sym_hcb *np, int reason);
1059void sym_interrupt(struct sym_hcb *np); 1059irqreturn_t sym_interrupt(struct Scsi_Host *);
1060int sym_clear_tasks(struct sym_hcb *np, int cam_status, int target, int lun, int task); 1060int sym_clear_tasks(struct sym_hcb *np, int cam_status, int target, int lun, int task);
1061struct sym_ccb *sym_get_ccb(struct sym_hcb *np, struct scsi_cmnd *cmd, u_char tag_order); 1061struct sym_ccb *sym_get_ccb(struct sym_hcb *np, struct scsi_cmnd *cmd, u_char tag_order);
1062void sym_free_ccb(struct sym_hcb *np, struct sym_ccb *cp); 1062void sym_free_ccb(struct sym_hcb *np, struct sym_ccb *cp);