projects
/
firefly-linux-kernel-4.4.55.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
Merge branch 'v3.10/topic/gator' into linux-linaro-lsk-v3.10
[firefly-linux-kernel-4.4.55.git]
/
drivers
/
ata
/
libata-core.c
diff --git
a/drivers/ata/libata-core.c
b/drivers/ata/libata-core.c
index 9cf616b5210bcb7b866284caed4f66fa52971a4b..ca7c23d58a038c17c3799c3b75e2156e04024d8a 100644
(file)
--- a/
drivers/ata/libata-core.c
+++ b/
drivers/ata/libata-core.c
@@
-4758,6
+4758,10
@@
void swap_buf_le16(u16 *buf, unsigned int buf_words)
* ata_qc_new - Request an available ATA command, for queueing
* @ap: target port
*
* ata_qc_new - Request an available ATA command, for queueing
* @ap: target port
*
+ * Some ATA host controllers may implement a queue depth which is less
+ * than ATA_MAX_QUEUE. So we shouldn't allocate a tag which is beyond
+ * the hardware limitation.
+ *
* LOCKING:
* None.
*/
* LOCKING:
* None.
*/
@@
-4765,14
+4769,15
@@
void swap_buf_le16(u16 *buf, unsigned int buf_words)
static struct ata_queued_cmd *ata_qc_new(struct ata_port *ap)
{
struct ata_queued_cmd *qc = NULL;
static struct ata_queued_cmd *ata_qc_new(struct ata_port *ap)
{
struct ata_queued_cmd *qc = NULL;
+ unsigned int max_queue = ap->host->n_tags;
unsigned int i, tag;
/* no command while frozen */
if (unlikely(ap->pflags & ATA_PFLAG_FROZEN))
return NULL;
unsigned int i, tag;
/* no command while frozen */
if (unlikely(ap->pflags & ATA_PFLAG_FROZEN))
return NULL;
- for (i = 0
; i < ATA_MAX_QUEUE; i
++) {
- tag =
(i + ap->last_tag + 1) % ATA_MAX_QUEUE
;
+ for (i = 0
, tag = ap->last_tag + 1; i < max_queue; i++, tag
++) {
+ tag =
tag < max_queue ? tag : 0
;
/* the last tag is reserved for internal command. */
if (tag == ATA_TAG_INTERNAL)
/* the last tag is reserved for internal command. */
if (tag == ATA_TAG_INTERNAL)
@@
-6073,6
+6078,7
@@
void ata_host_init(struct ata_host *host, struct device *dev,
{
spin_lock_init(&host->lock);
mutex_init(&host->eh_mutex);
{
spin_lock_init(&host->lock);
mutex_init(&host->eh_mutex);
+ host->n_tags = ATA_MAX_QUEUE - 1;
host->dev = dev;
host->ops = ops;
}
host->dev = dev;
host->ops = ops;
}
@@
-6154,6
+6160,8
@@
int ata_host_register(struct ata_host *host, struct scsi_host_template *sht)
{
int i, rc;
{
int i, rc;
+ host->n_tags = clamp(sht->can_queue, 1, ATA_MAX_QUEUE - 1);
+
/* host must have been started */
if (!(host->flags & ATA_HOST_STARTED)) {
dev_err(host->dev, "BUG: trying to register unstarted host\n");
/* host must have been started */
if (!(host->flags & ATA_HOST_STARTED)) {
dev_err(host->dev, "BUG: trying to register unstarted host\n");
@@
-6300,6
+6308,8
@@
int ata_host_activate(struct ata_host *host, int irq,
static void ata_port_detach(struct ata_port *ap)
{
unsigned long flags;
static void ata_port_detach(struct ata_port *ap)
{
unsigned long flags;
+ struct ata_link *link;
+ struct ata_device *dev;
if (!ap->ops->error_handler)
goto skip_eh;
if (!ap->ops->error_handler)
goto skip_eh;
@@
-6319,6
+6329,13
@@
static void ata_port_detach(struct ata_port *ap)
cancel_delayed_work_sync(&ap->hotplug_task);
skip_eh:
cancel_delayed_work_sync(&ap->hotplug_task);
skip_eh:
+ /* clean up zpodd on port removal */
+ ata_for_each_link(link, ap, HOST_FIRST) {
+ ata_for_each_dev(dev, link, ALL) {
+ if (zpodd_dev_enabled(dev))
+ zpodd_exit(dev);
+ }
+ }
if (ap->pmp_link) {
int i;
for (i = 0; i < SATA_PMP_MAX_PORTS; i++)
if (ap->pmp_link) {
int i;
for (i = 0; i < SATA_PMP_MAX_PORTS; i++)