Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+17 −76
Original line number Diff line number Diff line
@@ -1525,15 +1525,6 @@ static void ata_qc_complete_internal(struct ata_queued_cmd *qc)
	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
 *	@dev: Device to which the command is sent
@@ -1594,7 +1585,6 @@ unsigned ata_exec_internal_sg(struct ata_device *dev,
	else
		tag = 0;

	BUG_ON(!ata_valid_internal_tag(ap, dev, tag));
	qc = __ata_qc_from_tag(ap, tag);

	qc->tag = tag;
@@ -4734,80 +4724,36 @@ void swap_buf_le16(u16 *buf, unsigned int buf_words)
}

/**
 *	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.
 *	ata_qc_new_init - Request an available ATA command, and initialize it
 *	@dev: Device from whom we request an available command structure
 *
 *	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 *ata_qc_new_init(struct ata_device *dev, int tag)
{
	struct ata_port *ap = dev->link->ap;
	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);
	/* libsas case */
	if (!ap->scsi_host) {
		tag = ata_sas_allocate_tag(ap);
		if (tag < 0)
			return NULL;
	}

/**
 *	ata_qc_new_init - Request an available ATA command, and initialize it
 *	@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 = __ata_qc_from_tag(ap, tag);
	qc->tag = tag;
	qc->scsicmd = NULL;
	qc->ap = ap;
	qc->dev = dev;

	ata_qc_reinit(qc);
	}

	return qc;
}
@@ -4822,12 +4768,6 @@ struct ata_queued_cmd *ata_qc_new_init(struct ata_device *dev, int blktag)
 *	LOCKING:
 *	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)
{
	struct ata_port *ap;
@@ -4840,7 +4780,8 @@ void ata_qc_free(struct ata_queued_cmd *qc)
	tag = qc->tag;
	if (likely(ata_tag_valid(tag))) {
		qc->tag = ATA_TAG_POISON;
		sas_ata_qc_free(tag, ap);
		if (!ap->scsi_host)
			ata_sas_free_tag(tag, ap);
	}
}

+27 −1
Original line number Diff line number Diff line
@@ -3666,7 +3666,8 @@ int ata_scsi_add_hosts(struct ata_host *host, struct scsi_host_template *sht)
		 */
		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,
						&ap->tdev, ap->host->dev);
@@ -4230,3 +4231,28 @@ int ata_sas_queuecmd(struct scsi_cmnd *cmd, struct ata_port *ap)
	return rc;
}
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);
}
+2 −0
Original line number Diff line number Diff line
@@ -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_scsi_user_scan(struct Scsi_Host *shost, unsigned int channel,
			      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 */