diff options
Diffstat (limited to 'drivers/ata')
| -rw-r--r-- | drivers/ata/libata-core.c | 23 | ||||
| -rw-r--r-- | drivers/ata/libata-scsi.c | 7 | ||||
| -rw-r--r-- | drivers/ata/pata_pxa.c | 1 | ||||
| -rw-r--r-- | drivers/ata/sata_gemini.c | 2 |
4 files changed, 27 insertions, 6 deletions
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 5ee4adc62342..22ce6accbc5b 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -1324,7 +1324,7 @@ static int ata_hpa_resize(struct ata_device *dev) /* do we need to do it? */ if ((dev->class != ATA_DEV_ATA && dev->class != ATA_DEV_ZAC) || !ata_id_has_lba(dev->id) || !ata_id_hpa_enabled(dev->id) || - (dev->quirks & ATA_QUIRK_BROKEN_HPA)) + (dev->quirks & ATA_QUIRK_BROKEN_HPA) || ata_id_is_locked(dev->id)) return 0; /* read native max address */ @@ -1526,6 +1526,7 @@ unsigned int ata_exec_internal(struct ata_device *dev, struct ata_taskfile *tf, { struct ata_link *link = dev->link; struct ata_port *ap = link->ap; + const bool owns_eh_mutex = ap->host->eh_owner == current; u8 command = tf->command; struct ata_queued_cmd *qc; struct scatterlist sgl; @@ -1603,11 +1604,25 @@ unsigned int ata_exec_internal(struct ata_device *dev, struct ata_taskfile *tf, } } - ata_eh_release(ap); + if (owns_eh_mutex) { + /* + * To prevent that the compiler complains about the + * ata_eh_release() call below. + */ + __acquire(&ap->host->eh_mutex); + ata_eh_release(ap); + } rc = wait_for_completion_timeout(&wait, msecs_to_jiffies(timeout)); - ata_eh_acquire(ap); + if (owns_eh_mutex) { + ata_eh_acquire(ap); + /* + * To prevent that the compiler complains about the above + * ata_eh_acquire() call. + */ + __release(&ap->host->eh_mutex); + } ata_sff_flush_pio_task(ap); @@ -3948,7 +3963,7 @@ int ata_dev_revalidate(struct ata_device *dev, unsigned int new_class, /* verify n_sectors hasn't changed */ if (dev->class != ATA_DEV_ATA || !n_sectors || - dev->n_sectors == n_sectors) + dev->n_sectors == n_sectors || ata_id_is_locked(dev->id)) return 0; /* n_sectors has changed */ diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index c7d2addf3487..46ef1ef6f812 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c @@ -1930,8 +1930,13 @@ static void ata_scsi_rbuf_fill(struct ata_device *dev, struct scsi_cmnd *cmd, memset(ata_scsi_rbuf, 0, ATA_SCSI_RBUF_SIZE); len = actor(dev, cmd, ata_scsi_rbuf); if (len) { + if (WARN_ON(len > ATA_SCSI_RBUF_SIZE)) { + ata_scsi_set_sense(dev, cmd, ABORTED_COMMAND, 0, 0); + spin_unlock_irqrestore(&ata_scsi_rbuf_lock, flags); + return; + } sg_copy_from_buffer(scsi_sglist(cmd), scsi_sg_count(cmd), - ata_scsi_rbuf, ATA_SCSI_RBUF_SIZE); + ata_scsi_rbuf, len); cmd->result = SAM_STAT_GOOD; if (scsi_bufflen(cmd) > len) scsi_set_resid(cmd, scsi_bufflen(cmd) - len); diff --git a/drivers/ata/pata_pxa.c b/drivers/ata/pata_pxa.c index 03dbaf4a13a7..9f63bdfb8576 100644 --- a/drivers/ata/pata_pxa.c +++ b/drivers/ata/pata_pxa.c @@ -286,6 +286,7 @@ static int pxa_ata_probe(struct platform_device *pdev) ret = dmaengine_slave_config(data->dma_chan, &config); if (ret < 0) { dev_err(&pdev->dev, "dma configuration failed: %d\n", ret); + dma_release_channel(data->dma_chan); return ret; } diff --git a/drivers/ata/sata_gemini.c b/drivers/ata/sata_gemini.c index 530ee26b3012..56ae2820df58 100644 --- a/drivers/ata/sata_gemini.c +++ b/drivers/ata/sata_gemini.c @@ -353,7 +353,7 @@ static int gemini_sata_probe(struct platform_device *pdev) if (sg->ide_pins) { ret = gemini_setup_ide_pins(dev); if (ret) - return ret; + goto out_unprep_clk; } dev_info(dev, "set up the Gemini IDE/SATA nexus\n"); |
