diff options
author | Tejun Heo <htejun@gmail.com> | 2008-04-03 01:40:55 -0400 |
---|---|---|
committer | Jeff Garzik <jeff@garzik.org> | 2008-04-04 02:43:38 -0400 |
commit | 8243e636c060fe7c10c9cf3bf53fdd2d48901525 (patch) | |
tree | 0324fb9ab401b403333a9d25ac87f0358a86c9ef /drivers | |
parent | e52dcc4899cf1b7601379c31542bd91cd2997a64 (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')
-rw-r--r-- | drivers/ata/pata_ali.c | 40 |
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 | ||
39 | 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 | */ |
@@ -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,6 +320,18 @@ 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 (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, |