mirror of
https://github.com/torvalds/linux.git
synced 2024-11-18 01:51:53 +00:00
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: Shaohua Li <shli@fb.com> Signed-off-by: Jens Axboe <axboe@fb.com>
This commit is contained in:
parent
12cb5ce101
commit
98bd4be1ba
@ -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,
|
|||||||
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;
|
||||||
@ -4733,60 +4723,6 @@ void swap_buf_le16(u16 *buf, unsigned int buf_words)
|
|||||||
#endif /* __BIG_ENDIAN */
|
#endif /* __BIG_ENDIAN */
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
static struct ata_queued_cmd *sas_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;
|
|
||||||
|
|
||||||
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_queued_cmd *qc;
|
|
||||||
|
|
||||||
/* no command while frozen */
|
|
||||||
if (unlikely(ap->pflags & ATA_PFLAG_FROZEN))
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
/* SATA will directly use block tag. libsas need its own tag management */
|
|
||||||
if (ap->scsi_host) {
|
|
||||||
qc = __ata_qc_from_tag(ap, blktag);
|
|
||||||
qc->tag = blktag;
|
|
||||||
return qc;
|
|
||||||
}
|
|
||||||
|
|
||||||
return sas_ata_qc_new(ap);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ata_qc_new_init - Request an available ATA command, and initialize it
|
* ata_qc_new_init - Request an available ATA command, and initialize it
|
||||||
* @dev: Device from whom we request an available command structure
|
* @dev: Device from whom we request an available command structure
|
||||||
@ -4795,20 +4731,30 @@ static struct ata_queued_cmd *ata_qc_new(struct ata_port *ap, int blktag)
|
|||||||
* None.
|
* None.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
struct ata_queued_cmd *ata_qc_new_init(struct ata_device *dev, int blktag)
|
struct ata_queued_cmd *ata_qc_new_init(struct ata_device *dev, int tag)
|
||||||
{
|
{
|
||||||
struct ata_port *ap = dev->link->ap;
|
struct ata_port *ap = dev->link->ap;
|
||||||
struct ata_queued_cmd *qc;
|
struct ata_queued_cmd *qc;
|
||||||
|
|
||||||
qc = ata_qc_new(ap, blktag);
|
/* no command while frozen */
|
||||||
if (qc) {
|
if (unlikely(ap->pflags & ATA_PFLAG_FROZEN))
|
||||||
qc->scsicmd = NULL;
|
return NULL;
|
||||||
qc->ap = ap;
|
|
||||||
qc->dev = dev;
|
|
||||||
|
|
||||||
ata_qc_reinit(qc);
|
/* libsas case */
|
||||||
|
if (!ap->scsi_host) {
|
||||||
|
tag = ata_sas_allocate_tag(ap);
|
||||||
|
if (tag < 0)
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
qc = __ata_qc_from_tag(ap, tag);
|
||||||
|
qc->tag = tag;
|
||||||
|
qc->scsicmd = NULL;
|
||||||
|
qc->ap = ap;
|
||||||
|
qc->dev = dev;
|
||||||
|
|
||||||
|
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)
|
|||||||
* 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)
|
|||||||
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)
|
|||||||
*/
|
*/
|
||||||
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)
|
|||||||
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);
|
|||||||
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 */
|
||||||
|
Loading…
Reference in New Issue
Block a user