Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[SCSI] sparc: Port esp to new SBUS driver layer.

This also turns the driver into a new-style scsi driver.

Signed-off-by: David S. Miller <davem@davemloft.net>

+161 -169
+161 -165
drivers/scsi/esp.c
··· 1 - /* $Id: esp.c,v 1.101 2002/01/15 06:48:55 davem Exp $ 2 - * esp.c: EnhancedScsiProcessor Sun SCSI driver code. 1 + /* esp.c: ESP Sun SCSI driver. 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 6 /* TODO: ··· 183 184 /*4*/ do_work_bus, 184 185 /*5*/ do_intr_end 185 186 }; 186 - 187 - /* The master ring of all esp hosts we are managing in this driver. */ 188 - static struct esp *espchain; 189 - static DEFINE_SPINLOCK(espchain_lock); 190 - static int esps_running = 0; 191 187 192 188 /* Forward declarations. */ 193 189 static irqreturn_t esp_intr(int irq, void *dev_id, struct pt_regs *pregs); ··· 688 694 sbus_readb(esp->eregs + ESP_INTRPT); 689 695 } 690 696 691 - static void esp_chain_add(struct esp *esp) 692 - { 693 - spin_lock_irq(&espchain_lock); 694 - if (espchain) { 695 - struct esp *elink = espchain; 696 - while (elink->next) 697 - elink = elink->next; 698 - elink->next = esp; 699 - } else { 700 - espchain = esp; 701 - } 702 - esp->next = NULL; 703 - spin_unlock_irq(&espchain_lock); 704 - } 705 - 706 - static void esp_chain_del(struct esp *esp) 707 - { 708 - spin_lock_irq(&espchain_lock); 709 - if (espchain == esp) { 710 - espchain = esp->next; 711 - } else { 712 - struct esp *elink = espchain; 713 - while (elink->next != esp) 714 - elink = elink->next; 715 - elink->next = esp->next; 716 - } 717 - esp->next = NULL; 718 - spin_unlock_irq(&espchain_lock); 719 - } 720 - 721 697 static int __init esp_find_dvma(struct esp *esp, struct sbus_dev *dma_sdev) 722 698 { 723 699 struct sbus_dev *sdev = esp->sdev; ··· 794 830 static void __init esp_get_scsi_id(struct esp *esp) 795 831 { 796 832 struct sbus_dev *sdev = esp->sdev; 833 + struct device_node *dp = sdev->ofdev.node; 797 834 798 - esp->scsi_id = prom_getintdefault(esp->prom_node, 799 - "initiator-id", 800 - -1); 835 + esp->scsi_id = of_getintprop_default(dp, 836 + "initiator-id", 837 + -1); 801 838 if (esp->scsi_id == -1) 802 - esp->scsi_id = prom_getintdefault(esp->prom_node, 803 - "scsi-initiator-id", 804 - -1); 839 + esp->scsi_id = of_getintprop_default(dp, 840 + "scsi-initiator-id", 841 + -1); 805 842 if (esp->scsi_id == -1) 806 843 esp->scsi_id = (sdev->bus == NULL) ? 7 : 807 - prom_getintdefault(sdev->bus->prom_node, 808 - "scsi-initiator-id", 809 - 7); 844 + of_getintprop_default(sdev->bus->ofdev.node, 845 + "scsi-initiator-id", 846 + 7); 810 847 esp->ehost->this_id = esp->scsi_id; 811 848 esp->scsi_id_mask = (1 << esp->scsi_id); 812 849 ··· 1032 1067 esp->prev_hme_dmacsr = 0xffffffff; 1033 1068 } 1034 1069 1035 - static int __init detect_one_esp(struct scsi_host_template *tpnt, struct sbus_dev *esp_dev, 1036 - struct sbus_dev *espdma, struct sbus_bus *sbus, 1037 - int id, int hme) 1070 + static int __init detect_one_esp(struct scsi_host_template *tpnt, 1071 + struct device *dev, 1072 + struct sbus_dev *esp_dev, 1073 + struct sbus_dev *espdma, 1074 + struct sbus_bus *sbus, 1075 + int hme) 1038 1076 { 1039 - struct Scsi_Host *esp_host = scsi_register(tpnt, sizeof(struct esp)); 1077 + static int instance; 1078 + struct Scsi_Host *esp_host = scsi_host_alloc(tpnt, sizeof(struct esp)); 1040 1079 struct esp *esp; 1041 1080 1042 - if (!esp_host) { 1043 - printk("ESP: Cannot register SCSI host\n"); 1044 - return -1; 1045 - } 1081 + if (!esp_host) 1082 + return -ENOMEM; 1083 + 1046 1084 if (hme) 1047 1085 esp_host->max_id = 16; 1048 1086 esp = (struct esp *) esp_host->hostdata; 1049 1087 esp->ehost = esp_host; 1050 1088 esp->sdev = esp_dev; 1051 - esp->esp_id = id; 1089 + esp->esp_id = instance; 1052 1090 esp->prom_node = esp_dev->prom_node; 1053 1091 prom_getstring(esp->prom_node, "name", esp->prom_name, 1054 1092 sizeof(esp->prom_name)); 1055 1093 1056 - esp_chain_add(esp); 1057 1094 if (esp_find_dvma(esp, espdma) < 0) 1058 1095 goto fail_unlink; 1059 1096 if (esp_map_regs(esp, hme) < 0) { ··· 1082 1115 1083 1116 esp_bootup_reset(esp); 1084 1117 1118 + if (scsi_add_host(esp_host, dev)) 1119 + goto fail_free_irq; 1120 + 1121 + dev_set_drvdata(&esp_dev->ofdev.dev, esp); 1122 + 1123 + scsi_scan_host(esp_host); 1124 + instance++; 1125 + 1085 1126 return 0; 1127 + 1128 + fail_free_irq: 1129 + free_irq(esp->ehost->irq, esp); 1086 1130 1087 1131 fail_unmap_cmdarea: 1088 1132 sbus_free_consistent(esp->sdev, 16, ··· 1107 1129 esp->dma->allocated = 0; 1108 1130 1109 1131 fail_unlink: 1110 - esp_chain_del(esp); 1111 - scsi_unregister(esp_host); 1132 + scsi_host_put(esp_host); 1112 1133 return -1; 1113 1134 } 1114 1135 1115 1136 /* Detecting ESP chips on the machine. This is the simple and easy 1116 1137 * version. 1117 1138 */ 1118 - 1119 - #ifdef CONFIG_SUN4 1120 - 1121 - #include <asm/sun4paddr.h> 1122 - 1123 - static int __init esp_detect(struct scsi_host_template *tpnt) 1139 + static int __devexit esp_remove_common(struct esp *esp) 1124 1140 { 1125 - static struct sbus_dev esp_dev; 1126 - int esps_in_use = 0; 1141 + unsigned int irq = esp->ehost->irq; 1127 1142 1128 - espchain = NULL; 1143 + scsi_remove_host(esp->ehost); 1129 1144 1130 - if (sun4_esp_physaddr) { 1131 - memset (&esp_dev, 0, sizeof(esp_dev)); 1132 - esp_dev.reg_addrs[0].phys_addr = sun4_esp_physaddr; 1133 - esp_dev.irqs[0] = 4; 1134 - esp_dev.resource[0].start = sun4_esp_physaddr; 1135 - esp_dev.resource[0].end = sun4_esp_physaddr + ESP_REG_SIZE - 1; 1136 - esp_dev.resource[0].flags = IORESOURCE_IO; 1137 - 1138 - if (!detect_one_esp(tpnt, &esp_dev, NULL, NULL, 0, 0)) 1139 - esps_in_use++; 1140 - printk("ESP: Total of 1 ESP hosts found, %d actually in use.\n", esps_in_use); 1141 - esps_running = esps_in_use; 1142 - } 1143 - return esps_in_use; 1144 - } 1145 - 1146 - #else /* !CONFIG_SUN4 */ 1147 - 1148 - static int __init esp_detect(struct scsi_host_template *tpnt) 1149 - { 1150 - struct sbus_bus *sbus; 1151 - struct sbus_dev *esp_dev, *sbdev_iter; 1152 - int nesps = 0, esps_in_use = 0; 1153 - 1154 - espchain = 0; 1155 - if (!sbus_root) { 1156 - #ifdef CONFIG_PCI 1157 - return 0; 1158 - #else 1159 - panic("No SBUS in esp_detect()"); 1160 - #endif 1161 - } 1162 - for_each_sbus(sbus) { 1163 - for_each_sbusdev(sbdev_iter, sbus) { 1164 - struct sbus_dev *espdma = NULL; 1165 - int hme = 0; 1166 - 1167 - /* Is it an esp sbus device? */ 1168 - esp_dev = sbdev_iter; 1169 - if (strcmp(esp_dev->prom_name, "esp") && 1170 - strcmp(esp_dev->prom_name, "SUNW,esp")) { 1171 - if (!strcmp(esp_dev->prom_name, "SUNW,fas")) { 1172 - hme = 1; 1173 - espdma = esp_dev; 1174 - } else { 1175 - if (!esp_dev->child || 1176 - (strcmp(esp_dev->prom_name, "espdma") && 1177 - strcmp(esp_dev->prom_name, "dma"))) 1178 - continue; /* nope... */ 1179 - espdma = esp_dev; 1180 - esp_dev = esp_dev->child; 1181 - if (strcmp(esp_dev->prom_name, "esp") && 1182 - strcmp(esp_dev->prom_name, "SUNW,esp")) 1183 - continue; /* how can this happen? */ 1184 - } 1185 - } 1186 - 1187 - if (detect_one_esp(tpnt, esp_dev, espdma, sbus, nesps++, hme) < 0) 1188 - continue; 1189 - 1190 - esps_in_use++; 1191 - } /* for each sbusdev */ 1192 - } /* for each sbus */ 1193 - printk("ESP: Total of %d ESP hosts found, %d actually in use.\n", nesps, 1194 - esps_in_use); 1195 - esps_running = esps_in_use; 1196 - return esps_in_use; 1197 - } 1198 - 1199 - #endif /* !CONFIG_SUN4 */ 1200 - 1201 - /* 1202 - */ 1203 - static int esp_release(struct Scsi_Host *host) 1204 - { 1205 - struct esp *esp = (struct esp *) host->hostdata; 1145 + scsi_host_put(esp->ehost); 1146 + esp->ehost = NULL; 1206 1147 1207 1148 ESP_INTSOFF(esp->dregs); 1208 1149 #if 0 ··· 1129 1232 esp_reset_esp(esp); 1130 1233 #endif 1131 1234 1132 - free_irq(esp->ehost->irq, esp); 1235 + free_irq(irq, esp); 1133 1236 sbus_free_consistent(esp->sdev, 16, 1134 1237 (void *) esp->esp_command, esp->esp_command_dvma); 1135 1238 sbus_iounmap(esp->eregs, ESP_REG_SIZE); 1136 1239 esp->dma->allocated = 0; 1137 - esp_chain_del(esp); 1138 1240 1139 - return 0; 1241 + kfree(esp); 1242 + 1243 + return 0; 1140 1244 } 1245 + 1246 + 1247 + #ifdef CONFIG_SUN4 1248 + 1249 + #include <asm/sun4paddr.h> 1250 + 1251 + static struct sbus_dev sun4_esp_dev; 1252 + 1253 + static int __init esp_sun4_probe(struct scsi_host_template *tpnt) 1254 + { 1255 + if (sun4_esp_physaddr) { 1256 + memset(&sun4_esp_dev, 0, sizeof(esp_dev)); 1257 + sun4_esp_dev.reg_addrs[0].phys_addr = sun4_esp_physaddr; 1258 + sun4_esp_dev.irqs[0] = 4; 1259 + sun4_esp_dev.resource[0].start = sun4_esp_physaddr; 1260 + sun4_esp_dev.resource[0].end = 1261 + sun4_esp_physaddr + ESP_REG_SIZE - 1; 1262 + sun4_esp_dev.resource[0].flags = IORESOURCE_IO; 1263 + 1264 + return detect_one_esp(tpnt, NULL, 1265 + &sun4_esp_dev, NULL, NULL, 0); 1266 + } 1267 + return 0; 1268 + } 1269 + 1270 + static int __devexit esp_sun4_remove(void) 1271 + { 1272 + struct esp *esp = dev_get_drvdata(&dev->dev); 1273 + 1274 + return esp_remove_common(esp); 1275 + } 1276 + 1277 + #else /* !CONFIG_SUN4 */ 1278 + 1279 + static int __devinit esp_sbus_probe(struct of_device *dev, const struct of_device_id *match) 1280 + { 1281 + struct sbus_dev *sdev = to_sbus_device(&dev->dev); 1282 + struct device_node *dp = dev->node; 1283 + struct sbus_dev *dma_sdev = NULL; 1284 + int hme = 0; 1285 + 1286 + if (dp->parent && 1287 + (!strcmp(dp->parent->name, "espdma") || 1288 + !strcmp(dp->parent->name, "dma"))) 1289 + dma_sdev = sdev->parent; 1290 + else if (!strcmp(dp->name, "SUNW,fas")) { 1291 + dma_sdev = sdev; 1292 + hme = 1; 1293 + } 1294 + 1295 + return detect_one_esp(match->data, &dev->dev, 1296 + sdev, dma_sdev, sdev->bus, hme); 1297 + } 1298 + 1299 + static int __devexit esp_sbus_remove(struct of_device *dev) 1300 + { 1301 + struct esp *esp = dev_get_drvdata(&dev->dev); 1302 + 1303 + return esp_remove_common(esp); 1304 + } 1305 + 1306 + #endif /* !CONFIG_SUN4 */ 1141 1307 1142 1308 /* The info function will return whatever useful 1143 1309 * information the developer sees fit. If not provided, then ··· 1375 1415 static int esp_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t offset, 1376 1416 int length, int inout) 1377 1417 { 1378 - struct esp *esp; 1418 + struct esp *esp = (struct esp *) host->hostdata; 1379 1419 1380 1420 if (inout) 1381 1421 return -EINVAL; /* not yet */ 1382 - 1383 - for_each_esp(esp) { 1384 - if (esp->ehost == host) 1385 - break; 1386 - } 1387 - if (!esp) 1388 - return -EINVAL; 1389 1422 1390 1423 if (start) 1391 1424 *start = buffer; ··· 4330 4377 SDptr->hostdata = NULL; 4331 4378 } 4332 4379 4333 - static struct scsi_host_template driver_template = { 4334 - .proc_name = "esp", 4335 - .proc_info = esp_proc_info, 4336 - .name = "Sun ESP 100/100a/200", 4337 - .detect = esp_detect, 4380 + static struct scsi_host_template esp_template = { 4381 + .module = THIS_MODULE, 4382 + .name = "esp", 4383 + .info = esp_info, 4338 4384 .slave_alloc = esp_slave_alloc, 4339 4385 .slave_destroy = esp_slave_destroy, 4340 - .release = esp_release, 4341 - .info = esp_info, 4342 4386 .queuecommand = esp_queue, 4343 4387 .eh_abort_handler = esp_abort, 4344 4388 .eh_bus_reset_handler = esp_reset, ··· 4344 4394 .sg_tablesize = SG_ALL, 4345 4395 .cmd_per_lun = 1, 4346 4396 .use_clustering = ENABLE_CLUSTERING, 4397 + .proc_name = "esp", 4398 + .proc_info = esp_proc_info, 4347 4399 }; 4348 4400 4349 - #include "scsi_module.c" 4401 + #ifndef CONFIG_SUN4 4402 + static struct of_device_id esp_match[] = { 4403 + { 4404 + .name = "SUNW,esp", 4405 + .data = &esp_template, 4406 + }, 4407 + { 4408 + .name = "SUNW,fas", 4409 + .data = &esp_template, 4410 + }, 4411 + { 4412 + .name = "esp", 4413 + .data = &esp_template, 4414 + }, 4415 + {}, 4416 + }; 4417 + MODULE_DEVICE_TABLE(of, esp_match); 4350 4418 4351 - MODULE_DESCRIPTION("EnhancedScsiProcessor Sun SCSI driver"); 4352 - MODULE_AUTHOR("David S. Miller (davem@redhat.com)"); 4419 + static struct of_platform_driver esp_sbus_driver = { 4420 + .name = "esp", 4421 + .match_table = esp_match, 4422 + .probe = esp_sbus_probe, 4423 + .remove = __devexit_p(esp_sbus_remove), 4424 + }; 4425 + #endif 4426 + 4427 + static int __init esp_init(void) 4428 + { 4429 + #ifdef CONFIG_SUN4 4430 + return esp_sun4_probe(&esp_template); 4431 + #else 4432 + return of_register_driver(&esp_sbus_driver, &sbus_bus_type); 4433 + #endif 4434 + } 4435 + 4436 + static void __exit esp_exit(void) 4437 + { 4438 + #ifdef CONFIG_SUN4 4439 + esp_sun4_remove(); 4440 + #else 4441 + of_unregister_driver(&esp_sbus_driver); 4442 + #endif 4443 + } 4444 + 4445 + MODULE_DESCRIPTION("ESP Sun SCSI driver"); 4446 + MODULE_AUTHOR("David S. Miller (davem@davemloft.net)"); 4353 4447 MODULE_LICENSE("GPL"); 4354 4448 MODULE_VERSION(DRV_VERSION); 4355 4449 4450 + module_init(esp_init); 4451 + module_exit(esp_exit);
-4
drivers/scsi/esp.h
··· 403 403 #define ESP_MHZ_TO_CYCLE(mhertz) ((1000000000) / ((mhertz) / 1000)) 404 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 406 #endif /* !(_SPARC_ESP_H) */