Commit 98bd4be1 authored by Shaohua Li's avatar Shaohua Li Committed by Jens Axboe

libata: move sas ata tag allocation to libata-scsi.c

Basically move the sas ata tag allocation to libata-scsi.c to make it clear
these staffs are just for sas.
Signed-off-by: default avatarShaohua Li <shli@fb.com>
Signed-off-by: default avatarJens Axboe <axboe@fb.com>
parent 12cb5ce1
...@@ -1525,15 +1525,6 @@ static void ata_qc_complete_internal(struct ata_queued_cmd *qc) ...@@ -1525,15 +1525,6 @@ static void ata_qc_complete_internal(struct ata_queued_cmd *qc)
complete(waiting); complete(waiting);
} }
static bool ata_valid_internal_tag(struct ata_port *ap, struct ata_device *dev,
unsigned int tag)
{
if (!ap->scsi_host)
return !test_and_set_bit(tag, &ap->sas_tag_allocated);
return !dev->sdev ||
!blk_queue_find_tag(dev->sdev->request_queue, tag);
}
/** /**
* ata_exec_internal_sg - execute libata internal command * ata_exec_internal_sg - execute libata internal command
* @dev: Device to which the command is sent * @dev: Device to which the command is sent
...@@ -1594,7 +1585,6 @@ unsigned ata_exec_internal_sg(struct ata_device *dev, ...@@ -1594,7 +1585,6 @@ unsigned ata_exec_internal_sg(struct ata_device *dev,
else else
tag = 0; tag = 0;
BUG_ON(!ata_valid_internal_tag(ap, dev, tag));
qc = __ata_qc_from_tag(ap, tag); qc = __ata_qc_from_tag(ap, tag);
qc->tag = tag; qc->tag = tag;
...@@ -4734,80 +4724,36 @@ void swap_buf_le16(u16 *buf, unsigned int buf_words) ...@@ -4734,80 +4724,36 @@ void swap_buf_le16(u16 *buf, unsigned int buf_words)
} }
/** /**
* ata_qc_new - Request an available ATA command, for queueing * ata_qc_new_init - Request an available ATA command, and initialize it
* @ap: target port * @dev: Device from whom we request an available command structure
*
* 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: * LOCKING:
* None. * None.
*/ */
static struct ata_queued_cmd *sas_ata_qc_new(struct ata_port *ap) struct ata_queued_cmd *ata_qc_new_init(struct ata_device *dev, int tag)
{
struct ata_queued_cmd *qc = NULL;
unsigned int max_queue = ap->host->n_tags;
unsigned int i, tag;
for (i = 0, tag = ap->sas_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)
continue;
if (!test_and_set_bit(tag, &ap->sas_tag_allocated)) {
qc = __ata_qc_from_tag(ap, tag);
qc->tag = tag;
ap->sas_last_tag = tag;
break;
}
}
return qc;
}
static struct ata_queued_cmd *ata_qc_new(struct ata_port *ap, int blktag)
{ {
struct ata_port *ap = dev->link->ap;
struct ata_queued_cmd *qc; struct ata_queued_cmd *qc;
/* no command while frozen */ /* no command while frozen */
if (unlikely(ap->pflags & ATA_PFLAG_FROZEN)) if (unlikely(ap->pflags & ATA_PFLAG_FROZEN))
return NULL; return NULL;
/* SATA will directly use block tag. libsas need its own tag management */ /* libsas case */
if (ap->scsi_host) { if (!ap->scsi_host) {
qc = __ata_qc_from_tag(ap, blktag); tag = ata_sas_allocate_tag(ap);
qc->tag = blktag; if (tag < 0)
return qc; return NULL;
} }
return sas_ata_qc_new(ap); qc = __ata_qc_from_tag(ap, tag);
} qc->tag = tag;
qc->scsicmd = NULL;
/** qc->ap = ap;
* ata_qc_new_init - Request an available ATA command, and initialize it qc->dev = dev;
* @dev: Device from whom we request an available command structure
*
* LOCKING:
* None.
*/
struct ata_queued_cmd *ata_qc_new_init(struct ata_device *dev, int blktag)
{
struct ata_port *ap = dev->link->ap;
struct ata_queued_cmd *qc;
qc = ata_qc_new(ap, blktag);
if (qc) {
qc->scsicmd = NULL;
qc->ap = ap;
qc->dev = dev;
ata_qc_reinit(qc); ata_qc_reinit(qc);
}
return qc; return qc;
} }
...@@ -4822,12 +4768,6 @@ struct ata_queued_cmd *ata_qc_new_init(struct ata_device *dev, int blktag) ...@@ -4822,12 +4768,6 @@ struct ata_queued_cmd *ata_qc_new_init(struct ata_device *dev, int blktag)
* LOCKING: * LOCKING:
* spin_lock_irqsave(host lock) * spin_lock_irqsave(host lock)
*/ */
static void sas_ata_qc_free(unsigned int tag, struct ata_port *ap)
{
if (!ap->scsi_host)
clear_bit(tag, &ap->sas_tag_allocated);
}
void ata_qc_free(struct ata_queued_cmd *qc) void ata_qc_free(struct ata_queued_cmd *qc)
{ {
struct ata_port *ap; struct ata_port *ap;
...@@ -4840,7 +4780,8 @@ void ata_qc_free(struct ata_queued_cmd *qc) ...@@ -4840,7 +4780,8 @@ void ata_qc_free(struct ata_queued_cmd *qc)
tag = qc->tag; tag = qc->tag;
if (likely(ata_tag_valid(tag))) { if (likely(ata_tag_valid(tag))) {
qc->tag = ATA_TAG_POISON; qc->tag = ATA_TAG_POISON;
sas_ata_qc_free(tag, ap); if (!ap->scsi_host)
ata_sas_free_tag(tag, ap);
} }
} }
......
...@@ -3666,7 +3666,8 @@ int ata_scsi_add_hosts(struct ata_host *host, struct scsi_host_template *sht) ...@@ -3666,7 +3666,8 @@ int ata_scsi_add_hosts(struct ata_host *host, struct scsi_host_template *sht)
*/ */
shost->max_host_blocked = 1; shost->max_host_blocked = 1;
scsi_init_shared_tag_map(shost, host->n_tags); if (scsi_init_shared_tag_map(shost, host->n_tags))
goto err_add;
rc = scsi_add_host_with_dma(ap->scsi_host, rc = scsi_add_host_with_dma(ap->scsi_host,
&ap->tdev, ap->host->dev); &ap->tdev, ap->host->dev);
...@@ -4230,3 +4231,28 @@ int ata_sas_queuecmd(struct scsi_cmnd *cmd, struct ata_port *ap) ...@@ -4230,3 +4231,28 @@ int ata_sas_queuecmd(struct scsi_cmnd *cmd, struct ata_port *ap)
return rc; return rc;
} }
EXPORT_SYMBOL_GPL(ata_sas_queuecmd); EXPORT_SYMBOL_GPL(ata_sas_queuecmd);
int ata_sas_allocate_tag(struct ata_port *ap)
{
unsigned int max_queue = ap->host->n_tags;
unsigned int i, tag;
for (i = 0, tag = ap->sas_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)
continue;
if (!test_and_set_bit(tag, &ap->sas_tag_allocated)) {
ap->sas_last_tag = tag;
return tag;
}
}
return -1;
}
void ata_sas_free_tag(unsigned int tag, struct ata_port *ap)
{
clear_bit(tag, &ap->sas_tag_allocated);
}
...@@ -145,6 +145,8 @@ extern void ata_scsi_dev_rescan(struct work_struct *work); ...@@ -145,6 +145,8 @@ extern void ata_scsi_dev_rescan(struct work_struct *work);
extern int ata_bus_probe(struct ata_port *ap); extern int ata_bus_probe(struct ata_port *ap);
extern int ata_scsi_user_scan(struct Scsi_Host *shost, unsigned int channel, extern int ata_scsi_user_scan(struct Scsi_Host *shost, unsigned int channel,
unsigned int id, u64 lun); unsigned int id, u64 lun);
int ata_sas_allocate_tag(struct ata_port *ap);
void ata_sas_free_tag(unsigned int tag, struct ata_port *ap);
/* libata-eh.c */ /* libata-eh.c */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment