1f2105c61SSimon Glass /*
2f2105c61SSimon Glass * sata_dwc.c
3f2105c61SSimon Glass *
4f2105c61SSimon Glass * Synopsys DesignWare Cores (DWC) SATA host driver
5f2105c61SSimon Glass *
6f2105c61SSimon Glass * Author: Mark Miesfeld <mmiesfeld@amcc.com>
7f2105c61SSimon Glass *
8f2105c61SSimon Glass * Ported from 2.6.19.2 to 2.6.25/26 by Stefan Roese <sr@denx.de>
9f2105c61SSimon Glass * Copyright 2008 DENX Software Engineering
10f2105c61SSimon Glass *
11f2105c61SSimon Glass * Based on versions provided by AMCC and Synopsys which are:
12f2105c61SSimon Glass * Copyright 2006 Applied Micro Circuits Corporation
13f2105c61SSimon Glass * COPYRIGHT (C) 2005 SYNOPSYS, INC. ALL RIGHTS RESERVED
14f2105c61SSimon Glass *
15f2105c61SSimon Glass * SPDX-License-Identifier: GPL-2.0+
16f2105c61SSimon Glass */
17f2105c61SSimon Glass /*
18f2105c61SSimon Glass * SATA support based on the chip canyonlands.
19f2105c61SSimon Glass *
20f2105c61SSimon Glass * 04-17-2009
21f2105c61SSimon Glass * The local version of this driver for the canyonlands board
22f2105c61SSimon Glass * does not use interrupts but polls the chip instead.
23f2105c61SSimon Glass */
24f2105c61SSimon Glass
25f2105c61SSimon Glass #include <common.h>
26f2105c61SSimon Glass #include <command.h>
27f2105c61SSimon Glass #include <pci.h>
28f2105c61SSimon Glass #include <asm/processor.h>
29*9ff3d014SMasahiro Yamada #include <linux/dma-direction.h>
30f2105c61SSimon Glass #include <linux/errno.h>
31f2105c61SSimon Glass #include <asm/io.h>
32f2105c61SSimon Glass #include <malloc.h>
33f2105c61SSimon Glass #include <ata.h>
34f2105c61SSimon Glass #include <sata.h>
35f2105c61SSimon Glass #include <linux/ctype.h>
36f2105c61SSimon Glass
37f2105c61SSimon Glass #include "sata_dwc.h"
38f2105c61SSimon Glass
39f2105c61SSimon Glass #define DMA_NUM_CHANS 1
40f2105c61SSimon Glass #define DMA_NUM_CHAN_REGS 8
41f2105c61SSimon Glass
42f2105c61SSimon Glass #define AHB_DMA_BRST_DFLT 16
43f2105c61SSimon Glass
44f2105c61SSimon Glass struct dmareg {
45f2105c61SSimon Glass u32 low;
46f2105c61SSimon Glass u32 high;
47f2105c61SSimon Glass };
48f2105c61SSimon Glass
49f2105c61SSimon Glass struct dma_chan_regs {
50f2105c61SSimon Glass struct dmareg sar;
51f2105c61SSimon Glass struct dmareg dar;
52f2105c61SSimon Glass struct dmareg llp;
53f2105c61SSimon Glass struct dmareg ctl;
54f2105c61SSimon Glass struct dmareg sstat;
55f2105c61SSimon Glass struct dmareg dstat;
56f2105c61SSimon Glass struct dmareg sstatar;
57f2105c61SSimon Glass struct dmareg dstatar;
58f2105c61SSimon Glass struct dmareg cfg;
59f2105c61SSimon Glass struct dmareg sgr;
60f2105c61SSimon Glass struct dmareg dsr;
61f2105c61SSimon Glass };
62f2105c61SSimon Glass
63f2105c61SSimon Glass struct dma_interrupt_regs {
64f2105c61SSimon Glass struct dmareg tfr;
65f2105c61SSimon Glass struct dmareg block;
66f2105c61SSimon Glass struct dmareg srctran;
67f2105c61SSimon Glass struct dmareg dsttran;
68f2105c61SSimon Glass struct dmareg error;
69f2105c61SSimon Glass };
70f2105c61SSimon Glass
71f2105c61SSimon Glass struct ahb_dma_regs {
72f2105c61SSimon Glass struct dma_chan_regs chan_regs[DMA_NUM_CHAN_REGS];
73f2105c61SSimon Glass struct dma_interrupt_regs interrupt_raw;
74f2105c61SSimon Glass struct dma_interrupt_regs interrupt_status;
75f2105c61SSimon Glass struct dma_interrupt_regs interrupt_mask;
76f2105c61SSimon Glass struct dma_interrupt_regs interrupt_clear;
77f2105c61SSimon Glass struct dmareg statusInt;
78f2105c61SSimon Glass struct dmareg rq_srcreg;
79f2105c61SSimon Glass struct dmareg rq_dstreg;
80f2105c61SSimon Glass struct dmareg rq_sgl_srcreg;
81f2105c61SSimon Glass struct dmareg rq_sgl_dstreg;
82f2105c61SSimon Glass struct dmareg rq_lst_srcreg;
83f2105c61SSimon Glass struct dmareg rq_lst_dstreg;
84f2105c61SSimon Glass struct dmareg dma_cfg;
85f2105c61SSimon Glass struct dmareg dma_chan_en;
86f2105c61SSimon Glass struct dmareg dma_id;
87f2105c61SSimon Glass struct dmareg dma_test;
88f2105c61SSimon Glass struct dmareg res1;
89f2105c61SSimon Glass struct dmareg res2;
90f2105c61SSimon Glass /* DMA Comp Params
91f2105c61SSimon Glass * Param 6 = dma_param[0], Param 5 = dma_param[1],
92f2105c61SSimon Glass * Param 4 = dma_param[2] ...
93f2105c61SSimon Glass */
94f2105c61SSimon Glass struct dmareg dma_params[6];
95f2105c61SSimon Glass };
96f2105c61SSimon Glass
97f2105c61SSimon Glass #define DMA_EN 0x00000001
98f2105c61SSimon Glass #define DMA_DI 0x00000000
99f2105c61SSimon Glass #define DMA_CHANNEL(ch) (0x00000001 << (ch))
100f2105c61SSimon Glass #define DMA_ENABLE_CHAN(ch) ((0x00000001 << (ch)) | \
101f2105c61SSimon Glass ((0x000000001 << (ch)) << 8))
102f2105c61SSimon Glass #define DMA_DISABLE_CHAN(ch) (0x00000000 | \
103f2105c61SSimon Glass ((0x000000001 << (ch)) << 8))
104f2105c61SSimon Glass
105f2105c61SSimon Glass #define SATA_DWC_MAX_PORTS 1
106f2105c61SSimon Glass #define SATA_DWC_SCR_OFFSET 0x24
107f2105c61SSimon Glass #define SATA_DWC_REG_OFFSET 0x64
108f2105c61SSimon Glass
109f2105c61SSimon Glass struct sata_dwc_regs {
110f2105c61SSimon Glass u32 fptagr;
111f2105c61SSimon Glass u32 fpbor;
112f2105c61SSimon Glass u32 fptcr;
113f2105c61SSimon Glass u32 dmacr;
114f2105c61SSimon Glass u32 dbtsr;
115f2105c61SSimon Glass u32 intpr;
116f2105c61SSimon Glass u32 intmr;
117f2105c61SSimon Glass u32 errmr;
118f2105c61SSimon Glass u32 llcr;
119f2105c61SSimon Glass u32 phycr;
120f2105c61SSimon Glass u32 physr;
121f2105c61SSimon Glass u32 rxbistpd;
122f2105c61SSimon Glass u32 rxbistpd1;
123f2105c61SSimon Glass u32 rxbistpd2;
124f2105c61SSimon Glass u32 txbistpd;
125f2105c61SSimon Glass u32 txbistpd1;
126f2105c61SSimon Glass u32 txbistpd2;
127f2105c61SSimon Glass u32 bistcr;
128f2105c61SSimon Glass u32 bistfctr;
129f2105c61SSimon Glass u32 bistsr;
130f2105c61SSimon Glass u32 bistdecr;
131f2105c61SSimon Glass u32 res[15];
132f2105c61SSimon Glass u32 testr;
133f2105c61SSimon Glass u32 versionr;
134f2105c61SSimon Glass u32 idr;
135f2105c61SSimon Glass u32 unimpl[192];
136f2105c61SSimon Glass u32 dmadr[256];
137f2105c61SSimon Glass };
138f2105c61SSimon Glass
139f2105c61SSimon Glass #define SATA_DWC_TXFIFO_DEPTH 0x01FF
140f2105c61SSimon Glass #define SATA_DWC_RXFIFO_DEPTH 0x01FF
141f2105c61SSimon Glass
142f2105c61SSimon Glass #define SATA_DWC_DBTSR_MWR(size) ((size / 4) & SATA_DWC_TXFIFO_DEPTH)
143f2105c61SSimon Glass #define SATA_DWC_DBTSR_MRD(size) (((size / 4) & \
144f2105c61SSimon Glass SATA_DWC_RXFIFO_DEPTH) << 16)
145f2105c61SSimon Glass #define SATA_DWC_INTPR_DMAT 0x00000001
146f2105c61SSimon Glass #define SATA_DWC_INTPR_NEWFP 0x00000002
147f2105c61SSimon Glass #define SATA_DWC_INTPR_PMABRT 0x00000004
148f2105c61SSimon Glass #define SATA_DWC_INTPR_ERR 0x00000008
149f2105c61SSimon Glass #define SATA_DWC_INTPR_NEWBIST 0x00000010
150f2105c61SSimon Glass #define SATA_DWC_INTPR_IPF 0x10000000
151f2105c61SSimon Glass #define SATA_DWC_INTMR_DMATM 0x00000001
152f2105c61SSimon Glass #define SATA_DWC_INTMR_NEWFPM 0x00000002
153f2105c61SSimon Glass #define SATA_DWC_INTMR_PMABRTM 0x00000004
154f2105c61SSimon Glass #define SATA_DWC_INTMR_ERRM 0x00000008
155f2105c61SSimon Glass #define SATA_DWC_INTMR_NEWBISTM 0x00000010
156f2105c61SSimon Glass
157f2105c61SSimon Glass #define SATA_DWC_DMACR_TMOD_TXCHEN 0x00000004
158f2105c61SSimon Glass #define SATA_DWC_DMACR_TXRXCH_CLEAR SATA_DWC_DMACR_TMOD_TXCHEN
159f2105c61SSimon Glass
160f2105c61SSimon Glass #define SATA_DWC_QCMD_MAX 32
161f2105c61SSimon Glass
162f2105c61SSimon Glass #define SATA_DWC_SERROR_ERR_BITS 0x0FFF0F03
163f2105c61SSimon Glass
164f2105c61SSimon Glass #define HSDEVP_FROM_AP(ap) (struct sata_dwc_device_port*) \
165f2105c61SSimon Glass (ap)->private_data
166f2105c61SSimon Glass
167f2105c61SSimon Glass struct sata_dwc_device {
168f2105c61SSimon Glass struct device *dev;
169f2105c61SSimon Glass struct ata_probe_ent *pe;
170f2105c61SSimon Glass struct ata_host *host;
171f2105c61SSimon Glass u8 *reg_base;
172f2105c61SSimon Glass struct sata_dwc_regs *sata_dwc_regs;
173f2105c61SSimon Glass int irq_dma;
174f2105c61SSimon Glass };
175f2105c61SSimon Glass
176f2105c61SSimon Glass struct sata_dwc_device_port {
177f2105c61SSimon Glass struct sata_dwc_device *hsdev;
178f2105c61SSimon Glass int cmd_issued[SATA_DWC_QCMD_MAX];
179f2105c61SSimon Glass u32 dma_chan[SATA_DWC_QCMD_MAX];
180f2105c61SSimon Glass int dma_pending[SATA_DWC_QCMD_MAX];
181f2105c61SSimon Glass };
182f2105c61SSimon Glass
183f2105c61SSimon Glass enum {
184f2105c61SSimon Glass SATA_DWC_CMD_ISSUED_NOT = 0,
185f2105c61SSimon Glass SATA_DWC_CMD_ISSUED_PEND = 1,
186f2105c61SSimon Glass SATA_DWC_CMD_ISSUED_EXEC = 2,
187f2105c61SSimon Glass SATA_DWC_CMD_ISSUED_NODATA = 3,
188f2105c61SSimon Glass
189f2105c61SSimon Glass SATA_DWC_DMA_PENDING_NONE = 0,
190f2105c61SSimon Glass SATA_DWC_DMA_PENDING_TX = 1,
191f2105c61SSimon Glass SATA_DWC_DMA_PENDING_RX = 2,
192f2105c61SSimon Glass };
193f2105c61SSimon Glass
194f2105c61SSimon Glass #define msleep(a) udelay(a * 1000)
195f2105c61SSimon Glass #define ssleep(a) msleep(a * 1000)
196f2105c61SSimon Glass
197f2105c61SSimon Glass static int ata_probe_timeout = (ATA_TMOUT_INTERNAL / 100);
198f2105c61SSimon Glass
199f2105c61SSimon Glass enum sata_dev_state {
200f2105c61SSimon Glass SATA_INIT = 0,
201f2105c61SSimon Glass SATA_READY = 1,
202f2105c61SSimon Glass SATA_NODEVICE = 2,
203f2105c61SSimon Glass SATA_ERROR = 3,
204f2105c61SSimon Glass };
205f2105c61SSimon Glass enum sata_dev_state dev_state = SATA_INIT;
206f2105c61SSimon Glass
207f2105c61SSimon Glass static struct ahb_dma_regs *sata_dma_regs = 0;
208f2105c61SSimon Glass static struct ata_host *phost;
209f2105c61SSimon Glass static struct ata_port ap;
210f2105c61SSimon Glass static struct ata_port *pap = ≈
211f2105c61SSimon Glass static struct ata_device ata_device;
212f2105c61SSimon Glass static struct sata_dwc_device_port dwc_devp;
213f2105c61SSimon Glass
214f2105c61SSimon Glass static void *scr_addr_sstatus;
215f2105c61SSimon Glass static u32 temp_n_block = 0;
216f2105c61SSimon Glass
217f2105c61SSimon Glass static unsigned ata_exec_internal(struct ata_device *dev,
218f2105c61SSimon Glass struct ata_taskfile *tf, const u8 *cdb,
219f2105c61SSimon Glass int dma_dir, unsigned int buflen,
220f2105c61SSimon Glass unsigned long timeout);
221f2105c61SSimon Glass static unsigned int ata_dev_set_feature(struct ata_device *dev,
222f2105c61SSimon Glass u8 enable,u8 feature);
223f2105c61SSimon Glass static unsigned int ata_dev_init_params(struct ata_device *dev,
224f2105c61SSimon Glass u16 heads, u16 sectors);
225f2105c61SSimon Glass static u8 ata_irq_on(struct ata_port *ap);
226f2105c61SSimon Glass static struct ata_queued_cmd *__ata_qc_from_tag(struct ata_port *ap,
227f2105c61SSimon Glass unsigned int tag);
228f2105c61SSimon Glass static int ata_hsm_move(struct ata_port *ap, struct ata_queued_cmd *qc,
229f2105c61SSimon Glass u8 status, int in_wq);
230f2105c61SSimon Glass static void ata_tf_to_host(struct ata_port *ap,
231f2105c61SSimon Glass const struct ata_taskfile *tf);
232f2105c61SSimon Glass static void ata_exec_command(struct ata_port *ap,
233f2105c61SSimon Glass const struct ata_taskfile *tf);
234f2105c61SSimon Glass static unsigned int ata_qc_issue_prot(struct ata_queued_cmd *qc);
235f2105c61SSimon Glass static u8 ata_check_altstatus(struct ata_port *ap);
236f2105c61SSimon Glass static u8 ata_check_status(struct ata_port *ap);
237f2105c61SSimon Glass static void ata_dev_select(struct ata_port *ap, unsigned int device,
238f2105c61SSimon Glass unsigned int wait, unsigned int can_sleep);
239f2105c61SSimon Glass static void ata_qc_issue(struct ata_queued_cmd *qc);
240f2105c61SSimon Glass static void ata_tf_load(struct ata_port *ap,
241f2105c61SSimon Glass const struct ata_taskfile *tf);
242f2105c61SSimon Glass static int ata_dev_read_sectors(unsigned char* pdata,
243f2105c61SSimon Glass unsigned long datalen, u32 block, u32 n_block);
244f2105c61SSimon Glass static int ata_dev_write_sectors(unsigned char* pdata,
245f2105c61SSimon Glass unsigned long datalen , u32 block, u32 n_block);
246f2105c61SSimon Glass static void ata_std_dev_select(struct ata_port *ap, unsigned int device);
247f2105c61SSimon Glass static void ata_qc_complete(struct ata_queued_cmd *qc);
248f2105c61SSimon Glass static void __ata_qc_complete(struct ata_queued_cmd *qc);
249f2105c61SSimon Glass static void fill_result_tf(struct ata_queued_cmd *qc);
250f2105c61SSimon Glass static void ata_tf_read(struct ata_port *ap, struct ata_taskfile *tf);
251f2105c61SSimon Glass static void ata_mmio_data_xfer(struct ata_device *dev,
252f2105c61SSimon Glass unsigned char *buf,
253f2105c61SSimon Glass unsigned int buflen,int do_write);
254f2105c61SSimon Glass static void ata_pio_task(struct ata_port *arg_ap);
255f2105c61SSimon Glass static void __ata_port_freeze(struct ata_port *ap);
256f2105c61SSimon Glass static int ata_port_freeze(struct ata_port *ap);
257f2105c61SSimon Glass static void ata_qc_free(struct ata_queued_cmd *qc);
258f2105c61SSimon Glass static void ata_pio_sectors(struct ata_queued_cmd *qc);
259f2105c61SSimon Glass static void ata_pio_sector(struct ata_queued_cmd *qc);
260f2105c61SSimon Glass static void ata_pio_queue_task(struct ata_port *ap,
261f2105c61SSimon Glass void *data,unsigned long delay);
262f2105c61SSimon Glass static void ata_hsm_qc_complete(struct ata_queued_cmd *qc, int in_wq);
263f2105c61SSimon Glass static int sata_dwc_softreset(struct ata_port *ap);
264f2105c61SSimon Glass static int ata_dev_read_id(struct ata_device *dev, unsigned int *p_class,
265f2105c61SSimon Glass unsigned int flags, u16 *id);
266f2105c61SSimon Glass static int check_sata_dev_state(void);
267f2105c61SSimon Glass
268f2105c61SSimon Glass static const struct ata_port_info sata_dwc_port_info[] = {
269f2105c61SSimon Glass {
270f2105c61SSimon Glass .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
271f2105c61SSimon Glass ATA_FLAG_MMIO | ATA_FLAG_PIO_POLLING |
272f2105c61SSimon Glass ATA_FLAG_SRST | ATA_FLAG_NCQ,
273f2105c61SSimon Glass .pio_mask = 0x1f,
274f2105c61SSimon Glass .mwdma_mask = 0x07,
275f2105c61SSimon Glass .udma_mask = 0x7f,
276f2105c61SSimon Glass },
277f2105c61SSimon Glass };
278f2105c61SSimon Glass
init_sata(int dev)279f2105c61SSimon Glass int init_sata(int dev)
280f2105c61SSimon Glass {
281f2105c61SSimon Glass struct sata_dwc_device hsdev;
282f2105c61SSimon Glass struct ata_host host;
283f2105c61SSimon Glass struct ata_port_info pi = sata_dwc_port_info[0];
284f2105c61SSimon Glass struct ata_link *link;
285f2105c61SSimon Glass struct sata_dwc_device_port hsdevp = dwc_devp;
286f2105c61SSimon Glass u8 *base = 0;
287f2105c61SSimon Glass u8 *sata_dma_regs_addr = 0;
288f2105c61SSimon Glass u8 status;
289f2105c61SSimon Glass unsigned long base_addr = 0;
290f2105c61SSimon Glass int chan = 0;
291f2105c61SSimon Glass int rc;
292f2105c61SSimon Glass int i;
293f2105c61SSimon Glass
294f2105c61SSimon Glass phost = &host;
295f2105c61SSimon Glass
296f2105c61SSimon Glass base = (u8*)SATA_BASE_ADDR;
297f2105c61SSimon Glass
298f2105c61SSimon Glass hsdev.sata_dwc_regs = (void *__iomem)(base + SATA_DWC_REG_OFFSET);
299f2105c61SSimon Glass
300f2105c61SSimon Glass host.n_ports = SATA_DWC_MAX_PORTS;
301f2105c61SSimon Glass
302f2105c61SSimon Glass for (i = 0; i < SATA_DWC_MAX_PORTS; i++) {
303f2105c61SSimon Glass ap.pflags |= ATA_PFLAG_INITIALIZING;
304f2105c61SSimon Glass ap.flags = ATA_FLAG_DISABLED;
305f2105c61SSimon Glass ap.print_id = -1;
306f2105c61SSimon Glass ap.ctl = ATA_DEVCTL_OBS;
307f2105c61SSimon Glass ap.host = &host;
308f2105c61SSimon Glass ap.last_ctl = 0xFF;
309f2105c61SSimon Glass
310f2105c61SSimon Glass link = &ap.link;
311f2105c61SSimon Glass link->ap = ≈
312f2105c61SSimon Glass link->pmp = 0;
313f2105c61SSimon Glass link->active_tag = ATA_TAG_POISON;
314f2105c61SSimon Glass link->hw_sata_spd_limit = 0;
315f2105c61SSimon Glass
316f2105c61SSimon Glass ap.port_no = i;
317f2105c61SSimon Glass host.ports[i] = ≈
318f2105c61SSimon Glass }
319f2105c61SSimon Glass
320f2105c61SSimon Glass ap.pio_mask = pi.pio_mask;
321f2105c61SSimon Glass ap.mwdma_mask = pi.mwdma_mask;
322f2105c61SSimon Glass ap.udma_mask = pi.udma_mask;
323f2105c61SSimon Glass ap.flags |= pi.flags;
324f2105c61SSimon Glass ap.link.flags |= pi.link_flags;
325f2105c61SSimon Glass
326f2105c61SSimon Glass host.ports[0]->ioaddr.cmd_addr = base;
327f2105c61SSimon Glass host.ports[0]->ioaddr.scr_addr = base + SATA_DWC_SCR_OFFSET;
328f2105c61SSimon Glass scr_addr_sstatus = base + SATA_DWC_SCR_OFFSET;
329f2105c61SSimon Glass
330f2105c61SSimon Glass base_addr = (unsigned long)base;
331f2105c61SSimon Glass
332f2105c61SSimon Glass host.ports[0]->ioaddr.cmd_addr = (void *)base_addr + 0x00;
333f2105c61SSimon Glass host.ports[0]->ioaddr.data_addr = (void *)base_addr + 0x00;
334f2105c61SSimon Glass
335f2105c61SSimon Glass host.ports[0]->ioaddr.error_addr = (void *)base_addr + 0x04;
336f2105c61SSimon Glass host.ports[0]->ioaddr.feature_addr = (void *)base_addr + 0x04;
337f2105c61SSimon Glass
338f2105c61SSimon Glass host.ports[0]->ioaddr.nsect_addr = (void *)base_addr + 0x08;
339f2105c61SSimon Glass
340f2105c61SSimon Glass host.ports[0]->ioaddr.lbal_addr = (void *)base_addr + 0x0c;
341f2105c61SSimon Glass host.ports[0]->ioaddr.lbam_addr = (void *)base_addr + 0x10;
342f2105c61SSimon Glass host.ports[0]->ioaddr.lbah_addr = (void *)base_addr + 0x14;
343f2105c61SSimon Glass
344f2105c61SSimon Glass host.ports[0]->ioaddr.device_addr = (void *)base_addr + 0x18;
345f2105c61SSimon Glass host.ports[0]->ioaddr.command_addr = (void *)base_addr + 0x1c;
346f2105c61SSimon Glass host.ports[0]->ioaddr.status_addr = (void *)base_addr + 0x1c;
347f2105c61SSimon Glass
348f2105c61SSimon Glass host.ports[0]->ioaddr.altstatus_addr = (void *)base_addr + 0x20;
349f2105c61SSimon Glass host.ports[0]->ioaddr.ctl_addr = (void *)base_addr + 0x20;
350f2105c61SSimon Glass
351f2105c61SSimon Glass sata_dma_regs_addr = (u8*)SATA_DMA_REG_ADDR;
352f2105c61SSimon Glass sata_dma_regs = (void *__iomem)sata_dma_regs_addr;
353f2105c61SSimon Glass
354f2105c61SSimon Glass status = ata_check_altstatus(&ap);
355f2105c61SSimon Glass
356f2105c61SSimon Glass if (status == 0x7f) {
357f2105c61SSimon Glass printf("Hard Disk not found.\n");
358f2105c61SSimon Glass dev_state = SATA_NODEVICE;
359f2105c61SSimon Glass rc = false;
360f2105c61SSimon Glass return rc;
361f2105c61SSimon Glass }
362f2105c61SSimon Glass
363f2105c61SSimon Glass printf("Waiting for device...");
364f2105c61SSimon Glass i = 0;
365f2105c61SSimon Glass while (1) {
366f2105c61SSimon Glass udelay(10000);
367f2105c61SSimon Glass
368f2105c61SSimon Glass status = ata_check_altstatus(&ap);
369f2105c61SSimon Glass
370f2105c61SSimon Glass if ((status & ATA_BUSY) == 0) {
371f2105c61SSimon Glass printf("\n");
372f2105c61SSimon Glass break;
373f2105c61SSimon Glass }
374f2105c61SSimon Glass
375f2105c61SSimon Glass i++;
376f2105c61SSimon Glass if (i > (ATA_RESET_TIME * 100)) {
377f2105c61SSimon Glass printf("** TimeOUT **\n");
378f2105c61SSimon Glass
379f2105c61SSimon Glass dev_state = SATA_NODEVICE;
380f2105c61SSimon Glass rc = false;
381f2105c61SSimon Glass return rc;
382f2105c61SSimon Glass }
383f2105c61SSimon Glass if ((i >= 100) && ((i % 100) == 0))
384f2105c61SSimon Glass printf(".");
385f2105c61SSimon Glass }
386f2105c61SSimon Glass
387f2105c61SSimon Glass rc = sata_dwc_softreset(&ap);
388f2105c61SSimon Glass
389f2105c61SSimon Glass if (rc) {
390f2105c61SSimon Glass printf("sata_dwc : error. soft reset failed\n");
391f2105c61SSimon Glass return rc;
392f2105c61SSimon Glass }
393f2105c61SSimon Glass
394f2105c61SSimon Glass for (chan = 0; chan < DMA_NUM_CHANS; chan++) {
395f2105c61SSimon Glass out_le32(&(sata_dma_regs->interrupt_mask.error.low),
396f2105c61SSimon Glass DMA_DISABLE_CHAN(chan));
397f2105c61SSimon Glass
398f2105c61SSimon Glass out_le32(&(sata_dma_regs->interrupt_mask.tfr.low),
399f2105c61SSimon Glass DMA_DISABLE_CHAN(chan));
400f2105c61SSimon Glass }
401f2105c61SSimon Glass
402f2105c61SSimon Glass out_le32(&(sata_dma_regs->dma_cfg.low), DMA_DI);
403f2105c61SSimon Glass
404f2105c61SSimon Glass out_le32(&hsdev.sata_dwc_regs->intmr,
405f2105c61SSimon Glass SATA_DWC_INTMR_ERRM |
406f2105c61SSimon Glass SATA_DWC_INTMR_PMABRTM);
407f2105c61SSimon Glass
408f2105c61SSimon Glass /* Unmask the error bits that should trigger
409f2105c61SSimon Glass * an error interrupt by setting the error mask register.
410f2105c61SSimon Glass */
411f2105c61SSimon Glass out_le32(&hsdev.sata_dwc_regs->errmr, SATA_DWC_SERROR_ERR_BITS);
412f2105c61SSimon Glass
413f2105c61SSimon Glass hsdev.host = ap.host;
414f2105c61SSimon Glass memset(&hsdevp, 0, sizeof(hsdevp));
415f2105c61SSimon Glass hsdevp.hsdev = &hsdev;
416f2105c61SSimon Glass
417f2105c61SSimon Glass for (i = 0; i < SATA_DWC_QCMD_MAX; i++)
418f2105c61SSimon Glass hsdevp.cmd_issued[i] = SATA_DWC_CMD_ISSUED_NOT;
419f2105c61SSimon Glass
420f2105c61SSimon Glass out_le32((void __iomem *)scr_addr_sstatus + 4,
421f2105c61SSimon Glass in_le32((void __iomem *)scr_addr_sstatus + 4));
422f2105c61SSimon Glass
423f2105c61SSimon Glass rc = 0;
424f2105c61SSimon Glass return rc;
425f2105c61SSimon Glass }
426f2105c61SSimon Glass
reset_sata(int dev)427f2105c61SSimon Glass int reset_sata(int dev)
428f2105c61SSimon Glass {
429f2105c61SSimon Glass return 0;
430f2105c61SSimon Glass }
431f2105c61SSimon Glass
ata_check_altstatus(struct ata_port * ap)432f2105c61SSimon Glass static u8 ata_check_altstatus(struct ata_port *ap)
433f2105c61SSimon Glass {
434f2105c61SSimon Glass u8 val = 0;
435f2105c61SSimon Glass val = readb(ap->ioaddr.altstatus_addr);
436f2105c61SSimon Glass return val;
437f2105c61SSimon Glass }
438f2105c61SSimon Glass
sata_dwc_softreset(struct ata_port * ap)439f2105c61SSimon Glass static int sata_dwc_softreset(struct ata_port *ap)
440f2105c61SSimon Glass {
441f2105c61SSimon Glass u8 nsect,lbal = 0;
442f2105c61SSimon Glass u8 tmp = 0;
443f2105c61SSimon Glass struct ata_ioports *ioaddr = &ap->ioaddr;
444f2105c61SSimon Glass
445f2105c61SSimon Glass in_le32((void *)ap->ioaddr.scr_addr + (SCR_ERROR * 4));
446f2105c61SSimon Glass
447f2105c61SSimon Glass writeb(0x55, ioaddr->nsect_addr);
448f2105c61SSimon Glass writeb(0xaa, ioaddr->lbal_addr);
449f2105c61SSimon Glass writeb(0xaa, ioaddr->nsect_addr);
450f2105c61SSimon Glass writeb(0x55, ioaddr->lbal_addr);
451f2105c61SSimon Glass writeb(0x55, ioaddr->nsect_addr);
452f2105c61SSimon Glass writeb(0xaa, ioaddr->lbal_addr);
453f2105c61SSimon Glass
454f2105c61SSimon Glass nsect = readb(ioaddr->nsect_addr);
455f2105c61SSimon Glass lbal = readb(ioaddr->lbal_addr);
456f2105c61SSimon Glass
457f2105c61SSimon Glass if ((nsect == 0x55) && (lbal == 0xaa)) {
458f2105c61SSimon Glass printf("Device found\n");
459f2105c61SSimon Glass } else {
460f2105c61SSimon Glass printf("No device found\n");
461f2105c61SSimon Glass dev_state = SATA_NODEVICE;
462f2105c61SSimon Glass return false;
463f2105c61SSimon Glass }
464f2105c61SSimon Glass
465f2105c61SSimon Glass tmp = ATA_DEVICE_OBS;
466f2105c61SSimon Glass writeb(tmp, ioaddr->device_addr);
467f2105c61SSimon Glass writeb(ap->ctl, ioaddr->ctl_addr);
468f2105c61SSimon Glass
469f2105c61SSimon Glass udelay(200);
470f2105c61SSimon Glass
471f2105c61SSimon Glass writeb(ap->ctl | ATA_SRST, ioaddr->ctl_addr);
472f2105c61SSimon Glass
473f2105c61SSimon Glass udelay(200);
474f2105c61SSimon Glass writeb(ap->ctl, ioaddr->ctl_addr);
475f2105c61SSimon Glass
476f2105c61SSimon Glass msleep(150);
477f2105c61SSimon Glass ata_check_status(ap);
478f2105c61SSimon Glass
479f2105c61SSimon Glass msleep(50);
480f2105c61SSimon Glass ata_check_status(ap);
481f2105c61SSimon Glass
482f2105c61SSimon Glass while (1) {
483f2105c61SSimon Glass u8 status = ata_check_status(ap);
484f2105c61SSimon Glass
485f2105c61SSimon Glass if (!(status & ATA_BUSY))
486f2105c61SSimon Glass break;
487f2105c61SSimon Glass
488f2105c61SSimon Glass printf("Hard Disk status is BUSY.\n");
489f2105c61SSimon Glass msleep(50);
490f2105c61SSimon Glass }
491f2105c61SSimon Glass
492f2105c61SSimon Glass tmp = ATA_DEVICE_OBS;
493f2105c61SSimon Glass writeb(tmp, ioaddr->device_addr);
494f2105c61SSimon Glass
495f2105c61SSimon Glass nsect = readb(ioaddr->nsect_addr);
496f2105c61SSimon Glass lbal = readb(ioaddr->lbal_addr);
497f2105c61SSimon Glass
498f2105c61SSimon Glass return 0;
499f2105c61SSimon Glass }
500f2105c61SSimon Glass
ata_check_status(struct ata_port * ap)501f2105c61SSimon Glass static u8 ata_check_status(struct ata_port *ap)
502f2105c61SSimon Glass {
503f2105c61SSimon Glass u8 val = 0;
504f2105c61SSimon Glass val = readb(ap->ioaddr.status_addr);
505f2105c61SSimon Glass return val;
506f2105c61SSimon Glass }
507f2105c61SSimon Glass
ata_id_has_hipm(const u16 * id)508f2105c61SSimon Glass static int ata_id_has_hipm(const u16 *id)
509f2105c61SSimon Glass {
510f2105c61SSimon Glass u16 val = id[76];
511f2105c61SSimon Glass
512f2105c61SSimon Glass if (val == 0 || val == 0xffff)
513f2105c61SSimon Glass return -1;
514f2105c61SSimon Glass
515f2105c61SSimon Glass return val & (1 << 9);
516f2105c61SSimon Glass }
517f2105c61SSimon Glass
ata_id_has_dipm(const u16 * id)518f2105c61SSimon Glass static int ata_id_has_dipm(const u16 *id)
519f2105c61SSimon Glass {
520f2105c61SSimon Glass u16 val = id[78];
521f2105c61SSimon Glass
522f2105c61SSimon Glass if (val == 0 || val == 0xffff)
523f2105c61SSimon Glass return -1;
524f2105c61SSimon Glass
525f2105c61SSimon Glass return val & (1 << 3);
526f2105c61SSimon Glass }
527f2105c61SSimon Glass
scan_sata(int dev)528f2105c61SSimon Glass int scan_sata(int dev)
529f2105c61SSimon Glass {
530f2105c61SSimon Glass int i;
531f2105c61SSimon Glass int rc;
532f2105c61SSimon Glass u8 status;
533f2105c61SSimon Glass const u16 *id;
534f2105c61SSimon Glass struct ata_device *ata_dev = &ata_device;
535f2105c61SSimon Glass unsigned long pio_mask, mwdma_mask;
536f2105c61SSimon Glass char revbuf[7];
537f2105c61SSimon Glass u16 iobuf[ATA_SECTOR_WORDS];
538f2105c61SSimon Glass
539f2105c61SSimon Glass memset(iobuf, 0, sizeof(iobuf));
540f2105c61SSimon Glass
541f2105c61SSimon Glass if (dev_state == SATA_NODEVICE)
542f2105c61SSimon Glass return 1;
543f2105c61SSimon Glass
544f2105c61SSimon Glass printf("Waiting for device...");
545f2105c61SSimon Glass i = 0;
546f2105c61SSimon Glass while (1) {
547f2105c61SSimon Glass udelay(10000);
548f2105c61SSimon Glass
549f2105c61SSimon Glass status = ata_check_altstatus(&ap);
550f2105c61SSimon Glass
551f2105c61SSimon Glass if ((status & ATA_BUSY) == 0) {
552f2105c61SSimon Glass printf("\n");
553f2105c61SSimon Glass break;
554f2105c61SSimon Glass }
555f2105c61SSimon Glass
556f2105c61SSimon Glass i++;
557f2105c61SSimon Glass if (i > (ATA_RESET_TIME * 100)) {
558f2105c61SSimon Glass printf("** TimeOUT **\n");
559f2105c61SSimon Glass
560f2105c61SSimon Glass dev_state = SATA_NODEVICE;
561f2105c61SSimon Glass return 1;
562f2105c61SSimon Glass }
563f2105c61SSimon Glass if ((i >= 100) && ((i % 100) == 0))
564f2105c61SSimon Glass printf(".");
565f2105c61SSimon Glass }
566f2105c61SSimon Glass
567f2105c61SSimon Glass udelay(1000);
568f2105c61SSimon Glass
569f2105c61SSimon Glass rc = ata_dev_read_id(ata_dev, &ata_dev->class,
570f2105c61SSimon Glass ATA_READID_POSTRESET,ata_dev->id);
571f2105c61SSimon Glass if (rc) {
572f2105c61SSimon Glass printf("sata_dwc : error. failed sata scan\n");
573f2105c61SSimon Glass return 1;
574f2105c61SSimon Glass }
575f2105c61SSimon Glass
576f2105c61SSimon Glass /* SATA drives indicate we have a bridge. We don't know which
577f2105c61SSimon Glass * end of the link the bridge is which is a problem
578f2105c61SSimon Glass */
579f2105c61SSimon Glass if (ata_id_is_sata(ata_dev->id))
580f2105c61SSimon Glass ap.cbl = ATA_CBL_SATA;
581f2105c61SSimon Glass
582f2105c61SSimon Glass id = ata_dev->id;
583f2105c61SSimon Glass
584f2105c61SSimon Glass ata_dev->flags &= ~ATA_DFLAG_CFG_MASK;
585f2105c61SSimon Glass ata_dev->max_sectors = 0;
586f2105c61SSimon Glass ata_dev->cdb_len = 0;
587f2105c61SSimon Glass ata_dev->n_sectors = 0;
588f2105c61SSimon Glass ata_dev->cylinders = 0;
589f2105c61SSimon Glass ata_dev->heads = 0;
590f2105c61SSimon Glass ata_dev->sectors = 0;
591f2105c61SSimon Glass
592f2105c61SSimon Glass if (id[ATA_ID_FIELD_VALID] & (1 << 1)) {
593f2105c61SSimon Glass pio_mask = id[ATA_ID_PIO_MODES] & 0x03;
594f2105c61SSimon Glass pio_mask <<= 3;
595f2105c61SSimon Glass pio_mask |= 0x7;
596f2105c61SSimon Glass } else {
597f2105c61SSimon Glass /* If word 64 isn't valid then Word 51 high byte holds
598f2105c61SSimon Glass * the PIO timing number for the maximum. Turn it into
599f2105c61SSimon Glass * a mask.
600f2105c61SSimon Glass */
601f2105c61SSimon Glass u8 mode = (id[ATA_ID_OLD_PIO_MODES] >> 8) & 0xFF;
602f2105c61SSimon Glass if (mode < 5) {
603f2105c61SSimon Glass pio_mask = (2 << mode) - 1;
604f2105c61SSimon Glass } else {
605f2105c61SSimon Glass pio_mask = 1;
606f2105c61SSimon Glass }
607f2105c61SSimon Glass }
608f2105c61SSimon Glass
609f2105c61SSimon Glass mwdma_mask = id[ATA_ID_MWDMA_MODES] & 0x07;
610f2105c61SSimon Glass
611f2105c61SSimon Glass if (ata_id_is_cfa(id)) {
612f2105c61SSimon Glass int pio = id[163] & 0x7;
613f2105c61SSimon Glass int dma = (id[163] >> 3) & 7;
614f2105c61SSimon Glass
615f2105c61SSimon Glass if (pio)
616f2105c61SSimon Glass pio_mask |= (1 << 5);
617f2105c61SSimon Glass if (pio > 1)
618f2105c61SSimon Glass pio_mask |= (1 << 6);
619f2105c61SSimon Glass if (dma)
620f2105c61SSimon Glass mwdma_mask |= (1 << 3);
621f2105c61SSimon Glass if (dma > 1)
622f2105c61SSimon Glass mwdma_mask |= (1 << 4);
623f2105c61SSimon Glass }
624f2105c61SSimon Glass
625f2105c61SSimon Glass if (ata_dev->class == ATA_DEV_ATA) {
626f2105c61SSimon Glass if (ata_id_is_cfa(id)) {
627f2105c61SSimon Glass if (id[162] & 1)
628f2105c61SSimon Glass printf("supports DRM functions and may "
629f2105c61SSimon Glass "not be fully accessable.\n");
630f2105c61SSimon Glass strcpy(revbuf, "CFA");
631f2105c61SSimon Glass } else {
632f2105c61SSimon Glass if (ata_id_has_tpm(id))
633f2105c61SSimon Glass printf("supports DRM functions and may "
634f2105c61SSimon Glass "not be fully accessable.\n");
635f2105c61SSimon Glass }
636f2105c61SSimon Glass
637f2105c61SSimon Glass ata_dev->n_sectors = ata_id_n_sectors((u16*)id);
638f2105c61SSimon Glass
639f2105c61SSimon Glass if (ata_dev->id[59] & 0x100)
640f2105c61SSimon Glass ata_dev->multi_count = ata_dev->id[59] & 0xff;
641f2105c61SSimon Glass
642f2105c61SSimon Glass if (ata_id_has_lba(id)) {
643f2105c61SSimon Glass char ncq_desc[20];
644f2105c61SSimon Glass
645f2105c61SSimon Glass ata_dev->flags |= ATA_DFLAG_LBA;
646f2105c61SSimon Glass if (ata_id_has_lba48(id)) {
647f2105c61SSimon Glass ata_dev->flags |= ATA_DFLAG_LBA48;
648f2105c61SSimon Glass
649f2105c61SSimon Glass if (ata_dev->n_sectors >= (1UL << 28) &&
650f2105c61SSimon Glass ata_id_has_flush_ext(id))
651f2105c61SSimon Glass ata_dev->flags |= ATA_DFLAG_FLUSH_EXT;
652f2105c61SSimon Glass }
653f2105c61SSimon Glass if (!ata_id_has_ncq(ata_dev->id))
654f2105c61SSimon Glass ncq_desc[0] = '\0';
655f2105c61SSimon Glass
656f2105c61SSimon Glass if (ata_dev->horkage & ATA_HORKAGE_NONCQ)
657f2105c61SSimon Glass strcpy(ncq_desc, "NCQ (not used)");
658f2105c61SSimon Glass
659f2105c61SSimon Glass if (ap.flags & ATA_FLAG_NCQ)
660f2105c61SSimon Glass ata_dev->flags |= ATA_DFLAG_NCQ;
661f2105c61SSimon Glass }
662f2105c61SSimon Glass ata_dev->cdb_len = 16;
663f2105c61SSimon Glass }
664f2105c61SSimon Glass ata_dev->max_sectors = ATA_MAX_SECTORS;
665f2105c61SSimon Glass if (ata_dev->flags & ATA_DFLAG_LBA48)
666f2105c61SSimon Glass ata_dev->max_sectors = ATA_MAX_SECTORS_LBA48;
667f2105c61SSimon Glass
668f2105c61SSimon Glass if (!(ata_dev->horkage & ATA_HORKAGE_IPM)) {
669f2105c61SSimon Glass if (ata_id_has_hipm(ata_dev->id))
670f2105c61SSimon Glass ata_dev->flags |= ATA_DFLAG_HIPM;
671f2105c61SSimon Glass if (ata_id_has_dipm(ata_dev->id))
672f2105c61SSimon Glass ata_dev->flags |= ATA_DFLAG_DIPM;
673f2105c61SSimon Glass }
674f2105c61SSimon Glass
675f2105c61SSimon Glass if ((ap.cbl == ATA_CBL_SATA) && (!ata_id_is_sata(ata_dev->id))) {
676f2105c61SSimon Glass ata_dev->udma_mask &= ATA_UDMA5;
677f2105c61SSimon Glass ata_dev->max_sectors = ATA_MAX_SECTORS;
678f2105c61SSimon Glass }
679f2105c61SSimon Glass
680f2105c61SSimon Glass if (ata_dev->horkage & ATA_HORKAGE_DIAGNOSTIC) {
681f2105c61SSimon Glass printf("Drive reports diagnostics failure."
682f2105c61SSimon Glass "This may indicate a drive\n");
683f2105c61SSimon Glass printf("fault or invalid emulation."
684f2105c61SSimon Glass "Contact drive vendor for information.\n");
685f2105c61SSimon Glass }
686f2105c61SSimon Glass
687f2105c61SSimon Glass rc = check_sata_dev_state();
688f2105c61SSimon Glass
689f2105c61SSimon Glass ata_id_c_string(ata_dev->id,
690f2105c61SSimon Glass (unsigned char *)sata_dev_desc[dev].revision,
691f2105c61SSimon Glass ATA_ID_FW_REV, sizeof(sata_dev_desc[dev].revision));
692f2105c61SSimon Glass ata_id_c_string(ata_dev->id,
693f2105c61SSimon Glass (unsigned char *)sata_dev_desc[dev].vendor,
694f2105c61SSimon Glass ATA_ID_PROD, sizeof(sata_dev_desc[dev].vendor));
695f2105c61SSimon Glass ata_id_c_string(ata_dev->id,
696f2105c61SSimon Glass (unsigned char *)sata_dev_desc[dev].product,
697f2105c61SSimon Glass ATA_ID_SERNO, sizeof(sata_dev_desc[dev].product));
698f2105c61SSimon Glass
699f2105c61SSimon Glass sata_dev_desc[dev].lba = (u32) ata_dev->n_sectors;
700f2105c61SSimon Glass
701f2105c61SSimon Glass #ifdef CONFIG_LBA48
702f2105c61SSimon Glass if (ata_dev->id[83] & (1 << 10)) {
703f2105c61SSimon Glass sata_dev_desc[dev].lba48 = 1;
704f2105c61SSimon Glass } else {
705f2105c61SSimon Glass sata_dev_desc[dev].lba48 = 0;
706f2105c61SSimon Glass }
707f2105c61SSimon Glass #endif
708f2105c61SSimon Glass
709f2105c61SSimon Glass return 0;
710f2105c61SSimon Glass }
711f2105c61SSimon Glass
ata_busy_wait(struct ata_port * ap,unsigned int bits,unsigned int max)712f2105c61SSimon Glass static u8 ata_busy_wait(struct ata_port *ap,
713f2105c61SSimon Glass unsigned int bits,unsigned int max)
714f2105c61SSimon Glass {
715f2105c61SSimon Glass u8 status;
716f2105c61SSimon Glass
717f2105c61SSimon Glass do {
718f2105c61SSimon Glass udelay(10);
719f2105c61SSimon Glass status = ata_check_status(ap);
720f2105c61SSimon Glass max--;
721f2105c61SSimon Glass } while (status != 0xff && (status & bits) && (max > 0));
722f2105c61SSimon Glass
723f2105c61SSimon Glass return status;
724f2105c61SSimon Glass }
725f2105c61SSimon Glass
ata_dev_read_id(struct ata_device * dev,unsigned int * p_class,unsigned int flags,u16 * id)726f2105c61SSimon Glass static int ata_dev_read_id(struct ata_device *dev, unsigned int *p_class,
727f2105c61SSimon Glass unsigned int flags, u16 *id)
728f2105c61SSimon Glass {
729f2105c61SSimon Glass struct ata_port *ap = pap;
730f2105c61SSimon Glass unsigned int class = *p_class;
731f2105c61SSimon Glass struct ata_taskfile tf;
732f2105c61SSimon Glass unsigned int err_mask = 0;
733f2105c61SSimon Glass const char *reason;
734f2105c61SSimon Glass int may_fallback = 1, tried_spinup = 0;
735f2105c61SSimon Glass u8 status;
736f2105c61SSimon Glass int rc;
737f2105c61SSimon Glass
738f2105c61SSimon Glass status = ata_busy_wait(ap, ATA_BUSY, 30000);
739f2105c61SSimon Glass if (status & ATA_BUSY) {
740f2105c61SSimon Glass printf("BSY = 0 check. timeout.\n");
741f2105c61SSimon Glass rc = false;
742f2105c61SSimon Glass return rc;
743f2105c61SSimon Glass }
744f2105c61SSimon Glass
745f2105c61SSimon Glass ata_dev_select(ap, dev->devno, 1, 1);
746f2105c61SSimon Glass
747f2105c61SSimon Glass retry:
748f2105c61SSimon Glass memset(&tf, 0, sizeof(tf));
749f2105c61SSimon Glass ap->print_id = 1;
750f2105c61SSimon Glass ap->flags &= ~ATA_FLAG_DISABLED;
751f2105c61SSimon Glass tf.ctl = ap->ctl;
752f2105c61SSimon Glass tf.device = ATA_DEVICE_OBS;
753f2105c61SSimon Glass tf.command = ATA_CMD_ID_ATA;
754f2105c61SSimon Glass tf.protocol = ATA_PROT_PIO;
755f2105c61SSimon Glass
756f2105c61SSimon Glass /* Some devices choke if TF registers contain garbage. Make
757f2105c61SSimon Glass * sure those are properly initialized.
758f2105c61SSimon Glass */
759f2105c61SSimon Glass tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE;
760f2105c61SSimon Glass
761f2105c61SSimon Glass /* Device presence detection is unreliable on some
762f2105c61SSimon Glass * controllers. Always poll IDENTIFY if available.
763f2105c61SSimon Glass */
764f2105c61SSimon Glass tf.flags |= ATA_TFLAG_POLLING;
765f2105c61SSimon Glass
766f2105c61SSimon Glass temp_n_block = 1;
767f2105c61SSimon Glass
768f2105c61SSimon Glass err_mask = ata_exec_internal(dev, &tf, NULL, DMA_FROM_DEVICE,
769f2105c61SSimon Glass sizeof(id[0]) * ATA_ID_WORDS, 0);
770f2105c61SSimon Glass
771f2105c61SSimon Glass if (err_mask) {
772f2105c61SSimon Glass if (err_mask & AC_ERR_NODEV_HINT) {
773f2105c61SSimon Glass printf("NODEV after polling detection\n");
774f2105c61SSimon Glass return -ENOENT;
775f2105c61SSimon Glass }
776f2105c61SSimon Glass
777f2105c61SSimon Glass if ((err_mask == AC_ERR_DEV) && (tf.feature & ATA_ABORTED)) {
778f2105c61SSimon Glass /* Device or controller might have reported
779f2105c61SSimon Glass * the wrong device class. Give a shot at the
780f2105c61SSimon Glass * other IDENTIFY if the current one is
781f2105c61SSimon Glass * aborted by the device.
782f2105c61SSimon Glass */
783f2105c61SSimon Glass if (may_fallback) {
784f2105c61SSimon Glass may_fallback = 0;
785f2105c61SSimon Glass
786f2105c61SSimon Glass if (class == ATA_DEV_ATA) {
787f2105c61SSimon Glass class = ATA_DEV_ATAPI;
788f2105c61SSimon Glass } else {
789f2105c61SSimon Glass class = ATA_DEV_ATA;
790f2105c61SSimon Glass }
791f2105c61SSimon Glass goto retry;
792f2105c61SSimon Glass }
793f2105c61SSimon Glass /* Control reaches here iff the device aborted
794f2105c61SSimon Glass * both flavors of IDENTIFYs which happens
795f2105c61SSimon Glass * sometimes with phantom devices.
796f2105c61SSimon Glass */
797f2105c61SSimon Glass printf("both IDENTIFYs aborted, assuming NODEV\n");
798f2105c61SSimon Glass return -ENOENT;
799f2105c61SSimon Glass }
800f2105c61SSimon Glass rc = -EIO;
801f2105c61SSimon Glass reason = "I/O error";
802f2105c61SSimon Glass goto err_out;
803f2105c61SSimon Glass }
804f2105c61SSimon Glass
805f2105c61SSimon Glass /* Falling back doesn't make sense if ID data was read
806f2105c61SSimon Glass * successfully at least once.
807f2105c61SSimon Glass */
808f2105c61SSimon Glass may_fallback = 0;
809f2105c61SSimon Glass
810f2105c61SSimon Glass unsigned int id_cnt;
811f2105c61SSimon Glass
812f2105c61SSimon Glass for (id_cnt = 0; id_cnt < ATA_ID_WORDS; id_cnt++)
813f2105c61SSimon Glass id[id_cnt] = le16_to_cpu(id[id_cnt]);
814f2105c61SSimon Glass
815f2105c61SSimon Glass
816f2105c61SSimon Glass rc = -EINVAL;
817f2105c61SSimon Glass reason = "device reports invalid type";
818f2105c61SSimon Glass
819f2105c61SSimon Glass if (class == ATA_DEV_ATA) {
820f2105c61SSimon Glass if (!ata_id_is_ata(id) && !ata_id_is_cfa(id))
821f2105c61SSimon Glass goto err_out;
822f2105c61SSimon Glass } else {
823f2105c61SSimon Glass if (ata_id_is_ata(id))
824f2105c61SSimon Glass goto err_out;
825f2105c61SSimon Glass }
826f2105c61SSimon Glass if (!tried_spinup && (id[2] == 0x37c8 || id[2] == 0x738c)) {
827f2105c61SSimon Glass tried_spinup = 1;
828f2105c61SSimon Glass /*
829f2105c61SSimon Glass * Drive powered-up in standby mode, and requires a specific
830f2105c61SSimon Glass * SET_FEATURES spin-up subcommand before it will accept
831f2105c61SSimon Glass * anything other than the original IDENTIFY command.
832f2105c61SSimon Glass */
833f2105c61SSimon Glass err_mask = ata_dev_set_feature(dev, SETFEATURES_SPINUP, 0);
834f2105c61SSimon Glass if (err_mask && id[2] != 0x738c) {
835f2105c61SSimon Glass rc = -EIO;
836f2105c61SSimon Glass reason = "SPINUP failed";
837f2105c61SSimon Glass goto err_out;
838f2105c61SSimon Glass }
839f2105c61SSimon Glass /*
840f2105c61SSimon Glass * If the drive initially returned incomplete IDENTIFY info,
841f2105c61SSimon Glass * we now must reissue the IDENTIFY command.
842f2105c61SSimon Glass */
843f2105c61SSimon Glass if (id[2] == 0x37c8)
844f2105c61SSimon Glass goto retry;
845f2105c61SSimon Glass }
846f2105c61SSimon Glass
847f2105c61SSimon Glass if ((flags & ATA_READID_POSTRESET) && class == ATA_DEV_ATA) {
848f2105c61SSimon Glass /*
849f2105c61SSimon Glass * The exact sequence expected by certain pre-ATA4 drives is:
850f2105c61SSimon Glass * SRST RESET
851f2105c61SSimon Glass * IDENTIFY (optional in early ATA)
852f2105c61SSimon Glass * INITIALIZE DEVICE PARAMETERS (later IDE and ATA)
853f2105c61SSimon Glass * anything else..
854f2105c61SSimon Glass * Some drives were very specific about that exact sequence.
855f2105c61SSimon Glass *
856f2105c61SSimon Glass * Note that ATA4 says lba is mandatory so the second check
857f2105c61SSimon Glass * shoud never trigger.
858f2105c61SSimon Glass */
859f2105c61SSimon Glass if (ata_id_major_version(id) < 4 || !ata_id_has_lba(id)) {
860f2105c61SSimon Glass err_mask = ata_dev_init_params(dev, id[3], id[6]);
861f2105c61SSimon Glass if (err_mask) {
862f2105c61SSimon Glass rc = -EIO;
863f2105c61SSimon Glass reason = "INIT_DEV_PARAMS failed";
864f2105c61SSimon Glass goto err_out;
865f2105c61SSimon Glass }
866f2105c61SSimon Glass
867f2105c61SSimon Glass /* current CHS translation info (id[53-58]) might be
868f2105c61SSimon Glass * changed. reread the identify device info.
869f2105c61SSimon Glass */
870f2105c61SSimon Glass flags &= ~ATA_READID_POSTRESET;
871f2105c61SSimon Glass goto retry;
872f2105c61SSimon Glass }
873f2105c61SSimon Glass }
874f2105c61SSimon Glass
875f2105c61SSimon Glass *p_class = class;
876f2105c61SSimon Glass return 0;
877f2105c61SSimon Glass
878f2105c61SSimon Glass err_out:
879f2105c61SSimon Glass printf("failed to READ ID (%s, err_mask=0x%x)\n", reason, err_mask);
880f2105c61SSimon Glass return rc;
881f2105c61SSimon Glass }
882f2105c61SSimon Glass
ata_wait_idle(struct ata_port * ap)883f2105c61SSimon Glass static u8 ata_wait_idle(struct ata_port *ap)
884f2105c61SSimon Glass {
885f2105c61SSimon Glass u8 status = ata_busy_wait(ap, ATA_BUSY | ATA_DRQ, 1000);
886f2105c61SSimon Glass return status;
887f2105c61SSimon Glass }
888f2105c61SSimon Glass
ata_dev_select(struct ata_port * ap,unsigned int device,unsigned int wait,unsigned int can_sleep)889f2105c61SSimon Glass static void ata_dev_select(struct ata_port *ap, unsigned int device,
890f2105c61SSimon Glass unsigned int wait, unsigned int can_sleep)
891f2105c61SSimon Glass {
892f2105c61SSimon Glass if (wait)
893f2105c61SSimon Glass ata_wait_idle(ap);
894f2105c61SSimon Glass
895f2105c61SSimon Glass ata_std_dev_select(ap, device);
896f2105c61SSimon Glass
897f2105c61SSimon Glass if (wait)
898f2105c61SSimon Glass ata_wait_idle(ap);
899f2105c61SSimon Glass }
900f2105c61SSimon Glass
ata_std_dev_select(struct ata_port * ap,unsigned int device)901f2105c61SSimon Glass static void ata_std_dev_select(struct ata_port *ap, unsigned int device)
902f2105c61SSimon Glass {
903f2105c61SSimon Glass u8 tmp;
904f2105c61SSimon Glass
905f2105c61SSimon Glass if (device == 0) {
906f2105c61SSimon Glass tmp = ATA_DEVICE_OBS;
907f2105c61SSimon Glass } else {
908f2105c61SSimon Glass tmp = ATA_DEVICE_OBS | ATA_DEV1;
909f2105c61SSimon Glass }
910f2105c61SSimon Glass
911f2105c61SSimon Glass writeb(tmp, ap->ioaddr.device_addr);
912f2105c61SSimon Glass
913f2105c61SSimon Glass readb(ap->ioaddr.altstatus_addr);
914f2105c61SSimon Glass
915f2105c61SSimon Glass udelay(1);
916f2105c61SSimon Glass }
917f2105c61SSimon Glass
waiting_for_reg_state(volatile u8 * offset,int timeout_msec,u32 sign)918f2105c61SSimon Glass static int waiting_for_reg_state(volatile u8 *offset,
919f2105c61SSimon Glass int timeout_msec,
920f2105c61SSimon Glass u32 sign)
921f2105c61SSimon Glass {
922f2105c61SSimon Glass int i;
923f2105c61SSimon Glass u32 status;
924f2105c61SSimon Glass
925f2105c61SSimon Glass for (i = 0; i < timeout_msec; i++) {
926f2105c61SSimon Glass status = readl(offset);
927f2105c61SSimon Glass if ((status & sign) != 0)
928f2105c61SSimon Glass break;
929f2105c61SSimon Glass msleep(1);
930f2105c61SSimon Glass }
931f2105c61SSimon Glass
932f2105c61SSimon Glass return (i < timeout_msec) ? 0 : -1;
933f2105c61SSimon Glass }
934f2105c61SSimon Glass
ata_qc_reinit(struct ata_queued_cmd * qc)935f2105c61SSimon Glass static void ata_qc_reinit(struct ata_queued_cmd *qc)
936f2105c61SSimon Glass {
937f2105c61SSimon Glass qc->dma_dir = DMA_NONE;
938f2105c61SSimon Glass qc->flags = 0;
939f2105c61SSimon Glass qc->nbytes = qc->extrabytes = qc->curbytes = 0;
940f2105c61SSimon Glass qc->n_elem = 0;
941f2105c61SSimon Glass qc->err_mask = 0;
942f2105c61SSimon Glass qc->sect_size = ATA_SECT_SIZE;
943f2105c61SSimon Glass qc->nbytes = ATA_SECT_SIZE * temp_n_block;
944f2105c61SSimon Glass
945f2105c61SSimon Glass memset(&qc->tf, 0, sizeof(qc->tf));
946f2105c61SSimon Glass qc->tf.ctl = 0;
947f2105c61SSimon Glass qc->tf.device = ATA_DEVICE_OBS;
948f2105c61SSimon Glass
949f2105c61SSimon Glass qc->result_tf.command = ATA_DRDY;
950f2105c61SSimon Glass qc->result_tf.feature = 0;
951f2105c61SSimon Glass }
952f2105c61SSimon Glass
__ata_qc_from_tag(struct ata_port * ap,unsigned int tag)953f2105c61SSimon Glass struct ata_queued_cmd *__ata_qc_from_tag(struct ata_port *ap,
954f2105c61SSimon Glass unsigned int tag)
955f2105c61SSimon Glass {
956f2105c61SSimon Glass if (tag < ATA_MAX_QUEUE)
957f2105c61SSimon Glass return &ap->qcmd[tag];
958f2105c61SSimon Glass return NULL;
959f2105c61SSimon Glass }
960f2105c61SSimon Glass
__ata_port_freeze(struct ata_port * ap)961f2105c61SSimon Glass static void __ata_port_freeze(struct ata_port *ap)
962f2105c61SSimon Glass {
963f2105c61SSimon Glass printf("set port freeze.\n");
964f2105c61SSimon Glass ap->pflags |= ATA_PFLAG_FROZEN;
965f2105c61SSimon Glass }
966f2105c61SSimon Glass
ata_port_freeze(struct ata_port * ap)967f2105c61SSimon Glass static int ata_port_freeze(struct ata_port *ap)
968f2105c61SSimon Glass {
969f2105c61SSimon Glass __ata_port_freeze(ap);
970f2105c61SSimon Glass return 0;
971f2105c61SSimon Glass }
972f2105c61SSimon Glass
ata_exec_internal(struct ata_device * dev,struct ata_taskfile * tf,const u8 * cdb,int dma_dir,unsigned int buflen,unsigned long timeout)973f2105c61SSimon Glass unsigned ata_exec_internal(struct ata_device *dev,
974f2105c61SSimon Glass struct ata_taskfile *tf, const u8 *cdb,
975f2105c61SSimon Glass int dma_dir, unsigned int buflen,
976f2105c61SSimon Glass unsigned long timeout)
977f2105c61SSimon Glass {
978f2105c61SSimon Glass struct ata_link *link = dev->link;
979f2105c61SSimon Glass struct ata_port *ap = pap;
980f2105c61SSimon Glass struct ata_queued_cmd *qc;
981f2105c61SSimon Glass unsigned int tag, preempted_tag;
982f2105c61SSimon Glass u32 preempted_sactive, preempted_qc_active;
983f2105c61SSimon Glass int preempted_nr_active_links;
984f2105c61SSimon Glass unsigned int err_mask;
985f2105c61SSimon Glass int rc = 0;
986f2105c61SSimon Glass u8 status;
987f2105c61SSimon Glass
988f2105c61SSimon Glass status = ata_busy_wait(ap, ATA_BUSY, 300000);
989f2105c61SSimon Glass if (status & ATA_BUSY) {
990f2105c61SSimon Glass printf("BSY = 0 check. timeout.\n");
991f2105c61SSimon Glass rc = false;
992f2105c61SSimon Glass return rc;
993f2105c61SSimon Glass }
994f2105c61SSimon Glass
995f2105c61SSimon Glass if (ap->pflags & ATA_PFLAG_FROZEN)
996f2105c61SSimon Glass return AC_ERR_SYSTEM;
997f2105c61SSimon Glass
998f2105c61SSimon Glass tag = ATA_TAG_INTERNAL;
999f2105c61SSimon Glass
1000f2105c61SSimon Glass if (test_and_set_bit(tag, &ap->qc_allocated)) {
1001f2105c61SSimon Glass rc = false;
1002f2105c61SSimon Glass return rc;
1003f2105c61SSimon Glass }
1004f2105c61SSimon Glass
1005f2105c61SSimon Glass qc = __ata_qc_from_tag(ap, tag);
1006f2105c61SSimon Glass qc->tag = tag;
1007f2105c61SSimon Glass qc->ap = ap;
1008f2105c61SSimon Glass qc->dev = dev;
1009f2105c61SSimon Glass
1010f2105c61SSimon Glass ata_qc_reinit(qc);
1011f2105c61SSimon Glass
1012f2105c61SSimon Glass preempted_tag = link->active_tag;
1013f2105c61SSimon Glass preempted_sactive = link->sactive;
1014f2105c61SSimon Glass preempted_qc_active = ap->qc_active;
1015f2105c61SSimon Glass preempted_nr_active_links = ap->nr_active_links;
1016f2105c61SSimon Glass link->active_tag = ATA_TAG_POISON;
1017f2105c61SSimon Glass link->sactive = 0;
1018f2105c61SSimon Glass ap->qc_active = 0;
1019f2105c61SSimon Glass ap->nr_active_links = 0;
1020f2105c61SSimon Glass
1021f2105c61SSimon Glass qc->tf = *tf;
1022f2105c61SSimon Glass if (cdb)
1023f2105c61SSimon Glass memcpy(qc->cdb, cdb, ATAPI_CDB_LEN);
1024f2105c61SSimon Glass qc->flags |= ATA_QCFLAG_RESULT_TF;
1025f2105c61SSimon Glass qc->dma_dir = dma_dir;
1026f2105c61SSimon Glass qc->private_data = 0;
1027f2105c61SSimon Glass
1028f2105c61SSimon Glass ata_qc_issue(qc);
1029f2105c61SSimon Glass
1030f2105c61SSimon Glass if (!timeout)
1031f2105c61SSimon Glass timeout = ata_probe_timeout * 1000 / HZ;
1032f2105c61SSimon Glass
1033f2105c61SSimon Glass status = ata_busy_wait(ap, ATA_BUSY, 30000);
1034f2105c61SSimon Glass if (status & ATA_BUSY) {
1035f2105c61SSimon Glass printf("BSY = 0 check. timeout.\n");
1036f2105c61SSimon Glass printf("altstatus = 0x%x.\n", status);
1037f2105c61SSimon Glass qc->err_mask |= AC_ERR_OTHER;
1038f2105c61SSimon Glass return qc->err_mask;
1039f2105c61SSimon Glass }
1040f2105c61SSimon Glass
1041f2105c61SSimon Glass if (waiting_for_reg_state(ap->ioaddr.altstatus_addr, 1000, 0x8)) {
1042f2105c61SSimon Glass u8 status = 0;
1043f2105c61SSimon Glass u8 errorStatus = 0;
1044f2105c61SSimon Glass
1045f2105c61SSimon Glass status = readb(ap->ioaddr.altstatus_addr);
1046f2105c61SSimon Glass if ((status & 0x01) != 0) {
1047f2105c61SSimon Glass errorStatus = readb(ap->ioaddr.feature_addr);
1048f2105c61SSimon Glass if (errorStatus == 0x04 &&
1049f2105c61SSimon Glass qc->tf.command == ATA_CMD_PIO_READ_EXT){
1050f2105c61SSimon Glass printf("Hard Disk doesn't support LBA48\n");
1051f2105c61SSimon Glass dev_state = SATA_ERROR;
1052f2105c61SSimon Glass qc->err_mask |= AC_ERR_OTHER;
1053f2105c61SSimon Glass return qc->err_mask;
1054f2105c61SSimon Glass }
1055f2105c61SSimon Glass }
1056f2105c61SSimon Glass qc->err_mask |= AC_ERR_OTHER;
1057f2105c61SSimon Glass return qc->err_mask;
1058f2105c61SSimon Glass }
1059f2105c61SSimon Glass
1060f2105c61SSimon Glass status = ata_busy_wait(ap, ATA_BUSY, 10);
1061f2105c61SSimon Glass if (status & ATA_BUSY) {
1062f2105c61SSimon Glass printf("BSY = 0 check. timeout.\n");
1063f2105c61SSimon Glass qc->err_mask |= AC_ERR_OTHER;
1064f2105c61SSimon Glass return qc->err_mask;
1065f2105c61SSimon Glass }
1066f2105c61SSimon Glass
1067f2105c61SSimon Glass ata_pio_task(ap);
1068f2105c61SSimon Glass
1069f2105c61SSimon Glass if (!rc) {
1070f2105c61SSimon Glass if (qc->flags & ATA_QCFLAG_ACTIVE) {
1071f2105c61SSimon Glass qc->err_mask |= AC_ERR_TIMEOUT;
1072f2105c61SSimon Glass ata_port_freeze(ap);
1073f2105c61SSimon Glass }
1074f2105c61SSimon Glass }
1075f2105c61SSimon Glass
1076f2105c61SSimon Glass if (qc->flags & ATA_QCFLAG_FAILED) {
1077f2105c61SSimon Glass if (qc->result_tf.command & (ATA_ERR | ATA_DF))
1078f2105c61SSimon Glass qc->err_mask |= AC_ERR_DEV;
1079f2105c61SSimon Glass
1080f2105c61SSimon Glass if (!qc->err_mask)
1081f2105c61SSimon Glass qc->err_mask |= AC_ERR_OTHER;
1082f2105c61SSimon Glass
1083f2105c61SSimon Glass if (qc->err_mask & ~AC_ERR_OTHER)
1084f2105c61SSimon Glass qc->err_mask &= ~AC_ERR_OTHER;
1085f2105c61SSimon Glass }
1086f2105c61SSimon Glass
1087f2105c61SSimon Glass *tf = qc->result_tf;
1088f2105c61SSimon Glass err_mask = qc->err_mask;
1089f2105c61SSimon Glass ata_qc_free(qc);
1090f2105c61SSimon Glass link->active_tag = preempted_tag;
1091f2105c61SSimon Glass link->sactive = preempted_sactive;
1092f2105c61SSimon Glass ap->qc_active = preempted_qc_active;
1093f2105c61SSimon Glass ap->nr_active_links = preempted_nr_active_links;
1094f2105c61SSimon Glass
1095f2105c61SSimon Glass if (ap->flags & ATA_FLAG_DISABLED) {
1096f2105c61SSimon Glass err_mask |= AC_ERR_SYSTEM;
1097f2105c61SSimon Glass ap->flags &= ~ATA_FLAG_DISABLED;
1098f2105c61SSimon Glass }
1099f2105c61SSimon Glass
1100f2105c61SSimon Glass return err_mask;
1101f2105c61SSimon Glass }
1102f2105c61SSimon Glass
ata_qc_issue(struct ata_queued_cmd * qc)1103f2105c61SSimon Glass static void ata_qc_issue(struct ata_queued_cmd *qc)
1104f2105c61SSimon Glass {
1105f2105c61SSimon Glass struct ata_port *ap = qc->ap;
1106f2105c61SSimon Glass struct ata_link *link = qc->dev->link;
1107f2105c61SSimon Glass u8 prot = qc->tf.protocol;
1108f2105c61SSimon Glass
1109f2105c61SSimon Glass if (ata_is_ncq(prot)) {
1110f2105c61SSimon Glass if (!link->sactive)
1111f2105c61SSimon Glass ap->nr_active_links++;
1112f2105c61SSimon Glass link->sactive |= 1 << qc->tag;
1113f2105c61SSimon Glass } else {
1114f2105c61SSimon Glass ap->nr_active_links++;
1115f2105c61SSimon Glass link->active_tag = qc->tag;
1116f2105c61SSimon Glass }
1117f2105c61SSimon Glass
1118f2105c61SSimon Glass qc->flags |= ATA_QCFLAG_ACTIVE;
1119f2105c61SSimon Glass ap->qc_active |= 1 << qc->tag;
1120f2105c61SSimon Glass
1121f2105c61SSimon Glass if (qc->dev->flags & ATA_DFLAG_SLEEPING) {
1122f2105c61SSimon Glass msleep(1);
1123f2105c61SSimon Glass return;
1124f2105c61SSimon Glass }
1125f2105c61SSimon Glass
1126f2105c61SSimon Glass qc->err_mask |= ata_qc_issue_prot(qc);
1127f2105c61SSimon Glass if (qc->err_mask)
1128f2105c61SSimon Glass goto err;
1129f2105c61SSimon Glass
1130f2105c61SSimon Glass return;
1131f2105c61SSimon Glass err:
1132f2105c61SSimon Glass ata_qc_complete(qc);
1133f2105c61SSimon Glass }
1134f2105c61SSimon Glass
ata_qc_issue_prot(struct ata_queued_cmd * qc)1135f2105c61SSimon Glass static unsigned int ata_qc_issue_prot(struct ata_queued_cmd *qc)
1136f2105c61SSimon Glass {
1137f2105c61SSimon Glass struct ata_port *ap = qc->ap;
1138f2105c61SSimon Glass
1139f2105c61SSimon Glass if (ap->flags & ATA_FLAG_PIO_POLLING) {
1140f2105c61SSimon Glass switch (qc->tf.protocol) {
1141f2105c61SSimon Glass case ATA_PROT_PIO:
1142f2105c61SSimon Glass case ATA_PROT_NODATA:
1143f2105c61SSimon Glass case ATAPI_PROT_PIO:
1144f2105c61SSimon Glass case ATAPI_PROT_NODATA:
1145f2105c61SSimon Glass qc->tf.flags |= ATA_TFLAG_POLLING;
1146f2105c61SSimon Glass break;
1147f2105c61SSimon Glass default:
1148f2105c61SSimon Glass break;
1149f2105c61SSimon Glass }
1150f2105c61SSimon Glass }
1151f2105c61SSimon Glass
1152f2105c61SSimon Glass ata_dev_select(ap, qc->dev->devno, 1, 0);
1153f2105c61SSimon Glass
1154f2105c61SSimon Glass switch (qc->tf.protocol) {
1155f2105c61SSimon Glass case ATA_PROT_PIO:
1156f2105c61SSimon Glass if (qc->tf.flags & ATA_TFLAG_POLLING)
1157f2105c61SSimon Glass qc->tf.ctl |= ATA_NIEN;
1158f2105c61SSimon Glass
1159f2105c61SSimon Glass ata_tf_to_host(ap, &qc->tf);
1160f2105c61SSimon Glass
1161f2105c61SSimon Glass ap->hsm_task_state = HSM_ST;
1162f2105c61SSimon Glass
1163f2105c61SSimon Glass if (qc->tf.flags & ATA_TFLAG_POLLING)
1164f2105c61SSimon Glass ata_pio_queue_task(ap, qc, 0);
1165f2105c61SSimon Glass
1166f2105c61SSimon Glass break;
1167f2105c61SSimon Glass
1168f2105c61SSimon Glass default:
1169f2105c61SSimon Glass return AC_ERR_SYSTEM;
1170f2105c61SSimon Glass }
1171f2105c61SSimon Glass
1172f2105c61SSimon Glass return 0;
1173f2105c61SSimon Glass }
1174f2105c61SSimon Glass
ata_tf_to_host(struct ata_port * ap,const struct ata_taskfile * tf)1175f2105c61SSimon Glass static void ata_tf_to_host(struct ata_port *ap,
1176f2105c61SSimon Glass const struct ata_taskfile *tf)
1177f2105c61SSimon Glass {
1178f2105c61SSimon Glass ata_tf_load(ap, tf);
1179f2105c61SSimon Glass ata_exec_command(ap, tf);
1180f2105c61SSimon Glass }
1181f2105c61SSimon Glass
ata_tf_load(struct ata_port * ap,const struct ata_taskfile * tf)1182f2105c61SSimon Glass static void ata_tf_load(struct ata_port *ap,
1183f2105c61SSimon Glass const struct ata_taskfile *tf)
1184f2105c61SSimon Glass {
1185f2105c61SSimon Glass struct ata_ioports *ioaddr = &ap->ioaddr;
1186f2105c61SSimon Glass unsigned int is_addr = tf->flags & ATA_TFLAG_ISADDR;
1187f2105c61SSimon Glass
1188f2105c61SSimon Glass if (tf->ctl != ap->last_ctl) {
1189f2105c61SSimon Glass if (ioaddr->ctl_addr)
1190f2105c61SSimon Glass writeb(tf->ctl, ioaddr->ctl_addr);
1191f2105c61SSimon Glass ap->last_ctl = tf->ctl;
1192f2105c61SSimon Glass ata_wait_idle(ap);
1193f2105c61SSimon Glass }
1194f2105c61SSimon Glass
1195f2105c61SSimon Glass if (is_addr && (tf->flags & ATA_TFLAG_LBA48)) {
1196f2105c61SSimon Glass writeb(tf->hob_feature, ioaddr->feature_addr);
1197f2105c61SSimon Glass writeb(tf->hob_nsect, ioaddr->nsect_addr);
1198f2105c61SSimon Glass writeb(tf->hob_lbal, ioaddr->lbal_addr);
1199f2105c61SSimon Glass writeb(tf->hob_lbam, ioaddr->lbam_addr);
1200f2105c61SSimon Glass writeb(tf->hob_lbah, ioaddr->lbah_addr);
1201f2105c61SSimon Glass }
1202f2105c61SSimon Glass
1203f2105c61SSimon Glass if (is_addr) {
1204f2105c61SSimon Glass writeb(tf->feature, ioaddr->feature_addr);
1205f2105c61SSimon Glass writeb(tf->nsect, ioaddr->nsect_addr);
1206f2105c61SSimon Glass writeb(tf->lbal, ioaddr->lbal_addr);
1207f2105c61SSimon Glass writeb(tf->lbam, ioaddr->lbam_addr);
1208f2105c61SSimon Glass writeb(tf->lbah, ioaddr->lbah_addr);
1209f2105c61SSimon Glass }
1210f2105c61SSimon Glass
1211f2105c61SSimon Glass if (tf->flags & ATA_TFLAG_DEVICE)
1212f2105c61SSimon Glass writeb(tf->device, ioaddr->device_addr);
1213f2105c61SSimon Glass
1214f2105c61SSimon Glass ata_wait_idle(ap);
1215f2105c61SSimon Glass }
1216f2105c61SSimon Glass
ata_exec_command(struct ata_port * ap,const struct ata_taskfile * tf)1217f2105c61SSimon Glass static void ata_exec_command(struct ata_port *ap,
1218f2105c61SSimon Glass const struct ata_taskfile *tf)
1219f2105c61SSimon Glass {
1220f2105c61SSimon Glass writeb(tf->command, ap->ioaddr.command_addr);
1221f2105c61SSimon Glass
1222f2105c61SSimon Glass readb(ap->ioaddr.altstatus_addr);
1223f2105c61SSimon Glass
1224f2105c61SSimon Glass udelay(1);
1225f2105c61SSimon Glass }
1226f2105c61SSimon Glass
ata_pio_queue_task(struct ata_port * ap,void * data,unsigned long delay)1227f2105c61SSimon Glass static void ata_pio_queue_task(struct ata_port *ap,
1228f2105c61SSimon Glass void *data,unsigned long delay)
1229f2105c61SSimon Glass {
1230f2105c61SSimon Glass ap->port_task_data = data;
1231f2105c61SSimon Glass }
1232f2105c61SSimon Glass
ac_err_mask(u8 status)1233f2105c61SSimon Glass static unsigned int ac_err_mask(u8 status)
1234f2105c61SSimon Glass {
1235f2105c61SSimon Glass if (status & (ATA_BUSY | ATA_DRQ))
1236f2105c61SSimon Glass return AC_ERR_HSM;
1237f2105c61SSimon Glass if (status & (ATA_ERR | ATA_DF))
1238f2105c61SSimon Glass return AC_ERR_DEV;
1239f2105c61SSimon Glass return 0;
1240f2105c61SSimon Glass }
1241f2105c61SSimon Glass
__ac_err_mask(u8 status)1242f2105c61SSimon Glass static unsigned int __ac_err_mask(u8 status)
1243f2105c61SSimon Glass {
1244f2105c61SSimon Glass unsigned int mask = ac_err_mask(status);
1245f2105c61SSimon Glass if (mask == 0)
1246f2105c61SSimon Glass return AC_ERR_OTHER;
1247f2105c61SSimon Glass return mask;
1248f2105c61SSimon Glass }
1249f2105c61SSimon Glass
ata_pio_task(struct ata_port * arg_ap)1250f2105c61SSimon Glass static void ata_pio_task(struct ata_port *arg_ap)
1251f2105c61SSimon Glass {
1252f2105c61SSimon Glass struct ata_port *ap = arg_ap;
1253f2105c61SSimon Glass struct ata_queued_cmd *qc = ap->port_task_data;
1254f2105c61SSimon Glass u8 status;
1255f2105c61SSimon Glass int poll_next;
1256f2105c61SSimon Glass
1257f2105c61SSimon Glass fsm_start:
1258f2105c61SSimon Glass /*
1259f2105c61SSimon Glass * This is purely heuristic. This is a fast path.
1260f2105c61SSimon Glass * Sometimes when we enter, BSY will be cleared in
1261f2105c61SSimon Glass * a chk-status or two. If not, the drive is probably seeking
1262f2105c61SSimon Glass * or something. Snooze for a couple msecs, then
1263f2105c61SSimon Glass * chk-status again. If still busy, queue delayed work.
1264f2105c61SSimon Glass */
1265f2105c61SSimon Glass status = ata_busy_wait(ap, ATA_BUSY, 5);
1266f2105c61SSimon Glass if (status & ATA_BUSY) {
1267f2105c61SSimon Glass msleep(2);
1268f2105c61SSimon Glass status = ata_busy_wait(ap, ATA_BUSY, 10);
1269f2105c61SSimon Glass if (status & ATA_BUSY) {
1270f2105c61SSimon Glass ata_pio_queue_task(ap, qc, ATA_SHORT_PAUSE);
1271f2105c61SSimon Glass return;
1272f2105c61SSimon Glass }
1273f2105c61SSimon Glass }
1274f2105c61SSimon Glass
1275f2105c61SSimon Glass poll_next = ata_hsm_move(ap, qc, status, 1);
1276f2105c61SSimon Glass
1277f2105c61SSimon Glass /* another command or interrupt handler
1278f2105c61SSimon Glass * may be running at this point.
1279f2105c61SSimon Glass */
1280f2105c61SSimon Glass if (poll_next)
1281f2105c61SSimon Glass goto fsm_start;
1282f2105c61SSimon Glass }
1283f2105c61SSimon Glass
ata_hsm_move(struct ata_port * ap,struct ata_queued_cmd * qc,u8 status,int in_wq)1284f2105c61SSimon Glass static int ata_hsm_move(struct ata_port *ap, struct ata_queued_cmd *qc,
1285f2105c61SSimon Glass u8 status, int in_wq)
1286f2105c61SSimon Glass {
1287f2105c61SSimon Glass int poll_next;
1288f2105c61SSimon Glass
1289f2105c61SSimon Glass fsm_start:
1290f2105c61SSimon Glass switch (ap->hsm_task_state) {
1291f2105c61SSimon Glass case HSM_ST_FIRST:
1292f2105c61SSimon Glass poll_next = (qc->tf.flags & ATA_TFLAG_POLLING);
1293f2105c61SSimon Glass
1294f2105c61SSimon Glass if ((status & ATA_DRQ) == 0) {
1295f2105c61SSimon Glass if (status & (ATA_ERR | ATA_DF)) {
1296f2105c61SSimon Glass qc->err_mask |= AC_ERR_DEV;
1297f2105c61SSimon Glass } else {
1298f2105c61SSimon Glass qc->err_mask |= AC_ERR_HSM;
1299f2105c61SSimon Glass }
1300f2105c61SSimon Glass ap->hsm_task_state = HSM_ST_ERR;
1301f2105c61SSimon Glass goto fsm_start;
1302f2105c61SSimon Glass }
1303f2105c61SSimon Glass
1304f2105c61SSimon Glass /* Device should not ask for data transfer (DRQ=1)
1305f2105c61SSimon Glass * when it finds something wrong.
1306f2105c61SSimon Glass * We ignore DRQ here and stop the HSM by
1307f2105c61SSimon Glass * changing hsm_task_state to HSM_ST_ERR and
1308f2105c61SSimon Glass * let the EH abort the command or reset the device.
1309f2105c61SSimon Glass */
1310f2105c61SSimon Glass if (status & (ATA_ERR | ATA_DF)) {
1311f2105c61SSimon Glass if (!(qc->dev->horkage & ATA_HORKAGE_STUCK_ERR)) {
1312f2105c61SSimon Glass printf("DRQ=1 with device error, "
1313f2105c61SSimon Glass "dev_stat 0x%X\n", status);
1314f2105c61SSimon Glass qc->err_mask |= AC_ERR_HSM;
1315f2105c61SSimon Glass ap->hsm_task_state = HSM_ST_ERR;
1316f2105c61SSimon Glass goto fsm_start;
1317f2105c61SSimon Glass }
1318f2105c61SSimon Glass }
1319f2105c61SSimon Glass
1320f2105c61SSimon Glass if (qc->tf.protocol == ATA_PROT_PIO) {
1321f2105c61SSimon Glass /* PIO data out protocol.
1322f2105c61SSimon Glass * send first data block.
1323f2105c61SSimon Glass */
1324f2105c61SSimon Glass /* ata_pio_sectors() might change the state
1325f2105c61SSimon Glass * to HSM_ST_LAST. so, the state is changed here
1326f2105c61SSimon Glass * before ata_pio_sectors().
1327f2105c61SSimon Glass */
1328f2105c61SSimon Glass ap->hsm_task_state = HSM_ST;
1329f2105c61SSimon Glass ata_pio_sectors(qc);
1330f2105c61SSimon Glass } else {
1331f2105c61SSimon Glass printf("protocol is not ATA_PROT_PIO \n");
1332f2105c61SSimon Glass }
1333f2105c61SSimon Glass break;
1334f2105c61SSimon Glass
1335f2105c61SSimon Glass case HSM_ST:
1336f2105c61SSimon Glass if ((status & ATA_DRQ) == 0) {
1337f2105c61SSimon Glass if (status & (ATA_ERR | ATA_DF)) {
1338f2105c61SSimon Glass qc->err_mask |= AC_ERR_DEV;
1339f2105c61SSimon Glass } else {
1340f2105c61SSimon Glass /* HSM violation. Let EH handle this.
1341f2105c61SSimon Glass * Phantom devices also trigger this
1342f2105c61SSimon Glass * condition. Mark hint.
1343f2105c61SSimon Glass */
1344f2105c61SSimon Glass qc->err_mask |= AC_ERR_HSM | AC_ERR_NODEV_HINT;
1345f2105c61SSimon Glass }
1346f2105c61SSimon Glass
1347f2105c61SSimon Glass ap->hsm_task_state = HSM_ST_ERR;
1348f2105c61SSimon Glass goto fsm_start;
1349f2105c61SSimon Glass }
1350f2105c61SSimon Glass /* For PIO reads, some devices may ask for
1351f2105c61SSimon Glass * data transfer (DRQ=1) alone with ERR=1.
1352f2105c61SSimon Glass * We respect DRQ here and transfer one
1353f2105c61SSimon Glass * block of junk data before changing the
1354f2105c61SSimon Glass * hsm_task_state to HSM_ST_ERR.
1355f2105c61SSimon Glass *
1356f2105c61SSimon Glass * For PIO writes, ERR=1 DRQ=1 doesn't make
1357f2105c61SSimon Glass * sense since the data block has been
1358f2105c61SSimon Glass * transferred to the device.
1359f2105c61SSimon Glass */
1360f2105c61SSimon Glass if (status & (ATA_ERR | ATA_DF)) {
1361f2105c61SSimon Glass qc->err_mask |= AC_ERR_DEV;
1362f2105c61SSimon Glass
1363f2105c61SSimon Glass if (!(qc->tf.flags & ATA_TFLAG_WRITE)) {
1364f2105c61SSimon Glass ata_pio_sectors(qc);
1365f2105c61SSimon Glass status = ata_wait_idle(ap);
1366f2105c61SSimon Glass }
1367f2105c61SSimon Glass
1368f2105c61SSimon Glass if (status & (ATA_BUSY | ATA_DRQ))
1369f2105c61SSimon Glass qc->err_mask |= AC_ERR_HSM;
1370f2105c61SSimon Glass
1371f2105c61SSimon Glass /* ata_pio_sectors() might change the
1372f2105c61SSimon Glass * state to HSM_ST_LAST. so, the state
1373f2105c61SSimon Glass * is changed after ata_pio_sectors().
1374f2105c61SSimon Glass */
1375f2105c61SSimon Glass ap->hsm_task_state = HSM_ST_ERR;
1376f2105c61SSimon Glass goto fsm_start;
1377f2105c61SSimon Glass }
1378f2105c61SSimon Glass
1379f2105c61SSimon Glass ata_pio_sectors(qc);
1380f2105c61SSimon Glass if (ap->hsm_task_state == HSM_ST_LAST &&
1381f2105c61SSimon Glass (!(qc->tf.flags & ATA_TFLAG_WRITE))) {
1382f2105c61SSimon Glass status = ata_wait_idle(ap);
1383f2105c61SSimon Glass goto fsm_start;
1384f2105c61SSimon Glass }
1385f2105c61SSimon Glass
1386f2105c61SSimon Glass poll_next = 1;
1387f2105c61SSimon Glass break;
1388f2105c61SSimon Glass
1389f2105c61SSimon Glass case HSM_ST_LAST:
1390f2105c61SSimon Glass if (!ata_ok(status)) {
1391f2105c61SSimon Glass qc->err_mask |= __ac_err_mask(status);
1392f2105c61SSimon Glass ap->hsm_task_state = HSM_ST_ERR;
1393f2105c61SSimon Glass goto fsm_start;
1394f2105c61SSimon Glass }
1395f2105c61SSimon Glass
1396f2105c61SSimon Glass ap->hsm_task_state = HSM_ST_IDLE;
1397f2105c61SSimon Glass
1398f2105c61SSimon Glass ata_hsm_qc_complete(qc, in_wq);
1399f2105c61SSimon Glass
1400f2105c61SSimon Glass poll_next = 0;
1401f2105c61SSimon Glass break;
1402f2105c61SSimon Glass
1403f2105c61SSimon Glass case HSM_ST_ERR:
1404f2105c61SSimon Glass /* make sure qc->err_mask is available to
1405f2105c61SSimon Glass * know what's wrong and recover
1406f2105c61SSimon Glass */
1407f2105c61SSimon Glass ap->hsm_task_state = HSM_ST_IDLE;
1408f2105c61SSimon Glass
1409f2105c61SSimon Glass ata_hsm_qc_complete(qc, in_wq);
1410f2105c61SSimon Glass
1411f2105c61SSimon Glass poll_next = 0;
1412f2105c61SSimon Glass break;
1413f2105c61SSimon Glass default:
1414f2105c61SSimon Glass poll_next = 0;
1415f2105c61SSimon Glass }
1416f2105c61SSimon Glass
1417f2105c61SSimon Glass return poll_next;
1418f2105c61SSimon Glass }
1419f2105c61SSimon Glass
ata_pio_sectors(struct ata_queued_cmd * qc)1420f2105c61SSimon Glass static void ata_pio_sectors(struct ata_queued_cmd *qc)
1421f2105c61SSimon Glass {
1422f2105c61SSimon Glass struct ata_port *ap;
1423f2105c61SSimon Glass ap = pap;
1424f2105c61SSimon Glass qc->pdata = ap->pdata;
1425f2105c61SSimon Glass
1426f2105c61SSimon Glass ata_pio_sector(qc);
1427f2105c61SSimon Glass
1428f2105c61SSimon Glass readb(qc->ap->ioaddr.altstatus_addr);
1429f2105c61SSimon Glass udelay(1);
1430f2105c61SSimon Glass }
1431f2105c61SSimon Glass
ata_pio_sector(struct ata_queued_cmd * qc)1432f2105c61SSimon Glass static void ata_pio_sector(struct ata_queued_cmd *qc)
1433f2105c61SSimon Glass {
1434f2105c61SSimon Glass int do_write = (qc->tf.flags & ATA_TFLAG_WRITE);
1435f2105c61SSimon Glass struct ata_port *ap = qc->ap;
1436f2105c61SSimon Glass unsigned int offset;
1437f2105c61SSimon Glass unsigned char *buf;
1438f2105c61SSimon Glass char temp_data_buf[512];
1439f2105c61SSimon Glass
1440f2105c61SSimon Glass if (qc->curbytes == qc->nbytes - qc->sect_size)
1441f2105c61SSimon Glass ap->hsm_task_state = HSM_ST_LAST;
1442f2105c61SSimon Glass
1443f2105c61SSimon Glass offset = qc->curbytes;
1444f2105c61SSimon Glass
1445f2105c61SSimon Glass switch (qc->tf.command) {
1446f2105c61SSimon Glass case ATA_CMD_ID_ATA:
1447f2105c61SSimon Glass buf = (unsigned char *)&ata_device.id[0];
1448f2105c61SSimon Glass break;
1449f2105c61SSimon Glass case ATA_CMD_PIO_READ_EXT:
1450f2105c61SSimon Glass case ATA_CMD_PIO_READ:
1451f2105c61SSimon Glass case ATA_CMD_PIO_WRITE_EXT:
1452f2105c61SSimon Glass case ATA_CMD_PIO_WRITE:
1453f2105c61SSimon Glass buf = qc->pdata + offset;
1454f2105c61SSimon Glass break;
1455f2105c61SSimon Glass default:
1456f2105c61SSimon Glass buf = (unsigned char *)&temp_data_buf[0];
1457f2105c61SSimon Glass }
1458f2105c61SSimon Glass
1459f2105c61SSimon Glass ata_mmio_data_xfer(qc->dev, buf, qc->sect_size, do_write);
1460f2105c61SSimon Glass
1461f2105c61SSimon Glass qc->curbytes += qc->sect_size;
1462f2105c61SSimon Glass
1463f2105c61SSimon Glass }
1464f2105c61SSimon Glass
ata_mmio_data_xfer(struct ata_device * dev,unsigned char * buf,unsigned int buflen,int do_write)1465f2105c61SSimon Glass static void ata_mmio_data_xfer(struct ata_device *dev, unsigned char *buf,
1466f2105c61SSimon Glass unsigned int buflen, int do_write)
1467f2105c61SSimon Glass {
1468f2105c61SSimon Glass struct ata_port *ap = pap;
1469f2105c61SSimon Glass void __iomem *data_addr = ap->ioaddr.data_addr;
1470f2105c61SSimon Glass unsigned int words = buflen >> 1;
1471f2105c61SSimon Glass u16 *buf16 = (u16 *)buf;
1472f2105c61SSimon Glass unsigned int i = 0;
1473f2105c61SSimon Glass
1474f2105c61SSimon Glass udelay(100);
1475f2105c61SSimon Glass if (do_write) {
1476f2105c61SSimon Glass for (i = 0; i < words; i++)
1477f2105c61SSimon Glass writew(le16_to_cpu(buf16[i]), data_addr);
1478f2105c61SSimon Glass } else {
1479f2105c61SSimon Glass for (i = 0; i < words; i++)
1480f2105c61SSimon Glass buf16[i] = cpu_to_le16(readw(data_addr));
1481f2105c61SSimon Glass }
1482f2105c61SSimon Glass
1483f2105c61SSimon Glass if (buflen & 0x01) {
1484f2105c61SSimon Glass __le16 align_buf[1] = { 0 };
1485f2105c61SSimon Glass unsigned char *trailing_buf = buf + buflen - 1;
1486f2105c61SSimon Glass
1487f2105c61SSimon Glass if (do_write) {
1488f2105c61SSimon Glass memcpy(align_buf, trailing_buf, 1);
1489f2105c61SSimon Glass writew(le16_to_cpu(align_buf[0]), data_addr);
1490f2105c61SSimon Glass } else {
1491f2105c61SSimon Glass align_buf[0] = cpu_to_le16(readw(data_addr));
1492f2105c61SSimon Glass memcpy(trailing_buf, align_buf, 1);
1493f2105c61SSimon Glass }
1494f2105c61SSimon Glass }
1495f2105c61SSimon Glass }
1496f2105c61SSimon Glass
ata_hsm_qc_complete(struct ata_queued_cmd * qc,int in_wq)1497f2105c61SSimon Glass static void ata_hsm_qc_complete(struct ata_queued_cmd *qc, int in_wq)
1498f2105c61SSimon Glass {
1499f2105c61SSimon Glass struct ata_port *ap = qc->ap;
1500f2105c61SSimon Glass
1501f2105c61SSimon Glass if (in_wq) {
1502f2105c61SSimon Glass /* EH might have kicked in while host lock is
1503f2105c61SSimon Glass * released.
1504f2105c61SSimon Glass */
1505f2105c61SSimon Glass qc = &ap->qcmd[qc->tag];
1506f2105c61SSimon Glass if (qc) {
1507f2105c61SSimon Glass if (!(qc->err_mask & AC_ERR_HSM)) {
1508f2105c61SSimon Glass ata_irq_on(ap);
1509f2105c61SSimon Glass ata_qc_complete(qc);
1510f2105c61SSimon Glass } else {
1511f2105c61SSimon Glass ata_port_freeze(ap);
1512f2105c61SSimon Glass }
1513f2105c61SSimon Glass }
1514f2105c61SSimon Glass } else {
1515f2105c61SSimon Glass if (!(qc->err_mask & AC_ERR_HSM)) {
1516f2105c61SSimon Glass ata_qc_complete(qc);
1517f2105c61SSimon Glass } else {
1518f2105c61SSimon Glass ata_port_freeze(ap);
1519f2105c61SSimon Glass }
1520f2105c61SSimon Glass }
1521f2105c61SSimon Glass }
1522f2105c61SSimon Glass
ata_irq_on(struct ata_port * ap)1523f2105c61SSimon Glass static u8 ata_irq_on(struct ata_port *ap)
1524f2105c61SSimon Glass {
1525f2105c61SSimon Glass struct ata_ioports *ioaddr = &ap->ioaddr;
1526f2105c61SSimon Glass u8 tmp;
1527f2105c61SSimon Glass
1528f2105c61SSimon Glass ap->ctl &= ~ATA_NIEN;
1529f2105c61SSimon Glass ap->last_ctl = ap->ctl;
1530f2105c61SSimon Glass
1531f2105c61SSimon Glass if (ioaddr->ctl_addr)
1532f2105c61SSimon Glass writeb(ap->ctl, ioaddr->ctl_addr);
1533f2105c61SSimon Glass
1534f2105c61SSimon Glass tmp = ata_wait_idle(ap);
1535f2105c61SSimon Glass
1536f2105c61SSimon Glass return tmp;
1537f2105c61SSimon Glass }
1538f2105c61SSimon Glass
ata_tag_internal(unsigned int tag)1539f2105c61SSimon Glass static unsigned int ata_tag_internal(unsigned int tag)
1540f2105c61SSimon Glass {
1541f2105c61SSimon Glass return tag == ATA_MAX_QUEUE - 1;
1542f2105c61SSimon Glass }
1543f2105c61SSimon Glass
ata_qc_complete(struct ata_queued_cmd * qc)1544f2105c61SSimon Glass static void ata_qc_complete(struct ata_queued_cmd *qc)
1545f2105c61SSimon Glass {
1546f2105c61SSimon Glass struct ata_device *dev = qc->dev;
1547f2105c61SSimon Glass if (qc->err_mask)
1548f2105c61SSimon Glass qc->flags |= ATA_QCFLAG_FAILED;
1549f2105c61SSimon Glass
1550f2105c61SSimon Glass if (qc->flags & ATA_QCFLAG_FAILED) {
1551f2105c61SSimon Glass if (!ata_tag_internal(qc->tag)) {
1552f2105c61SSimon Glass fill_result_tf(qc);
1553f2105c61SSimon Glass return;
1554f2105c61SSimon Glass }
1555f2105c61SSimon Glass }
1556f2105c61SSimon Glass if (qc->flags & ATA_QCFLAG_RESULT_TF)
1557f2105c61SSimon Glass fill_result_tf(qc);
1558f2105c61SSimon Glass
1559f2105c61SSimon Glass /* Some commands need post-processing after successful
1560f2105c61SSimon Glass * completion.
1561f2105c61SSimon Glass */
1562f2105c61SSimon Glass switch (qc->tf.command) {
1563f2105c61SSimon Glass case ATA_CMD_SET_FEATURES:
1564f2105c61SSimon Glass if (qc->tf.feature != SETFEATURES_WC_ON &&
1565f2105c61SSimon Glass qc->tf.feature != SETFEATURES_WC_OFF)
1566f2105c61SSimon Glass break;
1567f2105c61SSimon Glass case ATA_CMD_INIT_DEV_PARAMS:
1568f2105c61SSimon Glass case ATA_CMD_SET_MULTI:
1569f2105c61SSimon Glass break;
1570f2105c61SSimon Glass
1571f2105c61SSimon Glass case ATA_CMD_SLEEP:
1572f2105c61SSimon Glass dev->flags |= ATA_DFLAG_SLEEPING;
1573f2105c61SSimon Glass break;
1574f2105c61SSimon Glass }
1575f2105c61SSimon Glass
1576f2105c61SSimon Glass __ata_qc_complete(qc);
1577f2105c61SSimon Glass }
1578f2105c61SSimon Glass
fill_result_tf(struct ata_queued_cmd * qc)1579f2105c61SSimon Glass static void fill_result_tf(struct ata_queued_cmd *qc)
1580f2105c61SSimon Glass {
1581f2105c61SSimon Glass struct ata_port *ap = qc->ap;
1582f2105c61SSimon Glass
1583f2105c61SSimon Glass qc->result_tf.flags = qc->tf.flags;
1584f2105c61SSimon Glass ata_tf_read(ap, &qc->result_tf);
1585f2105c61SSimon Glass }
1586f2105c61SSimon Glass
ata_tf_read(struct ata_port * ap,struct ata_taskfile * tf)1587f2105c61SSimon Glass static void ata_tf_read(struct ata_port *ap, struct ata_taskfile *tf)
1588f2105c61SSimon Glass {
1589f2105c61SSimon Glass struct ata_ioports *ioaddr = &ap->ioaddr;
1590f2105c61SSimon Glass
1591f2105c61SSimon Glass tf->command = ata_check_status(ap);
1592f2105c61SSimon Glass tf->feature = readb(ioaddr->error_addr);
1593f2105c61SSimon Glass tf->nsect = readb(ioaddr->nsect_addr);
1594f2105c61SSimon Glass tf->lbal = readb(ioaddr->lbal_addr);
1595f2105c61SSimon Glass tf->lbam = readb(ioaddr->lbam_addr);
1596f2105c61SSimon Glass tf->lbah = readb(ioaddr->lbah_addr);
1597f2105c61SSimon Glass tf->device = readb(ioaddr->device_addr);
1598f2105c61SSimon Glass
1599f2105c61SSimon Glass if (tf->flags & ATA_TFLAG_LBA48) {
1600f2105c61SSimon Glass if (ioaddr->ctl_addr) {
1601f2105c61SSimon Glass writeb(tf->ctl | ATA_HOB, ioaddr->ctl_addr);
1602f2105c61SSimon Glass
1603f2105c61SSimon Glass tf->hob_feature = readb(ioaddr->error_addr);
1604f2105c61SSimon Glass tf->hob_nsect = readb(ioaddr->nsect_addr);
1605f2105c61SSimon Glass tf->hob_lbal = readb(ioaddr->lbal_addr);
1606f2105c61SSimon Glass tf->hob_lbam = readb(ioaddr->lbam_addr);
1607f2105c61SSimon Glass tf->hob_lbah = readb(ioaddr->lbah_addr);
1608f2105c61SSimon Glass
1609f2105c61SSimon Glass writeb(tf->ctl, ioaddr->ctl_addr);
1610f2105c61SSimon Glass ap->last_ctl = tf->ctl;
1611f2105c61SSimon Glass } else {
1612f2105c61SSimon Glass printf("sata_dwc warnning register read.\n");
1613f2105c61SSimon Glass }
1614f2105c61SSimon Glass }
1615f2105c61SSimon Glass }
1616f2105c61SSimon Glass
__ata_qc_complete(struct ata_queued_cmd * qc)1617f2105c61SSimon Glass static void __ata_qc_complete(struct ata_queued_cmd *qc)
1618f2105c61SSimon Glass {
1619f2105c61SSimon Glass struct ata_port *ap = qc->ap;
1620f2105c61SSimon Glass struct ata_link *link = qc->dev->link;
1621f2105c61SSimon Glass
1622f2105c61SSimon Glass link->active_tag = ATA_TAG_POISON;
1623f2105c61SSimon Glass ap->nr_active_links--;
1624f2105c61SSimon Glass
1625f2105c61SSimon Glass if (qc->flags & ATA_QCFLAG_CLEAR_EXCL && ap->excl_link == link)
1626f2105c61SSimon Glass ap->excl_link = NULL;
1627f2105c61SSimon Glass
1628f2105c61SSimon Glass qc->flags &= ~ATA_QCFLAG_ACTIVE;
1629f2105c61SSimon Glass ap->qc_active &= ~(1 << qc->tag);
1630f2105c61SSimon Glass }
1631f2105c61SSimon Glass
ata_qc_free(struct ata_queued_cmd * qc)1632f2105c61SSimon Glass static void ata_qc_free(struct ata_queued_cmd *qc)
1633f2105c61SSimon Glass {
1634f2105c61SSimon Glass struct ata_port *ap = qc->ap;
1635f2105c61SSimon Glass unsigned int tag;
1636f2105c61SSimon Glass qc->flags = 0;
1637f2105c61SSimon Glass tag = qc->tag;
1638f2105c61SSimon Glass if (tag < ATA_MAX_QUEUE) {
1639f2105c61SSimon Glass qc->tag = ATA_TAG_POISON;
1640f2105c61SSimon Glass clear_bit(tag, &ap->qc_allocated);
1641f2105c61SSimon Glass }
1642f2105c61SSimon Glass }
1643f2105c61SSimon Glass
check_sata_dev_state(void)1644f2105c61SSimon Glass static int check_sata_dev_state(void)
1645f2105c61SSimon Glass {
1646f2105c61SSimon Glass unsigned long datalen;
1647f2105c61SSimon Glass unsigned char *pdata;
1648f2105c61SSimon Glass int ret = 0;
1649f2105c61SSimon Glass int i = 0;
1650f2105c61SSimon Glass char temp_data_buf[512];
1651f2105c61SSimon Glass
1652f2105c61SSimon Glass while (1) {
1653f2105c61SSimon Glass udelay(10000);
1654f2105c61SSimon Glass
1655f2105c61SSimon Glass pdata = (unsigned char*)&temp_data_buf[0];
1656f2105c61SSimon Glass datalen = 512;
1657f2105c61SSimon Glass
1658f2105c61SSimon Glass ret = ata_dev_read_sectors(pdata, datalen, 0, 1);
1659f2105c61SSimon Glass
1660f2105c61SSimon Glass if (ret == true)
1661f2105c61SSimon Glass break;
1662f2105c61SSimon Glass
1663f2105c61SSimon Glass i++;
1664f2105c61SSimon Glass if (i > (ATA_RESET_TIME * 100)) {
1665f2105c61SSimon Glass printf("** TimeOUT **\n");
1666f2105c61SSimon Glass dev_state = SATA_NODEVICE;
1667f2105c61SSimon Glass return false;
1668f2105c61SSimon Glass }
1669f2105c61SSimon Glass
1670f2105c61SSimon Glass if ((i >= 100) && ((i % 100) == 0))
1671f2105c61SSimon Glass printf(".");
1672f2105c61SSimon Glass }
1673f2105c61SSimon Glass
1674f2105c61SSimon Glass dev_state = SATA_READY;
1675f2105c61SSimon Glass
1676f2105c61SSimon Glass return true;
1677f2105c61SSimon Glass }
1678f2105c61SSimon Glass
ata_dev_set_feature(struct ata_device * dev,u8 enable,u8 feature)1679f2105c61SSimon Glass static unsigned int ata_dev_set_feature(struct ata_device *dev,
1680f2105c61SSimon Glass u8 enable, u8 feature)
1681f2105c61SSimon Glass {
1682f2105c61SSimon Glass struct ata_taskfile tf;
1683f2105c61SSimon Glass struct ata_port *ap;
1684f2105c61SSimon Glass ap = pap;
1685f2105c61SSimon Glass unsigned int err_mask;
1686f2105c61SSimon Glass
1687f2105c61SSimon Glass memset(&tf, 0, sizeof(tf));
1688f2105c61SSimon Glass tf.ctl = ap->ctl;
1689f2105c61SSimon Glass
1690f2105c61SSimon Glass tf.device = ATA_DEVICE_OBS;
1691f2105c61SSimon Glass tf.command = ATA_CMD_SET_FEATURES;
1692f2105c61SSimon Glass tf.feature = enable;
1693f2105c61SSimon Glass tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE;
1694f2105c61SSimon Glass tf.protocol = ATA_PROT_NODATA;
1695f2105c61SSimon Glass tf.nsect = feature;
1696f2105c61SSimon Glass
1697f2105c61SSimon Glass err_mask = ata_exec_internal(dev, &tf, NULL, DMA_NONE, 0, 0);
1698f2105c61SSimon Glass
1699f2105c61SSimon Glass return err_mask;
1700f2105c61SSimon Glass }
1701f2105c61SSimon Glass
ata_dev_init_params(struct ata_device * dev,u16 heads,u16 sectors)1702f2105c61SSimon Glass static unsigned int ata_dev_init_params(struct ata_device *dev,
1703f2105c61SSimon Glass u16 heads, u16 sectors)
1704f2105c61SSimon Glass {
1705f2105c61SSimon Glass struct ata_taskfile tf;
1706f2105c61SSimon Glass struct ata_port *ap;
1707f2105c61SSimon Glass ap = pap;
1708f2105c61SSimon Glass unsigned int err_mask;
1709f2105c61SSimon Glass
1710f2105c61SSimon Glass if (sectors < 1 || sectors > 255 || heads < 1 || heads > 16)
1711f2105c61SSimon Glass return AC_ERR_INVALID;
1712f2105c61SSimon Glass
1713f2105c61SSimon Glass memset(&tf, 0, sizeof(tf));
1714f2105c61SSimon Glass tf.ctl = ap->ctl;
1715f2105c61SSimon Glass tf.device = ATA_DEVICE_OBS;
1716f2105c61SSimon Glass tf.command = ATA_CMD_INIT_DEV_PARAMS;
1717f2105c61SSimon Glass tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE;
1718f2105c61SSimon Glass tf.protocol = ATA_PROT_NODATA;
1719f2105c61SSimon Glass tf.nsect = sectors;
1720f2105c61SSimon Glass tf.device |= (heads - 1) & 0x0f;
1721f2105c61SSimon Glass
1722f2105c61SSimon Glass err_mask = ata_exec_internal(dev, &tf, NULL, DMA_NONE, 0, 0);
1723f2105c61SSimon Glass
1724f2105c61SSimon Glass if (err_mask == AC_ERR_DEV && (tf.feature & ATA_ABORTED))
1725f2105c61SSimon Glass err_mask = 0;
1726f2105c61SSimon Glass
1727f2105c61SSimon Glass return err_mask;
1728f2105c61SSimon Glass }
1729f2105c61SSimon Glass
1730f2105c61SSimon Glass #if defined(CONFIG_SATA_DWC) && !defined(CONFIG_LBA48)
1731f2105c61SSimon Glass #define SATA_MAX_READ_BLK 0xFF
1732f2105c61SSimon Glass #else
1733f2105c61SSimon Glass #define SATA_MAX_READ_BLK 0xFFFF
1734f2105c61SSimon Glass #endif
1735f2105c61SSimon Glass
sata_read(int device,ulong blknr,lbaint_t blkcnt,void * buffer)1736f2105c61SSimon Glass ulong sata_read(int device, ulong blknr, lbaint_t blkcnt, void *buffer)
1737f2105c61SSimon Glass {
1738f2105c61SSimon Glass ulong start,blks, buf_addr;
1739f2105c61SSimon Glass unsigned short smallblks;
1740f2105c61SSimon Glass unsigned long datalen;
1741f2105c61SSimon Glass unsigned char *pdata;
1742f2105c61SSimon Glass device &= 0xff;
1743f2105c61SSimon Glass
1744f2105c61SSimon Glass u32 block = 0;
1745f2105c61SSimon Glass u32 n_block = 0;
1746f2105c61SSimon Glass
1747f2105c61SSimon Glass if (dev_state != SATA_READY)
1748f2105c61SSimon Glass return 0;
1749f2105c61SSimon Glass
1750f2105c61SSimon Glass buf_addr = (unsigned long)buffer;
1751f2105c61SSimon Glass start = blknr;
1752f2105c61SSimon Glass blks = blkcnt;
1753f2105c61SSimon Glass do {
1754f2105c61SSimon Glass pdata = (unsigned char *)buf_addr;
1755f2105c61SSimon Glass if (blks > SATA_MAX_READ_BLK) {
1756f2105c61SSimon Glass datalen = sata_dev_desc[device].blksz * SATA_MAX_READ_BLK;
1757f2105c61SSimon Glass smallblks = SATA_MAX_READ_BLK;
1758f2105c61SSimon Glass
1759f2105c61SSimon Glass block = (u32)start;
1760f2105c61SSimon Glass n_block = (u32)smallblks;
1761f2105c61SSimon Glass
1762f2105c61SSimon Glass start += SATA_MAX_READ_BLK;
1763f2105c61SSimon Glass blks -= SATA_MAX_READ_BLK;
1764f2105c61SSimon Glass } else {
1765f2105c61SSimon Glass datalen = sata_dev_desc[device].blksz * SATA_MAX_READ_BLK;
1766f2105c61SSimon Glass datalen = sata_dev_desc[device].blksz * blks;
1767f2105c61SSimon Glass smallblks = (unsigned short)blks;
1768f2105c61SSimon Glass
1769f2105c61SSimon Glass block = (u32)start;
1770f2105c61SSimon Glass n_block = (u32)smallblks;
1771f2105c61SSimon Glass
1772f2105c61SSimon Glass start += blks;
1773f2105c61SSimon Glass blks = 0;
1774f2105c61SSimon Glass }
1775f2105c61SSimon Glass
1776f2105c61SSimon Glass if (ata_dev_read_sectors(pdata, datalen, block, n_block) != true) {
1777f2105c61SSimon Glass printf("sata_dwc : Hard disk read error.\n");
1778f2105c61SSimon Glass blkcnt -= blks;
1779f2105c61SSimon Glass break;
1780f2105c61SSimon Glass }
1781f2105c61SSimon Glass buf_addr += datalen;
1782f2105c61SSimon Glass } while (blks != 0);
1783f2105c61SSimon Glass
1784f2105c61SSimon Glass return (blkcnt);
1785f2105c61SSimon Glass }
1786f2105c61SSimon Glass
ata_dev_read_sectors(unsigned char * pdata,unsigned long datalen,u32 block,u32 n_block)1787f2105c61SSimon Glass static int ata_dev_read_sectors(unsigned char *pdata, unsigned long datalen,
1788f2105c61SSimon Glass u32 block, u32 n_block)
1789f2105c61SSimon Glass {
1790f2105c61SSimon Glass struct ata_port *ap = pap;
1791f2105c61SSimon Glass struct ata_device *dev = &ata_device;
1792f2105c61SSimon Glass struct ata_taskfile tf;
1793f2105c61SSimon Glass unsigned int class = ATA_DEV_ATA;
1794f2105c61SSimon Glass unsigned int err_mask = 0;
1795f2105c61SSimon Glass const char *reason;
1796f2105c61SSimon Glass int may_fallback = 1;
1797f2105c61SSimon Glass
1798f2105c61SSimon Glass if (dev_state == SATA_ERROR)
1799f2105c61SSimon Glass return false;
1800f2105c61SSimon Glass
1801f2105c61SSimon Glass ata_dev_select(ap, dev->devno, 1, 1);
1802f2105c61SSimon Glass
1803f2105c61SSimon Glass retry:
1804f2105c61SSimon Glass memset(&tf, 0, sizeof(tf));
1805f2105c61SSimon Glass tf.ctl = ap->ctl;
1806f2105c61SSimon Glass ap->print_id = 1;
1807f2105c61SSimon Glass ap->flags &= ~ATA_FLAG_DISABLED;
1808f2105c61SSimon Glass
1809f2105c61SSimon Glass ap->pdata = pdata;
1810f2105c61SSimon Glass
1811f2105c61SSimon Glass tf.device = ATA_DEVICE_OBS;
1812f2105c61SSimon Glass
1813f2105c61SSimon Glass temp_n_block = n_block;
1814f2105c61SSimon Glass
1815f2105c61SSimon Glass #ifdef CONFIG_LBA48
1816f2105c61SSimon Glass tf.command = ATA_CMD_PIO_READ_EXT;
1817f2105c61SSimon Glass tf.flags |= ATA_TFLAG_LBA | ATA_TFLAG_LBA48;
1818f2105c61SSimon Glass
1819f2105c61SSimon Glass tf.hob_feature = 31;
1820f2105c61SSimon Glass tf.feature = 31;
1821f2105c61SSimon Glass tf.hob_nsect = (n_block >> 8) & 0xff;
1822f2105c61SSimon Glass tf.nsect = n_block & 0xff;
1823f2105c61SSimon Glass
1824f2105c61SSimon Glass tf.hob_lbah = 0x0;
1825f2105c61SSimon Glass tf.hob_lbam = 0x0;
1826f2105c61SSimon Glass tf.hob_lbal = (block >> 24) & 0xff;
1827f2105c61SSimon Glass tf.lbah = (block >> 16) & 0xff;
1828f2105c61SSimon Glass tf.lbam = (block >> 8) & 0xff;
1829f2105c61SSimon Glass tf.lbal = block & 0xff;
1830f2105c61SSimon Glass
1831f2105c61SSimon Glass tf.device = 1 << 6;
1832f2105c61SSimon Glass if (tf.flags & ATA_TFLAG_FUA)
1833f2105c61SSimon Glass tf.device |= 1 << 7;
1834f2105c61SSimon Glass #else
1835f2105c61SSimon Glass tf.command = ATA_CMD_PIO_READ;
1836f2105c61SSimon Glass tf.flags |= ATA_TFLAG_LBA ;
1837f2105c61SSimon Glass
1838f2105c61SSimon Glass tf.feature = 31;
1839f2105c61SSimon Glass tf.nsect = n_block & 0xff;
1840f2105c61SSimon Glass
1841f2105c61SSimon Glass tf.lbah = (block >> 16) & 0xff;
1842f2105c61SSimon Glass tf.lbam = (block >> 8) & 0xff;
1843f2105c61SSimon Glass tf.lbal = block & 0xff;
1844f2105c61SSimon Glass
1845f2105c61SSimon Glass tf.device = (block >> 24) & 0xf;
1846f2105c61SSimon Glass
1847f2105c61SSimon Glass tf.device |= 1 << 6;
1848f2105c61SSimon Glass if (tf.flags & ATA_TFLAG_FUA)
1849f2105c61SSimon Glass tf.device |= 1 << 7;
1850f2105c61SSimon Glass
1851f2105c61SSimon Glass #endif
1852f2105c61SSimon Glass
1853f2105c61SSimon Glass tf.protocol = ATA_PROT_PIO;
1854f2105c61SSimon Glass
1855f2105c61SSimon Glass /* Some devices choke if TF registers contain garbage. Make
1856f2105c61SSimon Glass * sure those are properly initialized.
1857f2105c61SSimon Glass */
1858f2105c61SSimon Glass tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE;
1859f2105c61SSimon Glass tf.flags |= ATA_TFLAG_POLLING;
1860f2105c61SSimon Glass
1861f2105c61SSimon Glass err_mask = ata_exec_internal(dev, &tf, NULL, DMA_FROM_DEVICE, 0, 0);
1862f2105c61SSimon Glass
1863f2105c61SSimon Glass if (err_mask) {
1864f2105c61SSimon Glass if (err_mask & AC_ERR_NODEV_HINT) {
1865f2105c61SSimon Glass printf("READ_SECTORS NODEV after polling detection\n");
1866f2105c61SSimon Glass return -ENOENT;
1867f2105c61SSimon Glass }
1868f2105c61SSimon Glass
1869f2105c61SSimon Glass if ((err_mask == AC_ERR_DEV) && (tf.feature & ATA_ABORTED)) {
1870f2105c61SSimon Glass /* Device or controller might have reported
1871f2105c61SSimon Glass * the wrong device class. Give a shot at the
1872f2105c61SSimon Glass * other IDENTIFY if the current one is
1873f2105c61SSimon Glass * aborted by the device.
1874f2105c61SSimon Glass */
1875f2105c61SSimon Glass if (may_fallback) {
1876f2105c61SSimon Glass may_fallback = 0;
1877f2105c61SSimon Glass
1878f2105c61SSimon Glass if (class == ATA_DEV_ATA) {
1879f2105c61SSimon Glass class = ATA_DEV_ATAPI;
1880f2105c61SSimon Glass } else {
1881f2105c61SSimon Glass class = ATA_DEV_ATA;
1882f2105c61SSimon Glass }
1883f2105c61SSimon Glass goto retry;
1884f2105c61SSimon Glass }
1885f2105c61SSimon Glass /* Control reaches here iff the device aborted
1886f2105c61SSimon Glass * both flavors of IDENTIFYs which happens
1887f2105c61SSimon Glass * sometimes with phantom devices.
1888f2105c61SSimon Glass */
1889f2105c61SSimon Glass printf("both IDENTIFYs aborted, assuming NODEV\n");
1890f2105c61SSimon Glass return -ENOENT;
1891f2105c61SSimon Glass }
1892f2105c61SSimon Glass
1893f2105c61SSimon Glass reason = "I/O error";
1894f2105c61SSimon Glass goto err_out;
1895f2105c61SSimon Glass }
1896f2105c61SSimon Glass
1897f2105c61SSimon Glass return true;
1898f2105c61SSimon Glass
1899f2105c61SSimon Glass err_out:
1900f2105c61SSimon Glass printf("failed to READ SECTORS (%s, err_mask=0x%x)\n", reason, err_mask);
1901f2105c61SSimon Glass return false;
1902f2105c61SSimon Glass }
1903f2105c61SSimon Glass
1904f2105c61SSimon Glass #if defined(CONFIG_SATA_DWC) && !defined(CONFIG_LBA48)
1905f2105c61SSimon Glass #define SATA_MAX_WRITE_BLK 0xFF
1906f2105c61SSimon Glass #else
1907f2105c61SSimon Glass #define SATA_MAX_WRITE_BLK 0xFFFF
1908f2105c61SSimon Glass #endif
1909f2105c61SSimon Glass
sata_write(int device,ulong blknr,lbaint_t blkcnt,const void * buffer)1910f2105c61SSimon Glass ulong sata_write(int device, ulong blknr, lbaint_t blkcnt, const void *buffer)
1911f2105c61SSimon Glass {
1912f2105c61SSimon Glass ulong start,blks, buf_addr;
1913f2105c61SSimon Glass unsigned short smallblks;
1914f2105c61SSimon Glass unsigned long datalen;
1915f2105c61SSimon Glass unsigned char *pdata;
1916f2105c61SSimon Glass device &= 0xff;
1917f2105c61SSimon Glass
1918f2105c61SSimon Glass
1919f2105c61SSimon Glass u32 block = 0;
1920f2105c61SSimon Glass u32 n_block = 0;
1921f2105c61SSimon Glass
1922f2105c61SSimon Glass if (dev_state != SATA_READY)
1923f2105c61SSimon Glass return 0;
1924f2105c61SSimon Glass
1925f2105c61SSimon Glass buf_addr = (unsigned long)buffer;
1926f2105c61SSimon Glass start = blknr;
1927f2105c61SSimon Glass blks = blkcnt;
1928f2105c61SSimon Glass do {
1929f2105c61SSimon Glass pdata = (unsigned char *)buf_addr;
1930f2105c61SSimon Glass if (blks > SATA_MAX_WRITE_BLK) {
1931f2105c61SSimon Glass datalen = sata_dev_desc[device].blksz * SATA_MAX_WRITE_BLK;
1932f2105c61SSimon Glass smallblks = SATA_MAX_WRITE_BLK;
1933f2105c61SSimon Glass
1934f2105c61SSimon Glass block = (u32)start;
1935f2105c61SSimon Glass n_block = (u32)smallblks;
1936f2105c61SSimon Glass
1937f2105c61SSimon Glass start += SATA_MAX_WRITE_BLK;
1938f2105c61SSimon Glass blks -= SATA_MAX_WRITE_BLK;
1939f2105c61SSimon Glass } else {
1940f2105c61SSimon Glass datalen = sata_dev_desc[device].blksz * blks;
1941f2105c61SSimon Glass smallblks = (unsigned short)blks;
1942f2105c61SSimon Glass
1943f2105c61SSimon Glass block = (u32)start;
1944f2105c61SSimon Glass n_block = (u32)smallblks;
1945f2105c61SSimon Glass
1946f2105c61SSimon Glass start += blks;
1947f2105c61SSimon Glass blks = 0;
1948f2105c61SSimon Glass }
1949f2105c61SSimon Glass
1950f2105c61SSimon Glass if (ata_dev_write_sectors(pdata, datalen, block, n_block) != true) {
1951f2105c61SSimon Glass printf("sata_dwc : Hard disk read error.\n");
1952f2105c61SSimon Glass blkcnt -= blks;
1953f2105c61SSimon Glass break;
1954f2105c61SSimon Glass }
1955f2105c61SSimon Glass buf_addr += datalen;
1956f2105c61SSimon Glass } while (blks != 0);
1957f2105c61SSimon Glass
1958f2105c61SSimon Glass return (blkcnt);
1959f2105c61SSimon Glass }
1960f2105c61SSimon Glass
ata_dev_write_sectors(unsigned char * pdata,unsigned long datalen,u32 block,u32 n_block)1961f2105c61SSimon Glass static int ata_dev_write_sectors(unsigned char* pdata, unsigned long datalen,
1962f2105c61SSimon Glass u32 block, u32 n_block)
1963f2105c61SSimon Glass {
1964f2105c61SSimon Glass struct ata_port *ap = pap;
1965f2105c61SSimon Glass struct ata_device *dev = &ata_device;
1966f2105c61SSimon Glass struct ata_taskfile tf;
1967f2105c61SSimon Glass unsigned int class = ATA_DEV_ATA;
1968f2105c61SSimon Glass unsigned int err_mask = 0;
1969f2105c61SSimon Glass const char *reason;
1970f2105c61SSimon Glass int may_fallback = 1;
1971f2105c61SSimon Glass
1972f2105c61SSimon Glass if (dev_state == SATA_ERROR)
1973f2105c61SSimon Glass return false;
1974f2105c61SSimon Glass
1975f2105c61SSimon Glass ata_dev_select(ap, dev->devno, 1, 1);
1976f2105c61SSimon Glass
1977f2105c61SSimon Glass retry:
1978f2105c61SSimon Glass memset(&tf, 0, sizeof(tf));
1979f2105c61SSimon Glass tf.ctl = ap->ctl;
1980f2105c61SSimon Glass ap->print_id = 1;
1981f2105c61SSimon Glass ap->flags &= ~ATA_FLAG_DISABLED;
1982f2105c61SSimon Glass
1983f2105c61SSimon Glass ap->pdata = pdata;
1984f2105c61SSimon Glass
1985f2105c61SSimon Glass tf.device = ATA_DEVICE_OBS;
1986f2105c61SSimon Glass
1987f2105c61SSimon Glass temp_n_block = n_block;
1988f2105c61SSimon Glass
1989f2105c61SSimon Glass
1990f2105c61SSimon Glass #ifdef CONFIG_LBA48
1991f2105c61SSimon Glass tf.command = ATA_CMD_PIO_WRITE_EXT;
1992f2105c61SSimon Glass tf.flags |= ATA_TFLAG_LBA | ATA_TFLAG_LBA48 | ATA_TFLAG_WRITE;
1993f2105c61SSimon Glass
1994f2105c61SSimon Glass tf.hob_feature = 31;
1995f2105c61SSimon Glass tf.feature = 31;
1996f2105c61SSimon Glass tf.hob_nsect = (n_block >> 8) & 0xff;
1997f2105c61SSimon Glass tf.nsect = n_block & 0xff;
1998f2105c61SSimon Glass
1999f2105c61SSimon Glass tf.hob_lbah = 0x0;
2000f2105c61SSimon Glass tf.hob_lbam = 0x0;
2001f2105c61SSimon Glass tf.hob_lbal = (block >> 24) & 0xff;
2002f2105c61SSimon Glass tf.lbah = (block >> 16) & 0xff;
2003f2105c61SSimon Glass tf.lbam = (block >> 8) & 0xff;
2004f2105c61SSimon Glass tf.lbal = block & 0xff;
2005f2105c61SSimon Glass
2006f2105c61SSimon Glass tf.device = 1 << 6;
2007f2105c61SSimon Glass if (tf.flags & ATA_TFLAG_FUA)
2008f2105c61SSimon Glass tf.device |= 1 << 7;
2009f2105c61SSimon Glass #else
2010f2105c61SSimon Glass tf.command = ATA_CMD_PIO_WRITE;
2011f2105c61SSimon Glass tf.flags |= ATA_TFLAG_LBA | ATA_TFLAG_WRITE;
2012f2105c61SSimon Glass
2013f2105c61SSimon Glass tf.feature = 31;
2014f2105c61SSimon Glass tf.nsect = n_block & 0xff;
2015f2105c61SSimon Glass
2016f2105c61SSimon Glass tf.lbah = (block >> 16) & 0xff;
2017f2105c61SSimon Glass tf.lbam = (block >> 8) & 0xff;
2018f2105c61SSimon Glass tf.lbal = block & 0xff;
2019f2105c61SSimon Glass
2020f2105c61SSimon Glass tf.device = (block >> 24) & 0xf;
2021f2105c61SSimon Glass
2022f2105c61SSimon Glass tf.device |= 1 << 6;
2023f2105c61SSimon Glass if (tf.flags & ATA_TFLAG_FUA)
2024f2105c61SSimon Glass tf.device |= 1 << 7;
2025f2105c61SSimon Glass
2026f2105c61SSimon Glass #endif
2027f2105c61SSimon Glass
2028f2105c61SSimon Glass tf.protocol = ATA_PROT_PIO;
2029f2105c61SSimon Glass
2030f2105c61SSimon Glass /* Some devices choke if TF registers contain garbage. Make
2031f2105c61SSimon Glass * sure those are properly initialized.
2032f2105c61SSimon Glass */
2033f2105c61SSimon Glass tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE;
2034f2105c61SSimon Glass tf.flags |= ATA_TFLAG_POLLING;
2035f2105c61SSimon Glass
2036f2105c61SSimon Glass err_mask = ata_exec_internal(dev, &tf, NULL, DMA_FROM_DEVICE, 0, 0);
2037f2105c61SSimon Glass
2038f2105c61SSimon Glass if (err_mask) {
2039f2105c61SSimon Glass if (err_mask & AC_ERR_NODEV_HINT) {
2040f2105c61SSimon Glass printf("READ_SECTORS NODEV after polling detection\n");
2041f2105c61SSimon Glass return -ENOENT;
2042f2105c61SSimon Glass }
2043f2105c61SSimon Glass
2044f2105c61SSimon Glass if ((err_mask == AC_ERR_DEV) && (tf.feature & ATA_ABORTED)) {
2045f2105c61SSimon Glass /* Device or controller might have reported
2046f2105c61SSimon Glass * the wrong device class. Give a shot at the
2047f2105c61SSimon Glass * other IDENTIFY if the current one is
2048f2105c61SSimon Glass * aborted by the device.
2049f2105c61SSimon Glass */
2050f2105c61SSimon Glass if (may_fallback) {
2051f2105c61SSimon Glass may_fallback = 0;
2052f2105c61SSimon Glass
2053f2105c61SSimon Glass if (class == ATA_DEV_ATA) {
2054f2105c61SSimon Glass class = ATA_DEV_ATAPI;
2055f2105c61SSimon Glass } else {
2056f2105c61SSimon Glass class = ATA_DEV_ATA;
2057f2105c61SSimon Glass }
2058f2105c61SSimon Glass goto retry;
2059f2105c61SSimon Glass }
2060f2105c61SSimon Glass /* Control reaches here iff the device aborted
2061f2105c61SSimon Glass * both flavors of IDENTIFYs which happens
2062f2105c61SSimon Glass * sometimes with phantom devices.
2063f2105c61SSimon Glass */
2064f2105c61SSimon Glass printf("both IDENTIFYs aborted, assuming NODEV\n");
2065f2105c61SSimon Glass return -ENOENT;
2066f2105c61SSimon Glass }
2067f2105c61SSimon Glass
2068f2105c61SSimon Glass reason = "I/O error";
2069f2105c61SSimon Glass goto err_out;
2070f2105c61SSimon Glass }
2071f2105c61SSimon Glass
2072f2105c61SSimon Glass return true;
2073f2105c61SSimon Glass
2074f2105c61SSimon Glass err_out:
2075f2105c61SSimon Glass printf("failed to WRITE SECTORS (%s, err_mask=0x%x)\n", reason, err_mask);
2076f2105c61SSimon Glass return false;
2077f2105c61SSimon Glass }
2078