mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 10:40:15 +02:00 
			
		
		
		
	libata: add extra internal command
Bump the internal tag to 32, instead of stealing the last tag in our regular command space. This works just fine, since we don't actually need a separate hardware tag for this. Internal commands cannot coexist with NCQ commands. As a bonus, we get rid of the special casing of what tag to use for the internal command. This is in preparation for utilizing all 32 commands for normal IO. Signed-off-by: Jens Axboe <axboe@kernel.dk> Signed-off-by: Tejun Heo <tj@kernel.org>
This commit is contained in:
		
							parent
							
								
									ba80c3a572
								
							
						
					
					
						commit
						28361c4036
					
				
					 3 changed files with 16 additions and 26 deletions
				
			
		| 
						 | 
					@ -1570,7 +1570,7 @@ unsigned ata_exec_internal_sg(struct ata_device *dev,
 | 
				
			||||||
	u8 command = tf->command;
 | 
						u8 command = tf->command;
 | 
				
			||||||
	int auto_timeout = 0;
 | 
						int auto_timeout = 0;
 | 
				
			||||||
	struct ata_queued_cmd *qc;
 | 
						struct ata_queued_cmd *qc;
 | 
				
			||||||
	unsigned int tag, preempted_tag;
 | 
						unsigned int preempted_tag;
 | 
				
			||||||
	u32 preempted_sactive;
 | 
						u32 preempted_sactive;
 | 
				
			||||||
	u64 preempted_qc_active;
 | 
						u64 preempted_qc_active;
 | 
				
			||||||
	int preempted_nr_active_links;
 | 
						int preempted_nr_active_links;
 | 
				
			||||||
| 
						 | 
					@ -1588,20 +1588,10 @@ unsigned ata_exec_internal_sg(struct ata_device *dev,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* initialize internal qc */
 | 
						/* initialize internal qc */
 | 
				
			||||||
 | 
						qc = __ata_qc_from_tag(ap, ATA_TAG_INTERNAL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* XXX: Tag 0 is used for drivers with legacy EH as some
 | 
						qc->tag = ATA_TAG_INTERNAL;
 | 
				
			||||||
	 * drivers choke if any other tag is given.  This breaks
 | 
						qc->hw_tag = 0;
 | 
				
			||||||
	 * ata_tag_internal() test for those drivers.  Don't use new
 | 
					 | 
				
			||||||
	 * EH stuff without converting to it.
 | 
					 | 
				
			||||||
	 */
 | 
					 | 
				
			||||||
	if (ap->ops->error_handler)
 | 
					 | 
				
			||||||
		tag = ATA_TAG_INTERNAL;
 | 
					 | 
				
			||||||
	else
 | 
					 | 
				
			||||||
		tag = 0;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	qc = __ata_qc_from_tag(ap, tag);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	qc->tag = qc->hw_tag = tag;
 | 
					 | 
				
			||||||
	qc->scsicmd = NULL;
 | 
						qc->scsicmd = NULL;
 | 
				
			||||||
	qc->ap = ap;
 | 
						qc->ap = ap;
 | 
				
			||||||
	qc->dev = dev;
 | 
						qc->dev = dev;
 | 
				
			||||||
| 
						 | 
					@ -5156,7 +5146,7 @@ void ata_qc_free(struct ata_queued_cmd *qc)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	qc->flags = 0;
 | 
						qc->flags = 0;
 | 
				
			||||||
	tag = qc->tag;
 | 
						tag = qc->tag;
 | 
				
			||||||
	if (likely(ata_tag_valid(tag))) {
 | 
						if (ata_tag_valid(tag)) {
 | 
				
			||||||
		qc->tag = ATA_TAG_POISON;
 | 
							qc->tag = ATA_TAG_POISON;
 | 
				
			||||||
		if (ap->flags & ATA_FLAG_SAS_HOST)
 | 
							if (ap->flags & ATA_FLAG_SAS_HOST)
 | 
				
			||||||
			ata_sas_free_tag(tag, ap);
 | 
								ata_sas_free_tag(tag, ap);
 | 
				
			||||||
| 
						 | 
					@ -5415,7 +5405,7 @@ void ata_qc_issue(struct ata_queued_cmd *qc)
 | 
				
			||||||
		WARN_ON_ONCE(link->sactive);
 | 
							WARN_ON_ONCE(link->sactive);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		ap->nr_active_links++;
 | 
							ap->nr_active_links++;
 | 
				
			||||||
		link->active_tag = qc->hw_tag;
 | 
							link->active_tag = qc->tag;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	qc->flags |= ATA_QCFLAG_ACTIVE;
 | 
						qc->flags |= ATA_QCFLAG_ACTIVE;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1057,7 +1057,8 @@ static int ata_do_link_abort(struct ata_port *ap, struct ata_link *link)
 | 
				
			||||||
	/* we're gonna abort all commands, no need for fast drain */
 | 
						/* we're gonna abort all commands, no need for fast drain */
 | 
				
			||||||
	ata_eh_set_pending(ap, 0);
 | 
						ata_eh_set_pending(ap, 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for (tag = 0; tag < ATA_MAX_QUEUE; tag++) {
 | 
						/* include internal tag in iteration */
 | 
				
			||||||
 | 
						for (tag = 0; tag <= ATA_MAX_QUEUE; tag++) {
 | 
				
			||||||
		struct ata_queued_cmd *qc = ata_qc_from_tag(ap, tag);
 | 
							struct ata_queued_cmd *qc = ata_qc_from_tag(ap, tag);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (qc && (!link || qc->dev->link == link)) {
 | 
							if (qc && (!link || qc->dev->link == link)) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -125,9 +125,8 @@ enum {
 | 
				
			||||||
	LIBATA_MAX_PRD		= ATA_MAX_PRD / 2,
 | 
						LIBATA_MAX_PRD		= ATA_MAX_PRD / 2,
 | 
				
			||||||
	LIBATA_DUMB_MAX_PRD	= ATA_MAX_PRD / 4,	/* Worst case */
 | 
						LIBATA_DUMB_MAX_PRD	= ATA_MAX_PRD / 4,	/* Worst case */
 | 
				
			||||||
	ATA_DEF_QUEUE		= 1,
 | 
						ATA_DEF_QUEUE		= 1,
 | 
				
			||||||
	/* tag ATA_MAX_QUEUE - 1 is reserved for internal commands */
 | 
					 | 
				
			||||||
	ATA_MAX_QUEUE		= 32,
 | 
						ATA_MAX_QUEUE		= 32,
 | 
				
			||||||
	ATA_TAG_INTERNAL	= ATA_MAX_QUEUE - 1,
 | 
						ATA_TAG_INTERNAL	= ATA_MAX_QUEUE,
 | 
				
			||||||
	ATA_SHORT_PAUSE		= 16,
 | 
						ATA_SHORT_PAUSE		= 16,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ATAPI_MAX_DRAIN		= 16 << 10,
 | 
						ATAPI_MAX_DRAIN		= 16 << 10,
 | 
				
			||||||
| 
						 | 
					@ -850,7 +849,7 @@ struct ata_port {
 | 
				
			||||||
	unsigned int		udma_mask;
 | 
						unsigned int		udma_mask;
 | 
				
			||||||
	unsigned int		cbl;	/* cable type; ATA_CBL_xxx */
 | 
						unsigned int		cbl;	/* cable type; ATA_CBL_xxx */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct ata_queued_cmd	qcmd[ATA_MAX_QUEUE];
 | 
						struct ata_queued_cmd	qcmd[ATA_MAX_QUEUE + 1];
 | 
				
			||||||
	unsigned long		sas_tag_allocated; /* for sas tag allocation only */
 | 
						unsigned long		sas_tag_allocated; /* for sas tag allocation only */
 | 
				
			||||||
	u64			qc_active;
 | 
						u64			qc_active;
 | 
				
			||||||
	int			nr_active_links; /* #links with active qcs */
 | 
						int			nr_active_links; /* #links with active qcs */
 | 
				
			||||||
| 
						 | 
					@ -1486,16 +1485,16 @@ extern void ata_port_pbar_desc(struct ata_port *ap, int bar, ssize_t offset,
 | 
				
			||||||
			       const char *name);
 | 
								       const char *name);
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static inline unsigned int ata_tag_valid(unsigned int tag)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	return (tag < ATA_MAX_QUEUE) ? 1 : 0;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static inline bool ata_tag_internal(unsigned int tag)
 | 
					static inline bool ata_tag_internal(unsigned int tag)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	return tag == ATA_TAG_INTERNAL;
 | 
						return tag == ATA_TAG_INTERNAL;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static inline bool ata_tag_valid(unsigned int tag)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return tag < ATA_MAX_QUEUE || ata_tag_internal(tag);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 * device helpers
 | 
					 * device helpers
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
| 
						 | 
					@ -1656,7 +1655,7 @@ static inline void ata_qc_set_polling(struct ata_queued_cmd *qc)
 | 
				
			||||||
static inline struct ata_queued_cmd *__ata_qc_from_tag(struct ata_port *ap,
 | 
					static inline struct ata_queued_cmd *__ata_qc_from_tag(struct ata_port *ap,
 | 
				
			||||||
						       unsigned int tag)
 | 
											       unsigned int tag)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	if (likely(ata_tag_valid(tag)))
 | 
						if (ata_tag_valid(tag))
 | 
				
			||||||
		return &ap->qcmd[tag];
 | 
							return &ap->qcmd[tag];
 | 
				
			||||||
	return NULL;
 | 
						return NULL;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue