diff options
Diffstat (limited to 'drivers/ata/sata_fsl.c')
-rw-r--r-- | drivers/ata/sata_fsl.c | 136 |
1 files changed, 33 insertions, 103 deletions
diff --git a/drivers/ata/sata_fsl.c b/drivers/ata/sata_fsl.c index 9d1e3cad4aa9..fddd346b1d57 100644 --- a/drivers/ata/sata_fsl.c +++ b/drivers/ata/sata_fsl.c | |||
@@ -35,7 +35,6 @@ enum { | |||
35 | SATA_FSL_HOST_FLAGS = (ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | | 35 | SATA_FSL_HOST_FLAGS = (ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | |
36 | ATA_FLAG_MMIO | ATA_FLAG_PIO_DMA | | 36 | ATA_FLAG_MMIO | ATA_FLAG_PIO_DMA | |
37 | ATA_FLAG_NCQ), | 37 | ATA_FLAG_NCQ), |
38 | SATA_FSL_HOST_LFLAGS = ATA_LFLAG_SKIP_D2H_BSY, | ||
39 | 38 | ||
40 | SATA_FSL_MAX_CMDS = SATA_FSL_QUEUE_DEPTH, | 39 | SATA_FSL_MAX_CMDS = SATA_FSL_QUEUE_DEPTH, |
41 | SATA_FSL_CMD_HDR_SIZE = 16, /* 4 DWORDS */ | 40 | SATA_FSL_CMD_HDR_SIZE = 16, /* 4 DWORDS */ |
@@ -245,17 +244,6 @@ struct sata_fsl_port_priv { | |||
245 | dma_addr_t cmdslot_paddr; | 244 | dma_addr_t cmdslot_paddr; |
246 | struct command_desc *cmdentry; | 245 | struct command_desc *cmdentry; |
247 | dma_addr_t cmdentry_paddr; | 246 | dma_addr_t cmdentry_paddr; |
248 | |||
249 | /* | ||
250 | * SATA FSL controller has a Status FIS which should contain the | ||
251 | * received D2H FIS & taskfile registers. This SFIS is present in | ||
252 | * the command descriptor, and to have a ready reference to it, | ||
253 | * we are caching it here, quite similar to what is done in H/W on | ||
254 | * AHCI compliant devices by copying taskfile fields to a 32-bit | ||
255 | * register. | ||
256 | */ | ||
257 | |||
258 | struct ata_taskfile tf; | ||
259 | }; | 247 | }; |
260 | 248 | ||
261 | /* | 249 | /* |
@@ -465,6 +453,20 @@ static unsigned int sata_fsl_qc_issue(struct ata_queued_cmd *qc) | |||
465 | return 0; | 453 | return 0; |
466 | } | 454 | } |
467 | 455 | ||
456 | static bool sata_fsl_qc_fill_rtf(struct ata_queued_cmd *qc) | ||
457 | { | ||
458 | struct sata_fsl_port_priv *pp = qc->ap->private_data; | ||
459 | struct sata_fsl_host_priv *host_priv = qc->ap->host->private_data; | ||
460 | void __iomem *hcr_base = host_priv->hcr_base; | ||
461 | unsigned int tag = sata_fsl_tag(qc->tag, hcr_base); | ||
462 | struct command_desc *cd; | ||
463 | |||
464 | cd = pp->cmdentry + tag; | ||
465 | |||
466 | ata_tf_from_fis(cd->sfis, &qc->result_tf); | ||
467 | return true; | ||
468 | } | ||
469 | |||
468 | static int sata_fsl_scr_write(struct ata_port *ap, unsigned int sc_reg_in, | 470 | static int sata_fsl_scr_write(struct ata_port *ap, unsigned int sc_reg_in, |
469 | u32 val) | 471 | u32 val) |
470 | { | 472 | { |
@@ -556,38 +558,6 @@ static void sata_fsl_thaw(struct ata_port *ap) | |||
556 | ioread32(hcr_base + HCONTROL), ioread32(hcr_base + HSTATUS)); | 558 | ioread32(hcr_base + HCONTROL), ioread32(hcr_base + HSTATUS)); |
557 | } | 559 | } |
558 | 560 | ||
559 | /* | ||
560 | * NOTE : 1st D2H FIS from device does not update sfis in command descriptor. | ||
561 | */ | ||
562 | static inline void sata_fsl_cache_taskfile_from_d2h_fis(struct ata_queued_cmd | ||
563 | *qc, | ||
564 | struct ata_port *ap) | ||
565 | { | ||
566 | struct sata_fsl_port_priv *pp = ap->private_data; | ||
567 | struct sata_fsl_host_priv *host_priv = ap->host->private_data; | ||
568 | void __iomem *hcr_base = host_priv->hcr_base; | ||
569 | unsigned int tag = sata_fsl_tag(qc->tag, hcr_base); | ||
570 | struct command_desc *cd; | ||
571 | |||
572 | cd = pp->cmdentry + tag; | ||
573 | |||
574 | ata_tf_from_fis(cd->sfis, &pp->tf); | ||
575 | } | ||
576 | |||
577 | static u8 sata_fsl_check_status(struct ata_port *ap) | ||
578 | { | ||
579 | struct sata_fsl_port_priv *pp = ap->private_data; | ||
580 | |||
581 | return pp->tf.command; | ||
582 | } | ||
583 | |||
584 | static void sata_fsl_tf_read(struct ata_port *ap, struct ata_taskfile *tf) | ||
585 | { | ||
586 | struct sata_fsl_port_priv *pp = ap->private_data; | ||
587 | |||
588 | *tf = pp->tf; | ||
589 | } | ||
590 | |||
591 | static int sata_fsl_port_start(struct ata_port *ap) | 561 | static int sata_fsl_port_start(struct ata_port *ap) |
592 | { | 562 | { |
593 | struct device *dev = ap->host->dev; | 563 | struct device *dev = ap->host->dev; |
@@ -708,6 +678,15 @@ static unsigned int sata_fsl_dev_classify(struct ata_port *ap) | |||
708 | return ata_dev_classify(&tf); | 678 | return ata_dev_classify(&tf); |
709 | } | 679 | } |
710 | 680 | ||
681 | static int sata_fsl_prereset(struct ata_linke *link, unsigned long deadline) | ||
682 | { | ||
683 | /* FIXME: Never skip softreset, sata_fsl_softreset() is | ||
684 | * combination of soft and hard resets. sata_fsl_softreset() | ||
685 | * needs to be splitted into soft and hard resets. | ||
686 | */ | ||
687 | return 0; | ||
688 | } | ||
689 | |||
711 | static int sata_fsl_softreset(struct ata_link *link, unsigned int *class, | 690 | static int sata_fsl_softreset(struct ata_link *link, unsigned int *class, |
712 | unsigned long deadline) | 691 | unsigned long deadline) |
713 | { | 692 | { |
@@ -913,16 +892,6 @@ err: | |||
913 | return -EIO; | 892 | return -EIO; |
914 | } | 893 | } |
915 | 894 | ||
916 | static void sata_fsl_error_handler(struct ata_port *ap) | ||
917 | { | ||
918 | |||
919 | DPRINTK("in xx_error_handler\n"); | ||
920 | |||
921 | /* perform recovery */ | ||
922 | ata_do_eh(ap, ata_std_prereset, sata_fsl_softreset, sata_std_hardreset, | ||
923 | ata_std_postreset); | ||
924 | } | ||
925 | |||
926 | static void sata_fsl_post_internal_cmd(struct ata_queued_cmd *qc) | 895 | static void sata_fsl_post_internal_cmd(struct ata_queued_cmd *qc) |
927 | { | 896 | { |
928 | if (qc->flags & ATA_QCFLAG_FAILED) | 897 | if (qc->flags & ATA_QCFLAG_FAILED) |
@@ -934,11 +903,6 @@ static void sata_fsl_post_internal_cmd(struct ata_queued_cmd *qc) | |||
934 | } | 903 | } |
935 | } | 904 | } |
936 | 905 | ||
937 | static void sata_fsl_irq_clear(struct ata_port *ap) | ||
938 | { | ||
939 | /* unused */ | ||
940 | } | ||
941 | |||
942 | static void sata_fsl_error_intr(struct ata_port *ap) | 906 | static void sata_fsl_error_intr(struct ata_port *ap) |
943 | { | 907 | { |
944 | struct ata_link *link = &ap->link; | 908 | struct ata_link *link = &ap->link; |
@@ -996,7 +960,7 @@ static void sata_fsl_error_intr(struct ata_port *ap) | |||
996 | /* handle fatal errors */ | 960 | /* handle fatal errors */ |
997 | if (hstatus & FATAL_ERROR_DECODE) { | 961 | if (hstatus & FATAL_ERROR_DECODE) { |
998 | err_mask |= AC_ERR_ATA_BUS; | 962 | err_mask |= AC_ERR_ATA_BUS; |
999 | action |= ATA_EH_SOFTRESET; | 963 | action |= ATA_EH_RESET; |
1000 | /* how will fatal error interrupts be completed ?? */ | 964 | /* how will fatal error interrupts be completed ?? */ |
1001 | freeze = 1; | 965 | freeze = 1; |
1002 | } | 966 | } |
@@ -1013,10 +977,9 @@ static void sata_fsl_error_intr(struct ata_port *ap) | |||
1013 | /* record error info */ | 977 | /* record error info */ |
1014 | qc = ata_qc_from_tag(ap, link->active_tag); | 978 | qc = ata_qc_from_tag(ap, link->active_tag); |
1015 | 979 | ||
1016 | if (qc) { | 980 | if (qc) |
1017 | sata_fsl_cache_taskfile_from_d2h_fis(qc, qc->ap); | ||
1018 | qc->err_mask |= err_mask; | 981 | qc->err_mask |= err_mask; |
1019 | } else | 982 | else |
1020 | ehi->err_mask |= err_mask; | 983 | ehi->err_mask |= err_mask; |
1021 | 984 | ||
1022 | ehi->action |= action; | 985 | ehi->action |= action; |
@@ -1029,14 +992,6 @@ static void sata_fsl_error_intr(struct ata_port *ap) | |||
1029 | ata_port_abort(ap); | 992 | ata_port_abort(ap); |
1030 | } | 993 | } |
1031 | 994 | ||
1032 | static void sata_fsl_qc_complete(struct ata_queued_cmd *qc) | ||
1033 | { | ||
1034 | if (qc->flags & ATA_QCFLAG_RESULT_TF) { | ||
1035 | DPRINTK("xx_qc_complete called\n"); | ||
1036 | sata_fsl_cache_taskfile_from_d2h_fis(qc, qc->ap); | ||
1037 | } | ||
1038 | } | ||
1039 | |||
1040 | static void sata_fsl_host_intr(struct ata_port *ap) | 995 | static void sata_fsl_host_intr(struct ata_port *ap) |
1041 | { | 996 | { |
1042 | struct ata_link *link = &ap->link; | 997 | struct ata_link *link = &ap->link; |
@@ -1077,10 +1032,8 @@ static void sata_fsl_host_intr(struct ata_port *ap) | |||
1077 | for (i = 0; i < SATA_FSL_QUEUE_DEPTH; i++) { | 1032 | for (i = 0; i < SATA_FSL_QUEUE_DEPTH; i++) { |
1078 | if (qc_active & (1 << i)) { | 1033 | if (qc_active & (1 << i)) { |
1079 | qc = ata_qc_from_tag(ap, i); | 1034 | qc = ata_qc_from_tag(ap, i); |
1080 | if (qc) { | 1035 | if (qc) |
1081 | sata_fsl_qc_complete(qc); | ||
1082 | ata_qc_complete(qc); | 1036 | ata_qc_complete(qc); |
1083 | } | ||
1084 | DPRINTK | 1037 | DPRINTK |
1085 | ("completing ncq cmd,tag=%d,CC=0x%x,CA=0x%x\n", | 1038 | ("completing ncq cmd,tag=%d,CC=0x%x,CA=0x%x\n", |
1086 | i, ioread32(hcr_base + CC), | 1039 | i, ioread32(hcr_base + CC), |
@@ -1096,10 +1049,8 @@ static void sata_fsl_host_intr(struct ata_port *ap) | |||
1096 | DPRINTK("completing non-ncq cmd, tag=%d,CC=0x%x\n", | 1049 | DPRINTK("completing non-ncq cmd, tag=%d,CC=0x%x\n", |
1097 | link->active_tag, ioread32(hcr_base + CC)); | 1050 | link->active_tag, ioread32(hcr_base + CC)); |
1098 | 1051 | ||
1099 | if (qc) { | 1052 | if (qc) |
1100 | sata_fsl_qc_complete(qc); | ||
1101 | ata_qc_complete(qc); | 1053 | ata_qc_complete(qc); |
1102 | } | ||
1103 | } else { | 1054 | } else { |
1104 | /* Spurious Interrupt!! */ | 1055 | /* Spurious Interrupt!! */ |
1105 | DPRINTK("spurious interrupt!!, CC = 0x%x\n", | 1056 | DPRINTK("spurious interrupt!!, CC = 0x%x\n", |
@@ -1197,41 +1148,26 @@ static int sata_fsl_init_controller(struct ata_host *host) | |||
1197 | * scsi mid-layer and libata interface structures | 1148 | * scsi mid-layer and libata interface structures |
1198 | */ | 1149 | */ |
1199 | static struct scsi_host_template sata_fsl_sht = { | 1150 | static struct scsi_host_template sata_fsl_sht = { |
1200 | .module = THIS_MODULE, | 1151 | ATA_NCQ_SHT("sata_fsl"), |
1201 | .name = "sata_fsl", | ||
1202 | .ioctl = ata_scsi_ioctl, | ||
1203 | .queuecommand = ata_scsi_queuecmd, | ||
1204 | .change_queue_depth = ata_scsi_change_queue_depth, | ||
1205 | .can_queue = SATA_FSL_QUEUE_DEPTH, | 1152 | .can_queue = SATA_FSL_QUEUE_DEPTH, |
1206 | .this_id = ATA_SHT_THIS_ID, | ||
1207 | .sg_tablesize = SATA_FSL_MAX_PRD_USABLE, | 1153 | .sg_tablesize = SATA_FSL_MAX_PRD_USABLE, |
1208 | .cmd_per_lun = ATA_SHT_CMD_PER_LUN, | ||
1209 | .emulated = ATA_SHT_EMULATED, | ||
1210 | .use_clustering = ATA_SHT_USE_CLUSTERING, | ||
1211 | .proc_name = "sata_fsl", | ||
1212 | .dma_boundary = ATA_DMA_BOUNDARY, | 1154 | .dma_boundary = ATA_DMA_BOUNDARY, |
1213 | .slave_configure = ata_scsi_slave_config, | ||
1214 | .slave_destroy = ata_scsi_slave_destroy, | ||
1215 | .bios_param = ata_std_bios_param, | ||
1216 | }; | 1155 | }; |
1217 | 1156 | ||
1218 | static const struct ata_port_operations sata_fsl_ops = { | 1157 | static const struct ata_port_operations sata_fsl_ops = { |
1219 | .check_status = sata_fsl_check_status, | 1158 | .inherits = &sata_port_ops, |
1220 | .check_altstatus = sata_fsl_check_status, | ||
1221 | .dev_select = ata_noop_dev_select, | ||
1222 | |||
1223 | .tf_read = sata_fsl_tf_read, | ||
1224 | 1159 | ||
1225 | .qc_prep = sata_fsl_qc_prep, | 1160 | .qc_prep = sata_fsl_qc_prep, |
1226 | .qc_issue = sata_fsl_qc_issue, | 1161 | .qc_issue = sata_fsl_qc_issue, |
1227 | .irq_clear = sata_fsl_irq_clear, | 1162 | .qc_fill_rtf = sata_fsl_qc_fill_rtf, |
1228 | 1163 | ||
1229 | .scr_read = sata_fsl_scr_read, | 1164 | .scr_read = sata_fsl_scr_read, |
1230 | .scr_write = sata_fsl_scr_write, | 1165 | .scr_write = sata_fsl_scr_write, |
1231 | 1166 | ||
1232 | .freeze = sata_fsl_freeze, | 1167 | .freeze = sata_fsl_freeze, |
1233 | .thaw = sata_fsl_thaw, | 1168 | .thaw = sata_fsl_thaw, |
1234 | .error_handler = sata_fsl_error_handler, | 1169 | .prereset = sata_fsl_prereset, |
1170 | .softreset = sata_fsl_softreset, | ||
1235 | .post_internal_cmd = sata_fsl_post_internal_cmd, | 1171 | .post_internal_cmd = sata_fsl_post_internal_cmd, |
1236 | 1172 | ||
1237 | .port_start = sata_fsl_port_start, | 1173 | .port_start = sata_fsl_port_start, |
@@ -1241,7 +1177,6 @@ static const struct ata_port_operations sata_fsl_ops = { | |||
1241 | static const struct ata_port_info sata_fsl_port_info[] = { | 1177 | static const struct ata_port_info sata_fsl_port_info[] = { |
1242 | { | 1178 | { |
1243 | .flags = SATA_FSL_HOST_FLAGS, | 1179 | .flags = SATA_FSL_HOST_FLAGS, |
1244 | .link_flags = SATA_FSL_HOST_LFLAGS, | ||
1245 | .pio_mask = 0x1f, /* pio 0-4 */ | 1180 | .pio_mask = 0x1f, /* pio 0-4 */ |
1246 | .udma_mask = 0x7f, /* udma 0-6 */ | 1181 | .udma_mask = 0x7f, /* udma 0-6 */ |
1247 | .port_ops = &sata_fsl_ops, | 1182 | .port_ops = &sata_fsl_ops, |
@@ -1297,11 +1232,6 @@ static int sata_fsl_probe(struct of_device *ofdev, | |||
1297 | /* host->iomap is not used currently */ | 1232 | /* host->iomap is not used currently */ |
1298 | host->private_data = host_priv; | 1233 | host->private_data = host_priv; |
1299 | 1234 | ||
1300 | /* setup port(s) */ | ||
1301 | |||
1302 | host->ports[0]->ioaddr.cmd_addr = host_priv->hcr_base; | ||
1303 | host->ports[0]->ioaddr.scr_addr = host_priv->ssr_base; | ||
1304 | |||
1305 | /* initialize host controller */ | 1235 | /* initialize host controller */ |
1306 | sata_fsl_init_controller(host); | 1236 | sata_fsl_init_controller(host); |
1307 | 1237 | ||