aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/esp.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/esp.c')
-rw-r--r--drivers/scsi/esp.c315
1 files changed, 154 insertions, 161 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);