diff options
author | David Woodhouse <dwmw2@infradead.org> | 2008-04-22 07:34:25 -0400 |
---|---|---|
committer | David Woodhouse <dwmw2@infradead.org> | 2008-04-22 07:34:25 -0400 |
commit | f838bad1b3be8ca0c785ee0e0c570dfda74cf377 (patch) | |
tree | 5a842a8056a708cfad55a20fa8ab733dd94b0903 /drivers/ata/pata_ali.c | |
parent | dd919660aacdf4adfcd279556aa03e595f7f0fc2 (diff) | |
parent | 807501475fce0ebe68baedf87f202c3e4ee0d12c (diff) |
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6
Diffstat (limited to 'drivers/ata/pata_ali.c')
-rw-r--r-- | drivers/ata/pata_ali.c | 207 |
1 files changed, 70 insertions, 137 deletions
diff --git a/drivers/ata/pata_ali.c b/drivers/ata/pata_ali.c index 7e68edf3c0f3..fcabe46f262b 100644 --- a/drivers/ata/pata_ali.c +++ b/drivers/ata/pata_ali.c | |||
@@ -36,6 +36,10 @@ | |||
36 | #define DRV_NAME "pata_ali" | 36 | #define DRV_NAME "pata_ali" |
37 | #define DRV_VERSION "0.7.5" | 37 | #define DRV_VERSION "0.7.5" |
38 | 38 | ||
39 | static int ali_atapi_dma = 0; | ||
40 | module_param_named(atapi_dma, ali_atapi_dma, int, 0644); | ||
41 | MODULE_PARM_DESC(atapi_dma, "Enable ATAPI DMA (0=disable, 1=enable)"); | ||
42 | |||
39 | /* | 43 | /* |
40 | * Cable special cases | 44 | * Cable special cases |
41 | */ | 45 | */ |
@@ -117,7 +121,7 @@ static unsigned long ali_20_filter(struct ata_device *adev, unsigned long mask) | |||
117 | ata_id_c_string(adev->id, model_num, ATA_ID_PROD, sizeof(model_num)); | 121 | ata_id_c_string(adev->id, model_num, ATA_ID_PROD, sizeof(model_num)); |
118 | if (strstr(model_num, "WDC")) | 122 | if (strstr(model_num, "WDC")) |
119 | return mask &= ~ATA_MASK_UDMA; | 123 | return mask &= ~ATA_MASK_UDMA; |
120 | return ata_pci_default_filter(adev, mask); | 124 | return ata_bmdma_mode_filter(adev, mask); |
121 | } | 125 | } |
122 | 126 | ||
123 | /** | 127 | /** |
@@ -270,6 +274,27 @@ static void ali_set_dmamode(struct ata_port *ap, struct ata_device *adev) | |||
270 | } | 274 | } |
271 | 275 | ||
272 | /** | 276 | /** |
277 | * ali_warn_atapi_dma - Warn about ATAPI DMA disablement | ||
278 | * @adev: Device | ||
279 | * | ||
280 | * Whine about ATAPI DMA disablement if @adev is an ATAPI device. | ||
281 | * Can be used as ->dev_config. | ||
282 | */ | ||
283 | |||
284 | static void ali_warn_atapi_dma(struct ata_device *adev) | ||
285 | { | ||
286 | struct ata_eh_context *ehc = &adev->link->eh_context; | ||
287 | int print_info = ehc->i.flags & ATA_EHI_PRINTINFO; | ||
288 | |||
289 | if (print_info && adev->class == ATA_DEV_ATAPI && !ali_atapi_dma) { | ||
290 | ata_dev_printk(adev, KERN_WARNING, | ||
291 | "WARNING: ATAPI DMA disabled for reliablity issues. It can be enabled\n"); | ||
292 | ata_dev_printk(adev, KERN_WARNING, | ||
293 | "WARNING: via pata_ali.atapi_dma modparam or corresponding sysfs node.\n"); | ||
294 | } | ||
295 | } | ||
296 | |||
297 | /** | ||
273 | * ali_lock_sectors - Keep older devices to 255 sector mode | 298 | * ali_lock_sectors - Keep older devices to 255 sector mode |
274 | * @adev: Device | 299 | * @adev: Device |
275 | * | 300 | * |
@@ -283,6 +308,7 @@ static void ali_set_dmamode(struct ata_port *ap, struct ata_device *adev) | |||
283 | static void ali_lock_sectors(struct ata_device *adev) | 308 | static void ali_lock_sectors(struct ata_device *adev) |
284 | { | 309 | { |
285 | adev->max_sectors = 255; | 310 | adev->max_sectors = 255; |
311 | ali_warn_atapi_dma(adev); | ||
286 | } | 312 | } |
287 | 313 | ||
288 | /** | 314 | /** |
@@ -294,28 +320,26 @@ static void ali_lock_sectors(struct ata_device *adev) | |||
294 | 320 | ||
295 | static int ali_check_atapi_dma(struct ata_queued_cmd *qc) | 321 | static int ali_check_atapi_dma(struct ata_queued_cmd *qc) |
296 | { | 322 | { |
323 | if (!ali_atapi_dma) { | ||
324 | /* FIXME: pata_ali can't do ATAPI DMA reliably but the | ||
325 | * IDE alim15x3 driver can. I tried lots of things | ||
326 | * but couldn't find what the actual difference was. | ||
327 | * If you got an idea, please write it to | ||
328 | * linux-ide@vger.kernel.org and cc htejun@gmail.com. | ||
329 | * | ||
330 | * Disable ATAPI DMA for now. | ||
331 | */ | ||
332 | return -EOPNOTSUPP; | ||
333 | } | ||
334 | |||
297 | /* If its not a media command, its not worth it */ | 335 | /* If its not a media command, its not worth it */ |
298 | if (qc->nbytes < 2048) | 336 | if (atapi_cmd_type(qc->cdb[0]) == ATAPI_MISC) |
299 | return -EOPNOTSUPP; | 337 | return -EOPNOTSUPP; |
300 | return 0; | 338 | return 0; |
301 | } | 339 | } |
302 | 340 | ||
303 | static struct scsi_host_template ali_sht = { | 341 | static struct scsi_host_template ali_sht = { |
304 | .module = THIS_MODULE, | 342 | ATA_BMDMA_SHT(DRV_NAME), |
305 | .name = DRV_NAME, | ||
306 | .ioctl = ata_scsi_ioctl, | ||
307 | .queuecommand = ata_scsi_queuecmd, | ||
308 | .can_queue = ATA_DEF_QUEUE, | ||
309 | .this_id = ATA_SHT_THIS_ID, | ||
310 | .sg_tablesize = LIBATA_MAX_PRD, | ||
311 | .cmd_per_lun = ATA_SHT_CMD_PER_LUN, | ||
312 | .emulated = ATA_SHT_EMULATED, | ||
313 | .use_clustering = ATA_SHT_USE_CLUSTERING, | ||
314 | .proc_name = DRV_NAME, | ||
315 | .dma_boundary = ATA_DMA_BOUNDARY, | ||
316 | .slave_configure = ata_scsi_slave_config, | ||
317 | .slave_destroy = ata_scsi_slave_destroy, | ||
318 | .bios_param = ata_std_bios_param, | ||
319 | }; | 343 | }; |
320 | 344 | ||
321 | /* | 345 | /* |
@@ -323,29 +347,15 @@ static struct scsi_host_template ali_sht = { | |||
323 | */ | 347 | */ |
324 | 348 | ||
325 | static struct ata_port_operations ali_early_port_ops = { | 349 | static struct ata_port_operations ali_early_port_ops = { |
326 | .set_piomode = ali_set_piomode, | 350 | .inherits = &ata_sff_port_ops, |
327 | .tf_load = ata_tf_load, | ||
328 | .tf_read = ata_tf_read, | ||
329 | .check_status = ata_check_status, | ||
330 | .exec_command = ata_exec_command, | ||
331 | .dev_select = ata_std_dev_select, | ||
332 | |||
333 | .freeze = ata_bmdma_freeze, | ||
334 | .thaw = ata_bmdma_thaw, | ||
335 | .error_handler = ata_bmdma_error_handler, | ||
336 | .post_internal_cmd = ata_bmdma_post_internal_cmd, | ||
337 | .cable_detect = ata_cable_40wire, | 351 | .cable_detect = ata_cable_40wire, |
352 | .set_piomode = ali_set_piomode, | ||
353 | }; | ||
338 | 354 | ||
339 | .qc_prep = ata_qc_prep, | 355 | static const struct ata_port_operations ali_dma_base_ops = { |
340 | .qc_issue = ata_qc_issue_prot, | 356 | .inherits = &ata_bmdma_port_ops, |
341 | 357 | .set_piomode = ali_set_piomode, | |
342 | .data_xfer = ata_data_xfer, | 358 | .set_dmamode = ali_set_dmamode, |
343 | |||
344 | .irq_handler = ata_interrupt, | ||
345 | .irq_clear = ata_bmdma_irq_clear, | ||
346 | .irq_on = ata_irq_on, | ||
347 | |||
348 | .port_start = ata_sff_port_start, | ||
349 | }; | 359 | }; |
350 | 360 | ||
351 | /* | 361 | /* |
@@ -353,113 +363,31 @@ static struct ata_port_operations ali_early_port_ops = { | |||
353 | * detect | 363 | * detect |
354 | */ | 364 | */ |
355 | static struct ata_port_operations ali_20_port_ops = { | 365 | static struct ata_port_operations ali_20_port_ops = { |
356 | .set_piomode = ali_set_piomode, | 366 | .inherits = &ali_dma_base_ops, |
357 | .set_dmamode = ali_set_dmamode, | 367 | .cable_detect = ata_cable_40wire, |
358 | .mode_filter = ali_20_filter, | 368 | .mode_filter = ali_20_filter, |
359 | 369 | .check_atapi_dma = ali_check_atapi_dma, | |
360 | .tf_load = ata_tf_load, | ||
361 | .tf_read = ata_tf_read, | ||
362 | .check_status = ata_check_status, | ||
363 | .exec_command = ata_exec_command, | ||
364 | .dev_select = ata_std_dev_select, | ||
365 | .dev_config = ali_lock_sectors, | 370 | .dev_config = ali_lock_sectors, |
366 | |||
367 | .freeze = ata_bmdma_freeze, | ||
368 | .thaw = ata_bmdma_thaw, | ||
369 | .error_handler = ata_bmdma_error_handler, | ||
370 | .post_internal_cmd = ata_bmdma_post_internal_cmd, | ||
371 | .cable_detect = ata_cable_40wire, | ||
372 | |||
373 | .bmdma_setup = ata_bmdma_setup, | ||
374 | .bmdma_start = ata_bmdma_start, | ||
375 | .bmdma_stop = ata_bmdma_stop, | ||
376 | .bmdma_status = ata_bmdma_status, | ||
377 | |||
378 | .qc_prep = ata_qc_prep, | ||
379 | .qc_issue = ata_qc_issue_prot, | ||
380 | |||
381 | .data_xfer = ata_data_xfer, | ||
382 | |||
383 | .irq_handler = ata_interrupt, | ||
384 | .irq_clear = ata_bmdma_irq_clear, | ||
385 | .irq_on = ata_irq_on, | ||
386 | |||
387 | .port_start = ata_sff_port_start, | ||
388 | }; | 371 | }; |
389 | 372 | ||
390 | /* | 373 | /* |
391 | * Port operations for DMA capable ALi with cable detect | 374 | * Port operations for DMA capable ALi with cable detect |
392 | */ | 375 | */ |
393 | static struct ata_port_operations ali_c2_port_ops = { | 376 | static struct ata_port_operations ali_c2_port_ops = { |
394 | .set_piomode = ali_set_piomode, | 377 | .inherits = &ali_dma_base_ops, |
395 | .set_dmamode = ali_set_dmamode, | ||
396 | .mode_filter = ata_pci_default_filter, | ||
397 | .tf_load = ata_tf_load, | ||
398 | .tf_read = ata_tf_read, | ||
399 | .check_atapi_dma = ali_check_atapi_dma, | 378 | .check_atapi_dma = ali_check_atapi_dma, |
400 | .check_status = ata_check_status, | ||
401 | .exec_command = ata_exec_command, | ||
402 | .dev_select = ata_std_dev_select, | ||
403 | .dev_config = ali_lock_sectors, | ||
404 | |||
405 | .freeze = ata_bmdma_freeze, | ||
406 | .thaw = ata_bmdma_thaw, | ||
407 | .error_handler = ata_bmdma_error_handler, | ||
408 | .post_internal_cmd = ata_bmdma_post_internal_cmd, | ||
409 | .cable_detect = ali_c2_cable_detect, | 379 | .cable_detect = ali_c2_cable_detect, |
410 | 380 | .dev_config = ali_lock_sectors, | |
411 | .bmdma_setup = ata_bmdma_setup, | ||
412 | .bmdma_start = ata_bmdma_start, | ||
413 | .bmdma_stop = ata_bmdma_stop, | ||
414 | .bmdma_status = ata_bmdma_status, | ||
415 | |||
416 | .qc_prep = ata_qc_prep, | ||
417 | .qc_issue = ata_qc_issue_prot, | ||
418 | |||
419 | .data_xfer = ata_data_xfer, | ||
420 | |||
421 | .irq_handler = ata_interrupt, | ||
422 | .irq_clear = ata_bmdma_irq_clear, | ||
423 | .irq_on = ata_irq_on, | ||
424 | |||
425 | .port_start = ata_sff_port_start, | ||
426 | }; | 381 | }; |
427 | 382 | ||
428 | /* | 383 | /* |
429 | * Port operations for DMA capable ALi with cable detect and LBA48 | 384 | * Port operations for DMA capable ALi with cable detect and LBA48 |
430 | */ | 385 | */ |
431 | static struct ata_port_operations ali_c5_port_ops = { | 386 | static struct ata_port_operations ali_c5_port_ops = { |
432 | .set_piomode = ali_set_piomode, | 387 | .inherits = &ali_dma_base_ops, |
433 | .set_dmamode = ali_set_dmamode, | ||
434 | .mode_filter = ata_pci_default_filter, | ||
435 | .tf_load = ata_tf_load, | ||
436 | .tf_read = ata_tf_read, | ||
437 | .check_atapi_dma = ali_check_atapi_dma, | 388 | .check_atapi_dma = ali_check_atapi_dma, |
438 | .check_status = ata_check_status, | 389 | .dev_config = ali_warn_atapi_dma, |
439 | .exec_command = ata_exec_command, | ||
440 | .dev_select = ata_std_dev_select, | ||
441 | |||
442 | .freeze = ata_bmdma_freeze, | ||
443 | .thaw = ata_bmdma_thaw, | ||
444 | .error_handler = ata_bmdma_error_handler, | ||
445 | .post_internal_cmd = ata_bmdma_post_internal_cmd, | ||
446 | .cable_detect = ali_c2_cable_detect, | 390 | .cable_detect = ali_c2_cable_detect, |
447 | |||
448 | .bmdma_setup = ata_bmdma_setup, | ||
449 | .bmdma_start = ata_bmdma_start, | ||
450 | .bmdma_stop = ata_bmdma_stop, | ||
451 | .bmdma_status = ata_bmdma_status, | ||
452 | |||
453 | .qc_prep = ata_qc_prep, | ||
454 | .qc_issue = ata_qc_issue_prot, | ||
455 | |||
456 | .data_xfer = ata_data_xfer, | ||
457 | |||
458 | .irq_handler = ata_interrupt, | ||
459 | .irq_clear = ata_bmdma_irq_clear, | ||
460 | .irq_on = ata_irq_on, | ||
461 | |||
462 | .port_start = ata_sff_port_start, | ||
463 | }; | 391 | }; |
464 | 392 | ||
465 | 393 | ||
@@ -521,7 +449,7 @@ static void ali_init_chipset(struct pci_dev *pdev) | |||
521 | } | 449 | } |
522 | pci_dev_put(isa_bridge); | 450 | pci_dev_put(isa_bridge); |
523 | pci_dev_put(north); | 451 | pci_dev_put(north); |
524 | ata_pci_clear_simplex(pdev); | 452 | ata_pci_bmdma_clear_simplex(pdev); |
525 | } | 453 | } |
526 | /** | 454 | /** |
527 | * ali_init_one - discovery callback | 455 | * ali_init_one - discovery callback |
@@ -535,14 +463,12 @@ static void ali_init_chipset(struct pci_dev *pdev) | |||
535 | static int ali_init_one(struct pci_dev *pdev, const struct pci_device_id *id) | 463 | static int ali_init_one(struct pci_dev *pdev, const struct pci_device_id *id) |
536 | { | 464 | { |
537 | static const struct ata_port_info info_early = { | 465 | static const struct ata_port_info info_early = { |
538 | .sht = &ali_sht, | ||
539 | .flags = ATA_FLAG_SLAVE_POSS, | 466 | .flags = ATA_FLAG_SLAVE_POSS, |
540 | .pio_mask = 0x1f, | 467 | .pio_mask = 0x1f, |
541 | .port_ops = &ali_early_port_ops | 468 | .port_ops = &ali_early_port_ops |
542 | }; | 469 | }; |
543 | /* Revision 0x20 added DMA */ | 470 | /* Revision 0x20 added DMA */ |
544 | static const struct ata_port_info info_20 = { | 471 | static const struct ata_port_info info_20 = { |
545 | .sht = &ali_sht, | ||
546 | .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_PIO_LBA48, | 472 | .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_PIO_LBA48, |
547 | .pio_mask = 0x1f, | 473 | .pio_mask = 0x1f, |
548 | .mwdma_mask = 0x07, | 474 | .mwdma_mask = 0x07, |
@@ -550,7 +476,6 @@ static int ali_init_one(struct pci_dev *pdev, const struct pci_device_id *id) | |||
550 | }; | 476 | }; |
551 | /* Revision 0x20 with support logic added UDMA */ | 477 | /* Revision 0x20 with support logic added UDMA */ |
552 | static const struct ata_port_info info_20_udma = { | 478 | static const struct ata_port_info info_20_udma = { |
553 | .sht = &ali_sht, | ||
554 | .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_PIO_LBA48, | 479 | .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_PIO_LBA48, |
555 | .pio_mask = 0x1f, | 480 | .pio_mask = 0x1f, |
556 | .mwdma_mask = 0x07, | 481 | .mwdma_mask = 0x07, |
@@ -559,7 +484,6 @@ static int ali_init_one(struct pci_dev *pdev, const struct pci_device_id *id) | |||
559 | }; | 484 | }; |
560 | /* Revision 0xC2 adds UDMA66 */ | 485 | /* Revision 0xC2 adds UDMA66 */ |
561 | static const struct ata_port_info info_c2 = { | 486 | static const struct ata_port_info info_c2 = { |
562 | .sht = &ali_sht, | ||
563 | .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_PIO_LBA48, | 487 | .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_PIO_LBA48, |
564 | .pio_mask = 0x1f, | 488 | .pio_mask = 0x1f, |
565 | .mwdma_mask = 0x07, | 489 | .mwdma_mask = 0x07, |
@@ -568,7 +492,6 @@ static int ali_init_one(struct pci_dev *pdev, const struct pci_device_id *id) | |||
568 | }; | 492 | }; |
569 | /* Revision 0xC3 is UDMA66 for now */ | 493 | /* Revision 0xC3 is UDMA66 for now */ |
570 | static const struct ata_port_info info_c3 = { | 494 | static const struct ata_port_info info_c3 = { |
571 | .sht = &ali_sht, | ||
572 | .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_PIO_LBA48, | 495 | .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_PIO_LBA48, |
573 | .pio_mask = 0x1f, | 496 | .pio_mask = 0x1f, |
574 | .mwdma_mask = 0x07, | 497 | .mwdma_mask = 0x07, |
@@ -577,7 +500,6 @@ static int ali_init_one(struct pci_dev *pdev, const struct pci_device_id *id) | |||
577 | }; | 500 | }; |
578 | /* Revision 0xC4 is UDMA100 */ | 501 | /* Revision 0xC4 is UDMA100 */ |
579 | static const struct ata_port_info info_c4 = { | 502 | static const struct ata_port_info info_c4 = { |
580 | .sht = &ali_sht, | ||
581 | .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_PIO_LBA48, | 503 | .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_PIO_LBA48, |
582 | .pio_mask = 0x1f, | 504 | .pio_mask = 0x1f, |
583 | .mwdma_mask = 0x07, | 505 | .mwdma_mask = 0x07, |
@@ -586,7 +508,6 @@ static int ali_init_one(struct pci_dev *pdev, const struct pci_device_id *id) | |||
586 | }; | 508 | }; |
587 | /* Revision 0xC5 is UDMA133 with LBA48 DMA */ | 509 | /* Revision 0xC5 is UDMA133 with LBA48 DMA */ |
588 | static const struct ata_port_info info_c5 = { | 510 | static const struct ata_port_info info_c5 = { |
589 | .sht = &ali_sht, | ||
590 | .flags = ATA_FLAG_SLAVE_POSS, | 511 | .flags = ATA_FLAG_SLAVE_POSS, |
591 | .pio_mask = 0x1f, | 512 | .pio_mask = 0x1f, |
592 | .mwdma_mask = 0x07, | 513 | .mwdma_mask = 0x07, |
@@ -597,6 +518,11 @@ static int ali_init_one(struct pci_dev *pdev, const struct pci_device_id *id) | |||
597 | const struct ata_port_info *ppi[] = { NULL, NULL }; | 518 | const struct ata_port_info *ppi[] = { NULL, NULL }; |
598 | u8 tmp; | 519 | u8 tmp; |
599 | struct pci_dev *isa_bridge; | 520 | struct pci_dev *isa_bridge; |
521 | int rc; | ||
522 | |||
523 | rc = pcim_enable_device(pdev); | ||
524 | if (rc) | ||
525 | return rc; | ||
600 | 526 | ||
601 | /* | 527 | /* |
602 | * The chipset revision selects the driver operations and | 528 | * The chipset revision selects the driver operations and |
@@ -626,14 +552,21 @@ static int ali_init_one(struct pci_dev *pdev, const struct pci_device_id *id) | |||
626 | ppi[0] = &info_20_udma; | 552 | ppi[0] = &info_20_udma; |
627 | pci_dev_put(isa_bridge); | 553 | pci_dev_put(isa_bridge); |
628 | } | 554 | } |
629 | return ata_pci_init_one(pdev, ppi); | 555 | return ata_pci_sff_init_one(pdev, ppi, &ali_sht, NULL); |
630 | } | 556 | } |
631 | 557 | ||
632 | #ifdef CONFIG_PM | 558 | #ifdef CONFIG_PM |
633 | static int ali_reinit_one(struct pci_dev *pdev) | 559 | static int ali_reinit_one(struct pci_dev *pdev) |
634 | { | 560 | { |
561 | struct ata_host *host = dev_get_drvdata(&pdev->dev); | ||
562 | int rc; | ||
563 | |||
564 | rc = ata_pci_device_do_resume(pdev); | ||
565 | if (rc) | ||
566 | return rc; | ||
635 | ali_init_chipset(pdev); | 567 | ali_init_chipset(pdev); |
636 | return ata_pci_device_resume(pdev); | 568 | ata_host_resume(host); |
569 | return 0; | ||
637 | } | 570 | } |
638 | #endif | 571 | #endif |
639 | 572 | ||