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.c335
1 files changed, 162 insertions, 173 deletions
diff --git a/drivers/scsi/esp.c b/drivers/scsi/esp.c
index 0a3e45d7a972..5630868c1b25 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:
@@ -13,7 +12,6 @@
13 * 3) Add tagged queueing. 12 * 3) Add tagged queueing.
14 */ 13 */
15 14
16#include <linux/config.h>
17#include <linux/kernel.h> 15#include <linux/kernel.h>
18#include <linux/delay.h> 16#include <linux/delay.h>
19#include <linux/types.h> 17#include <linux/types.h>
@@ -185,11 +183,6 @@ enum {
185/*5*/ do_intr_end 183/*5*/ do_intr_end
186}; 184};
187 185
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. */ 186/* Forward declarations. */
194static irqreturn_t esp_intr(int irq, void *dev_id, struct pt_regs *pregs); 187static irqreturn_t esp_intr(int irq, void *dev_id, struct pt_regs *pregs);
195 188
@@ -694,36 +687,6 @@ static void __init esp_bootup_reset(struct esp *esp)
694 sbus_readb(esp->eregs + ESP_INTRPT); 687 sbus_readb(esp->eregs + ESP_INTRPT);
695} 688}
696 689
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) 690static int __init esp_find_dvma(struct esp *esp, struct sbus_dev *dma_sdev)
728{ 691{
729 struct sbus_dev *sdev = esp->sdev; 692 struct sbus_dev *sdev = esp->sdev;
@@ -815,7 +778,7 @@ static int __init esp_register_irq(struct esp *esp)
815 * sanely maintain. 778 * sanely maintain.
816 */ 779 */
817 if (request_irq(esp->ehost->irq, esp_intr, 780 if (request_irq(esp->ehost->irq, esp_intr,
818 SA_SHIRQ, "ESP SCSI", esp)) { 781 IRQF_SHARED, "ESP SCSI", esp)) {
819 printk("esp%d: Cannot acquire irq line\n", 782 printk("esp%d: Cannot acquire irq line\n",
820 esp->esp_id); 783 esp->esp_id);
821 return -1; 784 return -1;
@@ -830,19 +793,20 @@ static int __init esp_register_irq(struct esp *esp)
830static void __init esp_get_scsi_id(struct esp *esp) 793static void __init esp_get_scsi_id(struct esp *esp)
831{ 794{
832 struct sbus_dev *sdev = esp->sdev; 795 struct sbus_dev *sdev = esp->sdev;
796 struct device_node *dp = sdev->ofdev.node;
833 797
834 esp->scsi_id = prom_getintdefault(esp->prom_node, 798 esp->scsi_id = of_getintprop_default(dp,
835 "initiator-id", 799 "initiator-id",
836 -1); 800 -1);
837 if (esp->scsi_id == -1) 801 if (esp->scsi_id == -1)
838 esp->scsi_id = prom_getintdefault(esp->prom_node, 802 esp->scsi_id = of_getintprop_default(dp,
839 "scsi-initiator-id", 803 "scsi-initiator-id",
840 -1); 804 -1);
841 if (esp->scsi_id == -1) 805 if (esp->scsi_id == -1)
842 esp->scsi_id = (sdev->bus == NULL) ? 7 : 806 esp->scsi_id = (sdev->bus == NULL) ? 7 :
843 prom_getintdefault(sdev->bus->prom_node, 807 of_getintprop_default(sdev->bus->ofdev.node,
844 "scsi-initiator-id", 808 "scsi-initiator-id",
845 7); 809 7);
846 esp->ehost->this_id = esp->scsi_id; 810 esp->ehost->this_id = esp->scsi_id;
847 esp->scsi_id_mask = (1 << esp->scsi_id); 811 esp->scsi_id_mask = (1 << esp->scsi_id);
848 812
@@ -1067,28 +1031,30 @@ static void __init esp_init_swstate(struct esp *esp)
1067 esp->prev_hme_dmacsr = 0xffffffff; 1031 esp->prev_hme_dmacsr = 0xffffffff;
1068} 1032}
1069 1033
1070static int __init detect_one_esp(struct scsi_host_template *tpnt, struct sbus_dev *esp_dev, 1034static int __init detect_one_esp(struct scsi_host_template *tpnt,
1071 struct sbus_dev *espdma, struct sbus_bus *sbus, 1035 struct device *dev,
1072 int id, int hme) 1036 struct sbus_dev *esp_dev,
1037 struct sbus_dev *espdma,
1038 struct sbus_bus *sbus,
1039 int hme)
1073{ 1040{
1074 struct Scsi_Host *esp_host = scsi_register(tpnt, sizeof(struct esp)); 1041 static int instance;
1042 struct Scsi_Host *esp_host = scsi_host_alloc(tpnt, sizeof(struct esp));
1075 struct esp *esp; 1043 struct esp *esp;
1076 1044
1077 if (!esp_host) { 1045 if (!esp_host)
1078 printk("ESP: Cannot register SCSI host\n"); 1046 return -ENOMEM;
1079 return -1; 1047
1080 }
1081 if (hme) 1048 if (hme)
1082 esp_host->max_id = 16; 1049 esp_host->max_id = 16;
1083 esp = (struct esp *) esp_host->hostdata; 1050 esp = (struct esp *) esp_host->hostdata;
1084 esp->ehost = esp_host; 1051 esp->ehost = esp_host;
1085 esp->sdev = esp_dev; 1052 esp->sdev = esp_dev;
1086 esp->esp_id = id; 1053 esp->esp_id = instance;
1087 esp->prom_node = esp_dev->prom_node; 1054 esp->prom_node = esp_dev->prom_node;
1088 prom_getstring(esp->prom_node, "name", esp->prom_name, 1055 prom_getstring(esp->prom_node, "name", esp->prom_name,
1089 sizeof(esp->prom_name)); 1056 sizeof(esp->prom_name));
1090 1057
1091 esp_chain_add(esp);
1092 if (esp_find_dvma(esp, espdma) < 0) 1058 if (esp_find_dvma(esp, espdma) < 0)
1093 goto fail_unlink; 1059 goto fail_unlink;
1094 if (esp_map_regs(esp, hme) < 0) { 1060 if (esp_map_regs(esp, hme) < 0) {
@@ -1115,8 +1081,19 @@ static int __init detect_one_esp(struct scsi_host_template *tpnt, struct sbus_de
1115 1081
1116 esp_bootup_reset(esp); 1082 esp_bootup_reset(esp);
1117 1083
1084 if (scsi_add_host(esp_host, dev))
1085 goto fail_free_irq;
1086
1087 dev_set_drvdata(&esp_dev->ofdev.dev, esp);
1088
1089 scsi_scan_host(esp_host);
1090 instance++;
1091
1118 return 0; 1092 return 0;
1119 1093
1094fail_free_irq:
1095 free_irq(esp->ehost->irq, esp);
1096
1120fail_unmap_cmdarea: 1097fail_unmap_cmdarea:
1121 sbus_free_consistent(esp->sdev, 16, 1098 sbus_free_consistent(esp->sdev, 16,
1122 (void *) esp->esp_command, 1099 (void *) esp->esp_command,
@@ -1129,119 +1106,99 @@ fail_dvma_release:
1129 esp->dma->allocated = 0; 1106 esp->dma->allocated = 0;
1130 1107
1131fail_unlink: 1108fail_unlink:
1132 esp_chain_del(esp); 1109 scsi_host_put(esp_host);
1133 scsi_unregister(esp_host);
1134 return -1; 1110 return -1;
1135} 1111}
1136 1112
1137/* Detecting ESP chips on the machine. This is the simple and easy 1113/* Detecting ESP chips on the machine. This is the simple and easy
1138 * version. 1114 * version.
1139 */ 1115 */
1116static int __devexit esp_remove_common(struct esp *esp)
1117{
1118 unsigned int irq = esp->ehost->irq;
1119
1120 scsi_remove_host(esp->ehost);
1121
1122 ESP_INTSOFF(esp->dregs);
1123#if 0
1124 esp_reset_dma(esp);
1125 esp_reset_esp(esp);
1126#endif
1127
1128 free_irq(irq, esp);
1129 sbus_free_consistent(esp->sdev, 16,
1130 (void *) esp->esp_command, esp->esp_command_dvma);
1131 sbus_iounmap(esp->eregs, ESP_REG_SIZE);
1132 esp->dma->allocated = 0;
1133
1134 scsi_host_put(esp->ehost);
1135
1136 return 0;
1137}
1138
1140 1139
1141#ifdef CONFIG_SUN4 1140#ifdef CONFIG_SUN4
1142 1141
1143#include <asm/sun4paddr.h> 1142#include <asm/sun4paddr.h>
1144 1143
1145static int __init esp_detect(struct scsi_host_template *tpnt) 1144static 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 1145
1146static int __init esp_sun4_probe(struct scsi_host_template *tpnt)
1147{
1152 if (sun4_esp_physaddr) { 1148 if (sun4_esp_physaddr) {
1153 memset (&esp_dev, 0, sizeof(esp_dev)); 1149 memset(&sun4_esp_dev, 0, sizeof(sun4_esp_dev));
1154 esp_dev.reg_addrs[0].phys_addr = sun4_esp_physaddr; 1150 sun4_esp_dev.reg_addrs[0].phys_addr = sun4_esp_physaddr;
1155 esp_dev.irqs[0] = 4; 1151 sun4_esp_dev.irqs[0] = 4;
1156 esp_dev.resource[0].start = sun4_esp_physaddr; 1152 sun4_esp_dev.resource[0].start = sun4_esp_physaddr;
1157 esp_dev.resource[0].end = sun4_esp_physaddr + ESP_REG_SIZE - 1; 1153 sun4_esp_dev.resource[0].end =
1158 esp_dev.resource[0].flags = IORESOURCE_IO; 1154 sun4_esp_physaddr + ESP_REG_SIZE - 1;
1159 1155 sun4_esp_dev.resource[0].flags = IORESOURCE_IO;
1160 if (!detect_one_esp(tpnt, &esp_dev, NULL, NULL, 0, 0)) 1156
1161 esps_in_use++; 1157 return detect_one_esp(tpnt, NULL,
1162 printk("ESP: Total of 1 ESP hosts found, %d actually in use.\n", esps_in_use); 1158 &sun4_esp_dev, NULL, NULL, 0);
1163 esps_running = esps_in_use;
1164 } 1159 }
1165 return esps_in_use; 1160 return 0;
1166} 1161}
1167 1162
1168#else /* !CONFIG_SUN4 */ 1163static int __devexit esp_sun4_remove(void)
1169
1170static int __init esp_detect(struct scsi_host_template *tpnt)
1171{ 1164{
1172 struct sbus_bus *sbus; 1165 struct of_device *dev = &sun4_esp_dev.ofdev;
1173 struct sbus_dev *esp_dev, *sbdev_iter; 1166 struct esp *esp = dev_get_drvdata(&dev->dev);
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
@@ -1448,7 +1398,7 @@ static void esp_get_dmabufs(struct esp *esp, struct scsi_cmnd *sp)
1448 sp->SCp.ptr = NULL; 1398 sp->SCp.ptr = NULL;
1449 } 1399 }
1450 } else { 1400 } else {
1451 sp->SCp.buffer = (struct scatterlist *) sp->buffer; 1401 sp->SCp.buffer = (struct scatterlist *) sp->request_buffer;
1452 sp->SCp.buffers_residual = sbus_map_sg(esp->sdev, 1402 sp->SCp.buffers_residual = sbus_map_sg(esp->sdev,
1453 sp->SCp.buffer, 1403 sp->SCp.buffer,
1454 sp->use_sg, 1404 sp->use_sg,
@@ -1461,7 +1411,7 @@ static void esp_get_dmabufs(struct esp *esp, struct scsi_cmnd *sp)
1461static void esp_release_dmabufs(struct esp *esp, struct scsi_cmnd *sp) 1411static void esp_release_dmabufs(struct esp *esp, struct scsi_cmnd *sp)
1462{ 1412{
1463 if (sp->use_sg) { 1413 if (sp->use_sg) {
1464 sbus_unmap_sg(esp->sdev, sp->buffer, sp->use_sg, 1414 sbus_unmap_sg(esp->sdev, sp->request_buffer, sp->use_sg,
1465 sp->sc_data_direction); 1415 sp->sc_data_direction);
1466 } else if (sp->request_bufflen) { 1416 } else if (sp->request_bufflen) {
1467 sbus_unmap_single(esp->sdev, 1417 sbus_unmap_single(esp->sdev,
@@ -2805,18 +2755,15 @@ static int esp_do_data_finale(struct esp *esp)
2805 */ 2755 */
2806static int esp_should_clear_sync(struct scsi_cmnd *sp) 2756static int esp_should_clear_sync(struct scsi_cmnd *sp)
2807{ 2757{
2808 u8 cmd1 = sp->cmnd[0]; 2758 u8 cmd = sp->cmnd[0];
2809 u8 cmd2 = sp->data_cmnd[0];
2810 2759
2811 /* These cases are for spinning up a disk and 2760 /* These cases are for spinning up a disk and
2812 * waiting for that spinup to complete. 2761 * waiting for that spinup to complete.
2813 */ 2762 */
2814 if (cmd1 == START_STOP || 2763 if (cmd == START_STOP)
2815 cmd2 == START_STOP)
2816 return 0; 2764 return 0;
2817 2765
2818 if (cmd1 == TEST_UNIT_READY || 2766 if (cmd == TEST_UNIT_READY)
2819 cmd2 == TEST_UNIT_READY)
2820 return 0; 2767 return 0;
2821 2768
2822 /* One more special case for SCSI tape drives, 2769 /* One more special case for SCSI tape drives,
@@ -2824,8 +2771,7 @@ static int esp_should_clear_sync(struct scsi_cmnd *sp)
2824 * completion of a rewind or tape load operation. 2771 * completion of a rewind or tape load operation.
2825 */ 2772 */
2826 if (sp->device->type == TYPE_TAPE) { 2773 if (sp->device->type == TYPE_TAPE) {
2827 if (cmd1 == MODE_SENSE || 2774 if (cmd == MODE_SENSE)
2828 cmd2 == MODE_SENSE)
2829 return 0; 2775 return 0;
2830 } 2776 }
2831 2777
@@ -4377,15 +4323,12 @@ static void esp_slave_destroy(struct scsi_device *SDptr)
4377 SDptr->hostdata = NULL; 4323 SDptr->hostdata = NULL;
4378} 4324}
4379 4325
4380static struct scsi_host_template driver_template = { 4326static struct scsi_host_template esp_template = {
4381 .proc_name = "esp", 4327 .module = THIS_MODULE,
4382 .proc_info = esp_proc_info, 4328 .name = "esp",
4383 .name = "Sun ESP 100/100a/200", 4329 .info = esp_info,
4384 .detect = esp_detect,
4385 .slave_alloc = esp_slave_alloc, 4330 .slave_alloc = esp_slave_alloc,
4386 .slave_destroy = esp_slave_destroy, 4331 .slave_destroy = esp_slave_destroy,
4387 .release = esp_release,
4388 .info = esp_info,
4389 .queuecommand = esp_queue, 4332 .queuecommand = esp_queue,
4390 .eh_abort_handler = esp_abort, 4333 .eh_abort_handler = esp_abort,
4391 .eh_bus_reset_handler = esp_reset, 4334 .eh_bus_reset_handler = esp_reset,
@@ -4394,12 +4337,58 @@ static struct scsi_host_template driver_template = {
4394 .sg_tablesize = SG_ALL, 4337 .sg_tablesize = SG_ALL,
4395 .cmd_per_lun = 1, 4338 .cmd_per_lun = 1,
4396 .use_clustering = ENABLE_CLUSTERING, 4339 .use_clustering = ENABLE_CLUSTERING,
4340 .proc_name = "esp",
4341 .proc_info = esp_proc_info,
4342};
4343
4344#ifndef CONFIG_SUN4
4345static struct of_device_id esp_match[] = {
4346 {
4347 .name = "SUNW,esp",
4348 .data = &esp_template,
4349 },
4350 {
4351 .name = "SUNW,fas",
4352 .data = &esp_template,
4353 },
4354 {
4355 .name = "esp",
4356 .data = &esp_template,
4357 },
4358 {},
4359};
4360MODULE_DEVICE_TABLE(of, esp_match);
4361
4362static struct of_platform_driver esp_sbus_driver = {
4363 .name = "esp",
4364 .match_table = esp_match,
4365 .probe = esp_sbus_probe,
4366 .remove = __devexit_p(esp_sbus_remove),
4397}; 4367};
4368#endif
4369
4370static int __init esp_init(void)
4371{
4372#ifdef CONFIG_SUN4
4373 return esp_sun4_probe(&esp_template);
4374#else
4375 return of_register_driver(&esp_sbus_driver, &sbus_bus_type);
4376#endif
4377}
4398 4378
4399#include "scsi_module.c" 4379static void __exit esp_exit(void)
4380{
4381#ifdef CONFIG_SUN4
4382 esp_sun4_remove();
4383#else
4384 of_unregister_driver(&esp_sbus_driver);
4385#endif
4386}
4400 4387
4401MODULE_DESCRIPTION("EnhancedScsiProcessor Sun SCSI driver"); 4388MODULE_DESCRIPTION("ESP Sun SCSI driver");
4402MODULE_AUTHOR("David S. Miller (davem@redhat.com)"); 4389MODULE_AUTHOR("David S. Miller (davem@davemloft.net)");
4403MODULE_LICENSE("GPL"); 4390MODULE_LICENSE("GPL");
4404MODULE_VERSION(DRV_VERSION); 4391MODULE_VERSION(DRV_VERSION);
4405 4392
4393module_init(esp_init);
4394module_exit(esp_exit);