diff options
author | Tejun Heo <htejun@gmail.com> | 2007-01-20 02:00:28 -0500 |
---|---|---|
committer | Jeff Garzik <jeff@garzik.org> | 2007-02-09 17:39:37 -0500 |
commit | 24dc5f33ea4b504cfbd23fa159a4cacba8e4d800 (patch) | |
tree | d76de456157f555c9a65b83f426fd805fee1e846 /drivers/ata/sata_sil24.c | |
parent | f0d36efdc624beb3d9e29b9ab9e9537bf0f25d5b (diff) |
libata: update libata LLDs to use devres
Update libata LLDs to use devres. Core layer is already converted to
support managed LLDs. This patch simplifies initialization and fixes
many resource related bugs in init failure and detach path. For
example, all converted drivers now handle ata_device_add() failure
gracefully without excessive resource rollback code.
As most resources are released automatically on driver detach, many
drivers don't need or can do with much simpler ->{port|host}_stop().
In general, stop callbacks are need iff port or host needs to be given
commands to shut it down. Note that freezing is enough in many cases
and ports are automatically frozen before being detached.
Signed-off-by: Tejun Heo <htejun@gmail.com>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'drivers/ata/sata_sil24.c')
-rw-r--r-- | drivers/ata/sata_sil24.c | 112 |
1 files changed, 28 insertions, 84 deletions
diff --git a/drivers/ata/sata_sil24.c b/drivers/ata/sata_sil24.c index da982ed4bc47..c7a3c0275bee 100644 --- a/drivers/ata/sata_sil24.c +++ b/drivers/ata/sata_sil24.c | |||
@@ -28,7 +28,6 @@ | |||
28 | #include <scsi/scsi_host.h> | 28 | #include <scsi/scsi_host.h> |
29 | #include <scsi/scsi_cmnd.h> | 29 | #include <scsi/scsi_cmnd.h> |
30 | #include <linux/libata.h> | 30 | #include <linux/libata.h> |
31 | #include <asm/io.h> | ||
32 | 31 | ||
33 | #define DRV_NAME "sata_sil24" | 32 | #define DRV_NAME "sata_sil24" |
34 | #define DRV_VERSION "0.3" | 33 | #define DRV_VERSION "0.3" |
@@ -341,8 +340,6 @@ static void sil24_thaw(struct ata_port *ap); | |||
341 | static void sil24_error_handler(struct ata_port *ap); | 340 | static void sil24_error_handler(struct ata_port *ap); |
342 | static void sil24_post_internal_cmd(struct ata_queued_cmd *qc); | 341 | static void sil24_post_internal_cmd(struct ata_queued_cmd *qc); |
343 | static int sil24_port_start(struct ata_port *ap); | 342 | static int sil24_port_start(struct ata_port *ap); |
344 | static void sil24_port_stop(struct ata_port *ap); | ||
345 | static void sil24_host_stop(struct ata_host *host); | ||
346 | static int sil24_init_one(struct pci_dev *pdev, const struct pci_device_id *ent); | 343 | static int sil24_init_one(struct pci_dev *pdev, const struct pci_device_id *ent); |
347 | #ifdef CONFIG_PM | 344 | #ifdef CONFIG_PM |
348 | static int sil24_pci_device_resume(struct pci_dev *pdev); | 345 | static int sil24_pci_device_resume(struct pci_dev *pdev); |
@@ -362,7 +359,7 @@ static struct pci_driver sil24_pci_driver = { | |||
362 | .name = DRV_NAME, | 359 | .name = DRV_NAME, |
363 | .id_table = sil24_pci_tbl, | 360 | .id_table = sil24_pci_tbl, |
364 | .probe = sil24_init_one, | 361 | .probe = sil24_init_one, |
365 | .remove = ata_pci_remove_one, /* safe? */ | 362 | .remove = ata_pci_remove_one, |
366 | #ifdef CONFIG_PM | 363 | #ifdef CONFIG_PM |
367 | .suspend = ata_pci_device_suspend, | 364 | .suspend = ata_pci_device_suspend, |
368 | .resume = sil24_pci_device_resume, | 365 | .resume = sil24_pci_device_resume, |
@@ -416,8 +413,6 @@ static const struct ata_port_operations sil24_ops = { | |||
416 | .post_internal_cmd = sil24_post_internal_cmd, | 413 | .post_internal_cmd = sil24_post_internal_cmd, |
417 | 414 | ||
418 | .port_start = sil24_port_start, | 415 | .port_start = sil24_port_start, |
419 | .port_stop = sil24_port_stop, | ||
420 | .host_stop = sil24_host_stop, | ||
421 | }; | 416 | }; |
422 | 417 | ||
423 | /* | 418 | /* |
@@ -938,13 +933,6 @@ static void sil24_post_internal_cmd(struct ata_queued_cmd *qc) | |||
938 | sil24_init_port(ap); | 933 | sil24_init_port(ap); |
939 | } | 934 | } |
940 | 935 | ||
941 | static inline void sil24_cblk_free(struct sil24_port_priv *pp, struct device *dev) | ||
942 | { | ||
943 | const size_t cb_size = sizeof(*pp->cmd_block) * SIL24_MAX_CMDS; | ||
944 | |||
945 | dma_free_coherent(dev, cb_size, pp->cmd_block, pp->cmd_block_dma); | ||
946 | } | ||
947 | |||
948 | static int sil24_port_start(struct ata_port *ap) | 936 | static int sil24_port_start(struct ata_port *ap) |
949 | { | 937 | { |
950 | struct device *dev = ap->host->dev; | 938 | struct device *dev = ap->host->dev; |
@@ -952,22 +940,22 @@ static int sil24_port_start(struct ata_port *ap) | |||
952 | union sil24_cmd_block *cb; | 940 | union sil24_cmd_block *cb; |
953 | size_t cb_size = sizeof(*cb) * SIL24_MAX_CMDS; | 941 | size_t cb_size = sizeof(*cb) * SIL24_MAX_CMDS; |
954 | dma_addr_t cb_dma; | 942 | dma_addr_t cb_dma; |
955 | int rc = -ENOMEM; | 943 | int rc; |
956 | 944 | ||
957 | pp = kzalloc(sizeof(*pp), GFP_KERNEL); | 945 | pp = devm_kzalloc(dev, sizeof(*pp), GFP_KERNEL); |
958 | if (!pp) | 946 | if (!pp) |
959 | goto err_out; | 947 | return -ENOMEM; |
960 | 948 | ||
961 | pp->tf.command = ATA_DRDY; | 949 | pp->tf.command = ATA_DRDY; |
962 | 950 | ||
963 | cb = dma_alloc_coherent(dev, cb_size, &cb_dma, GFP_KERNEL); | 951 | cb = dmam_alloc_coherent(dev, cb_size, &cb_dma, GFP_KERNEL); |
964 | if (!cb) | 952 | if (!cb) |
965 | goto err_out_pp; | 953 | return -ENOMEM; |
966 | memset(cb, 0, cb_size); | 954 | memset(cb, 0, cb_size); |
967 | 955 | ||
968 | rc = ata_pad_alloc(ap, dev); | 956 | rc = ata_pad_alloc(ap, dev); |
969 | if (rc) | 957 | if (rc) |
970 | goto err_out_pad; | 958 | return rc; |
971 | 959 | ||
972 | pp->cmd_block = cb; | 960 | pp->cmd_block = cb; |
973 | pp->cmd_block_dma = cb_dma; | 961 | pp->cmd_block_dma = cb_dma; |
@@ -975,33 +963,6 @@ static int sil24_port_start(struct ata_port *ap) | |||
975 | ap->private_data = pp; | 963 | ap->private_data = pp; |
976 | 964 | ||
977 | return 0; | 965 | return 0; |
978 | |||
979 | err_out_pad: | ||
980 | sil24_cblk_free(pp, dev); | ||
981 | err_out_pp: | ||
982 | kfree(pp); | ||
983 | err_out: | ||
984 | return rc; | ||
985 | } | ||
986 | |||
987 | static void sil24_port_stop(struct ata_port *ap) | ||
988 | { | ||
989 | struct device *dev = ap->host->dev; | ||
990 | struct sil24_port_priv *pp = ap->private_data; | ||
991 | |||
992 | sil24_cblk_free(pp, dev); | ||
993 | ata_pad_free(ap, dev); | ||
994 | kfree(pp); | ||
995 | } | ||
996 | |||
997 | static void sil24_host_stop(struct ata_host *host) | ||
998 | { | ||
999 | struct sil24_host_priv *hpriv = host->private_data; | ||
1000 | struct pci_dev *pdev = to_pci_dev(host->dev); | ||
1001 | |||
1002 | pci_iounmap(pdev, hpriv->host_base); | ||
1003 | pci_iounmap(pdev, hpriv->port_base); | ||
1004 | kfree(hpriv); | ||
1005 | } | 966 | } |
1006 | 967 | ||
1007 | static void sil24_init_controller(struct pci_dev *pdev, int n_ports, | 968 | static void sil24_init_controller(struct pci_dev *pdev, int n_ports, |
@@ -1066,43 +1027,38 @@ static void sil24_init_controller(struct pci_dev *pdev, int n_ports, | |||
1066 | static int sil24_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | 1027 | static int sil24_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) |
1067 | { | 1028 | { |
1068 | static int printed_version = 0; | 1029 | static int printed_version = 0; |
1030 | struct device *dev = &pdev->dev; | ||
1069 | unsigned int board_id = (unsigned int)ent->driver_data; | 1031 | unsigned int board_id = (unsigned int)ent->driver_data; |
1070 | struct ata_port_info *pinfo = &sil24_port_info[board_id]; | 1032 | struct ata_port_info *pinfo = &sil24_port_info[board_id]; |
1071 | struct ata_probe_ent *probe_ent = NULL; | 1033 | struct ata_probe_ent *probe_ent; |
1072 | struct sil24_host_priv *hpriv = NULL; | 1034 | struct sil24_host_priv *hpriv; |
1073 | void __iomem *host_base = NULL; | 1035 | void __iomem *host_base; |
1074 | void __iomem *port_base = NULL; | 1036 | void __iomem *port_base; |
1075 | int i, rc; | 1037 | int i, rc; |
1076 | u32 tmp; | 1038 | u32 tmp; |
1077 | 1039 | ||
1078 | if (!printed_version++) | 1040 | if (!printed_version++) |
1079 | dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n"); | 1041 | dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n"); |
1080 | 1042 | ||
1081 | rc = pci_enable_device(pdev); | 1043 | rc = pcim_enable_device(pdev); |
1082 | if (rc) | 1044 | if (rc) |
1083 | return rc; | 1045 | return rc; |
1084 | 1046 | ||
1085 | rc = pci_request_regions(pdev, DRV_NAME); | 1047 | rc = pci_request_regions(pdev, DRV_NAME); |
1086 | if (rc) | 1048 | if (rc) |
1087 | goto out_disable; | 1049 | return rc; |
1088 | 1050 | ||
1089 | rc = -ENOMEM; | ||
1090 | /* map mmio registers */ | 1051 | /* map mmio registers */ |
1091 | host_base = pci_iomap(pdev, 0, 0); | 1052 | host_base = pcim_iomap(pdev, 0, 0); |
1092 | if (!host_base) | 1053 | port_base = pcim_iomap(pdev, 2, 0); |
1093 | goto out_free; | 1054 | if (!host_base || !port_base) |
1094 | port_base = pci_iomap(pdev, 2, 0); | 1055 | return -ENOMEM; |
1095 | if (!port_base) | ||
1096 | goto out_free; | ||
1097 | 1056 | ||
1098 | /* allocate & init probe_ent and hpriv */ | 1057 | /* allocate & init probe_ent and hpriv */ |
1099 | probe_ent = kzalloc(sizeof(*probe_ent), GFP_KERNEL); | 1058 | probe_ent = devm_kzalloc(dev, sizeof(*probe_ent), GFP_KERNEL); |
1100 | if (!probe_ent) | 1059 | hpriv = devm_kzalloc(dev, sizeof(*hpriv), GFP_KERNEL); |
1101 | goto out_free; | 1060 | if (!probe_ent || !hpriv) |
1102 | 1061 | return -ENOMEM; | |
1103 | hpriv = kzalloc(sizeof(*hpriv), GFP_KERNEL); | ||
1104 | if (!hpriv) | ||
1105 | goto out_free; | ||
1106 | 1062 | ||
1107 | probe_ent->dev = pci_dev_to_dev(pdev); | 1063 | probe_ent->dev = pci_dev_to_dev(pdev); |
1108 | INIT_LIST_HEAD(&probe_ent->node); | 1064 | INIT_LIST_HEAD(&probe_ent->node); |
@@ -1132,7 +1088,7 @@ static int sil24_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
1132 | if (rc) { | 1088 | if (rc) { |
1133 | dev_printk(KERN_ERR, &pdev->dev, | 1089 | dev_printk(KERN_ERR, &pdev->dev, |
1134 | "64-bit DMA enable failed\n"); | 1090 | "64-bit DMA enable failed\n"); |
1135 | goto out_free; | 1091 | return rc; |
1136 | } | 1092 | } |
1137 | } | 1093 | } |
1138 | } else { | 1094 | } else { |
@@ -1140,13 +1096,13 @@ static int sil24_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
1140 | if (rc) { | 1096 | if (rc) { |
1141 | dev_printk(KERN_ERR, &pdev->dev, | 1097 | dev_printk(KERN_ERR, &pdev->dev, |
1142 | "32-bit DMA enable failed\n"); | 1098 | "32-bit DMA enable failed\n"); |
1143 | goto out_free; | 1099 | return rc; |
1144 | } | 1100 | } |
1145 | rc = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK); | 1101 | rc = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK); |
1146 | if (rc) { | 1102 | if (rc) { |
1147 | dev_printk(KERN_ERR, &pdev->dev, | 1103 | dev_printk(KERN_ERR, &pdev->dev, |
1148 | "32-bit consistent DMA enable failed\n"); | 1104 | "32-bit consistent DMA enable failed\n"); |
1149 | goto out_free; | 1105 | return rc; |
1150 | } | 1106 | } |
1151 | } | 1107 | } |
1152 | 1108 | ||
@@ -1176,23 +1132,11 @@ static int sil24_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
1176 | 1132 | ||
1177 | pci_set_master(pdev); | 1133 | pci_set_master(pdev); |
1178 | 1134 | ||
1179 | /* FIXME: check ata_device_add return value */ | 1135 | if (!ata_device_add(probe_ent)) |
1180 | ata_device_add(probe_ent); | 1136 | return -ENODEV; |
1181 | 1137 | ||
1182 | kfree(probe_ent); | 1138 | devm_kfree(dev, probe_ent); |
1183 | return 0; | 1139 | return 0; |
1184 | |||
1185 | out_free: | ||
1186 | if (host_base) | ||
1187 | pci_iounmap(pdev, host_base); | ||
1188 | if (port_base) | ||
1189 | pci_iounmap(pdev, port_base); | ||
1190 | kfree(probe_ent); | ||
1191 | kfree(hpriv); | ||
1192 | pci_release_regions(pdev); | ||
1193 | out_disable: | ||
1194 | pci_disable_device(pdev); | ||
1195 | return rc; | ||
1196 | } | 1140 | } |
1197 | 1141 | ||
1198 | #ifdef CONFIG_PM | 1142 | #ifdef CONFIG_PM |