aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi')
-rw-r--r--drivers/scsi/esp.c315
-rw-r--r--drivers/scsi/esp.h4
-rw-r--r--drivers/scsi/qlogicpti.c361
3 files changed, 340 insertions, 340 deletions
diff --git a/drivers/scsi/esp.c b/drivers/scsi/esp.c
index 0a3e45d7a972..ddb512463b45 100644
--- a/drivers/scsi/esp.c
+++ b/drivers/scsi/esp.c
@@ -1,7 +1,6 @@
1/* $Id: esp.c,v 1.101 2002/01/15 06:48:55 davem Exp $ 1/* esp.c: ESP Sun SCSI driver.
2 * esp.c: EnhancedScsiProcessor Sun SCSI driver code.
3 * 2 *
4 * Copyright (C) 1995, 1998 David S. Miller (davem@caip.rutgers.edu) 3 * Copyright (C) 1995, 1998, 2006 David S. Miller (davem@davemloft.net)
5 */ 4 */
6 5
7/* TODO: 6/* TODO:
@@ -185,11 +184,6 @@ enum {
185/*5*/ do_intr_end 184/*5*/ do_intr_end
186}; 185};
187 186
188/* The master ring of all esp hosts we are managing in this driver. */
189static struct esp *espchain;
190static DEFINE_SPINLOCK(espchain_lock);
191static int esps_running = 0;
192
193/* Forward declarations. */ 187/* Forward declarations. */
194static irqreturn_t esp_intr(int irq, void *dev_id, struct pt_regs *pregs); 188static irqreturn_t esp_intr(int irq, void *dev_id, struct pt_regs *pregs);
195 189
@@ -694,36 +688,6 @@ static void __init esp_bootup_reset(struct esp *esp)
694 sbus_readb(esp->eregs + ESP_INTRPT); 688 sbus_readb(esp->eregs + ESP_INTRPT);
695} 689}
696 690
697static void esp_chain_add(struct esp *esp)
698{
699 spin_lock_irq(&espchain_lock);
700 if (espchain) {
701 struct esp *elink = espchain;
702 while (elink->next)
703 elink = elink->next;
704 elink->next = esp;
705 } else {
706 espchain = esp;
707 }
708 esp->next = NULL;
709 spin_unlock_irq(&espchain_lock);
710}
711
712static void esp_chain_del(struct esp *esp)
713{
714 spin_lock_irq(&espchain_lock);
715 if (espchain == esp) {
716 espchain = esp->next;
717 } else {
718 struct esp *elink = espchain;
719 while (elink->next != esp)
720 elink = elink->next;
721 elink->next = esp->next;
722 }
723 esp->next = NULL;
724 spin_unlock_irq(&espchain_lock);
725}
726
727static int __init esp_find_dvma(struct esp *esp, struct sbus_dev *dma_sdev) 691static int __init esp_find_dvma(struct esp *esp, struct sbus_dev *dma_sdev)
728{ 692{
729 struct sbus_dev *sdev = esp->sdev; 693 struct sbus_dev *sdev = esp->sdev;
@@ -830,19 +794,20 @@ static int __init esp_register_irq(struct esp *esp)
830static void __init esp_get_scsi_id(struct esp *esp) 794static void __init esp_get_scsi_id(struct esp *esp)
831{ 795{
832 struct sbus_dev *sdev = esp->sdev; 796 struct sbus_dev *sdev = esp->sdev;
797 struct device_node *dp = sdev->ofdev.node;
833 798
834 esp->scsi_id = prom_getintdefault(esp->prom_node, 799 esp->scsi_id = of_getintprop_default(dp,
835 "initiator-id", 800 "initiator-id",
836 -1); 801 -1);
837 if (esp->scsi_id == -1) 802 if (esp->scsi_id == -1)
838 esp->scsi_id = prom_getintdefault(esp->prom_node, 803 esp->scsi_id = of_getintprop_default(dp,
839 "scsi-initiator-id", 804 "scsi-initiator-id",
840 -1); 805 -1);
841 if (esp->scsi_id == -1) 806 if (esp->scsi_id == -1)
842 esp->scsi_id = (sdev->bus == NULL) ? 7 : 807 esp->scsi_id = (sdev->bus == NULL) ? 7 :
843 prom_getintdefault(sdev->bus->prom_node, 808 of_getintprop_default(sdev->bus->ofdev.node,
844 "scsi-initiator-id", 809 "scsi-initiator-id",
845 7); 810 7);
846 esp->ehost->this_id = esp->scsi_id; 811 esp->ehost->this_id = esp->scsi_id;
847 esp->scsi_id_mask = (1 << esp->scsi_id); 812 esp->scsi_id_mask = (1 << esp->scsi_id);
848 813
@@ -1067,28 +1032,30 @@ static void __init esp_init_swstate(struct esp *esp)
1067 esp->prev_hme_dmacsr = 0xffffffff; 1032 esp->prev_hme_dmacsr = 0xffffffff;
1068} 1033}
1069 1034
1070static int __init detect_one_esp(struct scsi_host_template *tpnt, struct sbus_dev *esp_dev, 1035static int __init detect_one_esp(struct scsi_host_template *tpnt,
1071 struct sbus_dev *espdma, struct sbus_bus *sbus, 1036 struct device *dev,
1072 int id, int hme) 1037 struct sbus_dev *esp_dev,
1038 struct sbus_dev *espdma,
1039 struct sbus_bus *sbus,
1040 int hme)
1073{ 1041{
1074 struct Scsi_Host *esp_host = scsi_register(tpnt, sizeof(struct esp)); 1042 static int instance;
1043 struct Scsi_Host *esp_host = scsi_host_alloc(tpnt, sizeof(struct esp));
1075 struct esp *esp; 1044 struct esp *esp;
1076 1045
1077 if (!esp_host) { 1046 if (!esp_host)
1078 printk("ESP: Cannot register SCSI host\n"); 1047 return -ENOMEM;
1079 return -1; 1048
1080 }
1081 if (hme) 1049 if (hme)
1082 esp_host->max_id = 16; 1050 esp_host->max_id = 16;
1083 esp = (struct esp *) esp_host->hostdata; 1051 esp = (struct esp *) esp_host->hostdata;
1084 esp->ehost = esp_host; 1052 esp->ehost = esp_host;
1085 esp->sdev = esp_dev; 1053 esp->sdev = esp_dev;
1086 esp->esp_id = id; 1054 esp->esp_id = instance;
1087 esp->prom_node = esp_dev->prom_node; 1055 esp->prom_node = esp_dev->prom_node;
1088 prom_getstring(esp->prom_node, "name", esp->prom_name, 1056 prom_getstring(esp->prom_node, "name", esp->prom_name,
1089 sizeof(esp->prom_name)); 1057 sizeof(esp->prom_name));
1090 1058
1091 esp_chain_add(esp);
1092 if (esp_find_dvma(esp, espdma) < 0) 1059 if (esp_find_dvma(esp, espdma) < 0)
1093 goto fail_unlink; 1060 goto fail_unlink;
1094 if (esp_map_regs(esp, hme) < 0) { 1061 if (esp_map_regs(esp, hme) < 0) {
@@ -1115,8 +1082,19 @@ static int __init detect_one_esp(struct scsi_host_template *tpnt, struct sbus_de
1115 1082
1116 esp_bootup_reset(esp); 1083 esp_bootup_reset(esp);
1117 1084
1085 if (scsi_add_host(esp_host, dev))
1086 goto fail_free_irq;
1087
1088 dev_set_drvdata(&esp_dev->ofdev.dev, esp);
1089
1090 scsi_scan_host(esp_host);
1091 instance++;
1092
1118 return 0; 1093 return 0;
1119 1094
1095fail_free_irq:
1096 free_irq(esp->ehost->irq, esp);
1097
1120fail_unmap_cmdarea: 1098fail_unmap_cmdarea:
1121 sbus_free_consistent(esp->sdev, 16, 1099 sbus_free_consistent(esp->sdev, 16,
1122 (void *) esp->esp_command, 1100 (void *) esp->esp_command,
@@ -1129,119 +1107,98 @@ fail_dvma_release:
1129 esp->dma->allocated = 0; 1107 esp->dma->allocated = 0;
1130 1108
1131fail_unlink: 1109fail_unlink:
1132 esp_chain_del(esp); 1110 scsi_host_put(esp_host);
1133 scsi_unregister(esp_host);
1134 return -1; 1111 return -1;
1135} 1112}
1136 1113
1137/* Detecting ESP chips on the machine. This is the simple and easy 1114/* Detecting ESP chips on the machine. This is the simple and easy
1138 * version. 1115 * version.
1139 */ 1116 */
1117static int __devexit esp_remove_common(struct esp *esp)
1118{
1119 unsigned int irq = esp->ehost->irq;
1120
1121 scsi_remove_host(esp->ehost);
1122
1123 ESP_INTSOFF(esp->dregs);
1124#if 0
1125 esp_reset_dma(esp);
1126 esp_reset_esp(esp);
1127#endif
1128
1129 free_irq(irq, esp);
1130 sbus_free_consistent(esp->sdev, 16,
1131 (void *) esp->esp_command, esp->esp_command_dvma);
1132 sbus_iounmap(esp->eregs, ESP_REG_SIZE);
1133 esp->dma->allocated = 0;
1134
1135 scsi_host_put(esp->ehost);
1136
1137 return 0;
1138}
1139
1140 1140
1141#ifdef CONFIG_SUN4 1141#ifdef CONFIG_SUN4
1142 1142
1143#include <asm/sun4paddr.h> 1143#include <asm/sun4paddr.h>
1144 1144
1145static int __init esp_detect(struct scsi_host_template *tpnt) 1145static struct sbus_dev sun4_esp_dev;
1146{
1147 static struct sbus_dev esp_dev;
1148 int esps_in_use = 0;
1149
1150 espchain = NULL;
1151 1146
1147static int __init esp_sun4_probe(struct scsi_host_template *tpnt)
1148{
1152 if (sun4_esp_physaddr) { 1149 if (sun4_esp_physaddr) {
1153 memset (&esp_dev, 0, sizeof(esp_dev)); 1150 memset(&sun4_esp_dev, 0, sizeof(esp_dev));
1154 esp_dev.reg_addrs[0].phys_addr = sun4_esp_physaddr; 1151 sun4_esp_dev.reg_addrs[0].phys_addr = sun4_esp_physaddr;
1155 esp_dev.irqs[0] = 4; 1152 sun4_esp_dev.irqs[0] = 4;
1156 esp_dev.resource[0].start = sun4_esp_physaddr; 1153 sun4_esp_dev.resource[0].start = sun4_esp_physaddr;
1157 esp_dev.resource[0].end = sun4_esp_physaddr + ESP_REG_SIZE - 1; 1154 sun4_esp_dev.resource[0].end =
1158 esp_dev.resource[0].flags = IORESOURCE_IO; 1155 sun4_esp_physaddr + ESP_REG_SIZE - 1;
1159 1156 sun4_esp_dev.resource[0].flags = IORESOURCE_IO;
1160 if (!detect_one_esp(tpnt, &esp_dev, NULL, NULL, 0, 0)) 1157
1161 esps_in_use++; 1158 return detect_one_esp(tpnt, NULL,
1162 printk("ESP: Total of 1 ESP hosts found, %d actually in use.\n", esps_in_use); 1159 &sun4_esp_dev, NULL, NULL, 0);
1163 esps_running = esps_in_use;
1164 } 1160 }
1165 return esps_in_use; 1161 return 0;
1166} 1162}
1167 1163
1168#else /* !CONFIG_SUN4 */ 1164static int __devexit esp_sun4_remove(void)
1169
1170static int __init esp_detect(struct scsi_host_template *tpnt)
1171{ 1165{
1172 struct sbus_bus *sbus; 1166 struct esp *esp = dev_get_drvdata(&dev->dev);
1173 struct sbus_dev *esp_dev, *sbdev_iter;
1174 int nesps = 0, esps_in_use = 0;
1175 1167
1176 espchain = 0; 1168 return esp_remove_common(esp);
1177 if (!sbus_root) {
1178#ifdef CONFIG_PCI
1179 return 0;
1180#else
1181 panic("No SBUS in esp_detect()");
1182#endif
1183 }
1184 for_each_sbus(sbus) {
1185 for_each_sbusdev(sbdev_iter, sbus) {
1186 struct sbus_dev *espdma = NULL;
1187 int hme = 0;
1188
1189 /* Is it an esp sbus device? */
1190 esp_dev = sbdev_iter;
1191 if (strcmp(esp_dev->prom_name, "esp") &&
1192 strcmp(esp_dev->prom_name, "SUNW,esp")) {
1193 if (!strcmp(esp_dev->prom_name, "SUNW,fas")) {
1194 hme = 1;
1195 espdma = esp_dev;
1196 } else {
1197 if (!esp_dev->child ||
1198 (strcmp(esp_dev->prom_name, "espdma") &&
1199 strcmp(esp_dev->prom_name, "dma")))
1200 continue; /* nope... */
1201 espdma = esp_dev;
1202 esp_dev = esp_dev->child;
1203 if (strcmp(esp_dev->prom_name, "esp") &&
1204 strcmp(esp_dev->prom_name, "SUNW,esp"))
1205 continue; /* how can this happen? */
1206 }
1207 }
1208
1209 if (detect_one_esp(tpnt, esp_dev, espdma, sbus, nesps++, hme) < 0)
1210 continue;
1211
1212 esps_in_use++;
1213 } /* for each sbusdev */
1214 } /* for each sbus */
1215 printk("ESP: Total of %d ESP hosts found, %d actually in use.\n", nesps,
1216 esps_in_use);
1217 esps_running = esps_in_use;
1218 return esps_in_use;
1219} 1169}
1220 1170
1221#endif /* !CONFIG_SUN4 */ 1171#else /* !CONFIG_SUN4 */
1222 1172
1223/* 1173static int __devinit esp_sbus_probe(struct of_device *dev, const struct of_device_id *match)
1224 */
1225static int esp_release(struct Scsi_Host *host)
1226{ 1174{
1227 struct esp *esp = (struct esp *) host->hostdata; 1175 struct sbus_dev *sdev = to_sbus_device(&dev->dev);
1176 struct device_node *dp = dev->node;
1177 struct sbus_dev *dma_sdev = NULL;
1178 int hme = 0;
1179
1180 if (dp->parent &&
1181 (!strcmp(dp->parent->name, "espdma") ||
1182 !strcmp(dp->parent->name, "dma")))
1183 dma_sdev = sdev->parent;
1184 else if (!strcmp(dp->name, "SUNW,fas")) {
1185 dma_sdev = sdev;
1186 hme = 1;
1187 }
1228 1188
1229 ESP_INTSOFF(esp->dregs); 1189 return detect_one_esp(match->data, &dev->dev,
1230#if 0 1190 sdev, dma_sdev, sdev->bus, hme);
1231 esp_reset_dma(esp); 1191}
1232 esp_reset_esp(esp);
1233#endif
1234 1192
1235 free_irq(esp->ehost->irq, esp); 1193static int __devexit esp_sbus_remove(struct of_device *dev)
1236 sbus_free_consistent(esp->sdev, 16, 1194{
1237 (void *) esp->esp_command, esp->esp_command_dvma); 1195 struct esp *esp = dev_get_drvdata(&dev->dev);
1238 sbus_iounmap(esp->eregs, ESP_REG_SIZE);
1239 esp->dma->allocated = 0;
1240 esp_chain_del(esp);
1241 1196
1242 return 0; 1197 return esp_remove_common(esp);
1243} 1198}
1244 1199
1200#endif /* !CONFIG_SUN4 */
1201
1245/* The info function will return whatever useful 1202/* The info function will return whatever useful
1246 * information the developer sees fit. If not provided, then 1203 * information the developer sees fit. If not provided, then
1247 * the name field will be used instead. 1204 * the name field will be used instead.
@@ -1415,18 +1372,11 @@ static int esp_host_info(struct esp *esp, char *ptr, off_t offset, int len)
1415static int esp_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t offset, 1372static int esp_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t offset,
1416 int length, int inout) 1373 int length, int inout)
1417{ 1374{
1418 struct esp *esp; 1375 struct esp *esp = (struct esp *) host->hostdata;
1419 1376
1420 if (inout) 1377 if (inout)
1421 return -EINVAL; /* not yet */ 1378 return -EINVAL; /* not yet */
1422 1379
1423 for_each_esp(esp) {
1424 if (esp->ehost == host)
1425 break;
1426 }
1427 if (!esp)
1428 return -EINVAL;
1429
1430 if (start) 1380 if (start)
1431 *start = buffer; 1381 *start = buffer;
1432 1382
@@ -4377,15 +4327,12 @@ static void esp_slave_destroy(struct scsi_device *SDptr)
4377 SDptr->hostdata = NULL; 4327 SDptr->hostdata = NULL;
4378} 4328}
4379 4329
4380static struct scsi_host_template driver_template = { 4330static struct scsi_host_template esp_template = {
4381 .proc_name = "esp", 4331 .module = THIS_MODULE,
4382 .proc_info = esp_proc_info, 4332 .name = "esp",
4383 .name = "Sun ESP 100/100a/200", 4333 .info = esp_info,
4384 .detect = esp_detect,
4385 .slave_alloc = esp_slave_alloc, 4334 .slave_alloc = esp_slave_alloc,
4386 .slave_destroy = esp_slave_destroy, 4335 .slave_destroy = esp_slave_destroy,
4387 .release = esp_release,
4388 .info = esp_info,
4389 .queuecommand = esp_queue, 4336 .queuecommand = esp_queue,
4390 .eh_abort_handler = esp_abort, 4337 .eh_abort_handler = esp_abort,
4391 .eh_bus_reset_handler = esp_reset, 4338 .eh_bus_reset_handler = esp_reset,
@@ -4394,12 +4341,58 @@ static struct scsi_host_template driver_template = {
4394 .sg_tablesize = SG_ALL, 4341 .sg_tablesize = SG_ALL,
4395 .cmd_per_lun = 1, 4342 .cmd_per_lun = 1,
4396 .use_clustering = ENABLE_CLUSTERING, 4343 .use_clustering = ENABLE_CLUSTERING,
4344 .proc_name = "esp",
4345 .proc_info = esp_proc_info,
4346};
4347
4348#ifndef CONFIG_SUN4
4349static struct of_device_id esp_match[] = {
4350 {
4351 .name = "SUNW,esp",
4352 .data = &esp_template,
4353 },
4354 {
4355 .name = "SUNW,fas",
4356 .data = &esp_template,
4357 },
4358 {
4359 .name = "esp",
4360 .data = &esp_template,
4361 },
4362 {},
4363};
4364MODULE_DEVICE_TABLE(of, esp_match);
4365
4366static struct of_platform_driver esp_sbus_driver = {
4367 .name = "esp",
4368 .match_table = esp_match,
4369 .probe = esp_sbus_probe,
4370 .remove = __devexit_p(esp_sbus_remove),
4397}; 4371};
4372#endif
4373
4374static int __init esp_init(void)
4375{
4376#ifdef CONFIG_SUN4
4377 return esp_sun4_probe(&esp_template);
4378#else
4379 return of_register_driver(&esp_sbus_driver, &sbus_bus_type);
4380#endif
4381}
4398 4382
4399#include "scsi_module.c" 4383static void __exit esp_exit(void)
4384{
4385#ifdef CONFIG_SUN4
4386 esp_sun4_remove();
4387#else
4388 of_unregister_driver(&esp_sbus_driver);
4389#endif
4390}
4400 4391
4401MODULE_DESCRIPTION("EnhancedScsiProcessor Sun SCSI driver"); 4392MODULE_DESCRIPTION("ESP Sun SCSI driver");
4402MODULE_AUTHOR("David S. Miller (davem@redhat.com)"); 4393MODULE_AUTHOR("David S. Miller (davem@davemloft.net)");
4403MODULE_LICENSE("GPL"); 4394MODULE_LICENSE("GPL");
4404MODULE_VERSION(DRV_VERSION); 4395MODULE_VERSION(DRV_VERSION);
4405 4396
4397module_init(esp_init);
4398module_exit(esp_exit);
diff --git a/drivers/scsi/esp.h b/drivers/scsi/esp.h
index 73f7d6968ab6..a98cda9121fc 100644
--- a/drivers/scsi/esp.h
+++ b/drivers/scsi/esp.h
@@ -403,8 +403,4 @@ struct esp {
403#define ESP_MHZ_TO_CYCLE(mhertz) ((1000000000) / ((mhertz) / 1000)) 403#define ESP_MHZ_TO_CYCLE(mhertz) ((1000000000) / ((mhertz) / 1000))
404#define ESP_TICK(ccf, cycle) ((7682 * (ccf) * (cycle) / 1000)) 404#define ESP_TICK(ccf, cycle) ((7682 * (ccf) * (cycle) / 1000))
405 405
406/* For our interrupt engine. */
407#define for_each_esp(esp) \
408 for((esp) = espchain; (esp); (esp) = (esp)->next)
409
410#endif /* !(_SPARC_ESP_H) */ 406#endif /* !(_SPARC_ESP_H) */
diff --git a/drivers/scsi/qlogicpti.c b/drivers/scsi/qlogicpti.c
index 2203103adced..329ead263714 100644
--- a/drivers/scsi/qlogicpti.c
+++ b/drivers/scsi/qlogicpti.c
@@ -1,6 +1,6 @@
1/* qlogicpti.c: Performance Technologies QlogicISP sbus card driver. 1/* qlogicpti.c: Performance Technologies QlogicISP sbus card driver.
2 * 2 *
3 * Copyright (C) 1996 David S. Miller (davem@caipfs.rutgers.edu) 3 * Copyright (C) 1996, 2006 David S. Miller (davem@davemloft.net)
4 * 4 *
5 * A lot of this driver was directly stolen from Erik H. Moe's PCI 5 * A lot of this driver was directly stolen from Erik H. Moe's PCI
6 * Qlogic ISP driver. Mucho kudos to him for this code. 6 * Qlogic ISP driver. Mucho kudos to him for this code.
@@ -46,8 +46,6 @@
46#include <scsi/scsi_tcq.h> 46#include <scsi/scsi_tcq.h>
47#include <scsi/scsi_host.h> 47#include <scsi/scsi_host.h>
48 48
49
50
51#define MAX_TARGETS 16 49#define MAX_TARGETS 16
52#define MAX_LUNS 8 /* 32 for 1.31 F/W */ 50#define MAX_LUNS 8 /* 32 for 1.31 F/W */
53 51
@@ -57,7 +55,6 @@
57 55
58static struct qlogicpti *qptichain = NULL; 56static struct qlogicpti *qptichain = NULL;
59static DEFINE_SPINLOCK(qptichain_lock); 57static DEFINE_SPINLOCK(qptichain_lock);
60static int qptis_running = 0;
61 58
62#define PACKB(a, b) (((a)<<4)|(b)) 59#define PACKB(a, b) (((a)<<4)|(b))
63 60
@@ -815,173 +812,6 @@ static int __init qpti_map_queues(struct qlogicpti *qpti)
815 return 0; 812 return 0;
816} 813}
817 814
818/* Detect all PTI Qlogic ISP's in the machine. */
819static int __init qlogicpti_detect(struct scsi_host_template *tpnt)
820{
821 struct qlogicpti *qpti;
822 struct Scsi_Host *qpti_host;
823 struct sbus_bus *sbus;
824 struct sbus_dev *sdev;
825 int nqptis = 0, nqptis_in_use = 0;
826
827 tpnt->proc_name = "qlogicpti";
828 for_each_sbus(sbus) {
829 for_each_sbusdev(sdev, sbus) {
830 /* Is this a red snapper? */
831 if (strcmp(sdev->prom_name, "ptisp") &&
832 strcmp(sdev->prom_name, "PTI,ptisp") &&
833 strcmp(sdev->prom_name, "QLGC,isp") &&
834 strcmp(sdev->prom_name, "SUNW,isp"))
835 continue;
836
837 /* Sometimes Antares cards come up not completely
838 * setup, and we get a report of a zero IRQ.
839 * Skip over them in such cases so we survive.
840 */
841 if (sdev->irqs[0] == 0) {
842 printk("qpti%d: Adapter reports no interrupt, "
843 "skipping over this card.", nqptis);
844 continue;
845 }
846
847 /* Yep, register and allocate software state. */
848 qpti_host = scsi_register(tpnt, sizeof(struct qlogicpti));
849 if (!qpti_host) {
850 printk("QPTI: Cannot register PTI Qlogic ISP SCSI host");
851 continue;
852 }
853 qpti = (struct qlogicpti *) qpti_host->hostdata;
854
855 /* We are wide capable, 16 targets. */
856 qpti_host->max_id = MAX_TARGETS;
857
858 /* Setup back pointers and misc. state. */
859 qpti->qhost = qpti_host;
860 qpti->sdev = sdev;
861 qpti->qpti_id = nqptis++;
862 qpti->prom_node = sdev->prom_node;
863 prom_getstring(qpti->prom_node, "name",
864 qpti->prom_name,
865 sizeof(qpti->prom_name));
866
867 /* This is not correct, actually. There's a switch
868 * on the PTI cards that put them into "emulation"
869 * mode- i.e., report themselves as QLGC,isp
870 * instead of PTI,ptisp. The only real substantive
871 * difference between non-pti and pti cards is
872 * the tmon register. Which is possibly even
873 * there for Qlogic cards, but non-functional.
874 */
875 qpti->is_pti = (strcmp (qpti->prom_name, "QLGC,isp") != 0);
876
877 qpti_chain_add(qpti);
878 if (qpti_map_regs(qpti) < 0)
879 goto fail_unlink;
880
881 if (qpti_register_irq(qpti) < 0)
882 goto fail_unmap_regs;
883
884 qpti_get_scsi_id(qpti);
885 qpti_get_bursts(qpti);
886 qpti_get_clock(qpti);
887
888 /* Clear out scsi_cmnd array. */
889 memset(qpti->cmd_slots, 0, sizeof(qpti->cmd_slots));
890
891 if (qpti_map_queues(qpti) < 0)
892 goto fail_free_irq;
893
894 /* Load the firmware. */
895 if (qlogicpti_load_firmware(qpti))
896 goto fail_unmap_queues;
897 if (qpti->is_pti) {
898 /* Check the PTI status reg. */
899 if (qlogicpti_verify_tmon(qpti))
900 goto fail_unmap_queues;
901 }
902
903 /* Reset the ISP and init res/req queues. */
904 if (qlogicpti_reset_hardware(qpti_host))
905 goto fail_unmap_queues;
906
907 printk("(Firmware v%d.%d.%d)", qpti->fware_majrev,
908 qpti->fware_minrev, qpti->fware_micrev);
909 {
910 char buffer[60];
911
912 prom_getstring (qpti->prom_node,
913 "isp-fcode", buffer, 60);
914 if (buffer[0])
915 printk("(Firmware %s)", buffer);
916 if (prom_getbool(qpti->prom_node, "differential"))
917 qpti->differential = 1;
918 }
919
920 printk (" [%s Wide, using %s interface]\n",
921 (qpti->ultra ? "Ultra" : "Fast"),
922 (qpti->differential ? "differential" : "single ended"));
923
924 nqptis_in_use++;
925 continue;
926
927 fail_unmap_queues:
928#define QSIZE(entries) (((entries) + 1) * QUEUE_ENTRY_LEN)
929 sbus_free_consistent(qpti->sdev,
930 QSIZE(RES_QUEUE_LEN),
931 qpti->res_cpu, qpti->res_dvma);
932 sbus_free_consistent(qpti->sdev,
933 QSIZE(QLOGICPTI_REQ_QUEUE_LEN),
934 qpti->req_cpu, qpti->req_dvma);
935#undef QSIZE
936 fail_free_irq:
937 free_irq(qpti->irq, qpti);
938
939 fail_unmap_regs:
940 sbus_iounmap(qpti->qregs,
941 qpti->sdev->reg_addrs[0].reg_size);
942 if (qpti->is_pti)
943 sbus_iounmap(qpti->sreg, sizeof(unsigned char));
944 fail_unlink:
945 qpti_chain_del(qpti);
946 scsi_unregister(qpti->qhost);
947 }
948 }
949 if (nqptis)
950 printk("QPTI: Total of %d PTI Qlogic/ISP hosts found, %d actually in use.\n",
951 nqptis, nqptis_in_use);
952 qptis_running = nqptis_in_use;
953 return nqptis;
954}
955
956static int qlogicpti_release(struct Scsi_Host *host)
957{
958 struct qlogicpti *qpti = (struct qlogicpti *) host->hostdata;
959
960 /* Remove visibility from IRQ handlers. */
961 qpti_chain_del(qpti);
962
963 /* Shut up the card. */
964 sbus_writew(0, qpti->qregs + SBUS_CTRL);
965
966 /* Free IRQ handler and unmap Qlogic,ISP and PTI status regs. */
967 free_irq(qpti->irq, qpti);
968
969#define QSIZE(entries) (((entries) + 1) * QUEUE_ENTRY_LEN)
970 sbus_free_consistent(qpti->sdev,
971 QSIZE(RES_QUEUE_LEN),
972 qpti->res_cpu, qpti->res_dvma);
973 sbus_free_consistent(qpti->sdev,
974 QSIZE(QLOGICPTI_REQ_QUEUE_LEN),
975 qpti->req_cpu, qpti->req_dvma);
976#undef QSIZE
977
978 sbus_iounmap(qpti->qregs, qpti->sdev->reg_addrs[0].reg_size);
979 if (qpti->is_pti)
980 sbus_iounmap(qpti->sreg, sizeof(unsigned char));
981
982 return 0;
983}
984
985const char *qlogicpti_info(struct Scsi_Host *host) 815const char *qlogicpti_info(struct Scsi_Host *host)
986{ 816{
987 static char buf[80]; 817 static char buf[80];
@@ -1551,9 +1381,9 @@ static int qlogicpti_reset(struct scsi_cmnd *Cmnd)
1551 return return_status; 1381 return return_status;
1552} 1382}
1553 1383
1554static struct scsi_host_template driver_template = { 1384static struct scsi_host_template qpti_template = {
1555 .detect = qlogicpti_detect, 1385 .module = THIS_MODULE,
1556 .release = qlogicpti_release, 1386 .name = "qlogicpti",
1557 .info = qlogicpti_info, 1387 .info = qlogicpti_info,
1558 .queuecommand = qlogicpti_queuecommand_slow, 1388 .queuecommand = qlogicpti_queuecommand_slow,
1559 .eh_abort_handler = qlogicpti_abort, 1389 .eh_abort_handler = qlogicpti_abort,
@@ -1565,8 +1395,189 @@ static struct scsi_host_template driver_template = {
1565 .use_clustering = ENABLE_CLUSTERING, 1395 .use_clustering = ENABLE_CLUSTERING,
1566}; 1396};
1567 1397
1398static int __devinit qpti_sbus_probe(struct of_device *dev, const struct of_device_id *match)
1399{
1400 static int nqptis;
1401 struct sbus_dev *sdev = to_sbus_device(&dev->dev);
1402 struct device_node *dp = dev->node;
1403 struct scsi_host_template *tpnt = match->data;
1404 struct Scsi_Host *host;
1405 struct qlogicpti *qpti;
1406 char *fcode;
1407
1408 /* Sometimes Antares cards come up not completely
1409 * setup, and we get a report of a zero IRQ.
1410 */
1411 if (sdev->irqs[0] == 0)
1412 return -ENODEV;
1413
1414 host = scsi_host_alloc(tpnt, sizeof(struct qlogicpti));
1415 if (!host)
1416 return -ENOMEM;
1417
1418 qpti = (struct qlogicpti *) host->hostdata;
1419
1420 host->max_id = MAX_TARGETS;
1421 qpti->qhost = host;
1422 qpti->sdev = sdev;
1423 qpti->qpti_id = nqptis;
1424 qpti->prom_node = sdev->prom_node;
1425 strcpy(qpti->prom_name, sdev->ofdev.node->name);
1426 qpti->is_pti = strcmp(qpti->prom_name, "QLGC,isp");
1427
1428 if (qpti_map_regs(qpti) < 0)
1429 goto fail_unlink;
1430
1431 if (qpti_register_irq(qpti) < 0)
1432 goto fail_unmap_regs;
1433
1434 qpti_get_scsi_id(qpti);
1435 qpti_get_bursts(qpti);
1436 qpti_get_clock(qpti);
1437
1438 /* Clear out scsi_cmnd array. */
1439 memset(qpti->cmd_slots, 0, sizeof(qpti->cmd_slots));
1440
1441 if (qpti_map_queues(qpti) < 0)
1442 goto fail_free_irq;
1443
1444 /* Load the firmware. */
1445 if (qlogicpti_load_firmware(qpti))
1446 goto fail_unmap_queues;
1447 if (qpti->is_pti) {
1448 /* Check the PTI status reg. */
1449 if (qlogicpti_verify_tmon(qpti))
1450 goto fail_unmap_queues;
1451 }
1452
1453 /* Reset the ISP and init res/req queues. */
1454 if (qlogicpti_reset_hardware(host))
1455 goto fail_unmap_queues;
1456
1457 if (scsi_add_host(host, &dev->dev))
1458 goto fail_unmap_queues;
1459
1460 printk("(Firmware v%d.%d.%d)", qpti->fware_majrev,
1461 qpti->fware_minrev, qpti->fware_micrev);
1462
1463 fcode = of_get_property(dp, "isp-fcode", NULL);
1464 if (fcode && fcode[0])
1465 printk("(Firmware %s)", fcode);
1466 if (of_find_property(dp, "differential", NULL) != NULL)
1467 qpti->differential = 1;
1468
1469 printk (" [%s Wide, using %s interface]\n",
1470 (qpti->ultra ? "Ultra" : "Fast"),
1471 (qpti->differential ? "differential" : "single ended"));
1472
1473 dev_set_drvdata(&sdev->ofdev.dev, qpti);
1474
1475 qpti_chain_add(qpti);
1476
1477 scsi_scan_host(host);
1478 nqptis++;
1479
1480 return 0;
1481
1482fail_unmap_queues:
1483#define QSIZE(entries) (((entries) + 1) * QUEUE_ENTRY_LEN)
1484 sbus_free_consistent(qpti->sdev,
1485 QSIZE(RES_QUEUE_LEN),
1486 qpti->res_cpu, qpti->res_dvma);
1487 sbus_free_consistent(qpti->sdev,
1488 QSIZE(QLOGICPTI_REQ_QUEUE_LEN),
1489 qpti->req_cpu, qpti->req_dvma);
1490#undef QSIZE
1491
1492fail_unmap_regs:
1493 sbus_iounmap(qpti->qregs,
1494 qpti->sdev->reg_addrs[0].reg_size);
1495 if (qpti->is_pti)
1496 sbus_iounmap(qpti->sreg, sizeof(unsigned char));
1497
1498fail_free_irq:
1499 free_irq(qpti->irq, qpti);
1500
1501fail_unlink:
1502 scsi_host_put(host);
1503
1504 return -ENODEV;
1505}
1506
1507static int __devexit qpti_sbus_remove(struct of_device *dev)
1508{
1509 struct qlogicpti *qpti = dev_get_drvdata(&dev->dev);
1510
1511 qpti_chain_del(qpti);
1512
1513 scsi_remove_host(qpti->qhost);
1514
1515 /* Shut up the card. */
1516 sbus_writew(0, qpti->qregs + SBUS_CTRL);
1517
1518 /* Free IRQ handler and unmap Qlogic,ISP and PTI status regs. */
1519 free_irq(qpti->irq, qpti);
1520
1521#define QSIZE(entries) (((entries) + 1) * QUEUE_ENTRY_LEN)
1522 sbus_free_consistent(qpti->sdev,
1523 QSIZE(RES_QUEUE_LEN),
1524 qpti->res_cpu, qpti->res_dvma);
1525 sbus_free_consistent(qpti->sdev,
1526 QSIZE(QLOGICPTI_REQ_QUEUE_LEN),
1527 qpti->req_cpu, qpti->req_dvma);
1528#undef QSIZE
1529
1530 sbus_iounmap(qpti->qregs, qpti->sdev->reg_addrs[0].reg_size);
1531 if (qpti->is_pti)
1532 sbus_iounmap(qpti->sreg, sizeof(unsigned char));
1533
1534 scsi_host_put(qpti->qhost);
1535
1536 return 0;
1537}
1538
1539static struct of_device_id qpti_match[] = {
1540 {
1541 .name = "ptisp",
1542 .data = &qpti_template,
1543 },
1544 {
1545 .name = "PTI,ptisp",
1546 .data = &qpti_template,
1547 },
1548 {
1549 .name = "QLGC,isp",
1550 .data = &qpti_template,
1551 },
1552 {
1553 .name = "SUNW,isp",
1554 .data = &qpti_template,
1555 },
1556 {},
1557};
1558MODULE_DEVICE_TABLE(of, qpti_match);
1559
1560static struct of_platform_driver qpti_sbus_driver = {
1561 .name = "qpti",
1562 .match_table = qpti_match,
1563 .probe = qpti_sbus_probe,
1564 .remove = __devexit_p(qpti_sbus_remove),
1565};
1568 1566
1569#include "scsi_module.c" 1567static int __init qpti_init(void)
1568{
1569 return of_register_driver(&qpti_sbus_driver, &sbus_bus_type);
1570}
1571
1572static void __exit qpti_exit(void)
1573{
1574 of_unregister_driver(&qpti_sbus_driver);
1575}
1570 1576
1577MODULE_DESCRIPTION("QlogicISP SBUS driver");
1578MODULE_AUTHOR("David S. Miller (davem@davemloft.net)");
1571MODULE_LICENSE("GPL"); 1579MODULE_LICENSE("GPL");
1580MODULE_VERSION("2.0");
1572 1581
1582module_init(qpti_init);
1583module_exit(qpti_exit);