diff options
Diffstat (limited to 'drivers/ata/sata_nv.c')
-rw-r--r-- | drivers/ata/sata_nv.c | 1044 |
1 files changed, 1008 insertions, 36 deletions
diff --git a/drivers/ata/sata_nv.c b/drivers/ata/sata_nv.c index d65ebfd7c7b2..0d316eb3c214 100644 --- a/drivers/ata/sata_nv.c +++ b/drivers/ata/sata_nv.c | |||
@@ -29,6 +29,11 @@ | |||
29 | * NV-specific details such as register offsets, SATA phy location, | 29 | * NV-specific details such as register offsets, SATA phy location, |
30 | * hotplug info, etc. | 30 | * hotplug info, etc. |
31 | * | 31 | * |
32 | * CK804/MCP04 controllers support an alternate programming interface | ||
33 | * similar to the ADMA specification (with some modifications). | ||
34 | * This allows the use of NCQ. Non-DMA-mapped ATA commands are still | ||
35 | * sent through the legacy interface. | ||
36 | * | ||
32 | */ | 37 | */ |
33 | 38 | ||
34 | #include <linux/kernel.h> | 39 | #include <linux/kernel.h> |
@@ -40,10 +45,13 @@ | |||
40 | #include <linux/interrupt.h> | 45 | #include <linux/interrupt.h> |
41 | #include <linux/device.h> | 46 | #include <linux/device.h> |
42 | #include <scsi/scsi_host.h> | 47 | #include <scsi/scsi_host.h> |
48 | #include <scsi/scsi_device.h> | ||
43 | #include <linux/libata.h> | 49 | #include <linux/libata.h> |
44 | 50 | ||
45 | #define DRV_NAME "sata_nv" | 51 | #define DRV_NAME "sata_nv" |
46 | #define DRV_VERSION "2.0" | 52 | #define DRV_VERSION "3.2" |
53 | |||
54 | #define NV_ADMA_DMA_BOUNDARY 0xffffffffUL | ||
47 | 55 | ||
48 | enum { | 56 | enum { |
49 | NV_PORTS = 2, | 57 | NV_PORTS = 2, |
@@ -78,8 +86,138 @@ enum { | |||
78 | // For PCI config register 20 | 86 | // For PCI config register 20 |
79 | NV_MCP_SATA_CFG_20 = 0x50, | 87 | NV_MCP_SATA_CFG_20 = 0x50, |
80 | NV_MCP_SATA_CFG_20_SATA_SPACE_EN = 0x04, | 88 | NV_MCP_SATA_CFG_20_SATA_SPACE_EN = 0x04, |
89 | NV_MCP_SATA_CFG_20_PORT0_EN = (1 << 17), | ||
90 | NV_MCP_SATA_CFG_20_PORT1_EN = (1 << 16), | ||
91 | NV_MCP_SATA_CFG_20_PORT0_PWB_EN = (1 << 14), | ||
92 | NV_MCP_SATA_CFG_20_PORT1_PWB_EN = (1 << 12), | ||
93 | |||
94 | NV_ADMA_MAX_CPBS = 32, | ||
95 | NV_ADMA_CPB_SZ = 128, | ||
96 | NV_ADMA_APRD_SZ = 16, | ||
97 | NV_ADMA_SGTBL_LEN = (1024 - NV_ADMA_CPB_SZ) / | ||
98 | NV_ADMA_APRD_SZ, | ||
99 | NV_ADMA_SGTBL_TOTAL_LEN = NV_ADMA_SGTBL_LEN + 5, | ||
100 | NV_ADMA_SGTBL_SZ = NV_ADMA_SGTBL_LEN * NV_ADMA_APRD_SZ, | ||
101 | NV_ADMA_PORT_PRIV_DMA_SZ = NV_ADMA_MAX_CPBS * | ||
102 | (NV_ADMA_CPB_SZ + NV_ADMA_SGTBL_SZ), | ||
103 | |||
104 | /* BAR5 offset to ADMA general registers */ | ||
105 | NV_ADMA_GEN = 0x400, | ||
106 | NV_ADMA_GEN_CTL = 0x00, | ||
107 | NV_ADMA_NOTIFIER_CLEAR = 0x30, | ||
108 | |||
109 | /* BAR5 offset to ADMA ports */ | ||
110 | NV_ADMA_PORT = 0x480, | ||
111 | |||
112 | /* size of ADMA port register space */ | ||
113 | NV_ADMA_PORT_SIZE = 0x100, | ||
114 | |||
115 | /* ADMA port registers */ | ||
116 | NV_ADMA_CTL = 0x40, | ||
117 | NV_ADMA_CPB_COUNT = 0x42, | ||
118 | NV_ADMA_NEXT_CPB_IDX = 0x43, | ||
119 | NV_ADMA_STAT = 0x44, | ||
120 | NV_ADMA_CPB_BASE_LOW = 0x48, | ||
121 | NV_ADMA_CPB_BASE_HIGH = 0x4C, | ||
122 | NV_ADMA_APPEND = 0x50, | ||
123 | NV_ADMA_NOTIFIER = 0x68, | ||
124 | NV_ADMA_NOTIFIER_ERROR = 0x6C, | ||
125 | |||
126 | /* NV_ADMA_CTL register bits */ | ||
127 | NV_ADMA_CTL_HOTPLUG_IEN = (1 << 0), | ||
128 | NV_ADMA_CTL_CHANNEL_RESET = (1 << 5), | ||
129 | NV_ADMA_CTL_GO = (1 << 7), | ||
130 | NV_ADMA_CTL_AIEN = (1 << 8), | ||
131 | NV_ADMA_CTL_READ_NON_COHERENT = (1 << 11), | ||
132 | NV_ADMA_CTL_WRITE_NON_COHERENT = (1 << 12), | ||
133 | |||
134 | /* CPB response flag bits */ | ||
135 | NV_CPB_RESP_DONE = (1 << 0), | ||
136 | NV_CPB_RESP_ATA_ERR = (1 << 3), | ||
137 | NV_CPB_RESP_CMD_ERR = (1 << 4), | ||
138 | NV_CPB_RESP_CPB_ERR = (1 << 7), | ||
139 | |||
140 | /* CPB control flag bits */ | ||
141 | NV_CPB_CTL_CPB_VALID = (1 << 0), | ||
142 | NV_CPB_CTL_QUEUE = (1 << 1), | ||
143 | NV_CPB_CTL_APRD_VALID = (1 << 2), | ||
144 | NV_CPB_CTL_IEN = (1 << 3), | ||
145 | NV_CPB_CTL_FPDMA = (1 << 4), | ||
146 | |||
147 | /* APRD flags */ | ||
148 | NV_APRD_WRITE = (1 << 1), | ||
149 | NV_APRD_END = (1 << 2), | ||
150 | NV_APRD_CONT = (1 << 3), | ||
151 | |||
152 | /* NV_ADMA_STAT flags */ | ||
153 | NV_ADMA_STAT_TIMEOUT = (1 << 0), | ||
154 | NV_ADMA_STAT_HOTUNPLUG = (1 << 1), | ||
155 | NV_ADMA_STAT_HOTPLUG = (1 << 2), | ||
156 | NV_ADMA_STAT_CPBERR = (1 << 4), | ||
157 | NV_ADMA_STAT_SERROR = (1 << 5), | ||
158 | NV_ADMA_STAT_CMD_COMPLETE = (1 << 6), | ||
159 | NV_ADMA_STAT_IDLE = (1 << 8), | ||
160 | NV_ADMA_STAT_LEGACY = (1 << 9), | ||
161 | NV_ADMA_STAT_STOPPED = (1 << 10), | ||
162 | NV_ADMA_STAT_DONE = (1 << 12), | ||
163 | NV_ADMA_STAT_ERR = NV_ADMA_STAT_CPBERR | | ||
164 | NV_ADMA_STAT_TIMEOUT, | ||
165 | |||
166 | /* port flags */ | ||
167 | NV_ADMA_PORT_REGISTER_MODE = (1 << 0), | ||
168 | NV_ADMA_ATAPI_SETUP_COMPLETE = (1 << 1), | ||
169 | |||
170 | }; | ||
171 | |||
172 | /* ADMA Physical Region Descriptor - one SG segment */ | ||
173 | struct nv_adma_prd { | ||
174 | __le64 addr; | ||
175 | __le32 len; | ||
176 | u8 flags; | ||
177 | u8 packet_len; | ||
178 | __le16 reserved; | ||
179 | }; | ||
180 | |||
181 | enum nv_adma_regbits { | ||
182 | CMDEND = (1 << 15), /* end of command list */ | ||
183 | WNB = (1 << 14), /* wait-not-BSY */ | ||
184 | IGN = (1 << 13), /* ignore this entry */ | ||
185 | CS1n = (1 << (4 + 8)), /* std. PATA signals follow... */ | ||
186 | DA2 = (1 << (2 + 8)), | ||
187 | DA1 = (1 << (1 + 8)), | ||
188 | DA0 = (1 << (0 + 8)), | ||
189 | }; | ||
190 | |||
191 | /* ADMA Command Parameter Block | ||
192 | The first 5 SG segments are stored inside the Command Parameter Block itself. | ||
193 | If there are more than 5 segments the remainder are stored in a separate | ||
194 | memory area indicated by next_aprd. */ | ||
195 | struct nv_adma_cpb { | ||
196 | u8 resp_flags; /* 0 */ | ||
197 | u8 reserved1; /* 1 */ | ||
198 | u8 ctl_flags; /* 2 */ | ||
199 | /* len is length of taskfile in 64 bit words */ | ||
200 | u8 len; /* 3 */ | ||
201 | u8 tag; /* 4 */ | ||
202 | u8 next_cpb_idx; /* 5 */ | ||
203 | __le16 reserved2; /* 6-7 */ | ||
204 | __le16 tf[12]; /* 8-31 */ | ||
205 | struct nv_adma_prd aprd[5]; /* 32-111 */ | ||
206 | __le64 next_aprd; /* 112-119 */ | ||
207 | __le64 reserved3; /* 120-127 */ | ||
208 | }; | ||
209 | |||
210 | |||
211 | struct nv_adma_port_priv { | ||
212 | struct nv_adma_cpb *cpb; | ||
213 | dma_addr_t cpb_dma; | ||
214 | struct nv_adma_prd *aprd; | ||
215 | dma_addr_t aprd_dma; | ||
216 | u8 flags; | ||
81 | }; | 217 | }; |
82 | 218 | ||
219 | #define NV_ADMA_CHECK_INTR(GCTL, PORT) ((GCTL) & ( 1 << (19 + (12 * (PORT))))) | ||
220 | |||
83 | static int nv_init_one (struct pci_dev *pdev, const struct pci_device_id *ent); | 221 | static int nv_init_one (struct pci_dev *pdev, const struct pci_device_id *ent); |
84 | static void nv_ck804_host_stop(struct ata_host *host); | 222 | static void nv_ck804_host_stop(struct ata_host *host); |
85 | static irqreturn_t nv_generic_interrupt(int irq, void *dev_instance); | 223 | static irqreturn_t nv_generic_interrupt(int irq, void *dev_instance); |
@@ -93,13 +231,28 @@ static void nv_nf2_thaw(struct ata_port *ap); | |||
93 | static void nv_ck804_freeze(struct ata_port *ap); | 231 | static void nv_ck804_freeze(struct ata_port *ap); |
94 | static void nv_ck804_thaw(struct ata_port *ap); | 232 | static void nv_ck804_thaw(struct ata_port *ap); |
95 | static void nv_error_handler(struct ata_port *ap); | 233 | static void nv_error_handler(struct ata_port *ap); |
234 | static int nv_adma_slave_config(struct scsi_device *sdev); | ||
235 | static int nv_adma_check_atapi_dma(struct ata_queued_cmd *qc); | ||
236 | static void nv_adma_qc_prep(struct ata_queued_cmd *qc); | ||
237 | static unsigned int nv_adma_qc_issue(struct ata_queued_cmd *qc); | ||
238 | static irqreturn_t nv_adma_interrupt(int irq, void *dev_instance); | ||
239 | static void nv_adma_irq_clear(struct ata_port *ap); | ||
240 | static int nv_adma_port_start(struct ata_port *ap); | ||
241 | static void nv_adma_port_stop(struct ata_port *ap); | ||
242 | static void nv_adma_error_handler(struct ata_port *ap); | ||
243 | static void nv_adma_host_stop(struct ata_host *host); | ||
244 | static void nv_adma_bmdma_setup(struct ata_queued_cmd *qc); | ||
245 | static void nv_adma_bmdma_start(struct ata_queued_cmd *qc); | ||
246 | static void nv_adma_bmdma_stop(struct ata_queued_cmd *qc); | ||
247 | static u8 nv_adma_bmdma_status(struct ata_port *ap); | ||
96 | 248 | ||
97 | enum nv_host_type | 249 | enum nv_host_type |
98 | { | 250 | { |
99 | GENERIC, | 251 | GENERIC, |
100 | NFORCE2, | 252 | NFORCE2, |
101 | NFORCE3 = NFORCE2, /* NF2 == NF3 as far as sata_nv is concerned */ | 253 | NFORCE3 = NFORCE2, /* NF2 == NF3 as far as sata_nv is concerned */ |
102 | CK804 | 254 | CK804, |
255 | ADMA | ||
103 | }; | 256 | }; |
104 | 257 | ||
105 | static const struct pci_device_id nv_pci_tbl[] = { | 258 | static const struct pci_device_id nv_pci_tbl[] = { |
@@ -160,6 +313,24 @@ static struct scsi_host_template nv_sht = { | |||
160 | .bios_param = ata_std_bios_param, | 313 | .bios_param = ata_std_bios_param, |
161 | }; | 314 | }; |
162 | 315 | ||
316 | static struct scsi_host_template nv_adma_sht = { | ||
317 | .module = THIS_MODULE, | ||
318 | .name = DRV_NAME, | ||
319 | .ioctl = ata_scsi_ioctl, | ||
320 | .queuecommand = ata_scsi_queuecmd, | ||
321 | .can_queue = NV_ADMA_MAX_CPBS, | ||
322 | .this_id = ATA_SHT_THIS_ID, | ||
323 | .sg_tablesize = NV_ADMA_SGTBL_TOTAL_LEN, | ||
324 | .cmd_per_lun = ATA_SHT_CMD_PER_LUN, | ||
325 | .emulated = ATA_SHT_EMULATED, | ||
326 | .use_clustering = ATA_SHT_USE_CLUSTERING, | ||
327 | .proc_name = DRV_NAME, | ||
328 | .dma_boundary = NV_ADMA_DMA_BOUNDARY, | ||
329 | .slave_configure = nv_adma_slave_config, | ||
330 | .slave_destroy = ata_scsi_slave_destroy, | ||
331 | .bios_param = ata_std_bios_param, | ||
332 | }; | ||
333 | |||
163 | static const struct ata_port_operations nv_generic_ops = { | 334 | static const struct ata_port_operations nv_generic_ops = { |
164 | .port_disable = ata_port_disable, | 335 | .port_disable = ata_port_disable, |
165 | .tf_load = ata_tf_load, | 336 | .tf_load = ata_tf_load, |
@@ -241,11 +412,40 @@ static const struct ata_port_operations nv_ck804_ops = { | |||
241 | .host_stop = nv_ck804_host_stop, | 412 | .host_stop = nv_ck804_host_stop, |
242 | }; | 413 | }; |
243 | 414 | ||
415 | static const struct ata_port_operations nv_adma_ops = { | ||
416 | .port_disable = ata_port_disable, | ||
417 | .tf_load = ata_tf_load, | ||
418 | .tf_read = ata_tf_read, | ||
419 | .check_atapi_dma = nv_adma_check_atapi_dma, | ||
420 | .exec_command = ata_exec_command, | ||
421 | .check_status = ata_check_status, | ||
422 | .dev_select = ata_std_dev_select, | ||
423 | .bmdma_setup = nv_adma_bmdma_setup, | ||
424 | .bmdma_start = nv_adma_bmdma_start, | ||
425 | .bmdma_stop = nv_adma_bmdma_stop, | ||
426 | .bmdma_status = nv_adma_bmdma_status, | ||
427 | .qc_prep = nv_adma_qc_prep, | ||
428 | .qc_issue = nv_adma_qc_issue, | ||
429 | .freeze = nv_ck804_freeze, | ||
430 | .thaw = nv_ck804_thaw, | ||
431 | .error_handler = nv_adma_error_handler, | ||
432 | .post_internal_cmd = nv_adma_bmdma_stop, | ||
433 | .data_xfer = ata_mmio_data_xfer, | ||
434 | .irq_handler = nv_adma_interrupt, | ||
435 | .irq_clear = nv_adma_irq_clear, | ||
436 | .scr_read = nv_scr_read, | ||
437 | .scr_write = nv_scr_write, | ||
438 | .port_start = nv_adma_port_start, | ||
439 | .port_stop = nv_adma_port_stop, | ||
440 | .host_stop = nv_adma_host_stop, | ||
441 | }; | ||
442 | |||
244 | static struct ata_port_info nv_port_info[] = { | 443 | static struct ata_port_info nv_port_info[] = { |
245 | /* generic */ | 444 | /* generic */ |
246 | { | 445 | { |
247 | .sht = &nv_sht, | 446 | .sht = &nv_sht, |
248 | .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY, | 447 | .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | |
448 | ATA_FLAG_HRST_TO_RESUME, | ||
249 | .pio_mask = NV_PIO_MASK, | 449 | .pio_mask = NV_PIO_MASK, |
250 | .mwdma_mask = NV_MWDMA_MASK, | 450 | .mwdma_mask = NV_MWDMA_MASK, |
251 | .udma_mask = NV_UDMA_MASK, | 451 | .udma_mask = NV_UDMA_MASK, |
@@ -254,7 +454,8 @@ static struct ata_port_info nv_port_info[] = { | |||
254 | /* nforce2/3 */ | 454 | /* nforce2/3 */ |
255 | { | 455 | { |
256 | .sht = &nv_sht, | 456 | .sht = &nv_sht, |
257 | .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY, | 457 | .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | |
458 | ATA_FLAG_HRST_TO_RESUME, | ||
258 | .pio_mask = NV_PIO_MASK, | 459 | .pio_mask = NV_PIO_MASK, |
259 | .mwdma_mask = NV_MWDMA_MASK, | 460 | .mwdma_mask = NV_MWDMA_MASK, |
260 | .udma_mask = NV_UDMA_MASK, | 461 | .udma_mask = NV_UDMA_MASK, |
@@ -263,12 +464,23 @@ static struct ata_port_info nv_port_info[] = { | |||
263 | /* ck804 */ | 464 | /* ck804 */ |
264 | { | 465 | { |
265 | .sht = &nv_sht, | 466 | .sht = &nv_sht, |
266 | .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY, | 467 | .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | |
468 | ATA_FLAG_HRST_TO_RESUME, | ||
267 | .pio_mask = NV_PIO_MASK, | 469 | .pio_mask = NV_PIO_MASK, |
268 | .mwdma_mask = NV_MWDMA_MASK, | 470 | .mwdma_mask = NV_MWDMA_MASK, |
269 | .udma_mask = NV_UDMA_MASK, | 471 | .udma_mask = NV_UDMA_MASK, |
270 | .port_ops = &nv_ck804_ops, | 472 | .port_ops = &nv_ck804_ops, |
271 | }, | 473 | }, |
474 | /* ADMA */ | ||
475 | { | ||
476 | .sht = &nv_adma_sht, | ||
477 | .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | | ||
478 | ATA_FLAG_MMIO | ATA_FLAG_NCQ, | ||
479 | .pio_mask = NV_PIO_MASK, | ||
480 | .mwdma_mask = NV_MWDMA_MASK, | ||
481 | .udma_mask = NV_UDMA_MASK, | ||
482 | .port_ops = &nv_adma_ops, | ||
483 | }, | ||
272 | }; | 484 | }; |
273 | 485 | ||
274 | MODULE_AUTHOR("NVIDIA"); | 486 | MODULE_AUTHOR("NVIDIA"); |
@@ -277,37 +489,220 @@ MODULE_LICENSE("GPL"); | |||
277 | MODULE_DEVICE_TABLE(pci, nv_pci_tbl); | 489 | MODULE_DEVICE_TABLE(pci, nv_pci_tbl); |
278 | MODULE_VERSION(DRV_VERSION); | 490 | MODULE_VERSION(DRV_VERSION); |
279 | 491 | ||
280 | static irqreturn_t nv_generic_interrupt(int irq, void *dev_instance) | 492 | static int adma_enabled = 1; |
493 | |||
494 | static inline void __iomem *__nv_adma_ctl_block(void __iomem *mmio, | ||
495 | unsigned int port_no) | ||
281 | { | 496 | { |
282 | struct ata_host *host = dev_instance; | 497 | mmio += NV_ADMA_PORT + port_no * NV_ADMA_PORT_SIZE; |
283 | unsigned int i; | 498 | return mmio; |
284 | unsigned int handled = 0; | 499 | } |
285 | unsigned long flags; | ||
286 | 500 | ||
287 | spin_lock_irqsave(&host->lock, flags); | 501 | static inline void __iomem *nv_adma_ctl_block(struct ata_port *ap) |
502 | { | ||
503 | return __nv_adma_ctl_block(ap->host->mmio_base, ap->port_no); | ||
504 | } | ||
288 | 505 | ||
289 | for (i = 0; i < host->n_ports; i++) { | 506 | static inline void __iomem *nv_adma_gen_block(struct ata_port *ap) |
290 | struct ata_port *ap; | 507 | { |
508 | return (ap->host->mmio_base + NV_ADMA_GEN); | ||
509 | } | ||
291 | 510 | ||
292 | ap = host->ports[i]; | 511 | static inline void __iomem *nv_adma_notifier_clear_block(struct ata_port *ap) |
293 | if (ap && | 512 | { |
294 | !(ap->flags & ATA_FLAG_DISABLED)) { | 513 | return (nv_adma_gen_block(ap) + NV_ADMA_NOTIFIER_CLEAR + (4 * ap->port_no)); |
295 | struct ata_queued_cmd *qc; | 514 | } |
296 | 515 | ||
297 | qc = ata_qc_from_tag(ap, ap->active_tag); | 516 | static void nv_adma_register_mode(struct ata_port *ap) |
298 | if (qc && (!(qc->tf.flags & ATA_TFLAG_POLLING))) | 517 | { |
299 | handled += ata_host_intr(ap, qc); | 518 | void __iomem *mmio = nv_adma_ctl_block(ap); |
300 | else | 519 | struct nv_adma_port_priv *pp = ap->private_data; |
301 | // No request pending? Clear interrupt status | 520 | u16 tmp; |
302 | // anyway, in case there's one pending. | 521 | |
303 | ap->ops->check_status(ap); | 522 | if (pp->flags & NV_ADMA_PORT_REGISTER_MODE) |
304 | } | 523 | return; |
524 | |||
525 | tmp = readw(mmio + NV_ADMA_CTL); | ||
526 | writew(tmp & ~NV_ADMA_CTL_GO, mmio + NV_ADMA_CTL); | ||
527 | |||
528 | pp->flags |= NV_ADMA_PORT_REGISTER_MODE; | ||
529 | } | ||
530 | |||
531 | static void nv_adma_mode(struct ata_port *ap) | ||
532 | { | ||
533 | void __iomem *mmio = nv_adma_ctl_block(ap); | ||
534 | struct nv_adma_port_priv *pp = ap->private_data; | ||
535 | u16 tmp; | ||
305 | 536 | ||
537 | if (!(pp->flags & NV_ADMA_PORT_REGISTER_MODE)) | ||
538 | return; | ||
539 | |||
540 | WARN_ON(pp->flags & NV_ADMA_ATAPI_SETUP_COMPLETE); | ||
541 | |||
542 | tmp = readw(mmio + NV_ADMA_CTL); | ||
543 | writew(tmp | NV_ADMA_CTL_GO, mmio + NV_ADMA_CTL); | ||
544 | |||
545 | pp->flags &= ~NV_ADMA_PORT_REGISTER_MODE; | ||
546 | } | ||
547 | |||
548 | static int nv_adma_slave_config(struct scsi_device *sdev) | ||
549 | { | ||
550 | struct ata_port *ap = ata_shost_to_port(sdev->host); | ||
551 | struct nv_adma_port_priv *pp = ap->private_data; | ||
552 | struct pci_dev *pdev = to_pci_dev(ap->host->dev); | ||
553 | u64 bounce_limit; | ||
554 | unsigned long segment_boundary; | ||
555 | unsigned short sg_tablesize; | ||
556 | int rc; | ||
557 | int adma_enable; | ||
558 | u32 current_reg, new_reg, config_mask; | ||
559 | |||
560 | rc = ata_scsi_slave_config(sdev); | ||
561 | |||
562 | if (sdev->id >= ATA_MAX_DEVICES || sdev->channel || sdev->lun) | ||
563 | /* Not a proper libata device, ignore */ | ||
564 | return rc; | ||
565 | |||
566 | if (ap->device[sdev->id].class == ATA_DEV_ATAPI) { | ||
567 | /* | ||
568 | * NVIDIA reports that ADMA mode does not support ATAPI commands. | ||
569 | * Therefore ATAPI commands are sent through the legacy interface. | ||
570 | * However, the legacy interface only supports 32-bit DMA. | ||
571 | * Restrict DMA parameters as required by the legacy interface | ||
572 | * when an ATAPI device is connected. | ||
573 | */ | ||
574 | bounce_limit = ATA_DMA_MASK; | ||
575 | segment_boundary = ATA_DMA_BOUNDARY; | ||
576 | /* Subtract 1 since an extra entry may be needed for padding, see | ||
577 | libata-scsi.c */ | ||
578 | sg_tablesize = LIBATA_MAX_PRD - 1; | ||
579 | |||
580 | /* Since the legacy DMA engine is in use, we need to disable ADMA | ||
581 | on the port. */ | ||
582 | adma_enable = 0; | ||
583 | nv_adma_register_mode(ap); | ||
584 | } | ||
585 | else { | ||
586 | bounce_limit = *ap->dev->dma_mask; | ||
587 | segment_boundary = NV_ADMA_DMA_BOUNDARY; | ||
588 | sg_tablesize = NV_ADMA_SGTBL_TOTAL_LEN; | ||
589 | adma_enable = 1; | ||
590 | } | ||
591 | |||
592 | pci_read_config_dword(pdev, NV_MCP_SATA_CFG_20, ¤t_reg); | ||
593 | |||
594 | if(ap->port_no == 1) | ||
595 | config_mask = NV_MCP_SATA_CFG_20_PORT1_EN | | ||
596 | NV_MCP_SATA_CFG_20_PORT1_PWB_EN; | ||
597 | else | ||
598 | config_mask = NV_MCP_SATA_CFG_20_PORT0_EN | | ||
599 | NV_MCP_SATA_CFG_20_PORT0_PWB_EN; | ||
600 | |||
601 | if(adma_enable) { | ||
602 | new_reg = current_reg | config_mask; | ||
603 | pp->flags &= ~NV_ADMA_ATAPI_SETUP_COMPLETE; | ||
604 | } | ||
605 | else { | ||
606 | new_reg = current_reg & ~config_mask; | ||
607 | pp->flags |= NV_ADMA_ATAPI_SETUP_COMPLETE; | ||
306 | } | 608 | } |
609 | |||
610 | if(current_reg != new_reg) | ||
611 | pci_write_config_dword(pdev, NV_MCP_SATA_CFG_20, new_reg); | ||
612 | |||
613 | blk_queue_bounce_limit(sdev->request_queue, bounce_limit); | ||
614 | blk_queue_segment_boundary(sdev->request_queue, segment_boundary); | ||
615 | blk_queue_max_hw_segments(sdev->request_queue, sg_tablesize); | ||
616 | ata_port_printk(ap, KERN_INFO, | ||
617 | "bounce limit 0x%llX, segment boundary 0x%lX, hw segs %hu\n", | ||
618 | (unsigned long long)bounce_limit, segment_boundary, sg_tablesize); | ||
619 | return rc; | ||
620 | } | ||
307 | 621 | ||
308 | spin_unlock_irqrestore(&host->lock, flags); | 622 | static int nv_adma_check_atapi_dma(struct ata_queued_cmd *qc) |
623 | { | ||
624 | struct nv_adma_port_priv *pp = qc->ap->private_data; | ||
625 | return !(pp->flags & NV_ADMA_ATAPI_SETUP_COMPLETE); | ||
626 | } | ||
309 | 627 | ||
310 | return IRQ_RETVAL(handled); | 628 | static unsigned int nv_adma_tf_to_cpb(struct ata_taskfile *tf, __le16 *cpb) |
629 | { | ||
630 | unsigned int idx = 0; | ||
631 | |||
632 | cpb[idx++] = cpu_to_le16((ATA_REG_DEVICE << 8) | tf->device | WNB); | ||
633 | |||
634 | if ((tf->flags & ATA_TFLAG_LBA48) == 0) { | ||
635 | cpb[idx++] = cpu_to_le16(IGN); | ||
636 | cpb[idx++] = cpu_to_le16(IGN); | ||
637 | cpb[idx++] = cpu_to_le16(IGN); | ||
638 | cpb[idx++] = cpu_to_le16(IGN); | ||
639 | cpb[idx++] = cpu_to_le16(IGN); | ||
640 | } | ||
641 | else { | ||
642 | cpb[idx++] = cpu_to_le16((ATA_REG_ERR << 8) | tf->hob_feature); | ||
643 | cpb[idx++] = cpu_to_le16((ATA_REG_NSECT << 8) | tf->hob_nsect); | ||
644 | cpb[idx++] = cpu_to_le16((ATA_REG_LBAL << 8) | tf->hob_lbal); | ||
645 | cpb[idx++] = cpu_to_le16((ATA_REG_LBAM << 8) | tf->hob_lbam); | ||
646 | cpb[idx++] = cpu_to_le16((ATA_REG_LBAH << 8) | tf->hob_lbah); | ||
647 | } | ||
648 | cpb[idx++] = cpu_to_le16((ATA_REG_ERR << 8) | tf->feature); | ||
649 | cpb[idx++] = cpu_to_le16((ATA_REG_NSECT << 8) | tf->nsect); | ||
650 | cpb[idx++] = cpu_to_le16((ATA_REG_LBAL << 8) | tf->lbal); | ||
651 | cpb[idx++] = cpu_to_le16((ATA_REG_LBAM << 8) | tf->lbam); | ||
652 | cpb[idx++] = cpu_to_le16((ATA_REG_LBAH << 8) | tf->lbah); | ||
653 | |||
654 | cpb[idx++] = cpu_to_le16((ATA_REG_CMD << 8) | tf->command | CMDEND); | ||
655 | |||
656 | return idx; | ||
657 | } | ||
658 | |||
659 | static void nv_adma_check_cpb(struct ata_port *ap, int cpb_num, int force_err) | ||
660 | { | ||
661 | struct nv_adma_port_priv *pp = ap->private_data; | ||
662 | int complete = 0, have_err = 0; | ||
663 | u8 flags = pp->cpb[cpb_num].resp_flags; | ||
664 | |||
665 | VPRINTK("CPB %d, flags=0x%x\n", cpb_num, flags); | ||
666 | |||
667 | if (flags & NV_CPB_RESP_DONE) { | ||
668 | VPRINTK("CPB flags done, flags=0x%x\n", flags); | ||
669 | complete = 1; | ||
670 | } | ||
671 | if (flags & NV_CPB_RESP_ATA_ERR) { | ||
672 | ata_port_printk(ap, KERN_ERR, "CPB flags ATA err, flags=0x%x\n", flags); | ||
673 | have_err = 1; | ||
674 | complete = 1; | ||
675 | } | ||
676 | if (flags & NV_CPB_RESP_CMD_ERR) { | ||
677 | ata_port_printk(ap, KERN_ERR, "CPB flags CMD err, flags=0x%x\n", flags); | ||
678 | have_err = 1; | ||
679 | complete = 1; | ||
680 | } | ||
681 | if (flags & NV_CPB_RESP_CPB_ERR) { | ||
682 | ata_port_printk(ap, KERN_ERR, "CPB flags CPB err, flags=0x%x\n", flags); | ||
683 | have_err = 1; | ||
684 | complete = 1; | ||
685 | } | ||
686 | if(complete || force_err) | ||
687 | { | ||
688 | struct ata_queued_cmd *qc = ata_qc_from_tag(ap, cpb_num); | ||
689 | if(likely(qc)) { | ||
690 | u8 ata_status = 0; | ||
691 | /* Only use the ATA port status for non-NCQ commands. | ||
692 | For NCQ commands the current status may have nothing to do with | ||
693 | the command just completed. */ | ||
694 | if(qc->tf.protocol != ATA_PROT_NCQ) | ||
695 | ata_status = readb(nv_adma_ctl_block(ap) + (ATA_REG_STATUS * 4)); | ||
696 | |||
697 | if(have_err || force_err) | ||
698 | ata_status |= ATA_ERR; | ||
699 | |||
700 | qc->err_mask |= ac_err_mask(ata_status); | ||
701 | DPRINTK("Completing qc from tag %d with err_mask %u\n",cpb_num, | ||
702 | qc->err_mask); | ||
703 | ata_qc_complete(qc); | ||
704 | } | ||
705 | } | ||
311 | } | 706 | } |
312 | 707 | ||
313 | static int nv_host_intr(struct ata_port *ap, u8 irq_stat) | 708 | static int nv_host_intr(struct ata_port *ap, u8 irq_stat) |
@@ -341,6 +736,486 @@ static int nv_host_intr(struct ata_port *ap, u8 irq_stat) | |||
341 | return 1; | 736 | return 1; |
342 | } | 737 | } |
343 | 738 | ||
739 | static irqreturn_t nv_adma_interrupt(int irq, void *dev_instance) | ||
740 | { | ||
741 | struct ata_host *host = dev_instance; | ||
742 | int i, handled = 0; | ||
743 | u32 notifier_clears[2]; | ||
744 | |||
745 | spin_lock(&host->lock); | ||
746 | |||
747 | for (i = 0; i < host->n_ports; i++) { | ||
748 | struct ata_port *ap = host->ports[i]; | ||
749 | notifier_clears[i] = 0; | ||
750 | |||
751 | if (ap && !(ap->flags & ATA_FLAG_DISABLED)) { | ||
752 | struct nv_adma_port_priv *pp = ap->private_data; | ||
753 | void __iomem *mmio = nv_adma_ctl_block(ap); | ||
754 | u16 status; | ||
755 | u32 gen_ctl; | ||
756 | int have_global_err = 0; | ||
757 | u32 notifier, notifier_error; | ||
758 | |||
759 | /* if in ATA register mode, use standard ata interrupt handler */ | ||
760 | if (pp->flags & NV_ADMA_PORT_REGISTER_MODE) { | ||
761 | u8 irq_stat = readb(host->mmio_base + NV_INT_STATUS_CK804) | ||
762 | >> (NV_INT_PORT_SHIFT * i); | ||
763 | handled += nv_host_intr(ap, irq_stat); | ||
764 | continue; | ||
765 | } | ||
766 | |||
767 | notifier = readl(mmio + NV_ADMA_NOTIFIER); | ||
768 | notifier_error = readl(mmio + NV_ADMA_NOTIFIER_ERROR); | ||
769 | notifier_clears[i] = notifier | notifier_error; | ||
770 | |||
771 | gen_ctl = readl(nv_adma_gen_block(ap) + NV_ADMA_GEN_CTL); | ||
772 | |||
773 | if( !NV_ADMA_CHECK_INTR(gen_ctl, ap->port_no) && !notifier && | ||
774 | !notifier_error) | ||
775 | /* Nothing to do */ | ||
776 | continue; | ||
777 | |||
778 | status = readw(mmio + NV_ADMA_STAT); | ||
779 | |||
780 | /* Clear status. Ensure the controller sees the clearing before we start | ||
781 | looking at any of the CPB statuses, so that any CPB completions after | ||
782 | this point in the handler will raise another interrupt. */ | ||
783 | writew(status, mmio + NV_ADMA_STAT); | ||
784 | readw(mmio + NV_ADMA_STAT); /* flush posted write */ | ||
785 | rmb(); | ||
786 | |||
787 | /* freeze if hotplugged */ | ||
788 | if (unlikely(status & (NV_ADMA_STAT_HOTPLUG | NV_ADMA_STAT_HOTUNPLUG))) { | ||
789 | ata_port_printk(ap, KERN_NOTICE, "Hotplug event, freezing\n"); | ||
790 | ata_port_freeze(ap); | ||
791 | handled++; | ||
792 | continue; | ||
793 | } | ||
794 | |||
795 | if (status & NV_ADMA_STAT_TIMEOUT) { | ||
796 | ata_port_printk(ap, KERN_ERR, "timeout, stat=0x%x\n", status); | ||
797 | have_global_err = 1; | ||
798 | } | ||
799 | if (status & NV_ADMA_STAT_CPBERR) { | ||
800 | ata_port_printk(ap, KERN_ERR, "CPB error, stat=0x%x\n", status); | ||
801 | have_global_err = 1; | ||
802 | } | ||
803 | if ((status & NV_ADMA_STAT_DONE) || have_global_err) { | ||
804 | /** Check CPBs for completed commands */ | ||
805 | |||
806 | if(ata_tag_valid(ap->active_tag)) | ||
807 | /* Non-NCQ command */ | ||
808 | nv_adma_check_cpb(ap, ap->active_tag, have_global_err || | ||
809 | (notifier_error & (1 << ap->active_tag))); | ||
810 | else { | ||
811 | int pos; | ||
812 | u32 active = ap->sactive; | ||
813 | while( (pos = ffs(active)) ) { | ||
814 | pos--; | ||
815 | nv_adma_check_cpb(ap, pos, have_global_err || | ||
816 | (notifier_error & (1 << pos)) ); | ||
817 | active &= ~(1 << pos ); | ||
818 | } | ||
819 | } | ||
820 | } | ||
821 | |||
822 | handled++; /* irq handled if we got here */ | ||
823 | } | ||
824 | } | ||
825 | |||
826 | if(notifier_clears[0] || notifier_clears[1]) { | ||
827 | /* Note: Both notifier clear registers must be written | ||
828 | if either is set, even if one is zero, according to NVIDIA. */ | ||
829 | writel(notifier_clears[0], | ||
830 | nv_adma_notifier_clear_block(host->ports[0])); | ||
831 | writel(notifier_clears[1], | ||
832 | nv_adma_notifier_clear_block(host->ports[1])); | ||
833 | } | ||
834 | |||
835 | spin_unlock(&host->lock); | ||
836 | |||
837 | return IRQ_RETVAL(handled); | ||
838 | } | ||
839 | |||
840 | static void nv_adma_irq_clear(struct ata_port *ap) | ||
841 | { | ||
842 | void __iomem *mmio = nv_adma_ctl_block(ap); | ||
843 | u16 status = readw(mmio + NV_ADMA_STAT); | ||
844 | u32 notifier = readl(mmio + NV_ADMA_NOTIFIER); | ||
845 | u32 notifier_error = readl(mmio + NV_ADMA_NOTIFIER_ERROR); | ||
846 | unsigned long dma_stat_addr = ap->ioaddr.bmdma_addr + ATA_DMA_STATUS; | ||
847 | |||
848 | /* clear ADMA status */ | ||
849 | writew(status, mmio + NV_ADMA_STAT); | ||
850 | writel(notifier | notifier_error, | ||
851 | nv_adma_notifier_clear_block(ap)); | ||
852 | |||
853 | /** clear legacy status */ | ||
854 | outb(inb(dma_stat_addr), dma_stat_addr); | ||
855 | } | ||
856 | |||
857 | static void nv_adma_bmdma_setup(struct ata_queued_cmd *qc) | ||
858 | { | ||
859 | struct ata_port *ap = qc->ap; | ||
860 | unsigned int rw = (qc->tf.flags & ATA_TFLAG_WRITE); | ||
861 | struct nv_adma_port_priv *pp = ap->private_data; | ||
862 | u8 dmactl; | ||
863 | |||
864 | if(!(pp->flags & NV_ADMA_PORT_REGISTER_MODE)) { | ||
865 | WARN_ON(1); | ||
866 | return; | ||
867 | } | ||
868 | |||
869 | /* load PRD table addr. */ | ||
870 | outl(ap->prd_dma, ap->ioaddr.bmdma_addr + ATA_DMA_TABLE_OFS); | ||
871 | |||
872 | /* specify data direction, triple-check start bit is clear */ | ||
873 | dmactl = inb(ap->ioaddr.bmdma_addr + ATA_DMA_CMD); | ||
874 | dmactl &= ~(ATA_DMA_WR | ATA_DMA_START); | ||
875 | if (!rw) | ||
876 | dmactl |= ATA_DMA_WR; | ||
877 | |||
878 | outb(dmactl, ap->ioaddr.bmdma_addr + ATA_DMA_CMD); | ||
879 | |||
880 | /* issue r/w command */ | ||
881 | ata_exec_command(ap, &qc->tf); | ||
882 | } | ||
883 | |||
884 | static void nv_adma_bmdma_start(struct ata_queued_cmd *qc) | ||
885 | { | ||
886 | struct ata_port *ap = qc->ap; | ||
887 | struct nv_adma_port_priv *pp = ap->private_data; | ||
888 | u8 dmactl; | ||
889 | |||
890 | if(!(pp->flags & NV_ADMA_PORT_REGISTER_MODE)) { | ||
891 | WARN_ON(1); | ||
892 | return; | ||
893 | } | ||
894 | |||
895 | /* start host DMA transaction */ | ||
896 | dmactl = inb(ap->ioaddr.bmdma_addr + ATA_DMA_CMD); | ||
897 | outb(dmactl | ATA_DMA_START, | ||
898 | ap->ioaddr.bmdma_addr + ATA_DMA_CMD); | ||
899 | } | ||
900 | |||
901 | static void nv_adma_bmdma_stop(struct ata_queued_cmd *qc) | ||
902 | { | ||
903 | struct ata_port *ap = qc->ap; | ||
904 | struct nv_adma_port_priv *pp = ap->private_data; | ||
905 | |||
906 | if(!(pp->flags & NV_ADMA_PORT_REGISTER_MODE)) | ||
907 | return; | ||
908 | |||
909 | /* clear start/stop bit */ | ||
910 | outb(inb(ap->ioaddr.bmdma_addr + ATA_DMA_CMD) & ~ATA_DMA_START, | ||
911 | ap->ioaddr.bmdma_addr + ATA_DMA_CMD); | ||
912 | |||
913 | /* one-PIO-cycle guaranteed wait, per spec, for HDMA1:0 transition */ | ||
914 | ata_altstatus(ap); /* dummy read */ | ||
915 | } | ||
916 | |||
917 | static u8 nv_adma_bmdma_status(struct ata_port *ap) | ||
918 | { | ||
919 | struct nv_adma_port_priv *pp = ap->private_data; | ||
920 | |||
921 | WARN_ON(!(pp->flags & NV_ADMA_PORT_REGISTER_MODE)); | ||
922 | |||
923 | return inb(ap->ioaddr.bmdma_addr + ATA_DMA_STATUS); | ||
924 | } | ||
925 | |||
926 | static int nv_adma_port_start(struct ata_port *ap) | ||
927 | { | ||
928 | struct device *dev = ap->host->dev; | ||
929 | struct nv_adma_port_priv *pp; | ||
930 | int rc; | ||
931 | void *mem; | ||
932 | dma_addr_t mem_dma; | ||
933 | void __iomem *mmio = nv_adma_ctl_block(ap); | ||
934 | u16 tmp; | ||
935 | |||
936 | VPRINTK("ENTER\n"); | ||
937 | |||
938 | rc = ata_port_start(ap); | ||
939 | if (rc) | ||
940 | return rc; | ||
941 | |||
942 | pp = kzalloc(sizeof(*pp), GFP_KERNEL); | ||
943 | if (!pp) { | ||
944 | rc = -ENOMEM; | ||
945 | goto err_out; | ||
946 | } | ||
947 | |||
948 | mem = dma_alloc_coherent(dev, NV_ADMA_PORT_PRIV_DMA_SZ, | ||
949 | &mem_dma, GFP_KERNEL); | ||
950 | |||
951 | if (!mem) { | ||
952 | rc = -ENOMEM; | ||
953 | goto err_out_kfree; | ||
954 | } | ||
955 | memset(mem, 0, NV_ADMA_PORT_PRIV_DMA_SZ); | ||
956 | |||
957 | /* | ||
958 | * First item in chunk of DMA memory: | ||
959 | * 128-byte command parameter block (CPB) | ||
960 | * one for each command tag | ||
961 | */ | ||
962 | pp->cpb = mem; | ||
963 | pp->cpb_dma = mem_dma; | ||
964 | |||
965 | writel(mem_dma & 0xFFFFFFFF, mmio + NV_ADMA_CPB_BASE_LOW); | ||
966 | writel((mem_dma >> 16 ) >> 16, mmio + NV_ADMA_CPB_BASE_HIGH); | ||
967 | |||
968 | mem += NV_ADMA_MAX_CPBS * NV_ADMA_CPB_SZ; | ||
969 | mem_dma += NV_ADMA_MAX_CPBS * NV_ADMA_CPB_SZ; | ||
970 | |||
971 | /* | ||
972 | * Second item: block of ADMA_SGTBL_LEN s/g entries | ||
973 | */ | ||
974 | pp->aprd = mem; | ||
975 | pp->aprd_dma = mem_dma; | ||
976 | |||
977 | ap->private_data = pp; | ||
978 | |||
979 | /* clear any outstanding interrupt conditions */ | ||
980 | writew(0xffff, mmio + NV_ADMA_STAT); | ||
981 | |||
982 | /* initialize port variables */ | ||
983 | pp->flags = NV_ADMA_PORT_REGISTER_MODE; | ||
984 | |||
985 | /* clear CPB fetch count */ | ||
986 | writew(0, mmio + NV_ADMA_CPB_COUNT); | ||
987 | |||
988 | /* clear GO for register mode */ | ||
989 | tmp = readw(mmio + NV_ADMA_CTL); | ||
990 | writew(tmp & ~NV_ADMA_CTL_GO, mmio + NV_ADMA_CTL); | ||
991 | |||
992 | tmp = readw(mmio + NV_ADMA_CTL); | ||
993 | writew(tmp | NV_ADMA_CTL_CHANNEL_RESET, mmio + NV_ADMA_CTL); | ||
994 | readl( mmio + NV_ADMA_CTL ); /* flush posted write */ | ||
995 | udelay(1); | ||
996 | writew(tmp & ~NV_ADMA_CTL_CHANNEL_RESET, mmio + NV_ADMA_CTL); | ||
997 | readl( mmio + NV_ADMA_CTL ); /* flush posted write */ | ||
998 | |||
999 | return 0; | ||
1000 | |||
1001 | err_out_kfree: | ||
1002 | kfree(pp); | ||
1003 | err_out: | ||
1004 | ata_port_stop(ap); | ||
1005 | return rc; | ||
1006 | } | ||
1007 | |||
1008 | static void nv_adma_port_stop(struct ata_port *ap) | ||
1009 | { | ||
1010 | struct device *dev = ap->host->dev; | ||
1011 | struct nv_adma_port_priv *pp = ap->private_data; | ||
1012 | void __iomem *mmio = nv_adma_ctl_block(ap); | ||
1013 | |||
1014 | VPRINTK("ENTER\n"); | ||
1015 | |||
1016 | writew(0, mmio + NV_ADMA_CTL); | ||
1017 | |||
1018 | ap->private_data = NULL; | ||
1019 | dma_free_coherent(dev, NV_ADMA_PORT_PRIV_DMA_SZ, pp->cpb, pp->cpb_dma); | ||
1020 | kfree(pp); | ||
1021 | ata_port_stop(ap); | ||
1022 | } | ||
1023 | |||
1024 | |||
1025 | static void nv_adma_setup_port(struct ata_probe_ent *probe_ent, unsigned int port) | ||
1026 | { | ||
1027 | void __iomem *mmio = probe_ent->mmio_base; | ||
1028 | struct ata_ioports *ioport = &probe_ent->port[port]; | ||
1029 | |||
1030 | VPRINTK("ENTER\n"); | ||
1031 | |||
1032 | mmio += NV_ADMA_PORT + port * NV_ADMA_PORT_SIZE; | ||
1033 | |||
1034 | ioport->cmd_addr = (unsigned long) mmio; | ||
1035 | ioport->data_addr = (unsigned long) mmio + (ATA_REG_DATA * 4); | ||
1036 | ioport->error_addr = | ||
1037 | ioport->feature_addr = (unsigned long) mmio + (ATA_REG_ERR * 4); | ||
1038 | ioport->nsect_addr = (unsigned long) mmio + (ATA_REG_NSECT * 4); | ||
1039 | ioport->lbal_addr = (unsigned long) mmio + (ATA_REG_LBAL * 4); | ||
1040 | ioport->lbam_addr = (unsigned long) mmio + (ATA_REG_LBAM * 4); | ||
1041 | ioport->lbah_addr = (unsigned long) mmio + (ATA_REG_LBAH * 4); | ||
1042 | ioport->device_addr = (unsigned long) mmio + (ATA_REG_DEVICE * 4); | ||
1043 | ioport->status_addr = | ||
1044 | ioport->command_addr = (unsigned long) mmio + (ATA_REG_STATUS * 4); | ||
1045 | ioport->altstatus_addr = | ||
1046 | ioport->ctl_addr = (unsigned long) mmio + 0x20; | ||
1047 | } | ||
1048 | |||
1049 | static int nv_adma_host_init(struct ata_probe_ent *probe_ent) | ||
1050 | { | ||
1051 | struct pci_dev *pdev = to_pci_dev(probe_ent->dev); | ||
1052 | unsigned int i; | ||
1053 | u32 tmp32; | ||
1054 | |||
1055 | VPRINTK("ENTER\n"); | ||
1056 | |||
1057 | /* enable ADMA on the ports */ | ||
1058 | pci_read_config_dword(pdev, NV_MCP_SATA_CFG_20, &tmp32); | ||
1059 | tmp32 |= NV_MCP_SATA_CFG_20_PORT0_EN | | ||
1060 | NV_MCP_SATA_CFG_20_PORT0_PWB_EN | | ||
1061 | NV_MCP_SATA_CFG_20_PORT1_EN | | ||
1062 | NV_MCP_SATA_CFG_20_PORT1_PWB_EN; | ||
1063 | |||
1064 | pci_write_config_dword(pdev, NV_MCP_SATA_CFG_20, tmp32); | ||
1065 | |||
1066 | for (i = 0; i < probe_ent->n_ports; i++) | ||
1067 | nv_adma_setup_port(probe_ent, i); | ||
1068 | |||
1069 | for (i = 0; i < probe_ent->n_ports; i++) { | ||
1070 | void __iomem *mmio = __nv_adma_ctl_block(probe_ent->mmio_base, i); | ||
1071 | u16 tmp; | ||
1072 | |||
1073 | /* enable interrupt, clear reset if not already clear */ | ||
1074 | tmp = readw(mmio + NV_ADMA_CTL); | ||
1075 | writew(tmp | NV_ADMA_CTL_AIEN, mmio + NV_ADMA_CTL); | ||
1076 | } | ||
1077 | |||
1078 | return 0; | ||
1079 | } | ||
1080 | |||
1081 | static void nv_adma_fill_aprd(struct ata_queued_cmd *qc, | ||
1082 | struct scatterlist *sg, | ||
1083 | int idx, | ||
1084 | struct nv_adma_prd *aprd) | ||
1085 | { | ||
1086 | u8 flags; | ||
1087 | |||
1088 | memset(aprd, 0, sizeof(struct nv_adma_prd)); | ||
1089 | |||
1090 | flags = 0; | ||
1091 | if (qc->tf.flags & ATA_TFLAG_WRITE) | ||
1092 | flags |= NV_APRD_WRITE; | ||
1093 | if (idx == qc->n_elem - 1) | ||
1094 | flags |= NV_APRD_END; | ||
1095 | else if (idx != 4) | ||
1096 | flags |= NV_APRD_CONT; | ||
1097 | |||
1098 | aprd->addr = cpu_to_le64(((u64)sg_dma_address(sg))); | ||
1099 | aprd->len = cpu_to_le32(((u32)sg_dma_len(sg))); /* len in bytes */ | ||
1100 | aprd->flags = flags; | ||
1101 | } | ||
1102 | |||
1103 | static void nv_adma_fill_sg(struct ata_queued_cmd *qc, struct nv_adma_cpb *cpb) | ||
1104 | { | ||
1105 | struct nv_adma_port_priv *pp = qc->ap->private_data; | ||
1106 | unsigned int idx; | ||
1107 | struct nv_adma_prd *aprd; | ||
1108 | struct scatterlist *sg; | ||
1109 | |||
1110 | VPRINTK("ENTER\n"); | ||
1111 | |||
1112 | idx = 0; | ||
1113 | |||
1114 | ata_for_each_sg(sg, qc) { | ||
1115 | aprd = (idx < 5) ? &cpb->aprd[idx] : &pp->aprd[NV_ADMA_SGTBL_LEN * qc->tag + (idx-5)]; | ||
1116 | nv_adma_fill_aprd(qc, sg, idx, aprd); | ||
1117 | idx++; | ||
1118 | } | ||
1119 | if (idx > 5) | ||
1120 | cpb->next_aprd = cpu_to_le64(((u64)(pp->aprd_dma + NV_ADMA_SGTBL_SZ * qc->tag))); | ||
1121 | } | ||
1122 | |||
1123 | static void nv_adma_qc_prep(struct ata_queued_cmd *qc) | ||
1124 | { | ||
1125 | struct nv_adma_port_priv *pp = qc->ap->private_data; | ||
1126 | struct nv_adma_cpb *cpb = &pp->cpb[qc->tag]; | ||
1127 | u8 ctl_flags = NV_CPB_CTL_CPB_VALID | | ||
1128 | NV_CPB_CTL_APRD_VALID | | ||
1129 | NV_CPB_CTL_IEN; | ||
1130 | |||
1131 | VPRINTK("qc->flags = 0x%lx\n", qc->flags); | ||
1132 | |||
1133 | if (!(qc->flags & ATA_QCFLAG_DMAMAP) || | ||
1134 | (pp->flags & NV_ADMA_ATAPI_SETUP_COMPLETE)) { | ||
1135 | nv_adma_register_mode(qc->ap); | ||
1136 | ata_qc_prep(qc); | ||
1137 | return; | ||
1138 | } | ||
1139 | |||
1140 | memset(cpb, 0, sizeof(struct nv_adma_cpb)); | ||
1141 | |||
1142 | cpb->len = 3; | ||
1143 | cpb->tag = qc->tag; | ||
1144 | cpb->next_cpb_idx = 0; | ||
1145 | |||
1146 | /* turn on NCQ flags for NCQ commands */ | ||
1147 | if (qc->tf.protocol == ATA_PROT_NCQ) | ||
1148 | ctl_flags |= NV_CPB_CTL_QUEUE | NV_CPB_CTL_FPDMA; | ||
1149 | |||
1150 | nv_adma_tf_to_cpb(&qc->tf, cpb->tf); | ||
1151 | |||
1152 | nv_adma_fill_sg(qc, cpb); | ||
1153 | |||
1154 | /* Be paranoid and don't let the device see NV_CPB_CTL_CPB_VALID until we are | ||
1155 | finished filling in all of the contents */ | ||
1156 | wmb(); | ||
1157 | cpb->ctl_flags = ctl_flags; | ||
1158 | } | ||
1159 | |||
1160 | static unsigned int nv_adma_qc_issue(struct ata_queued_cmd *qc) | ||
1161 | { | ||
1162 | struct nv_adma_port_priv *pp = qc->ap->private_data; | ||
1163 | void __iomem *mmio = nv_adma_ctl_block(qc->ap); | ||
1164 | |||
1165 | VPRINTK("ENTER\n"); | ||
1166 | |||
1167 | if (!(qc->flags & ATA_QCFLAG_DMAMAP) || | ||
1168 | (pp->flags & NV_ADMA_ATAPI_SETUP_COMPLETE)) { | ||
1169 | /* use ATA register mode */ | ||
1170 | VPRINTK("no dmamap or ATAPI, using ATA register mode: 0x%lx\n", qc->flags); | ||
1171 | nv_adma_register_mode(qc->ap); | ||
1172 | return ata_qc_issue_prot(qc); | ||
1173 | } else | ||
1174 | nv_adma_mode(qc->ap); | ||
1175 | |||
1176 | /* write append register, command tag in lower 8 bits | ||
1177 | and (number of cpbs to append -1) in top 8 bits */ | ||
1178 | wmb(); | ||
1179 | writew(qc->tag, mmio + NV_ADMA_APPEND); | ||
1180 | |||
1181 | DPRINTK("Issued tag %u\n",qc->tag); | ||
1182 | |||
1183 | return 0; | ||
1184 | } | ||
1185 | |||
1186 | static irqreturn_t nv_generic_interrupt(int irq, void *dev_instance) | ||
1187 | { | ||
1188 | struct ata_host *host = dev_instance; | ||
1189 | unsigned int i; | ||
1190 | unsigned int handled = 0; | ||
1191 | unsigned long flags; | ||
1192 | |||
1193 | spin_lock_irqsave(&host->lock, flags); | ||
1194 | |||
1195 | for (i = 0; i < host->n_ports; i++) { | ||
1196 | struct ata_port *ap; | ||
1197 | |||
1198 | ap = host->ports[i]; | ||
1199 | if (ap && | ||
1200 | !(ap->flags & ATA_FLAG_DISABLED)) { | ||
1201 | struct ata_queued_cmd *qc; | ||
1202 | |||
1203 | qc = ata_qc_from_tag(ap, ap->active_tag); | ||
1204 | if (qc && (!(qc->tf.flags & ATA_TFLAG_POLLING))) | ||
1205 | handled += ata_host_intr(ap, qc); | ||
1206 | else | ||
1207 | // No request pending? Clear interrupt status | ||
1208 | // anyway, in case there's one pending. | ||
1209 | ap->ops->check_status(ap); | ||
1210 | } | ||
1211 | |||
1212 | } | ||
1213 | |||
1214 | spin_unlock_irqrestore(&host->lock, flags); | ||
1215 | |||
1216 | return IRQ_RETVAL(handled); | ||
1217 | } | ||
1218 | |||
344 | static irqreturn_t nv_do_interrupt(struct ata_host *host, u8 irq_stat) | 1219 | static irqreturn_t nv_do_interrupt(struct ata_host *host, u8 irq_stat) |
345 | { | 1220 | { |
346 | int i, handled = 0; | 1221 | int i, handled = 0; |
@@ -466,6 +1341,56 @@ static void nv_error_handler(struct ata_port *ap) | |||
466 | nv_hardreset, ata_std_postreset); | 1341 | nv_hardreset, ata_std_postreset); |
467 | } | 1342 | } |
468 | 1343 | ||
1344 | static void nv_adma_error_handler(struct ata_port *ap) | ||
1345 | { | ||
1346 | struct nv_adma_port_priv *pp = ap->private_data; | ||
1347 | if(!(pp->flags & NV_ADMA_PORT_REGISTER_MODE)) { | ||
1348 | void __iomem *mmio = nv_adma_ctl_block(ap); | ||
1349 | int i; | ||
1350 | u16 tmp; | ||
1351 | |||
1352 | u32 notifier = readl(mmio + NV_ADMA_NOTIFIER); | ||
1353 | u32 notifier_error = readl(mmio + NV_ADMA_NOTIFIER_ERROR); | ||
1354 | u32 gen_ctl = readl(nv_adma_gen_block(ap) + NV_ADMA_GEN_CTL); | ||
1355 | u32 status = readw(mmio + NV_ADMA_STAT); | ||
1356 | |||
1357 | ata_port_printk(ap, KERN_ERR, "EH in ADMA mode, notifier 0x%X " | ||
1358 | "notifier_error 0x%X gen_ctl 0x%X status 0x%X\n", | ||
1359 | notifier, notifier_error, gen_ctl, status); | ||
1360 | |||
1361 | for( i=0;i<NV_ADMA_MAX_CPBS;i++) { | ||
1362 | struct nv_adma_cpb *cpb = &pp->cpb[i]; | ||
1363 | if( cpb->ctl_flags || cpb->resp_flags ) | ||
1364 | ata_port_printk(ap, KERN_ERR, | ||
1365 | "CPB %d: ctl_flags 0x%x, resp_flags 0x%x\n", | ||
1366 | i, cpb->ctl_flags, cpb->resp_flags); | ||
1367 | } | ||
1368 | |||
1369 | /* Push us back into port register mode for error handling. */ | ||
1370 | nv_adma_register_mode(ap); | ||
1371 | |||
1372 | ata_port_printk(ap, KERN_ERR, "Resetting port\n"); | ||
1373 | |||
1374 | /* Mark all of the CPBs as invalid to prevent them from being executed */ | ||
1375 | for( i=0;i<NV_ADMA_MAX_CPBS;i++) | ||
1376 | pp->cpb[i].ctl_flags &= ~NV_CPB_CTL_CPB_VALID; | ||
1377 | |||
1378 | /* clear CPB fetch count */ | ||
1379 | writew(0, mmio + NV_ADMA_CPB_COUNT); | ||
1380 | |||
1381 | /* Reset channel */ | ||
1382 | tmp = readw(mmio + NV_ADMA_CTL); | ||
1383 | writew(tmp | NV_ADMA_CTL_CHANNEL_RESET, mmio + NV_ADMA_CTL); | ||
1384 | readl( mmio + NV_ADMA_CTL ); /* flush posted write */ | ||
1385 | udelay(1); | ||
1386 | writew(tmp & ~NV_ADMA_CTL_CHANNEL_RESET, mmio + NV_ADMA_CTL); | ||
1387 | readl( mmio + NV_ADMA_CTL ); /* flush posted write */ | ||
1388 | } | ||
1389 | |||
1390 | ata_bmdma_drive_eh(ap, ata_std_prereset, ata_std_softreset, | ||
1391 | nv_hardreset, ata_std_postreset); | ||
1392 | } | ||
1393 | |||
469 | static int nv_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) | 1394 | static int nv_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) |
470 | { | 1395 | { |
471 | static int printed_version = 0; | 1396 | static int printed_version = 0; |
@@ -475,6 +1400,8 @@ static int nv_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) | |||
475 | int rc; | 1400 | int rc; |
476 | u32 bar; | 1401 | u32 bar; |
477 | unsigned long base; | 1402 | unsigned long base; |
1403 | unsigned long type = ent->driver_data; | ||
1404 | int mask_set = 0; | ||
478 | 1405 | ||
479 | // Make sure this is a SATA controller by counting the number of bars | 1406 | // Make sure this is a SATA controller by counting the number of bars |
480 | // (NVIDIA SATA controllers will always have six bars). Otherwise, | 1407 | // (NVIDIA SATA controllers will always have six bars). Otherwise, |
@@ -483,7 +1410,7 @@ static int nv_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) | |||
483 | if (pci_resource_start(pdev, bar) == 0) | 1410 | if (pci_resource_start(pdev, bar) == 0) |
484 | return -ENODEV; | 1411 | return -ENODEV; |
485 | 1412 | ||
486 | if (!printed_version++) | 1413 | if ( !printed_version++) |
487 | dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n"); | 1414 | dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n"); |
488 | 1415 | ||
489 | rc = pci_enable_device(pdev); | 1416 | rc = pci_enable_device(pdev); |
@@ -496,16 +1423,26 @@ static int nv_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) | |||
496 | goto err_out_disable; | 1423 | goto err_out_disable; |
497 | } | 1424 | } |
498 | 1425 | ||
499 | rc = pci_set_dma_mask(pdev, ATA_DMA_MASK); | 1426 | if(type >= CK804 && adma_enabled) { |
500 | if (rc) | 1427 | dev_printk(KERN_NOTICE, &pdev->dev, "Using ADMA mode\n"); |
501 | goto err_out_regions; | 1428 | type = ADMA; |
502 | rc = pci_set_consistent_dma_mask(pdev, ATA_DMA_MASK); | 1429 | if(!pci_set_dma_mask(pdev, DMA_64BIT_MASK) && |
503 | if (rc) | 1430 | !pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK)) |
504 | goto err_out_regions; | 1431 | mask_set = 1; |
1432 | } | ||
1433 | |||
1434 | if(!mask_set) { | ||
1435 | rc = pci_set_dma_mask(pdev, ATA_DMA_MASK); | ||
1436 | if (rc) | ||
1437 | goto err_out_regions; | ||
1438 | rc = pci_set_consistent_dma_mask(pdev, ATA_DMA_MASK); | ||
1439 | if (rc) | ||
1440 | goto err_out_regions; | ||
1441 | } | ||
505 | 1442 | ||
506 | rc = -ENOMEM; | 1443 | rc = -ENOMEM; |
507 | 1444 | ||
508 | ppi[0] = ppi[1] = &nv_port_info[ent->driver_data]; | 1445 | ppi[0] = ppi[1] = &nv_port_info[type]; |
509 | probe_ent = ata_pci_init_native_mode(pdev, ppi, ATA_PORT_PRIMARY | ATA_PORT_SECONDARY); | 1446 | probe_ent = ata_pci_init_native_mode(pdev, ppi, ATA_PORT_PRIMARY | ATA_PORT_SECONDARY); |
510 | if (!probe_ent) | 1447 | if (!probe_ent) |
511 | goto err_out_regions; | 1448 | goto err_out_regions; |
@@ -522,7 +1459,7 @@ static int nv_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) | |||
522 | probe_ent->port[1].scr_addr = base + NV_PORT1_SCR_REG_OFFSET; | 1459 | probe_ent->port[1].scr_addr = base + NV_PORT1_SCR_REG_OFFSET; |
523 | 1460 | ||
524 | /* enable SATA space for CK804 */ | 1461 | /* enable SATA space for CK804 */ |
525 | if (ent->driver_data == CK804) { | 1462 | if (type >= CK804) { |
526 | u8 regval; | 1463 | u8 regval; |
527 | 1464 | ||
528 | pci_read_config_byte(pdev, NV_MCP_SATA_CFG_20, ®val); | 1465 | pci_read_config_byte(pdev, NV_MCP_SATA_CFG_20, ®val); |
@@ -532,6 +1469,12 @@ static int nv_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) | |||
532 | 1469 | ||
533 | pci_set_master(pdev); | 1470 | pci_set_master(pdev); |
534 | 1471 | ||
1472 | if (type == ADMA) { | ||
1473 | rc = nv_adma_host_init(probe_ent); | ||
1474 | if (rc) | ||
1475 | goto err_out_iounmap; | ||
1476 | } | ||
1477 | |||
535 | rc = ata_device_add(probe_ent); | 1478 | rc = ata_device_add(probe_ent); |
536 | if (rc != NV_PORTS) | 1479 | if (rc != NV_PORTS) |
537 | goto err_out_iounmap; | 1480 | goto err_out_iounmap; |
@@ -566,6 +1509,33 @@ static void nv_ck804_host_stop(struct ata_host *host) | |||
566 | ata_pci_host_stop(host); | 1509 | ata_pci_host_stop(host); |
567 | } | 1510 | } |
568 | 1511 | ||
1512 | static void nv_adma_host_stop(struct ata_host *host) | ||
1513 | { | ||
1514 | struct pci_dev *pdev = to_pci_dev(host->dev); | ||
1515 | int i; | ||
1516 | u32 tmp32; | ||
1517 | |||
1518 | for (i = 0; i < host->n_ports; i++) { | ||
1519 | void __iomem *mmio = __nv_adma_ctl_block(host->mmio_base, i); | ||
1520 | u16 tmp; | ||
1521 | |||
1522 | /* disable interrupt */ | ||
1523 | tmp = readw(mmio + NV_ADMA_CTL); | ||
1524 | writew(tmp & ~NV_ADMA_CTL_AIEN, mmio + NV_ADMA_CTL); | ||
1525 | } | ||
1526 | |||
1527 | /* disable ADMA on the ports */ | ||
1528 | pci_read_config_dword(pdev, NV_MCP_SATA_CFG_20, &tmp32); | ||
1529 | tmp32 &= ~(NV_MCP_SATA_CFG_20_PORT0_EN | | ||
1530 | NV_MCP_SATA_CFG_20_PORT0_PWB_EN | | ||
1531 | NV_MCP_SATA_CFG_20_PORT1_EN | | ||
1532 | NV_MCP_SATA_CFG_20_PORT1_PWB_EN); | ||
1533 | |||
1534 | pci_write_config_dword(pdev, NV_MCP_SATA_CFG_20, tmp32); | ||
1535 | |||
1536 | nv_ck804_host_stop(host); | ||
1537 | } | ||
1538 | |||
569 | static int __init nv_init(void) | 1539 | static int __init nv_init(void) |
570 | { | 1540 | { |
571 | return pci_register_driver(&nv_pci_driver); | 1541 | return pci_register_driver(&nv_pci_driver); |
@@ -578,3 +1548,5 @@ static void __exit nv_exit(void) | |||
578 | 1548 | ||
579 | module_init(nv_init); | 1549 | module_init(nv_init); |
580 | module_exit(nv_exit); | 1550 | module_exit(nv_exit); |
1551 | module_param_named(adma, adma_enabled, bool, 0444); | ||
1552 | MODULE_PARM_DESC(adma, "Enable use of ADMA (Default: true)"); | ||