xref: /rk3399_rockchip-uboot/drivers/ata/sata_dwc.c (revision 9ff3d0147e970e15128c2e0436f2f4069b687ad4)
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 = &ap;
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 = &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] = &ap;
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