Blame view

drivers/ata/sata_sil24.c 37.9 KB
edb336670   Tejun Heo   [PATCH] SATA: rew...
1
2
3
4
5
6
7
  /*
   * sata_sil24.c - Driver for Silicon Image 3124/3132 SATA-2 controllers
   *
   * Copyright 2005  Tejun Heo
   *
   * Based on preview driver from Silicon Image.
   *
edb336670   Tejun Heo   [PATCH] SATA: rew...
8
9
10
11
12
13
14
15
16
17
18
19
20
21
   * This program is free software; you can redistribute it and/or modify it
   * under the terms of the GNU General Public License as published by the
   * Free Software Foundation; either version 2, or (at your option) any
   * later version.
   *
   * This program is distributed in the hope that it will be useful, but
   * WITHOUT ANY WARRANTY; without even the implied warranty of
   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   * General Public License for more details.
   *
   */
  
  #include <linux/kernel.h>
  #include <linux/module.h>
5a0e3ad6a   Tejun Heo   include cleanup: ...
22
  #include <linux/gfp.h>
edb336670   Tejun Heo   [PATCH] SATA: rew...
23
24
25
26
27
  #include <linux/pci.h>
  #include <linux/blkdev.h>
  #include <linux/delay.h>
  #include <linux/interrupt.h>
  #include <linux/dma-mapping.h>
a9524a76f   Jeff Garzik   [libata] use dev_...
28
  #include <linux/device.h>
edb336670   Tejun Heo   [PATCH] SATA: rew...
29
  #include <scsi/scsi_host.h>
193515d51   Jeff Garzik   [libata] eliminat...
30
  #include <scsi/scsi_cmnd.h>
edb336670   Tejun Heo   [PATCH] SATA: rew...
31
  #include <linux/libata.h>
edb336670   Tejun Heo   [PATCH] SATA: rew...
32
33
  
  #define DRV_NAME	"sata_sil24"
3454dc692   Tejun Heo   sata_sil24: imple...
34
  #define DRV_VERSION	"1.1"
edb336670   Tejun Heo   [PATCH] SATA: rew...
35

edb336670   Tejun Heo   [PATCH] SATA: rew...
36
37
38
39
  /*
   * Port request block (PRB) 32 bytes
   */
  struct sil24_prb {
b47725743   Alexey Dobriyan   [PATCH] sata_sil2...
40
41
42
  	__le16	ctrl;
  	__le16	prot;
  	__le32	rx_cnt;
edb336670   Tejun Heo   [PATCH] SATA: rew...
43
44
45
46
47
48
49
  	u8	fis[6 * 4];
  };
  
  /*
   * Scatter gather entry (SGE) 16 bytes
   */
  struct sil24_sge {
b47725743   Alexey Dobriyan   [PATCH] sata_sil2...
50
51
52
  	__le64	addr;
  	__le32	cnt;
  	__le32	flags;
edb336670   Tejun Heo   [PATCH] SATA: rew...
53
  };
edb336670   Tejun Heo   [PATCH] SATA: rew...
54
55
  
  enum {
0d5ff5667   Tejun Heo   libata: convert t...
56
57
  	SIL24_HOST_BAR		= 0,
  	SIL24_PORT_BAR		= 2,
93e2618e0   Tejun Heo   sata_sil24: fix s...
58
59
60
61
62
63
64
65
66
67
68
69
70
71
  	/* sil24 fetches in chunks of 64bytes.  The first block
  	 * contains the PRB and two SGEs.  From the second block, it's
  	 * consisted of four SGEs and called SGT.  Calculate the
  	 * number of SGTs that fit into one page.
  	 */
  	SIL24_PRB_SZ		= sizeof(struct sil24_prb)
  				  + 2 * sizeof(struct sil24_sge),
  	SIL24_MAX_SGT		= (PAGE_SIZE - SIL24_PRB_SZ)
  				  / (4 * sizeof(struct sil24_sge)),
  
  	/* This will give us one unused SGEs for ATA.  This extra SGE
  	 * will be used to store CDB for ATAPI devices.
  	 */
  	SIL24_MAX_SGE		= 4 * SIL24_MAX_SGT + 1,
edb336670   Tejun Heo   [PATCH] SATA: rew...
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
  	/*
  	 * Global controller registers (128 bytes @ BAR0)
  	 */
  		/* 32 bit regs */
  	HOST_SLOT_STAT		= 0x00, /* 32 bit slot stat * 4 */
  	HOST_CTRL		= 0x40,
  	HOST_IRQ_STAT		= 0x44,
  	HOST_PHY_CFG		= 0x48,
  	HOST_BIST_CTRL		= 0x50,
  	HOST_BIST_PTRN		= 0x54,
  	HOST_BIST_STAT		= 0x58,
  	HOST_MEM_BIST_STAT	= 0x5c,
  	HOST_FLASH_CMD		= 0x70,
  		/* 8 bit regs */
  	HOST_FLASH_DATA		= 0x74,
  	HOST_TRANSITION_DETECT	= 0x75,
  	HOST_GPIO_CTRL		= 0x76,
  	HOST_I2C_ADDR		= 0x78, /* 32 bit */
  	HOST_I2C_DATA		= 0x7c,
  	HOST_I2C_XFER_CNT	= 0x7e,
  	HOST_I2C_CTRL		= 0x7f,
  
  	/* HOST_SLOT_STAT bits */
  	HOST_SSTAT_ATTN		= (1 << 31),
7dafc3fd9   Tejun Heo   [PATCH] sata_sil2...
96
97
98
99
100
101
  	/* HOST_CTRL bits */
  	HOST_CTRL_M66EN		= (1 << 16), /* M66EN PCI bus signal */
  	HOST_CTRL_TRDY		= (1 << 17), /* latched PCI TRDY */
  	HOST_CTRL_STOP		= (1 << 18), /* latched PCI STOP */
  	HOST_CTRL_DEVSEL	= (1 << 19), /* latched PCI DEVSEL */
  	HOST_CTRL_REQ64		= (1 << 20), /* latched PCI REQ64 */
d2298dca9   Tejun Heo   [PATCH] sata_sil2...
102
  	HOST_CTRL_GLOBAL_RST	= (1 << 31), /* global reset */
7dafc3fd9   Tejun Heo   [PATCH] sata_sil2...
103

edb336670   Tejun Heo   [PATCH] SATA: rew...
104
105
106
107
108
  	/*
  	 * Port registers
  	 * (8192 bytes @ +0x0000, +0x2000, +0x4000 and +0x6000 @ BAR2)
  	 */
  	PORT_REGS_SIZE		= 0x2000,
135da3457   Tejun Heo   [PATCH] sata_sil2...
109

28c8f3b4f   Tejun Heo   [PATCH] sata_sil2...
110
  	PORT_LRAM		= 0x0000, /* 31 LRAM slots and PMP regs */
135da3457   Tejun Heo   [PATCH] sata_sil2...
111
  	PORT_LRAM_SLOT_SZ	= 0x0080, /* 32 bytes PRB + 2 SGE, ACT... */
edb336670   Tejun Heo   [PATCH] SATA: rew...
112

28c8f3b4f   Tejun Heo   [PATCH] sata_sil2...
113
  	PORT_PMP		= 0x0f80, /* 8 bytes PMP * 16 (128 bytes) */
c0c559083   Tejun Heo   [PATCH] sata_sil2...
114
115
116
  	PORT_PMP_STATUS		= 0x0000, /* port device status offset */
  	PORT_PMP_QACTIVE	= 0x0004, /* port device QActive offset */
  	PORT_PMP_SIZE		= 0x0008, /* 8 bytes per PMP */
edb336670   Tejun Heo   [PATCH] SATA: rew...
117
  		/* 32 bit regs */
83bbecc90   Tejun Heo   [PATCH] sil24: ad...
118
119
120
121
122
  	PORT_CTRL_STAT		= 0x1000, /* write: ctrl-set, read: stat */
  	PORT_CTRL_CLR		= 0x1004, /* write: ctrl-clear */
  	PORT_IRQ_STAT		= 0x1008, /* high: status, low: interrupt */
  	PORT_IRQ_ENABLE_SET	= 0x1010, /* write: enable-set */
  	PORT_IRQ_ENABLE_CLR	= 0x1014, /* write: enable-clear */
edb336670   Tejun Heo   [PATCH] SATA: rew...
123
  	PORT_ACTIVATE_UPPER_ADDR= 0x101c,
83bbecc90   Tejun Heo   [PATCH] sil24: ad...
124
125
  	PORT_EXEC_FIFO		= 0x1020, /* command execution fifo */
  	PORT_CMD_ERR		= 0x1024, /* command error number */
edb336670   Tejun Heo   [PATCH] SATA: rew...
126
127
128
129
130
131
132
133
134
135
136
137
138
  	PORT_FIS_CFG		= 0x1028,
  	PORT_FIFO_THRES		= 0x102c,
  		/* 16 bit regs */
  	PORT_DECODE_ERR_CNT	= 0x1040,
  	PORT_DECODE_ERR_THRESH	= 0x1042,
  	PORT_CRC_ERR_CNT	= 0x1044,
  	PORT_CRC_ERR_THRESH	= 0x1046,
  	PORT_HSHK_ERR_CNT	= 0x1048,
  	PORT_HSHK_ERR_THRESH	= 0x104a,
  		/* 32 bit regs */
  	PORT_PHY_CFG		= 0x1050,
  	PORT_SLOT_STAT		= 0x1800,
  	PORT_CMD_ACTIVATE	= 0x1c00, /* 64 bit cmd activate * 31 (248 bytes) */
c0c559083   Tejun Heo   [PATCH] sata_sil2...
139
  	PORT_CONTEXT		= 0x1e04,
edb336670   Tejun Heo   [PATCH] SATA: rew...
140
141
142
143
144
145
146
147
148
149
150
151
  	PORT_EXEC_DIAG		= 0x1e00, /* 32bit exec diag * 16 (64 bytes, 0-10 used on 3124) */
  	PORT_PSD_DIAG		= 0x1e40, /* 32bit psd diag * 16 (64 bytes, 0-8 used on 3124) */
  	PORT_SCONTROL		= 0x1f00,
  	PORT_SSTATUS		= 0x1f04,
  	PORT_SERROR		= 0x1f08,
  	PORT_SACTIVE		= 0x1f0c,
  
  	/* PORT_CTRL_STAT bits */
  	PORT_CS_PORT_RST	= (1 << 0), /* port reset */
  	PORT_CS_DEV_RST		= (1 << 1), /* device reset */
  	PORT_CS_INIT		= (1 << 2), /* port initialize */
  	PORT_CS_IRQ_WOC		= (1 << 3), /* interrupt write one to clear */
d10cb35a8   Tejun Heo   [PATCH] sil24: ad...
152
  	PORT_CS_CDB16		= (1 << 5), /* 0=12b cdb, 1=16b cdb */
28c8f3b4f   Tejun Heo   [PATCH] sata_sil2...
153
  	PORT_CS_PMP_RESUME	= (1 << 6), /* PMP resume */
e382eb1db   Tejun Heo   [PATCH] sil24: fi...
154
  	PORT_CS_32BIT_ACTV	= (1 << 10), /* 32-bit activation */
28c8f3b4f   Tejun Heo   [PATCH] sata_sil2...
155
  	PORT_CS_PMP_EN		= (1 << 13), /* port multiplier enable */
e382eb1db   Tejun Heo   [PATCH] sil24: fi...
156
  	PORT_CS_RDY		= (1 << 31), /* port ready to accept commands */
edb336670   Tejun Heo   [PATCH] SATA: rew...
157
158
159
160
161
162
163
164
165
  
  	/* PORT_IRQ_STAT/ENABLE_SET/CLR */
  	/* bits[11:0] are masked */
  	PORT_IRQ_COMPLETE	= (1 << 0), /* command(s) completed */
  	PORT_IRQ_ERROR		= (1 << 1), /* command execution error */
  	PORT_IRQ_PORTRDY_CHG	= (1 << 2), /* port ready change */
  	PORT_IRQ_PWR_CHG	= (1 << 3), /* power management change */
  	PORT_IRQ_PHYRDY_CHG	= (1 << 4), /* PHY ready change */
  	PORT_IRQ_COMWAKE	= (1 << 5), /* COMWAKE received */
7dafc3fd9   Tejun Heo   [PATCH] sata_sil2...
166
167
168
169
170
  	PORT_IRQ_UNK_FIS	= (1 << 6), /* unknown FIS received */
  	PORT_IRQ_DEV_XCHG	= (1 << 7), /* device exchanged */
  	PORT_IRQ_8B10B		= (1 << 8), /* 8b/10b decode error threshold */
  	PORT_IRQ_CRC		= (1 << 9), /* CRC error threshold */
  	PORT_IRQ_HANDSHAKE	= (1 << 10), /* handshake error threshold */
3b9f1d0fb   Tejun Heo   [PATCH] sata_sil2...
171
  	PORT_IRQ_SDB_NOTIFY	= (1 << 11), /* SDB notify received */
edb336670   Tejun Heo   [PATCH] SATA: rew...
172

88ce7550c   Tejun Heo   [PATCH] sata_sil2...
173
  	DEF_PORT_IRQ		= PORT_IRQ_COMPLETE | PORT_IRQ_ERROR |
0542925b2   Tejun Heo   [PATCH] sata_sil2...
174
  				  PORT_IRQ_PHYRDY_CHG | PORT_IRQ_DEV_XCHG |
854c73a2f   Tejun Heo   libata: misc upda...
175
  				  PORT_IRQ_UNK_FIS | PORT_IRQ_SDB_NOTIFY,
88ce7550c   Tejun Heo   [PATCH] sata_sil2...
176

edb336670   Tejun Heo   [PATCH] SATA: rew...
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
  	/* bits[27:16] are unmasked (raw) */
  	PORT_IRQ_RAW_SHIFT	= 16,
  	PORT_IRQ_MASKED_MASK	= 0x7ff,
  	PORT_IRQ_RAW_MASK	= (0x7ff << PORT_IRQ_RAW_SHIFT),
  
  	/* ENABLE_SET/CLR specific, intr steering - 2 bit field */
  	PORT_IRQ_STEER_SHIFT	= 30,
  	PORT_IRQ_STEER_MASK	= (3 << PORT_IRQ_STEER_SHIFT),
  
  	/* PORT_CMD_ERR constants */
  	PORT_CERR_DEV		= 1, /* Error bit in D2H Register FIS */
  	PORT_CERR_SDB		= 2, /* Error bit in SDB FIS */
  	PORT_CERR_DATA		= 3, /* Error in data FIS not detected by dev */
  	PORT_CERR_SEND		= 4, /* Initial cmd FIS transmission failure */
  	PORT_CERR_INCONSISTENT	= 5, /* Protocol mismatch */
  	PORT_CERR_DIRECTION	= 6, /* Data direction mismatch */
  	PORT_CERR_UNDERRUN	= 7, /* Ran out of SGEs while writing */
  	PORT_CERR_OVERRUN	= 8, /* Ran out of SGEs while reading */
  	PORT_CERR_PKT_PROT	= 11, /* DIR invalid in 1st PIO setup of ATAPI */
  	PORT_CERR_SGT_BOUNDARY	= 16, /* PLD ecode 00 - SGT not on qword boundary */
  	PORT_CERR_SGT_TGTABRT	= 17, /* PLD ecode 01 - target abort */
  	PORT_CERR_SGT_MSTABRT	= 18, /* PLD ecode 10 - master abort */
  	PORT_CERR_SGT_PCIPERR	= 19, /* PLD ecode 11 - PCI parity err while fetching SGT */
  	PORT_CERR_CMD_BOUNDARY	= 24, /* ctrl[15:13] 001 - PRB not on qword boundary */
  	PORT_CERR_CMD_TGTABRT	= 25, /* ctrl[15:13] 010 - target abort */
  	PORT_CERR_CMD_MSTABRT	= 26, /* ctrl[15:13] 100 - master abort */
  	PORT_CERR_CMD_PCIPERR	= 27, /* ctrl[15:13] 110 - PCI parity err while fetching PRB */
  	PORT_CERR_XFR_UNDEF	= 32, /* PSD ecode 00 - undefined */
  	PORT_CERR_XFR_TGTABRT	= 33, /* PSD ecode 01 - target abort */
640088024   Tejun Heo   [PATCH] sata_sil2...
206
  	PORT_CERR_XFR_MSTABRT	= 34, /* PSD ecode 10 - master abort */
edb336670   Tejun Heo   [PATCH] SATA: rew...
207
  	PORT_CERR_XFR_PCIPERR	= 35, /* PSD ecode 11 - PCI prity err during transfer */
83bbecc90   Tejun Heo   [PATCH] sil24: ad...
208
  	PORT_CERR_SENDSERVICE	= 36, /* FIS received while sending service */
edb336670   Tejun Heo   [PATCH] SATA: rew...
209

d10cb35a8   Tejun Heo   [PATCH] sil24: ad...
210
211
212
213
214
215
216
217
218
219
220
221
222
223
  	/* bits of PRB control field */
  	PRB_CTRL_PROTOCOL	= (1 << 0), /* override def. ATA protocol */
  	PRB_CTRL_PACKET_READ	= (1 << 4), /* PACKET cmd read */
  	PRB_CTRL_PACKET_WRITE	= (1 << 5), /* PACKET cmd write */
  	PRB_CTRL_NIEN		= (1 << 6), /* Mask completion irq */
  	PRB_CTRL_SRST		= (1 << 7), /* Soft reset request (ign BSY?) */
  
  	/* PRB protocol field */
  	PRB_PROT_PACKET		= (1 << 0),
  	PRB_PROT_TCQ		= (1 << 1),
  	PRB_PROT_NCQ		= (1 << 2),
  	PRB_PROT_READ		= (1 << 3),
  	PRB_PROT_WRITE		= (1 << 4),
  	PRB_PROT_TRANSPARENT	= (1 << 5),
edb336670   Tejun Heo   [PATCH] SATA: rew...
224
225
226
227
  	/*
  	 * Other constants
  	 */
  	SGE_TRM			= (1 << 31), /* Last SGE in chain */
d10cb35a8   Tejun Heo   [PATCH] sil24: ad...
228
229
230
231
  	SGE_LNK			= (1 << 30), /* linked list
  						Points to SGT, not SGE */
  	SGE_DRD			= (1 << 29), /* discard data read (/dev/null)
  						data address ignored */
edb336670   Tejun Heo   [PATCH] SATA: rew...
232

aee10a03e   Tejun Heo   [PATCH] sata_sil2...
233
  	SIL24_MAX_CMDS		= 31,
edb336670   Tejun Heo   [PATCH] SATA: rew...
234
235
236
  	/* board id */
  	BID_SIL3124		= 0,
  	BID_SIL3132		= 1,
042c21fd2   Tejun Heo   [libata sata_sil2...
237
  	BID_SIL3131		= 2,
edb336670   Tejun Heo   [PATCH] SATA: rew...
238

9466d85bb   Tejun Heo   [PATCH] sata_sil2...
239
  	/* host flags */
9cbe056f6   Sergei Shtylyov   libata: remove AT...
240
241
242
  	SIL24_COMMON_FLAGS	= ATA_FLAG_SATA | ATA_FLAG_PIO_DMA |
  				  ATA_FLAG_NCQ | ATA_FLAG_ACPI_SATA |
  				  ATA_FLAG_AN | ATA_FLAG_PMP,
37024e8ee   Tejun Heo   [PATCH] sata_sil2...
243
  	SIL24_FLAG_PCIX_IRQ_WOC	= (1 << 24), /* IRQ loss errata on PCI-X */
9466d85bb   Tejun Heo   [PATCH] sata_sil2...
244

edb336670   Tejun Heo   [PATCH] SATA: rew...
245
246
  	IRQ_STAT_4PORTS		= 0xf,
  };
69ad185fa   Tejun Heo   [PATCH] sil24: ad...
247
  struct sil24_ata_block {
edb336670   Tejun Heo   [PATCH] SATA: rew...
248
  	struct sil24_prb prb;
93e2618e0   Tejun Heo   sata_sil24: fix s...
249
  	struct sil24_sge sge[SIL24_MAX_SGE];
edb336670   Tejun Heo   [PATCH] SATA: rew...
250
  };
69ad185fa   Tejun Heo   [PATCH] sil24: ad...
251
252
253
  struct sil24_atapi_block {
  	struct sil24_prb prb;
  	u8 cdb[16];
93e2618e0   Tejun Heo   sata_sil24: fix s...
254
  	struct sil24_sge sge[SIL24_MAX_SGE];
69ad185fa   Tejun Heo   [PATCH] sil24: ad...
255
256
257
258
259
260
  };
  
  union sil24_cmd_block {
  	struct sil24_ata_block ata;
  	struct sil24_atapi_block atapi;
  };
fc8cc1d5b   Joe Perches   sata_sil24: Use c...
261
  static const struct sil24_cerr_info {
88ce7550c   Tejun Heo   [PATCH] sata_sil2...
262
263
264
  	unsigned int err_mask, action;
  	const char *desc;
  } sil24_cerr_db[] = {
f90f0828e   Tejun Heo   libata: stop bein...
265
  	[0]			= { AC_ERR_DEV, 0,
88ce7550c   Tejun Heo   [PATCH] sata_sil2...
266
  				    "device error" },
f90f0828e   Tejun Heo   libata: stop bein...
267
  	[PORT_CERR_DEV]		= { AC_ERR_DEV, 0,
88ce7550c   Tejun Heo   [PATCH] sata_sil2...
268
  				    "device error via D2H FIS" },
f90f0828e   Tejun Heo   libata: stop bein...
269
  	[PORT_CERR_SDB]		= { AC_ERR_DEV, 0,
88ce7550c   Tejun Heo   [PATCH] sata_sil2...
270
  				    "device error via SDB FIS" },
cf4806265   Tejun Heo   libata: prefer ha...
271
  	[PORT_CERR_DATA]	= { AC_ERR_ATA_BUS, ATA_EH_RESET,
88ce7550c   Tejun Heo   [PATCH] sata_sil2...
272
  				    "error in data FIS" },
cf4806265   Tejun Heo   libata: prefer ha...
273
  	[PORT_CERR_SEND]	= { AC_ERR_ATA_BUS, ATA_EH_RESET,
88ce7550c   Tejun Heo   [PATCH] sata_sil2...
274
  				    "failed to transmit command FIS" },
cf4806265   Tejun Heo   libata: prefer ha...
275
  	[PORT_CERR_INCONSISTENT] = { AC_ERR_HSM, ATA_EH_RESET,
88ce7550c   Tejun Heo   [PATCH] sata_sil2...
276
  				     "protocol mismatch" },
cf4806265   Tejun Heo   libata: prefer ha...
277
  	[PORT_CERR_DIRECTION]	= { AC_ERR_HSM, ATA_EH_RESET,
88ce7550c   Tejun Heo   [PATCH] sata_sil2...
278
  				    "data directon mismatch" },
cf4806265   Tejun Heo   libata: prefer ha...
279
  	[PORT_CERR_UNDERRUN]	= { AC_ERR_HSM, ATA_EH_RESET,
88ce7550c   Tejun Heo   [PATCH] sata_sil2...
280
  				    "ran out of SGEs while writing" },
cf4806265   Tejun Heo   libata: prefer ha...
281
  	[PORT_CERR_OVERRUN]	= { AC_ERR_HSM, ATA_EH_RESET,
88ce7550c   Tejun Heo   [PATCH] sata_sil2...
282
  				    "ran out of SGEs while reading" },
cf4806265   Tejun Heo   libata: prefer ha...
283
  	[PORT_CERR_PKT_PROT]	= { AC_ERR_HSM, ATA_EH_RESET,
88ce7550c   Tejun Heo   [PATCH] sata_sil2...
284
  				    "invalid data directon for ATAPI CDB" },
cf4806265   Tejun Heo   libata: prefer ha...
285
  	[PORT_CERR_SGT_BOUNDARY] = { AC_ERR_SYSTEM, ATA_EH_RESET,
7293fa8fb   Tejun Heo   sata_sil24: fix s...
286
  				     "SGT not on qword boundary" },
cf4806265   Tejun Heo   libata: prefer ha...
287
  	[PORT_CERR_SGT_TGTABRT]	= { AC_ERR_HOST_BUS, ATA_EH_RESET,
88ce7550c   Tejun Heo   [PATCH] sata_sil2...
288
  				    "PCI target abort while fetching SGT" },
cf4806265   Tejun Heo   libata: prefer ha...
289
  	[PORT_CERR_SGT_MSTABRT]	= { AC_ERR_HOST_BUS, ATA_EH_RESET,
88ce7550c   Tejun Heo   [PATCH] sata_sil2...
290
  				    "PCI master abort while fetching SGT" },
cf4806265   Tejun Heo   libata: prefer ha...
291
  	[PORT_CERR_SGT_PCIPERR]	= { AC_ERR_HOST_BUS, ATA_EH_RESET,
88ce7550c   Tejun Heo   [PATCH] sata_sil2...
292
  				    "PCI parity error while fetching SGT" },
cf4806265   Tejun Heo   libata: prefer ha...
293
  	[PORT_CERR_CMD_BOUNDARY] = { AC_ERR_SYSTEM, ATA_EH_RESET,
88ce7550c   Tejun Heo   [PATCH] sata_sil2...
294
  				     "PRB not on qword boundary" },
cf4806265   Tejun Heo   libata: prefer ha...
295
  	[PORT_CERR_CMD_TGTABRT]	= { AC_ERR_HOST_BUS, ATA_EH_RESET,
88ce7550c   Tejun Heo   [PATCH] sata_sil2...
296
  				    "PCI target abort while fetching PRB" },
cf4806265   Tejun Heo   libata: prefer ha...
297
  	[PORT_CERR_CMD_MSTABRT]	= { AC_ERR_HOST_BUS, ATA_EH_RESET,
88ce7550c   Tejun Heo   [PATCH] sata_sil2...
298
  				    "PCI master abort while fetching PRB" },
cf4806265   Tejun Heo   libata: prefer ha...
299
  	[PORT_CERR_CMD_PCIPERR]	= { AC_ERR_HOST_BUS, ATA_EH_RESET,
88ce7550c   Tejun Heo   [PATCH] sata_sil2...
300
  				    "PCI parity error while fetching PRB" },
cf4806265   Tejun Heo   libata: prefer ha...
301
  	[PORT_CERR_XFR_UNDEF]	= { AC_ERR_HOST_BUS, ATA_EH_RESET,
88ce7550c   Tejun Heo   [PATCH] sata_sil2...
302
  				    "undefined error while transferring data" },
cf4806265   Tejun Heo   libata: prefer ha...
303
  	[PORT_CERR_XFR_TGTABRT]	= { AC_ERR_HOST_BUS, ATA_EH_RESET,
88ce7550c   Tejun Heo   [PATCH] sata_sil2...
304
  				    "PCI target abort while transferring data" },
cf4806265   Tejun Heo   libata: prefer ha...
305
  	[PORT_CERR_XFR_MSTABRT]	= { AC_ERR_HOST_BUS, ATA_EH_RESET,
88ce7550c   Tejun Heo   [PATCH] sata_sil2...
306
  				    "PCI master abort while transferring data" },
cf4806265   Tejun Heo   libata: prefer ha...
307
  	[PORT_CERR_XFR_PCIPERR]	= { AC_ERR_HOST_BUS, ATA_EH_RESET,
88ce7550c   Tejun Heo   [PATCH] sata_sil2...
308
  				    "PCI parity error while transferring data" },
cf4806265   Tejun Heo   libata: prefer ha...
309
  	[PORT_CERR_SENDSERVICE]	= { AC_ERR_HSM, ATA_EH_RESET,
88ce7550c   Tejun Heo   [PATCH] sata_sil2...
310
311
  				    "FIS received while sending service FIS" },
  };
edb336670   Tejun Heo   [PATCH] SATA: rew...
312
313
314
315
316
317
318
  /*
   * ap->private_data
   *
   * The preview driver always returned 0 for status.  We emulate it
   * here from the previous interrupt.
   */
  struct sil24_port_priv {
69ad185fa   Tejun Heo   [PATCH] sil24: ad...
319
  	union sil24_cmd_block *cmd_block;	/* 32 cmd blocks */
edb336670   Tejun Heo   [PATCH] SATA: rew...
320
  	dma_addr_t cmd_block_dma;		/* DMA base addr for them */
238180343   Tejun Heo   sata_sil24: imple...
321
  	int do_port_rst;
edb336670   Tejun Heo   [PATCH] SATA: rew...
322
  };
cd0d3bbcd   Alan Cox   libata: dev_confi...
323
  static void sil24_dev_config(struct ata_device *dev);
82ef04fb4   Tejun Heo   libata: make SCR ...
324
325
  static int sil24_scr_read(struct ata_link *link, unsigned sc_reg, u32 *val);
  static int sil24_scr_write(struct ata_link *link, unsigned sc_reg, u32 val);
3454dc692   Tejun Heo   sata_sil24: imple...
326
  static int sil24_qc_defer(struct ata_queued_cmd *qc);
edb336670   Tejun Heo   [PATCH] SATA: rew...
327
  static void sil24_qc_prep(struct ata_queued_cmd *qc);
9a3d9eb01   Tejun Heo   [PATCH] libata: r...
328
  static unsigned int sil24_qc_issue(struct ata_queued_cmd *qc);
79f97dadf   Tejun Heo   libata: drop @fin...
329
  static bool sil24_qc_fill_rtf(struct ata_queued_cmd *qc);
3454dc692   Tejun Heo   sata_sil24: imple...
330
331
  static void sil24_pmp_attach(struct ata_port *ap);
  static void sil24_pmp_detach(struct ata_port *ap);
88ce7550c   Tejun Heo   [PATCH] sata_sil2...
332
333
  static void sil24_freeze(struct ata_port *ap);
  static void sil24_thaw(struct ata_port *ap);
a1efdaba2   Tejun Heo   libata: make rese...
334
335
336
337
  static int sil24_softreset(struct ata_link *link, unsigned int *class,
  			   unsigned long deadline);
  static int sil24_hardreset(struct ata_link *link, unsigned int *class,
  			   unsigned long deadline);
a1efdaba2   Tejun Heo   libata: make rese...
338
339
  static int sil24_pmp_hardreset(struct ata_link *link, unsigned int *class,
  			       unsigned long deadline);
88ce7550c   Tejun Heo   [PATCH] sata_sil2...
340
341
  static void sil24_error_handler(struct ata_port *ap);
  static void sil24_post_internal_cmd(struct ata_queued_cmd *qc);
edb336670   Tejun Heo   [PATCH] SATA: rew...
342
  static int sil24_port_start(struct ata_port *ap);
edb336670   Tejun Heo   [PATCH] SATA: rew...
343
  static int sil24_init_one(struct pci_dev *pdev, const struct pci_device_id *ent);
281d426c7   Alexey Dobriyan   [PATCH] CONFIG_PM...
344
  #ifdef CONFIG_PM
d2298dca9   Tejun Heo   [PATCH] sata_sil2...
345
  static int sil24_pci_device_resume(struct pci_dev *pdev);
3454dc692   Tejun Heo   sata_sil24: imple...
346
  static int sil24_port_resume(struct ata_port *ap);
281d426c7   Alexey Dobriyan   [PATCH] CONFIG_PM...
347
  #endif
edb336670   Tejun Heo   [PATCH] SATA: rew...
348

3b7d697df   Jeff Garzik   [libata] constify...
349
  static const struct pci_device_id sil24_pci_tbl[] = {
54bb3a94b   Jeff Garzik   [libata] Use new ...
350
351
352
  	{ PCI_VDEVICE(CMD, 0x3124), BID_SIL3124 },
  	{ PCI_VDEVICE(INTEL, 0x3124), BID_SIL3124 },
  	{ PCI_VDEVICE(CMD, 0x3132), BID_SIL3132 },
722d67b62   Jamie Clark   sata_sil24: Add A...
353
  	{ PCI_VDEVICE(CMD, 0x0242), BID_SIL3132 },
464b3286b   Tejun Heo   sata_sil24: add D...
354
  	{ PCI_VDEVICE(CMD, 0x0244), BID_SIL3132 },
54bb3a94b   Jeff Garzik   [libata] Use new ...
355
356
  	{ PCI_VDEVICE(CMD, 0x3131), BID_SIL3131 },
  	{ PCI_VDEVICE(CMD, 0x3531), BID_SIL3131 },
1fcce839a   Tejun Heo   [libata sata_sil2...
357
  	{ } /* terminate list */
edb336670   Tejun Heo   [PATCH] SATA: rew...
358
359
360
361
362
363
  };
  
  static struct pci_driver sil24_pci_driver = {
  	.name			= DRV_NAME,
  	.id_table		= sil24_pci_tbl,
  	.probe			= sil24_init_one,
24dc5f33e   Tejun Heo   libata: update li...
364
  	.remove			= ata_pci_remove_one,
281d426c7   Alexey Dobriyan   [PATCH] CONFIG_PM...
365
  #ifdef CONFIG_PM
d2298dca9   Tejun Heo   [PATCH] sata_sil2...
366
367
  	.suspend		= ata_pci_device_suspend,
  	.resume			= sil24_pci_device_resume,
281d426c7   Alexey Dobriyan   [PATCH] CONFIG_PM...
368
  #endif
edb336670   Tejun Heo   [PATCH] SATA: rew...
369
  };
193515d51   Jeff Garzik   [libata] eliminat...
370
  static struct scsi_host_template sil24_sht = {
68d1d07b5   Tejun Heo   libata: implement...
371
  	ATA_NCQ_SHT(DRV_NAME),
aee10a03e   Tejun Heo   [PATCH] sata_sil2...
372
  	.can_queue		= SIL24_MAX_CMDS,
93e2618e0   Tejun Heo   sata_sil24: fix s...
373
  	.sg_tablesize		= SIL24_MAX_SGE,
edb336670   Tejun Heo   [PATCH] SATA: rew...
374
  	.dma_boundary		= ATA_DMA_BOUNDARY,
edb336670   Tejun Heo   [PATCH] SATA: rew...
375
  };
029cfd6b7   Tejun Heo   libata: implement...
376
377
  static struct ata_port_operations sil24_ops = {
  	.inherits		= &sata_pmp_port_ops,
69ad185fa   Tejun Heo   [PATCH] sil24: ad...
378

3454dc692   Tejun Heo   sata_sil24: imple...
379
  	.qc_defer		= sil24_qc_defer,
edb336670   Tejun Heo   [PATCH] SATA: rew...
380
381
  	.qc_prep		= sil24_qc_prep,
  	.qc_issue		= sil24_qc_issue,
79f97dadf   Tejun Heo   libata: drop @fin...
382
  	.qc_fill_rtf		= sil24_qc_fill_rtf,
edb336670   Tejun Heo   [PATCH] SATA: rew...
383

029cfd6b7   Tejun Heo   libata: implement...
384
385
  	.freeze			= sil24_freeze,
  	.thaw			= sil24_thaw,
a1efdaba2   Tejun Heo   libata: make rese...
386
387
  	.softreset		= sil24_softreset,
  	.hardreset		= sil24_hardreset,
071f44b1d   Tejun Heo   libata: implement...
388
  	.pmp_softreset		= sil24_softreset,
a1efdaba2   Tejun Heo   libata: make rese...
389
  	.pmp_hardreset		= sil24_pmp_hardreset,
029cfd6b7   Tejun Heo   libata: implement...
390
391
392
  	.error_handler		= sil24_error_handler,
  	.post_internal_cmd	= sil24_post_internal_cmd,
  	.dev_config		= sil24_dev_config,
edb336670   Tejun Heo   [PATCH] SATA: rew...
393
394
395
  
  	.scr_read		= sil24_scr_read,
  	.scr_write		= sil24_scr_write,
3454dc692   Tejun Heo   sata_sil24: imple...
396
397
  	.pmp_attach		= sil24_pmp_attach,
  	.pmp_detach		= sil24_pmp_detach,
3454dc692   Tejun Heo   sata_sil24: imple...
398

edb336670   Tejun Heo   [PATCH] SATA: rew...
399
  	.port_start		= sil24_port_start,
3454dc692   Tejun Heo   sata_sil24: imple...
400
401
402
  #ifdef CONFIG_PM
  	.port_resume		= sil24_port_resume,
  #endif
edb336670   Tejun Heo   [PATCH] SATA: rew...
403
  };
90ab5ee94   Rusty Russell   module_param: mak...
404
  static bool sata_sil24_msi;    /* Disable MSI */
dae77214f   Vivek Mahajan   sata_sil24: MSI s...
405
406
  module_param_named(msi, sata_sil24_msi, bool, S_IRUGO);
  MODULE_PARM_DESC(msi, "Enable MSI (Default: false)");
042c21fd2   Tejun Heo   [libata sata_sil2...
407
  /*
cca3974e4   Jeff Garzik   libata: Grand ren...
408
   * Use bits 30-31 of port_flags to encode available port numbers.
042c21fd2   Tejun Heo   [libata sata_sil2...
409
410
411
412
   * Current maxium is 4.
   */
  #define SIL24_NPORTS2FLAG(nports)	((((unsigned)(nports) - 1) & 0x3) << 30)
  #define SIL24_FLAG2NPORTS(flag)		((((flag) >> 30) & 0x3) + 1)
4447d3515   Tejun Heo   libata: convert t...
413
  static const struct ata_port_info sil24_port_info[] = {
edb336670   Tejun Heo   [PATCH] SATA: rew...
414
415
  	/* sil_3124 */
  	{
cca3974e4   Jeff Garzik   libata: Grand ren...
416
  		.flags		= SIL24_COMMON_FLAGS | SIL24_NPORTS2FLAG(4) |
37024e8ee   Tejun Heo   [PATCH] sata_sil2...
417
  				  SIL24_FLAG_PCIX_IRQ_WOC,
14bdef982   Erik Inge Bolsø   [libata] convert ...
418
419
420
  		.pio_mask	= ATA_PIO4,
  		.mwdma_mask	= ATA_MWDMA2,
  		.udma_mask	= ATA_UDMA5,
edb336670   Tejun Heo   [PATCH] SATA: rew...
421
422
  		.port_ops	= &sil24_ops,
  	},
2e9edbf81   Jeff Garzik   [libata] export a...
423
  	/* sil_3132 */
edb336670   Tejun Heo   [PATCH] SATA: rew...
424
  	{
cca3974e4   Jeff Garzik   libata: Grand ren...
425
  		.flags		= SIL24_COMMON_FLAGS | SIL24_NPORTS2FLAG(2),
14bdef982   Erik Inge Bolsø   [libata] convert ...
426
427
428
  		.pio_mask	= ATA_PIO4,
  		.mwdma_mask	= ATA_MWDMA2,
  		.udma_mask	= ATA_UDMA5,
042c21fd2   Tejun Heo   [libata sata_sil2...
429
430
431
432
  		.port_ops	= &sil24_ops,
  	},
  	/* sil_3131/sil_3531 */
  	{
cca3974e4   Jeff Garzik   libata: Grand ren...
433
  		.flags		= SIL24_COMMON_FLAGS | SIL24_NPORTS2FLAG(1),
14bdef982   Erik Inge Bolsø   [libata] convert ...
434
435
436
  		.pio_mask	= ATA_PIO4,
  		.mwdma_mask	= ATA_MWDMA2,
  		.udma_mask	= ATA_UDMA5,
edb336670   Tejun Heo   [PATCH] SATA: rew...
437
438
439
  		.port_ops	= &sil24_ops,
  	},
  };
aee10a03e   Tejun Heo   [PATCH] sata_sil2...
440
441
442
443
444
445
  static int sil24_tag(int tag)
  {
  	if (unlikely(ata_tag_internal(tag)))
  		return 0;
  	return tag;
  }
350756f6d   Tejun Heo   libata: don't use...
446
447
448
449
450
451
452
453
454
  static unsigned long sil24_port_offset(struct ata_port *ap)
  {
  	return ap->port_no * PORT_REGS_SIZE;
  }
  
  static void __iomem *sil24_port_base(struct ata_port *ap)
  {
  	return ap->host->iomap[SIL24_PORT_BAR] + sil24_port_offset(ap);
  }
cd0d3bbcd   Alan Cox   libata: dev_confi...
455
  static void sil24_dev_config(struct ata_device *dev)
69ad185fa   Tejun Heo   [PATCH] sil24: ad...
456
  {
350756f6d   Tejun Heo   libata: don't use...
457
  	void __iomem *port = sil24_port_base(dev->link->ap);
69ad185fa   Tejun Heo   [PATCH] sil24: ad...
458

6e7846e9c   Tejun Heo   [PATCH] libata: m...
459
  	if (dev->cdb_len == 16)
69ad185fa   Tejun Heo   [PATCH] sil24: ad...
460
461
462
463
  		writel(PORT_CS_CDB16, port + PORT_CTRL_STAT);
  	else
  		writel(PORT_CS_CDB16, port + PORT_CTRL_CLR);
  }
e59f0dad3   Tejun Heo   sata_sil24: repla...
464
  static void sil24_read_tf(struct ata_port *ap, int tag, struct ata_taskfile *tf)
6a575fa96   Tejun Heo   [PATCH] sil24: im...
465
  {
350756f6d   Tejun Heo   libata: don't use...
466
  	void __iomem *port = sil24_port_base(ap);
e59f0dad3   Tejun Heo   sata_sil24: repla...
467
  	struct sil24_prb __iomem *prb;
4b4a5eaed   Al Viro   [PATCH] sata_sil2...
468
  	u8 fis[6 * 4];
6a575fa96   Tejun Heo   [PATCH] sil24: im...
469

e59f0dad3   Tejun Heo   sata_sil24: repla...
470
471
472
  	prb = port + PORT_LRAM + sil24_tag(tag) * PORT_LRAM_SLOT_SZ;
  	memcpy_fromio(fis, prb->fis, sizeof(fis));
  	ata_tf_from_fis(fis, tf);
6a575fa96   Tejun Heo   [PATCH] sil24: im...
473
  }
edb336670   Tejun Heo   [PATCH] SATA: rew...
474
475
476
477
478
479
  static int sil24_scr_map[] = {
  	[SCR_CONTROL]	= 0,
  	[SCR_STATUS]	= 1,
  	[SCR_ERROR]	= 2,
  	[SCR_ACTIVE]	= 3,
  };
82ef04fb4   Tejun Heo   libata: make SCR ...
480
  static int sil24_scr_read(struct ata_link *link, unsigned sc_reg, u32 *val)
edb336670   Tejun Heo   [PATCH] SATA: rew...
481
  {
82ef04fb4   Tejun Heo   libata: make SCR ...
482
  	void __iomem *scr_addr = sil24_port_base(link->ap) + PORT_SCONTROL;
da3dbb17a   Tejun Heo   libata: make ->sc...
483

edb336670   Tejun Heo   [PATCH] SATA: rew...
484
  	if (sc_reg < ARRAY_SIZE(sil24_scr_map)) {
4b4a5eaed   Al Viro   [PATCH] sata_sil2...
485
  		void __iomem *addr;
edb336670   Tejun Heo   [PATCH] SATA: rew...
486
  		addr = scr_addr + sil24_scr_map[sc_reg] * 4;
da3dbb17a   Tejun Heo   libata: make ->sc...
487
488
  		*val = readl(scr_addr + sil24_scr_map[sc_reg] * 4);
  		return 0;
edb336670   Tejun Heo   [PATCH] SATA: rew...
489
  	}
da3dbb17a   Tejun Heo   libata: make ->sc...
490
  	return -EINVAL;
edb336670   Tejun Heo   [PATCH] SATA: rew...
491
  }
82ef04fb4   Tejun Heo   libata: make SCR ...
492
  static int sil24_scr_write(struct ata_link *link, unsigned sc_reg, u32 val)
edb336670   Tejun Heo   [PATCH] SATA: rew...
493
  {
82ef04fb4   Tejun Heo   libata: make SCR ...
494
  	void __iomem *scr_addr = sil24_port_base(link->ap) + PORT_SCONTROL;
da3dbb17a   Tejun Heo   libata: make ->sc...
495

edb336670   Tejun Heo   [PATCH] SATA: rew...
496
  	if (sc_reg < ARRAY_SIZE(sil24_scr_map)) {
4b4a5eaed   Al Viro   [PATCH] sata_sil2...
497
  		void __iomem *addr;
edb336670   Tejun Heo   [PATCH] SATA: rew...
498
499
  		addr = scr_addr + sil24_scr_map[sc_reg] * 4;
  		writel(val, scr_addr + sil24_scr_map[sc_reg] * 4);
da3dbb17a   Tejun Heo   libata: make ->sc...
500
  		return 0;
edb336670   Tejun Heo   [PATCH] SATA: rew...
501
  	}
da3dbb17a   Tejun Heo   libata: make ->sc...
502
  	return -EINVAL;
edb336670   Tejun Heo   [PATCH] SATA: rew...
503
  }
238180343   Tejun Heo   sata_sil24: imple...
504
505
  static void sil24_config_port(struct ata_port *ap)
  {
350756f6d   Tejun Heo   libata: don't use...
506
  	void __iomem *port = sil24_port_base(ap);
238180343   Tejun Heo   sata_sil24: imple...
507
508
509
510
511
512
513
514
  
  	/* configure IRQ WoC */
  	if (ap->flags & SIL24_FLAG_PCIX_IRQ_WOC)
  		writel(PORT_CS_IRQ_WOC, port + PORT_CTRL_STAT);
  	else
  		writel(PORT_CS_IRQ_WOC, port + PORT_CTRL_CLR);
  
  	/* zero error counters. */
7a4f876b8   Colin Tuckley   sata_sil24: fix k...
515
516
517
518
519
520
  	writew(0x8000, port + PORT_DECODE_ERR_THRESH);
  	writew(0x8000, port + PORT_CRC_ERR_THRESH);
  	writew(0x8000, port + PORT_HSHK_ERR_THRESH);
  	writew(0x0000, port + PORT_DECODE_ERR_CNT);
  	writew(0x0000, port + PORT_CRC_ERR_CNT);
  	writew(0x0000, port + PORT_HSHK_ERR_CNT);
238180343   Tejun Heo   sata_sil24: imple...
521
522
523
524
525
526
527
  
  	/* always use 64bit activation */
  	writel(PORT_CS_32BIT_ACTV, port + PORT_CTRL_CLR);
  
  	/* clear port multiplier enable and resume bits */
  	writel(PORT_CS_PMP_EN | PORT_CS_PMP_RESUME, port + PORT_CTRL_CLR);
  }
3454dc692   Tejun Heo   sata_sil24: imple...
528
529
  static void sil24_config_pmp(struct ata_port *ap, int attached)
  {
350756f6d   Tejun Heo   libata: don't use...
530
  	void __iomem *port = sil24_port_base(ap);
3454dc692   Tejun Heo   sata_sil24: imple...
531
532
533
534
535
536
537
538
539
  
  	if (attached)
  		writel(PORT_CS_PMP_EN, port + PORT_CTRL_STAT);
  	else
  		writel(PORT_CS_PMP_EN, port + PORT_CTRL_CLR);
  }
  
  static void sil24_clear_pmp(struct ata_port *ap)
  {
350756f6d   Tejun Heo   libata: don't use...
540
  	void __iomem *port = sil24_port_base(ap);
3454dc692   Tejun Heo   sata_sil24: imple...
541
542
543
544
545
546
547
548
549
550
551
  	int i;
  
  	writel(PORT_CS_PMP_RESUME, port + PORT_CTRL_CLR);
  
  	for (i = 0; i < SATA_PMP_MAX_PORTS; i++) {
  		void __iomem *pmp_base = port + PORT_PMP + i * PORT_PMP_SIZE;
  
  		writel(0, pmp_base + PORT_PMP_STATUS);
  		writel(0, pmp_base + PORT_PMP_QACTIVE);
  	}
  }
b5bc421c9   Tejun Heo   [PATCH] sata_sil2...
552
553
  static int sil24_init_port(struct ata_port *ap)
  {
350756f6d   Tejun Heo   libata: don't use...
554
  	void __iomem *port = sil24_port_base(ap);
238180343   Tejun Heo   sata_sil24: imple...
555
  	struct sil24_port_priv *pp = ap->private_data;
b5bc421c9   Tejun Heo   [PATCH] sata_sil2...
556
  	u32 tmp;
3454dc692   Tejun Heo   sata_sil24: imple...
557
  	/* clear PMP error status */
071f44b1d   Tejun Heo   libata: implement...
558
  	if (sata_pmp_attached(ap))
3454dc692   Tejun Heo   sata_sil24: imple...
559
  		sil24_clear_pmp(ap);
b5bc421c9   Tejun Heo   [PATCH] sata_sil2...
560
  	writel(PORT_CS_INIT, port + PORT_CTRL_STAT);
97750cebb   Tejun Heo   libata: add @ap t...
561
  	ata_wait_register(ap, port + PORT_CTRL_STAT,
b5bc421c9   Tejun Heo   [PATCH] sata_sil2...
562
  			  PORT_CS_INIT, PORT_CS_INIT, 10, 100);
97750cebb   Tejun Heo   libata: add @ap t...
563
  	tmp = ata_wait_register(ap, port + PORT_CTRL_STAT,
b5bc421c9   Tejun Heo   [PATCH] sata_sil2...
564
  				PORT_CS_RDY, 0, 10, 100);
238180343   Tejun Heo   sata_sil24: imple...
565
566
  	if ((tmp & (PORT_CS_INIT | PORT_CS_RDY)) != PORT_CS_RDY) {
  		pp->do_port_rst = 1;
cf4806265   Tejun Heo   libata: prefer ha...
567
  		ap->link.eh_context.i.action |= ATA_EH_RESET;
b5bc421c9   Tejun Heo   [PATCH] sata_sil2...
568
  		return -EIO;
238180343   Tejun Heo   sata_sil24: imple...
569
  	}
b5bc421c9   Tejun Heo   [PATCH] sata_sil2...
570
571
  	return 0;
  }
37b99cba8   Tejun Heo   sata_sil24: separ...
572
573
574
575
  static int sil24_exec_polled_cmd(struct ata_port *ap, int pmp,
  				 const struct ata_taskfile *tf,
  				 int is_cmd, u32 ctrl,
  				 unsigned long timeout_msec)
edb336670   Tejun Heo   [PATCH] SATA: rew...
576
  {
350756f6d   Tejun Heo   libata: don't use...
577
  	void __iomem *port = sil24_port_base(ap);
ca45160db   Tejun Heo   [PATCH] sil24: us...
578
  	struct sil24_port_priv *pp = ap->private_data;
69ad185fa   Tejun Heo   [PATCH] sil24: ad...
579
  	struct sil24_prb *prb = &pp->cmd_block[0].ata.prb;
ca45160db   Tejun Heo   [PATCH] sil24: us...
580
  	dma_addr_t paddr = pp->cmd_block_dma;
37b99cba8   Tejun Heo   sata_sil24: separ...
581
582
583
584
585
586
587
588
589
  	u32 irq_enabled, irq_mask, irq_stat;
  	int rc;
  
  	prb->ctrl = cpu_to_le16(ctrl);
  	ata_tf_to_fis(tf, pmp, is_cmd, prb->fis);
  
  	/* temporarily plug completion and error interrupts */
  	irq_enabled = readl(port + PORT_IRQ_ENABLE_SET);
  	writel(PORT_IRQ_COMPLETE | PORT_IRQ_ERROR, port + PORT_IRQ_ENABLE_CLR);
108234529   Catalin Marinas   sata_sil24: Use m...
590
591
592
593
594
  	/*
  	 * The barrier is required to ensure that writes to cmd_block reach
  	 * the memory before the write to PORT_CMD_ACTIVATE.
  	 */
  	wmb();
37b99cba8   Tejun Heo   sata_sil24: separ...
595
596
597
598
  	writel((u32)paddr, port + PORT_CMD_ACTIVATE);
  	writel((u64)paddr >> 32, port + PORT_CMD_ACTIVATE + 4);
  
  	irq_mask = (PORT_IRQ_COMPLETE | PORT_IRQ_ERROR) << PORT_IRQ_RAW_SHIFT;
97750cebb   Tejun Heo   libata: add @ap t...
599
  	irq_stat = ata_wait_register(ap, port + PORT_IRQ_STAT, irq_mask, 0x0,
37b99cba8   Tejun Heo   sata_sil24: separ...
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
  				     10, timeout_msec);
  
  	writel(irq_mask, port + PORT_IRQ_STAT); /* clear IRQs */
  	irq_stat >>= PORT_IRQ_RAW_SHIFT;
  
  	if (irq_stat & PORT_IRQ_COMPLETE)
  		rc = 0;
  	else {
  		/* force port into known state */
  		sil24_init_port(ap);
  
  		if (irq_stat & PORT_IRQ_ERROR)
  			rc = -EIO;
  		else
  			rc = -EBUSY;
  	}
  
  	/* restore IRQ enabled */
  	writel(irq_enabled, port + PORT_IRQ_ENABLE_SET);
  
  	return rc;
  }
071f44b1d   Tejun Heo   libata: implement...
622
623
  static int sil24_softreset(struct ata_link *link, unsigned int *class,
  			   unsigned long deadline)
37b99cba8   Tejun Heo   sata_sil24: separ...
624
  {
cc0680a58   Tejun Heo   libata-link: link...
625
  	struct ata_port *ap = link->ap;
071f44b1d   Tejun Heo   libata: implement...
626
  	int pmp = sata_srst_pmp(link);
37b99cba8   Tejun Heo   sata_sil24: separ...
627
  	unsigned long timeout_msec = 0;
e59f0dad3   Tejun Heo   sata_sil24: repla...
628
  	struct ata_taskfile tf;
643be977f   Tejun Heo   [PATCH] sata_sil2...
629
  	const char *reason;
37b99cba8   Tejun Heo   sata_sil24: separ...
630
  	int rc;
ca45160db   Tejun Heo   [PATCH] sil24: us...
631

07b734702   Tejun Heo   [PATCH] sata_sil2...
632
633
  	DPRINTK("ENTER
  ");
2555d6c26   Tejun Heo   [PATCH] sata_sil2...
634
635
  	/* put the port into known state */
  	if (sil24_init_port(ap)) {
5796d1c4c   Jeff Garzik   [libata] Address ...
636
  		reason = "port not ready";
2555d6c26   Tejun Heo   [PATCH] sata_sil2...
637
638
  		goto err;
  	}
0eaa6058a   Tejun Heo   [PATCH] sata_sil2...
639
  	/* do SRST */
37b99cba8   Tejun Heo   sata_sil24: separ...
640
641
  	if (time_after(deadline, jiffies))
  		timeout_msec = jiffies_to_msecs(deadline - jiffies);
ca45160db   Tejun Heo   [PATCH] sil24: us...
642

cc0680a58   Tejun Heo   libata-link: link...
643
  	ata_tf_init(link->device, &tf);	/* doesn't really matter */
975530e8a   Tejun Heo   sata_sil24: separ...
644
645
  	rc = sil24_exec_polled_cmd(ap, pmp, &tf, 0, PRB_CTRL_SRST,
  				   timeout_msec);
37b99cba8   Tejun Heo   sata_sil24: separ...
646
647
648
649
650
  	if (rc == -EBUSY) {
  		reason = "timeout";
  		goto err;
  	} else if (rc) {
  		reason = "SRST command error";
643be977f   Tejun Heo   [PATCH] sata_sil2...
651
  		goto err;
07b734702   Tejun Heo   [PATCH] sata_sil2...
652
  	}
10d996ad1   Tejun Heo   [PATCH] sata_sil2...
653

e59f0dad3   Tejun Heo   sata_sil24: repla...
654
655
  	sil24_read_tf(ap, 0, &tf);
  	*class = ata_dev_classify(&tf);
10d996ad1   Tejun Heo   [PATCH] sata_sil2...
656

07b734702   Tejun Heo   [PATCH] sata_sil2...
657
658
  	DPRINTK("EXIT, class=%u
  ", *class);
ca45160db   Tejun Heo   [PATCH] sil24: us...
659
  	return 0;
643be977f   Tejun Heo   [PATCH] sata_sil2...
660
661
  
   err:
a9a79dfec   Joe Perches   ata: Convert ata_...
662
663
  	ata_link_err(link, "softreset failed (%s)
  ", reason);
643be977f   Tejun Heo   [PATCH] sata_sil2...
664
  	return -EIO;
ca45160db   Tejun Heo   [PATCH] sil24: us...
665
  }
cc0680a58   Tejun Heo   libata-link: link...
666
  static int sil24_hardreset(struct ata_link *link, unsigned int *class,
d4b2bab4f   Tejun Heo   libata: add deadl...
667
  			   unsigned long deadline)
489ff4c7d   Tejun Heo   [PATCH] sata_sil2...
668
  {
cc0680a58   Tejun Heo   libata-link: link...
669
  	struct ata_port *ap = link->ap;
350756f6d   Tejun Heo   libata: don't use...
670
  	void __iomem *port = sil24_port_base(ap);
238180343   Tejun Heo   sata_sil24: imple...
671
672
  	struct sil24_port_priv *pp = ap->private_data;
  	int did_port_rst = 0;
ecc2e2b9c   Tejun Heo   [PATCH] sata_sil2...
673
  	const char *reason;
e8e008e7b   Tejun Heo   [PATCH] sata_sil2...
674
  	int tout_msec, rc;
ecc2e2b9c   Tejun Heo   [PATCH] sata_sil2...
675
  	u32 tmp;
238180343   Tejun Heo   sata_sil24: imple...
676
677
678
679
680
   retry:
  	/* Sometimes, DEV_RST is not enough to recover the controller.
  	 * This happens often after PM DMA CS errata.
  	 */
  	if (pp->do_port_rst) {
a9a79dfec   Joe Perches   ata: Convert ata_...
681
682
683
  		ata_port_warn(ap,
  			      "controller in dubious state, performing PORT_RST
  ");
238180343   Tejun Heo   sata_sil24: imple...
684
685
  
  		writel(PORT_CS_PORT_RST, port + PORT_CTRL_STAT);
97750cebb   Tejun Heo   libata: add @ap t...
686
  		ata_msleep(ap, 10);
238180343   Tejun Heo   sata_sil24: imple...
687
  		writel(PORT_CS_PORT_RST, port + PORT_CTRL_CLR);
97750cebb   Tejun Heo   libata: add @ap t...
688
  		ata_wait_register(ap, port + PORT_CTRL_STAT, PORT_CS_RDY, 0,
238180343   Tejun Heo   sata_sil24: imple...
689
690
691
692
693
694
695
696
697
  				  10, 5000);
  
  		/* restore port configuration */
  		sil24_config_port(ap);
  		sil24_config_pmp(ap, ap->nr_pmp_links);
  
  		pp->do_port_rst = 0;
  		did_port_rst = 1;
  	}
ecc2e2b9c   Tejun Heo   [PATCH] sata_sil2...
698
  	/* sil24 does the right thing(tm) without any protection */
cc0680a58   Tejun Heo   libata-link: link...
699
  	sata_set_spd(link);
ecc2e2b9c   Tejun Heo   [PATCH] sata_sil2...
700
701
  
  	tout_msec = 100;
cc0680a58   Tejun Heo   libata-link: link...
702
  	if (ata_link_online(link))
ecc2e2b9c   Tejun Heo   [PATCH] sata_sil2...
703
704
705
  		tout_msec = 5000;
  
  	writel(PORT_CS_DEV_RST, port + PORT_CTRL_STAT);
97750cebb   Tejun Heo   libata: add @ap t...
706
  	tmp = ata_wait_register(ap, port + PORT_CTRL_STAT,
5796d1c4c   Jeff Garzik   [libata] Address ...
707
708
  				PORT_CS_DEV_RST, PORT_CS_DEV_RST, 10,
  				tout_msec);
ecc2e2b9c   Tejun Heo   [PATCH] sata_sil2...
709

e8e008e7b   Tejun Heo   [PATCH] sata_sil2...
710
711
  	/* SStatus oscillates between zero and valid status after
  	 * DEV_RST, debounce it.
ecc2e2b9c   Tejun Heo   [PATCH] sata_sil2...
712
  	 */
cc0680a58   Tejun Heo   libata-link: link...
713
  	rc = sata_link_debounce(link, sata_deb_timing_long, deadline);
e8e008e7b   Tejun Heo   [PATCH] sata_sil2...
714
715
716
717
  	if (rc) {
  		reason = "PHY debouncing failed";
  		goto err;
  	}
ecc2e2b9c   Tejun Heo   [PATCH] sata_sil2...
718
719
  
  	if (tmp & PORT_CS_DEV_RST) {
cc0680a58   Tejun Heo   libata-link: link...
720
  		if (ata_link_offline(link))
ecc2e2b9c   Tejun Heo   [PATCH] sata_sil2...
721
722
723
724
  			return 0;
  		reason = "link not ready";
  		goto err;
  	}
e8e008e7b   Tejun Heo   [PATCH] sata_sil2...
725
726
727
728
729
  	/* Sil24 doesn't store signature FIS after hardreset, so we
  	 * can't wait for BSY to clear.  Some devices take a long time
  	 * to get ready and those devices will choke if we don't wait
  	 * for BSY clearance here.  Tell libata to perform follow-up
  	 * softreset.
ecc2e2b9c   Tejun Heo   [PATCH] sata_sil2...
730
  	 */
e8e008e7b   Tejun Heo   [PATCH] sata_sil2...
731
  	return -EAGAIN;
ecc2e2b9c   Tejun Heo   [PATCH] sata_sil2...
732
733
  
   err:
238180343   Tejun Heo   sata_sil24: imple...
734
735
736
737
  	if (!did_port_rst) {
  		pp->do_port_rst = 1;
  		goto retry;
  	}
a9a79dfec   Joe Perches   ata: Convert ata_...
738
739
  	ata_link_err(link, "hardreset failed (%s)
  ", reason);
ecc2e2b9c   Tejun Heo   [PATCH] sata_sil2...
740
  	return -EIO;
489ff4c7d   Tejun Heo   [PATCH] sata_sil2...
741
  }
edb336670   Tejun Heo   [PATCH] SATA: rew...
742
  static inline void sil24_fill_sg(struct ata_queued_cmd *qc,
69ad185fa   Tejun Heo   [PATCH] sil24: ad...
743
  				 struct sil24_sge *sge)
edb336670   Tejun Heo   [PATCH] SATA: rew...
744
  {
972c26bdd   Jeff Garzik   libata: add ata_s...
745
  	struct scatterlist *sg;
3be6cbd73   Jeff Garzik   [libata] kill ata...
746
  	struct sil24_sge *last_sge = NULL;
ff2aeb1eb   Tejun Heo   libata: convert t...
747
  	unsigned int si;
edb336670   Tejun Heo   [PATCH] SATA: rew...
748

ff2aeb1eb   Tejun Heo   libata: convert t...
749
  	for_each_sg(qc->sg, sg, qc->n_elem, si) {
edb336670   Tejun Heo   [PATCH] SATA: rew...
750
751
  		sge->addr = cpu_to_le64(sg_dma_address(sg));
  		sge->cnt = cpu_to_le32(sg_dma_len(sg));
3be6cbd73   Jeff Garzik   [libata] kill ata...
752
753
754
  		sge->flags = 0;
  
  		last_sge = sge;
972c26bdd   Jeff Garzik   libata: add ata_s...
755
  		sge++;
edb336670   Tejun Heo   [PATCH] SATA: rew...
756
  	}
3be6cbd73   Jeff Garzik   [libata] kill ata...
757

ff2aeb1eb   Tejun Heo   libata: convert t...
758
  	last_sge->flags = cpu_to_le32(SGE_TRM);
edb336670   Tejun Heo   [PATCH] SATA: rew...
759
  }
3454dc692   Tejun Heo   sata_sil24: imple...
760
761
762
763
764
  static int sil24_qc_defer(struct ata_queued_cmd *qc)
  {
  	struct ata_link *link = qc->dev->link;
  	struct ata_port *ap = link->ap;
  	u8 prot = qc->tf.protocol;
13cc546be   Gwendal Grignou   sata_sil24: preve...
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
  
  	/*
  	 * There is a bug in the chip:
  	 * Port LRAM Causes the PRB/SGT Data to be Corrupted
  	 * If the host issues a read request for LRAM and SActive registers
  	 * while active commands are available in the port, PRB/SGT data in
  	 * the LRAM can become corrupted. This issue applies only when
  	 * reading from, but not writing to, the LRAM.
  	 *
  	 * Therefore, reading LRAM when there is no particular error [and
  	 * other commands may be outstanding] is prohibited.
  	 *
  	 * To avoid this bug there are two situations where a command must run
  	 * exclusive of any other commands on the port:
  	 *
  	 * - ATAPI commands which check the sense data
  	 * - Passthrough ATA commands which always have ATA_QCFLAG_RESULT_TF
  	 *   set.
  	 *
   	 */
405e66b38   Tejun Heo   libata: implement...
785
  	int is_excl = (ata_is_atapi(prot) ||
13cc546be   Gwendal Grignou   sata_sil24: preve...
786
  		       (qc->flags & ATA_QCFLAG_RESULT_TF));
3454dc692   Tejun Heo   sata_sil24: imple...
787
788
789
790
791
792
793
  	if (unlikely(ap->excl_link)) {
  		if (link == ap->excl_link) {
  			if (ap->nr_active_links)
  				return ATA_DEFER_PORT;
  			qc->flags |= ATA_QCFLAG_CLEAR_EXCL;
  		} else
  			return ATA_DEFER_PORT;
13cc546be   Gwendal Grignou   sata_sil24: preve...
794
  	} else if (unlikely(is_excl)) {
3454dc692   Tejun Heo   sata_sil24: imple...
795
796
797
798
799
800
801
802
  		ap->excl_link = link;
  		if (ap->nr_active_links)
  			return ATA_DEFER_PORT;
  		qc->flags |= ATA_QCFLAG_CLEAR_EXCL;
  	}
  
  	return ata_std_qc_defer(qc);
  }
edb336670   Tejun Heo   [PATCH] SATA: rew...
803
804
805
806
  static void sil24_qc_prep(struct ata_queued_cmd *qc)
  {
  	struct ata_port *ap = qc->ap;
  	struct sil24_port_priv *pp = ap->private_data;
aee10a03e   Tejun Heo   [PATCH] sata_sil2...
807
  	union sil24_cmd_block *cb;
69ad185fa   Tejun Heo   [PATCH] sil24: ad...
808
809
  	struct sil24_prb *prb;
  	struct sil24_sge *sge;
bad28a37f   Tejun Heo   [PATCH] sata_sil2...
810
  	u16 ctrl = 0;
edb336670   Tejun Heo   [PATCH] SATA: rew...
811

aee10a03e   Tejun Heo   [PATCH] sata_sil2...
812
  	cb = &pp->cmd_block[sil24_tag(qc->tag)];
405e66b38   Tejun Heo   libata: implement...
813
  	if (!ata_is_atapi(qc->tf.protocol)) {
69ad185fa   Tejun Heo   [PATCH] sil24: ad...
814
815
  		prb = &cb->ata.prb;
  		sge = cb->ata.sge;
4f1a0ee11   Robert Hancock   sata_sil24: alway...
816
817
818
819
820
821
822
823
824
825
826
  		if (ata_is_data(qc->tf.protocol)) {
  			u16 prot = 0;
  			ctrl = PRB_CTRL_PROTOCOL;
  			if (ata_is_ncq(qc->tf.protocol))
  				prot |= PRB_PROT_NCQ;
  			if (qc->tf.flags & ATA_TFLAG_WRITE)
  				prot |= PRB_PROT_WRITE;
  			else
  				prot |= PRB_PROT_READ;
  			prb->prot = cpu_to_le16(prot);
  		}
405e66b38   Tejun Heo   libata: implement...
827
  	} else {
69ad185fa   Tejun Heo   [PATCH] sil24: ad...
828
829
  		prb = &cb->atapi.prb;
  		sge = cb->atapi.sge;
14e45c15e   Dan Carpenter   sata_sil24: memse...
830
  		memset(cb->atapi.cdb, 0, sizeof(cb->atapi.cdb));
6e7846e9c   Tejun Heo   [PATCH] libata: m...
831
  		memcpy(cb->atapi.cdb, qc->cdb, qc->dev->cdb_len);
69ad185fa   Tejun Heo   [PATCH] sil24: ad...
832

405e66b38   Tejun Heo   libata: implement...
833
  		if (ata_is_data(qc->tf.protocol)) {
69ad185fa   Tejun Heo   [PATCH] sil24: ad...
834
  			if (qc->tf.flags & ATA_TFLAG_WRITE)
bad28a37f   Tejun Heo   [PATCH] sata_sil2...
835
  				ctrl = PRB_CTRL_PACKET_WRITE;
69ad185fa   Tejun Heo   [PATCH] sil24: ad...
836
  			else
bad28a37f   Tejun Heo   [PATCH] sata_sil2...
837
838
  				ctrl = PRB_CTRL_PACKET_READ;
  		}
edb336670   Tejun Heo   [PATCH] SATA: rew...
839
  	}
bad28a37f   Tejun Heo   [PATCH] sata_sil2...
840
  	prb->ctrl = cpu_to_le16(ctrl);
3454dc692   Tejun Heo   sata_sil24: imple...
841
  	ata_tf_to_fis(&qc->tf, qc->dev->link->pmp, 1, prb->fis);
edb336670   Tejun Heo   [PATCH] SATA: rew...
842
843
  
  	if (qc->flags & ATA_QCFLAG_DMAMAP)
69ad185fa   Tejun Heo   [PATCH] sil24: ad...
844
  		sil24_fill_sg(qc, sge);
edb336670   Tejun Heo   [PATCH] SATA: rew...
845
  }
9a3d9eb01   Tejun Heo   [PATCH] libata: r...
846
  static unsigned int sil24_qc_issue(struct ata_queued_cmd *qc)
edb336670   Tejun Heo   [PATCH] SATA: rew...
847
848
849
  {
  	struct ata_port *ap = qc->ap;
  	struct sil24_port_priv *pp = ap->private_data;
350756f6d   Tejun Heo   libata: don't use...
850
  	void __iomem *port = sil24_port_base(ap);
aee10a03e   Tejun Heo   [PATCH] sata_sil2...
851
852
853
  	unsigned int tag = sil24_tag(qc->tag);
  	dma_addr_t paddr;
  	void __iomem *activate;
edb336670   Tejun Heo   [PATCH] SATA: rew...
854

aee10a03e   Tejun Heo   [PATCH] sata_sil2...
855
856
  	paddr = pp->cmd_block_dma + tag * sizeof(*pp->cmd_block);
  	activate = port + PORT_CMD_ACTIVATE + tag * 8;
108234529   Catalin Marinas   sata_sil24: Use m...
857
858
859
860
861
  	/*
  	 * The barrier is required to ensure that writes to cmd_block reach
  	 * the memory before the write to PORT_CMD_ACTIVATE.
  	 */
  	wmb();
aee10a03e   Tejun Heo   [PATCH] sata_sil2...
862
863
  	writel((u32)paddr, activate);
  	writel((u64)paddr >> 32, activate + 4);
26ec634c3   Tejun Heo   [PATCH] sata_sil2...
864

edb336670   Tejun Heo   [PATCH] SATA: rew...
865
866
  	return 0;
  }
79f97dadf   Tejun Heo   libata: drop @fin...
867
868
869
870
871
  static bool sil24_qc_fill_rtf(struct ata_queued_cmd *qc)
  {
  	sil24_read_tf(qc->ap, qc->tag, &qc->result_tf);
  	return true;
  }
3454dc692   Tejun Heo   sata_sil24: imple...
872
873
  static void sil24_pmp_attach(struct ata_port *ap)
  {
906c1ff44   Tejun Heo   sata_sil24: don't...
874
  	u32 *gscr = ap->link.device->gscr;
3454dc692   Tejun Heo   sata_sil24: imple...
875
876
  	sil24_config_pmp(ap, 1);
  	sil24_init_port(ap);
906c1ff44   Tejun Heo   sata_sil24: don't...
877
878
879
  
  	if (sata_pmp_gscr_vendor(gscr) == 0x11ab &&
  	    sata_pmp_gscr_devid(gscr) == 0x4140) {
a9a79dfec   Joe Perches   ata: Convert ata_...
880
  		ata_port_info(ap,
906c1ff44   Tejun Heo   sata_sil24: don't...
881
882
883
884
  			"disabling NCQ support due to sil24-mv4140 quirk
  ");
  		ap->flags &= ~ATA_FLAG_NCQ;
  	}
3454dc692   Tejun Heo   sata_sil24: imple...
885
886
887
888
889
890
  }
  
  static void sil24_pmp_detach(struct ata_port *ap)
  {
  	sil24_init_port(ap);
  	sil24_config_pmp(ap, 0);
906c1ff44   Tejun Heo   sata_sil24: don't...
891
892
  
  	ap->flags |= ATA_FLAG_NCQ;
3454dc692   Tejun Heo   sata_sil24: imple...
893
  }
3454dc692   Tejun Heo   sata_sil24: imple...
894
895
896
897
898
899
900
  static int sil24_pmp_hardreset(struct ata_link *link, unsigned int *class,
  			       unsigned long deadline)
  {
  	int rc;
  
  	rc = sil24_init_port(link->ap);
  	if (rc) {
a9a79dfec   Joe Perches   ata: Convert ata_...
901
902
  		ata_link_err(link, "hardreset failed (port not ready)
  ");
3454dc692   Tejun Heo   sata_sil24: imple...
903
904
  		return rc;
  	}
5958e3025   Tejun Heo   libata: move PMP ...
905
  	return sata_std_hardreset(link, class, deadline);
3454dc692   Tejun Heo   sata_sil24: imple...
906
  }
88ce7550c   Tejun Heo   [PATCH] sata_sil2...
907
  static void sil24_freeze(struct ata_port *ap)
7d1ce682d   Tejun Heo   [PATCH] sil24: ad...
908
  {
350756f6d   Tejun Heo   libata: don't use...
909
  	void __iomem *port = sil24_port_base(ap);
7d1ce682d   Tejun Heo   [PATCH] sil24: ad...
910

88ce7550c   Tejun Heo   [PATCH] sata_sil2...
911
912
913
914
  	/* Port-wide IRQ mask in HOST_CTRL doesn't really work, clear
  	 * PORT_IRQ_ENABLE instead.
  	 */
  	writel(0xffff, port + PORT_IRQ_ENABLE_CLR);
7d1ce682d   Tejun Heo   [PATCH] sil24: ad...
915
  }
88ce7550c   Tejun Heo   [PATCH] sata_sil2...
916
  static void sil24_thaw(struct ata_port *ap)
edb336670   Tejun Heo   [PATCH] SATA: rew...
917
  {
350756f6d   Tejun Heo   libata: don't use...
918
  	void __iomem *port = sil24_port_base(ap);
edb336670   Tejun Heo   [PATCH] SATA: rew...
919
  	u32 tmp;
88ce7550c   Tejun Heo   [PATCH] sata_sil2...
920
921
922
  	/* clear IRQ */
  	tmp = readl(port + PORT_IRQ_STAT);
  	writel(tmp, port + PORT_IRQ_STAT);
edb336670   Tejun Heo   [PATCH] SATA: rew...
923

88ce7550c   Tejun Heo   [PATCH] sata_sil2...
924
925
  	/* turn IRQ back on */
  	writel(DEF_PORT_IRQ, port + PORT_IRQ_ENABLE_SET);
edb336670   Tejun Heo   [PATCH] SATA: rew...
926
  }
88ce7550c   Tejun Heo   [PATCH] sata_sil2...
927
  static void sil24_error_intr(struct ata_port *ap)
8746618d4   Tejun Heo   [PATCH] sil24: mo...
928
  {
350756f6d   Tejun Heo   libata: don't use...
929
  	void __iomem *port = sil24_port_base(ap);
e59f0dad3   Tejun Heo   sata_sil24: repla...
930
  	struct sil24_port_priv *pp = ap->private_data;
3454dc692   Tejun Heo   sata_sil24: imple...
931
932
933
934
  	struct ata_queued_cmd *qc = NULL;
  	struct ata_link *link;
  	struct ata_eh_info *ehi;
  	int abort = 0, freeze = 0;
88ce7550c   Tejun Heo   [PATCH] sata_sil2...
935
  	u32 irq_stat;
8746618d4   Tejun Heo   [PATCH] sil24: mo...
936

88ce7550c   Tejun Heo   [PATCH] sata_sil2...
937
  	/* on error, we need to clear IRQ explicitly */
8746618d4   Tejun Heo   [PATCH] sil24: mo...
938
  	irq_stat = readl(port + PORT_IRQ_STAT);
88ce7550c   Tejun Heo   [PATCH] sata_sil2...
939
  	writel(irq_stat, port + PORT_IRQ_STAT);
ad6e90f6d   Tejun Heo   [PATCH] sil24: ig...
940

88ce7550c   Tejun Heo   [PATCH] sata_sil2...
941
  	/* first, analyze and record host port events */
3454dc692   Tejun Heo   sata_sil24: imple...
942
943
  	link = &ap->link;
  	ehi = &link->eh_info;
88ce7550c   Tejun Heo   [PATCH] sata_sil2...
944
  	ata_ehi_clear_desc(ehi);
ad6e90f6d   Tejun Heo   [PATCH] sil24: ig...
945

88ce7550c   Tejun Heo   [PATCH] sata_sil2...
946
  	ata_ehi_push_desc(ehi, "irq_stat 0x%08x", irq_stat);
8746618d4   Tejun Heo   [PATCH] sil24: mo...
947

854c73a2f   Tejun Heo   libata: misc upda...
948
  	if (irq_stat & PORT_IRQ_SDB_NOTIFY) {
854c73a2f   Tejun Heo   libata: misc upda...
949
  		ata_ehi_push_desc(ehi, "SDB notify");
7d77b2470   Tejun Heo   libata-pmp-prep: ...
950
  		sata_async_notification(ap);
854c73a2f   Tejun Heo   libata: misc upda...
951
  	}
0542925b2   Tejun Heo   [PATCH] sata_sil2...
952
953
  	if (irq_stat & (PORT_IRQ_PHYRDY_CHG | PORT_IRQ_DEV_XCHG)) {
  		ata_ehi_hotplugged(ehi);
b64bbc39f   Tejun Heo   libata: improve E...
954
955
956
  		ata_ehi_push_desc(ehi, "%s",
  				  irq_stat & PORT_IRQ_PHYRDY_CHG ?
  				  "PHY RDY changed" : "device exchanged");
88ce7550c   Tejun Heo   [PATCH] sata_sil2...
957
  		freeze = 1;
6a575fa96   Tejun Heo   [PATCH] sil24: im...
958
  	}
88ce7550c   Tejun Heo   [PATCH] sata_sil2...
959
960
  	if (irq_stat & PORT_IRQ_UNK_FIS) {
  		ehi->err_mask |= AC_ERR_HSM;
cf4806265   Tejun Heo   libata: prefer ha...
961
  		ehi->action |= ATA_EH_RESET;
b64bbc39f   Tejun Heo   libata: improve E...
962
  		ata_ehi_push_desc(ehi, "unknown FIS");
88ce7550c   Tejun Heo   [PATCH] sata_sil2...
963
964
965
966
967
  		freeze = 1;
  	}
  
  	/* deal with command error */
  	if (irq_stat & PORT_IRQ_ERROR) {
fc8cc1d5b   Joe Perches   sata_sil24: Use c...
968
  		const struct sil24_cerr_info *ci = NULL;
88ce7550c   Tejun Heo   [PATCH] sata_sil2...
969
  		unsigned int err_mask = 0, action = 0;
3454dc692   Tejun Heo   sata_sil24: imple...
970
971
972
973
974
975
976
977
978
979
980
981
  		u32 context, cerr;
  		int pmp;
  
  		abort = 1;
  
  		/* DMA Context Switch Failure in Port Multiplier Mode
  		 * errata.  If we have active commands to 3 or more
  		 * devices, any error condition on active devices can
  		 * corrupt DMA context switching.
  		 */
  		if (ap->nr_active_links >= 3) {
  			ehi->err_mask |= AC_ERR_OTHER;
cf4806265   Tejun Heo   libata: prefer ha...
982
  			ehi->action |= ATA_EH_RESET;
3454dc692   Tejun Heo   sata_sil24: imple...
983
  			ata_ehi_push_desc(ehi, "PMP DMA CS errata");
238180343   Tejun Heo   sata_sil24: imple...
984
  			pp->do_port_rst = 1;
3454dc692   Tejun Heo   sata_sil24: imple...
985
986
987
988
  			freeze = 1;
  		}
  
  		/* find out the offending link and qc */
071f44b1d   Tejun Heo   libata: implement...
989
  		if (sata_pmp_attached(ap)) {
3454dc692   Tejun Heo   sata_sil24: imple...
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
  			context = readl(port + PORT_CONTEXT);
  			pmp = (context >> 5) & 0xf;
  
  			if (pmp < ap->nr_pmp_links) {
  				link = &ap->pmp_link[pmp];
  				ehi = &link->eh_info;
  				qc = ata_qc_from_tag(ap, link->active_tag);
  
  				ata_ehi_clear_desc(ehi);
  				ata_ehi_push_desc(ehi, "irq_stat 0x%08x",
  						  irq_stat);
  			} else {
  				err_mask |= AC_ERR_HSM;
cf4806265   Tejun Heo   libata: prefer ha...
1003
  				action |= ATA_EH_RESET;
3454dc692   Tejun Heo   sata_sil24: imple...
1004
1005
1006
1007
  				freeze = 1;
  			}
  		} else
  			qc = ata_qc_from_tag(ap, link->active_tag);
88ce7550c   Tejun Heo   [PATCH] sata_sil2...
1008
1009
1010
1011
1012
1013
1014
1015
1016
  
  		/* analyze CMD_ERR */
  		cerr = readl(port + PORT_CMD_ERR);
  		if (cerr < ARRAY_SIZE(sil24_cerr_db))
  			ci = &sil24_cerr_db[cerr];
  
  		if (ci && ci->desc) {
  			err_mask |= ci->err_mask;
  			action |= ci->action;
cf4806265   Tejun Heo   libata: prefer ha...
1017
  			if (action & ATA_EH_RESET)
c2e14f111   Tejun Heo   sata_sil24: freez...
1018
  				freeze = 1;
b64bbc39f   Tejun Heo   libata: improve E...
1019
  			ata_ehi_push_desc(ehi, "%s", ci->desc);
88ce7550c   Tejun Heo   [PATCH] sata_sil2...
1020
1021
  		} else {
  			err_mask |= AC_ERR_OTHER;
cf4806265   Tejun Heo   libata: prefer ha...
1022
  			action |= ATA_EH_RESET;
c2e14f111   Tejun Heo   sata_sil24: freez...
1023
  			freeze = 1;
b64bbc39f   Tejun Heo   libata: improve E...
1024
  			ata_ehi_push_desc(ehi, "unknown command error %d",
88ce7550c   Tejun Heo   [PATCH] sata_sil2...
1025
1026
1027
1028
  					  cerr);
  		}
  
  		/* record error info */
520d06f92   Tejun Heo   libata: remove ch...
1029
  		if (qc)
88ce7550c   Tejun Heo   [PATCH] sata_sil2...
1030
  			qc->err_mask |= err_mask;
520d06f92   Tejun Heo   libata: remove ch...
1031
  		else
88ce7550c   Tejun Heo   [PATCH] sata_sil2...
1032
1033
1034
  			ehi->err_mask |= err_mask;
  
  		ehi->action |= action;
3454dc692   Tejun Heo   sata_sil24: imple...
1035
1036
  
  		/* if PMP, resume */
071f44b1d   Tejun Heo   libata: implement...
1037
  		if (sata_pmp_attached(ap))
3454dc692   Tejun Heo   sata_sil24: imple...
1038
  			writel(PORT_CS_PMP_RESUME, port + PORT_CTRL_STAT);
a22e2eb07   Albert Lee   [PATCH] libata: m...
1039
  	}
88ce7550c   Tejun Heo   [PATCH] sata_sil2...
1040
1041
1042
1043
  
  	/* freeze or abort */
  	if (freeze)
  		ata_port_freeze(ap);
3454dc692   Tejun Heo   sata_sil24: imple...
1044
1045
1046
1047
1048
1049
  	else if (abort) {
  		if (qc)
  			ata_link_abort(qc->dev->link);
  		else
  			ata_port_abort(ap);
  	}
8746618d4   Tejun Heo   [PATCH] sil24: mo...
1050
  }
edb336670   Tejun Heo   [PATCH] SATA: rew...
1051
1052
  static inline void sil24_host_intr(struct ata_port *ap)
  {
350756f6d   Tejun Heo   libata: don't use...
1053
  	void __iomem *port = sil24_port_base(ap);
aee10a03e   Tejun Heo   [PATCH] sata_sil2...
1054
1055
  	u32 slot_stat, qc_active;
  	int rc;
edb336670   Tejun Heo   [PATCH] SATA: rew...
1056

228f47b95   Tejun Heo   sata_sil24: fix I...
1057
1058
1059
1060
1061
1062
1063
1064
1065
  	/* If PCIX_IRQ_WOC, there's an inherent race window between
  	 * clearing IRQ pending status and reading PORT_SLOT_STAT
  	 * which may cause spurious interrupts afterwards.  This is
  	 * unavoidable and much better than losing interrupts which
  	 * happens if IRQ pending is cleared after reading
  	 * PORT_SLOT_STAT.
  	 */
  	if (ap->flags & SIL24_FLAG_PCIX_IRQ_WOC)
  		writel(PORT_IRQ_COMPLETE, port + PORT_IRQ_STAT);
edb336670   Tejun Heo   [PATCH] SATA: rew...
1066
  	slot_stat = readl(port + PORT_SLOT_STAT);
37024e8ee   Tejun Heo   [PATCH] sata_sil2...
1067

88ce7550c   Tejun Heo   [PATCH] sata_sil2...
1068
1069
1070
1071
  	if (unlikely(slot_stat & HOST_SSTAT_ATTN)) {
  		sil24_error_intr(ap);
  		return;
  	}
aee10a03e   Tejun Heo   [PATCH] sata_sil2...
1072
  	qc_active = slot_stat & ~HOST_SSTAT_ATTN;
79f97dadf   Tejun Heo   libata: drop @fin...
1073
  	rc = ata_qc_complete_multiple(ap, qc_active);
aee10a03e   Tejun Heo   [PATCH] sata_sil2...
1074
1075
1076
  	if (rc > 0)
  		return;
  	if (rc < 0) {
9af5c9c97   Tejun Heo   libata-link: intr...
1077
  		struct ata_eh_info *ehi = &ap->link.eh_info;
aee10a03e   Tejun Heo   [PATCH] sata_sil2...
1078
  		ehi->err_mask |= AC_ERR_HSM;
cf4806265   Tejun Heo   libata: prefer ha...
1079
  		ehi->action |= ATA_EH_RESET;
aee10a03e   Tejun Heo   [PATCH] sata_sil2...
1080
  		ata_port_freeze(ap);
88ce7550c   Tejun Heo   [PATCH] sata_sil2...
1081
1082
  		return;
  	}
228f47b95   Tejun Heo   sata_sil24: fix I...
1083
1084
  	/* spurious interrupts are expected if PCIX_IRQ_WOC */
  	if (!(ap->flags & SIL24_FLAG_PCIX_IRQ_WOC) && ata_ratelimit())
a9a79dfec   Joe Perches   ata: Convert ata_...
1085
1086
1087
  		ata_port_info(ap,
  			"spurious interrupt (slot_stat 0x%x active_tag %d sactive 0x%x)
  ",
9af5c9c97   Tejun Heo   libata-link: intr...
1088
  			slot_stat, ap->link.active_tag, ap->link.sactive);
edb336670   Tejun Heo   [PATCH] SATA: rew...
1089
  }
7d12e780e   David Howells   IRQ: Maintain reg...
1090
  static irqreturn_t sil24_interrupt(int irq, void *dev_instance)
edb336670   Tejun Heo   [PATCH] SATA: rew...
1091
  {
cca3974e4   Jeff Garzik   libata: Grand ren...
1092
  	struct ata_host *host = dev_instance;
0d5ff5667   Tejun Heo   libata: convert t...
1093
  	void __iomem *host_base = host->iomap[SIL24_HOST_BAR];
edb336670   Tejun Heo   [PATCH] SATA: rew...
1094
1095
1096
  	unsigned handled = 0;
  	u32 status;
  	int i;
0d5ff5667   Tejun Heo   libata: convert t...
1097
  	status = readl(host_base + HOST_IRQ_STAT);
edb336670   Tejun Heo   [PATCH] SATA: rew...
1098

06460aeaa   Tejun Heo   [PATCH] sil24: ad...
1099
1100
1101
1102
1103
1104
  	if (status == 0xffffffff) {
  		printk(KERN_ERR DRV_NAME ": IRQ status == 0xffffffff, "
  		       "PCI fault or device removal?
  ");
  		goto out;
  	}
edb336670   Tejun Heo   [PATCH] SATA: rew...
1105
1106
  	if (!(status & IRQ_STAT_4PORTS))
  		goto out;
cca3974e4   Jeff Garzik   libata: Grand ren...
1107
  	spin_lock(&host->lock);
edb336670   Tejun Heo   [PATCH] SATA: rew...
1108

cca3974e4   Jeff Garzik   libata: Grand ren...
1109
  	for (i = 0; i < host->n_ports; i++)
edb336670   Tejun Heo   [PATCH] SATA: rew...
1110
  		if (status & (1 << i)) {
3e4ec3443   Tejun Heo   libata: kill ATA_...
1111
1112
  			sil24_host_intr(host->ports[i]);
  			handled++;
edb336670   Tejun Heo   [PATCH] SATA: rew...
1113
  		}
cca3974e4   Jeff Garzik   libata: Grand ren...
1114
  	spin_unlock(&host->lock);
edb336670   Tejun Heo   [PATCH] SATA: rew...
1115
1116
1117
   out:
  	return IRQ_RETVAL(handled);
  }
88ce7550c   Tejun Heo   [PATCH] sata_sil2...
1118
1119
  static void sil24_error_handler(struct ata_port *ap)
  {
238180343   Tejun Heo   sata_sil24: imple...
1120
  	struct sil24_port_priv *pp = ap->private_data;
3454dc692   Tejun Heo   sata_sil24: imple...
1121
  	if (sil24_init_port(ap))
88ce7550c   Tejun Heo   [PATCH] sata_sil2...
1122
  		ata_eh_freeze_port(ap);
88ce7550c   Tejun Heo   [PATCH] sata_sil2...
1123

a1efdaba2   Tejun Heo   libata: make rese...
1124
  	sata_pmp_error_handler(ap);
238180343   Tejun Heo   sata_sil24: imple...
1125
1126
  
  	pp->do_port_rst = 0;
88ce7550c   Tejun Heo   [PATCH] sata_sil2...
1127
1128
1129
1130
1131
  }
  
  static void sil24_post_internal_cmd(struct ata_queued_cmd *qc)
  {
  	struct ata_port *ap = qc->ap;
88ce7550c   Tejun Heo   [PATCH] sata_sil2...
1132
  	/* make DMA engine forget about the failed command */
3454dc692   Tejun Heo   sata_sil24: imple...
1133
1134
  	if ((qc->flags & ATA_QCFLAG_FAILED) && sil24_init_port(ap))
  		ata_eh_freeze_port(ap);
88ce7550c   Tejun Heo   [PATCH] sata_sil2...
1135
  }
edb336670   Tejun Heo   [PATCH] SATA: rew...
1136
1137
  static int sil24_port_start(struct ata_port *ap)
  {
cca3974e4   Jeff Garzik   libata: Grand ren...
1138
  	struct device *dev = ap->host->dev;
edb336670   Tejun Heo   [PATCH] SATA: rew...
1139
  	struct sil24_port_priv *pp;
69ad185fa   Tejun Heo   [PATCH] sil24: ad...
1140
  	union sil24_cmd_block *cb;
aee10a03e   Tejun Heo   [PATCH] sata_sil2...
1141
  	size_t cb_size = sizeof(*cb) * SIL24_MAX_CMDS;
edb336670   Tejun Heo   [PATCH] SATA: rew...
1142
  	dma_addr_t cb_dma;
24dc5f33e   Tejun Heo   libata: update li...
1143
  	pp = devm_kzalloc(dev, sizeof(*pp), GFP_KERNEL);
edb336670   Tejun Heo   [PATCH] SATA: rew...
1144
  	if (!pp)
24dc5f33e   Tejun Heo   libata: update li...
1145
  		return -ENOMEM;
edb336670   Tejun Heo   [PATCH] SATA: rew...
1146

24dc5f33e   Tejun Heo   libata: update li...
1147
  	cb = dmam_alloc_coherent(dev, cb_size, &cb_dma, GFP_KERNEL);
6037d6bbd   Jeff Garzik   [libata] ATAPI pa...
1148
  	if (!cb)
24dc5f33e   Tejun Heo   libata: update li...
1149
  		return -ENOMEM;
edb336670   Tejun Heo   [PATCH] SATA: rew...
1150
  	memset(cb, 0, cb_size);
edb336670   Tejun Heo   [PATCH] SATA: rew...
1151
1152
1153
1154
  	pp->cmd_block = cb;
  	pp->cmd_block_dma = cb_dma;
  
  	ap->private_data = pp;
350756f6d   Tejun Heo   libata: don't use...
1155
1156
  	ata_port_pbar_desc(ap, SIL24_HOST_BAR, -1, "host");
  	ata_port_pbar_desc(ap, SIL24_PORT_BAR, sil24_port_offset(ap), "port");
edb336670   Tejun Heo   [PATCH] SATA: rew...
1157
  	return 0;
edb336670   Tejun Heo   [PATCH] SATA: rew...
1158
  }
4447d3515   Tejun Heo   libata: convert t...
1159
  static void sil24_init_controller(struct ata_host *host)
2a41a6108   Tejun Heo   [PATCH] sata_sil2...
1160
  {
4447d3515   Tejun Heo   libata: convert t...
1161
  	void __iomem *host_base = host->iomap[SIL24_HOST_BAR];
2a41a6108   Tejun Heo   [PATCH] sata_sil2...
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
  	u32 tmp;
  	int i;
  
  	/* GPIO off */
  	writel(0, host_base + HOST_FLASH_CMD);
  
  	/* clear global reset & mask interrupts during initialization */
  	writel(0, host_base + HOST_CTRL);
  
  	/* init ports */
4447d3515   Tejun Heo   libata: convert t...
1172
  	for (i = 0; i < host->n_ports; i++) {
238180343   Tejun Heo   sata_sil24: imple...
1173
  		struct ata_port *ap = host->ports[i];
350756f6d   Tejun Heo   libata: don't use...
1174
  		void __iomem *port = sil24_port_base(ap);
2a41a6108   Tejun Heo   [PATCH] sata_sil2...
1175
1176
1177
1178
1179
1180
1181
1182
  
  		/* Initial PHY setting */
  		writel(0x20c, port + PORT_PHY_CFG);
  
  		/* Clear port RST */
  		tmp = readl(port + PORT_CTRL_STAT);
  		if (tmp & PORT_CS_PORT_RST) {
  			writel(PORT_CS_PORT_RST, port + PORT_CTRL_CLR);
97750cebb   Tejun Heo   libata: add @ap t...
1183
  			tmp = ata_wait_register(NULL, port + PORT_CTRL_STAT,
2a41a6108   Tejun Heo   [PATCH] sata_sil2...
1184
1185
1186
  						PORT_CS_PORT_RST,
  						PORT_CS_PORT_RST, 10, 100);
  			if (tmp & PORT_CS_PORT_RST)
a44fec1fc   Joe Perches   ata: Convert dev_...
1187
1188
1189
  				dev_err(host->dev,
  					"failed to clear port RST
  ");
2a41a6108   Tejun Heo   [PATCH] sata_sil2...
1190
  		}
238180343   Tejun Heo   sata_sil24: imple...
1191
1192
  		/* configure port */
  		sil24_config_port(ap);
2a41a6108   Tejun Heo   [PATCH] sata_sil2...
1193
1194
1195
1196
1197
  	}
  
  	/* Turn on interrupts */
  	writel(IRQ_STAT_4PORTS, host_base + HOST_CTRL);
  }
edb336670   Tejun Heo   [PATCH] SATA: rew...
1198
1199
  static int sil24_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
  {
93e2618e0   Tejun Heo   sata_sil24: fix s...
1200
  	extern int __MARKER__sil24_cmd_block_is_sized_wrongly;
4447d3515   Tejun Heo   libata: convert t...
1201
1202
1203
1204
  	struct ata_port_info pi = sil24_port_info[ent->driver_data];
  	const struct ata_port_info *ppi[] = { &pi, NULL };
  	void __iomem * const *iomap;
  	struct ata_host *host;
350756f6d   Tejun Heo   libata: don't use...
1205
  	int rc;
37024e8ee   Tejun Heo   [PATCH] sata_sil2...
1206
  	u32 tmp;
edb336670   Tejun Heo   [PATCH] SATA: rew...
1207

93e2618e0   Tejun Heo   sata_sil24: fix s...
1208
1209
1210
  	/* cause link error if sil24_cmd_block is sized wrongly */
  	if (sizeof(union sil24_cmd_block) != PAGE_SIZE)
  		__MARKER__sil24_cmd_block_is_sized_wrongly = 1;
06296a1e6   Joe Perches   ata: Add and use ...
1211
  	ata_print_version_once(&pdev->dev, DRV_VERSION);
edb336670   Tejun Heo   [PATCH] SATA: rew...
1212

4447d3515   Tejun Heo   libata: convert t...
1213
  	/* acquire resources */
24dc5f33e   Tejun Heo   libata: update li...
1214
  	rc = pcim_enable_device(pdev);
edb336670   Tejun Heo   [PATCH] SATA: rew...
1215
1216
  	if (rc)
  		return rc;
0d5ff5667   Tejun Heo   libata: convert t...
1217
1218
1219
  	rc = pcim_iomap_regions(pdev,
  				(1 << SIL24_HOST_BAR) | (1 << SIL24_PORT_BAR),
  				DRV_NAME);
edb336670   Tejun Heo   [PATCH] SATA: rew...
1220
  	if (rc)
24dc5f33e   Tejun Heo   libata: update li...
1221
  		return rc;
4447d3515   Tejun Heo   libata: convert t...
1222
  	iomap = pcim_iomap_table(pdev);
edb336670   Tejun Heo   [PATCH] SATA: rew...
1223

4447d3515   Tejun Heo   libata: convert t...
1224
1225
1226
1227
  	/* apply workaround for completion IRQ loss on PCI-X errata */
  	if (pi.flags & SIL24_FLAG_PCIX_IRQ_WOC) {
  		tmp = readl(iomap[SIL24_HOST_BAR] + HOST_CTRL);
  		if (tmp & (HOST_CTRL_TRDY | HOST_CTRL_STOP | HOST_CTRL_DEVSEL))
a44fec1fc   Joe Perches   ata: Convert dev_...
1228
1229
1230
  			dev_info(&pdev->dev,
  				 "Applying completion IRQ loss on PCI-X errata fix
  ");
4447d3515   Tejun Heo   libata: convert t...
1231
1232
1233
  		else
  			pi.flags &= ~SIL24_FLAG_PCIX_IRQ_WOC;
  	}
edb336670   Tejun Heo   [PATCH] SATA: rew...
1234

4447d3515   Tejun Heo   libata: convert t...
1235
1236
1237
1238
1239
1240
  	/* allocate and fill host */
  	host = ata_host_alloc_pinfo(&pdev->dev, ppi,
  				    SIL24_FLAG2NPORTS(ppi[0]->flags));
  	if (!host)
  		return -ENOMEM;
  	host->iomap = iomap;
edb336670   Tejun Heo   [PATCH] SATA: rew...
1241

4447d3515   Tejun Heo   libata: convert t...
1242
  	/* configure and activate the device */
6a35528a8   Yang Hongyang   dma-mapping: repl...
1243
1244
  	if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(64))) {
  		rc = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64));
26ec634c3   Tejun Heo   [PATCH] sata_sil2...
1245
  		if (rc) {
284901a90   Yang Hongyang   dma-mapping: repl...
1246
  			rc = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
26ec634c3   Tejun Heo   [PATCH] sata_sil2...
1247
  			if (rc) {
a44fec1fc   Joe Perches   ata: Convert dev_...
1248
1249
1250
  				dev_err(&pdev->dev,
  					"64-bit DMA enable failed
  ");
24dc5f33e   Tejun Heo   libata: update li...
1251
  				return rc;
26ec634c3   Tejun Heo   [PATCH] sata_sil2...
1252
1253
1254
  			}
  		}
  	} else {
284901a90   Yang Hongyang   dma-mapping: repl...
1255
  		rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
26ec634c3   Tejun Heo   [PATCH] sata_sil2...
1256
  		if (rc) {
a44fec1fc   Joe Perches   ata: Convert dev_...
1257
1258
  			dev_err(&pdev->dev, "32-bit DMA enable failed
  ");
24dc5f33e   Tejun Heo   libata: update li...
1259
  			return rc;
26ec634c3   Tejun Heo   [PATCH] sata_sil2...
1260
  		}
284901a90   Yang Hongyang   dma-mapping: repl...
1261
  		rc = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
26ec634c3   Tejun Heo   [PATCH] sata_sil2...
1262
  		if (rc) {
a44fec1fc   Joe Perches   ata: Convert dev_...
1263
1264
1265
  			dev_err(&pdev->dev,
  				"32-bit consistent DMA enable failed
  ");
24dc5f33e   Tejun Heo   libata: update li...
1266
  			return rc;
26ec634c3   Tejun Heo   [PATCH] sata_sil2...
1267
  		}
edb336670   Tejun Heo   [PATCH] SATA: rew...
1268
  	}
e8b3b5e9f   Tejun Heo   sata_sil24: confi...
1269
1270
1271
1272
  	/* Set max read request size to 4096.  This slightly increases
  	 * write throughput for pci-e variants.
  	 */
  	pcie_set_readrq(pdev, 4096);
4447d3515   Tejun Heo   libata: convert t...
1273
  	sil24_init_controller(host);
edb336670   Tejun Heo   [PATCH] SATA: rew...
1274

dae77214f   Vivek Mahajan   sata_sil24: MSI s...
1275
  	if (sata_sil24_msi && !pci_enable_msi(pdev)) {
a44fec1fc   Joe Perches   ata: Convert dev_...
1276
1277
  		dev_info(&pdev->dev, "Using MSI
  ");
dae77214f   Vivek Mahajan   sata_sil24: MSI s...
1278
1279
  		pci_intx(pdev, 0);
  	}
edb336670   Tejun Heo   [PATCH] SATA: rew...
1280
  	pci_set_master(pdev);
4447d3515   Tejun Heo   libata: convert t...
1281
1282
  	return ata_host_activate(host, pdev->irq, sil24_interrupt, IRQF_SHARED,
  				 &sil24_sht);
edb336670   Tejun Heo   [PATCH] SATA: rew...
1283
  }
281d426c7   Alexey Dobriyan   [PATCH] CONFIG_PM...
1284
  #ifdef CONFIG_PM
d2298dca9   Tejun Heo   [PATCH] sata_sil2...
1285
1286
  static int sil24_pci_device_resume(struct pci_dev *pdev)
  {
cca3974e4   Jeff Garzik   libata: Grand ren...
1287
  	struct ata_host *host = dev_get_drvdata(&pdev->dev);
0d5ff5667   Tejun Heo   libata: convert t...
1288
  	void __iomem *host_base = host->iomap[SIL24_HOST_BAR];
553c4aa63   Tejun Heo   libata: handle pc...
1289
  	int rc;
d2298dca9   Tejun Heo   [PATCH] sata_sil2...
1290

553c4aa63   Tejun Heo   libata: handle pc...
1291
1292
1293
  	rc = ata_pci_device_do_resume(pdev);
  	if (rc)
  		return rc;
d2298dca9   Tejun Heo   [PATCH] sata_sil2...
1294
1295
  
  	if (pdev->dev.power.power_state.event == PM_EVENT_SUSPEND)
0d5ff5667   Tejun Heo   libata: convert t...
1296
  		writel(HOST_CTRL_GLOBAL_RST, host_base + HOST_CTRL);
d2298dca9   Tejun Heo   [PATCH] sata_sil2...
1297

4447d3515   Tejun Heo   libata: convert t...
1298
  	sil24_init_controller(host);
d2298dca9   Tejun Heo   [PATCH] sata_sil2...
1299

cca3974e4   Jeff Garzik   libata: Grand ren...
1300
  	ata_host_resume(host);
d2298dca9   Tejun Heo   [PATCH] sata_sil2...
1301
1302
1303
  
  	return 0;
  }
3454dc692   Tejun Heo   sata_sil24: imple...
1304
1305
1306
1307
1308
1309
  
  static int sil24_port_resume(struct ata_port *ap)
  {
  	sil24_config_pmp(ap, ap->nr_pmp_links);
  	return 0;
  }
281d426c7   Alexey Dobriyan   [PATCH] CONFIG_PM...
1310
  #endif
d2298dca9   Tejun Heo   [PATCH] sata_sil2...
1311

edb336670   Tejun Heo   [PATCH] SATA: rew...
1312
1313
  static int __init sil24_init(void)
  {
b7887196e   Pavel Roskin   [PATCH] libata: r...
1314
  	return pci_register_driver(&sil24_pci_driver);
edb336670   Tejun Heo   [PATCH] SATA: rew...
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
  }
  
  static void __exit sil24_exit(void)
  {
  	pci_unregister_driver(&sil24_pci_driver);
  }
  
  MODULE_AUTHOR("Tejun Heo");
  MODULE_DESCRIPTION("Silicon Image 3124/3132 SATA low-level driver");
  MODULE_LICENSE("GPL");
  MODULE_DEVICE_TABLE(pci, sil24_pci_tbl);
  
  module_init(sil24_init);
  module_exit(sil24_exit);