aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ata
diff options
context:
space:
mode:
authorTejun Heo <htejun@gmail.com>2008-04-03 01:40:55 -0400
committerJeff Garzik <jeff@garzik.org>2008-04-04 02:43:38 -0400
commit8243e636c060fe7c10c9cf3bf53fdd2d48901525 (patch)
tree0324fb9ab401b403333a9d25ac87f0358a86c9ef /drivers/ata
parente52dcc4899cf1b7601379c31542bd91cd2997a64 (diff)
pata_ali: disable ATAPI DMA
ATAPI DMA just doesn't work reliably on pata_ali. The IDE driver can do it but for some mysterious reason, pata_ali can't. This patch disables it by default and makes the driver whine during initialization. "pata_ali.atapi_dma" parameter is added so that user can bypass the workaround. Signed-off-by: Tejun Heo <htejun@gmail.com> Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'drivers/ata')
-rw-r--r--drivers/ata/pata_ali.c40
1 files changed, 40 insertions, 0 deletions
diff --git a/drivers/ata/pata_ali.c b/drivers/ata/pata_ali.c
index 8786455c901d..ce830fe3a362 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
39int ali_atapi_dma = 0;
40module_param_named(atapi_dma, ali_atapi_dma, int, 0644);
41MODULE_PARM_DESC(atapi_dma, "Enable ATAPI DMA (0=disable, 1=enable)");
42
39/* 43/*
40 * Cable special cases 44 * Cable special cases
41 */ 45 */
@@ -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
284static 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)
283static void ali_lock_sectors(struct ata_device *adev) 308static 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,6 +320,18 @@ static void ali_lock_sectors(struct ata_device *adev)
294 320
295static int ali_check_atapi_dma(struct ata_queued_cmd *qc) 321static 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 (atapi_cmd_type(qc->cdb[0]) == ATAPI_MISC) 336 if (atapi_cmd_type(qc->cdb[0]) == ATAPI_MISC)
299 return -EOPNOTSUPP; 337 return -EOPNOTSUPP;
@@ -359,6 +397,7 @@ static struct ata_port_operations ali_20_port_ops = {
359 397
360 .tf_load = ata_tf_load, 398 .tf_load = ata_tf_load,
361 .tf_read = ata_tf_read, 399 .tf_read = ata_tf_read,
400 .check_atapi_dma = ali_check_atapi_dma,
362 .check_status = ata_check_status, 401 .check_status = ata_check_status,
363 .exec_command = ata_exec_command, 402 .exec_command = ata_exec_command,
364 .dev_select = ata_std_dev_select, 403 .dev_select = ata_std_dev_select,
@@ -438,6 +477,7 @@ static struct ata_port_operations ali_c5_port_ops = {
438 .check_status = ata_check_status, 477 .check_status = ata_check_status,
439 .exec_command = ata_exec_command, 478 .exec_command = ata_exec_command,
440 .dev_select = ata_std_dev_select, 479 .dev_select = ata_std_dev_select,
480 .dev_config = ali_warn_atapi_dma,
441 481
442 .freeze = ata_bmdma_freeze, 482 .freeze = ata_bmdma_freeze,
443 .thaw = ata_bmdma_thaw, 483 .thaw = ata_bmdma_thaw,