forked from mirrors/linux
		
	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; | ||||
| 	int auto_timeout = 0; | ||||
| 	struct ata_queued_cmd *qc; | ||||
| 	unsigned int tag, preempted_tag; | ||||
| 	unsigned int preempted_tag; | ||||
| 	u32 preempted_sactive; | ||||
| 	u64 preempted_qc_active; | ||||
| 	int preempted_nr_active_links; | ||||
|  | @ -1588,20 +1588,10 @@ unsigned ata_exec_internal_sg(struct ata_device *dev, | |||
| 	} | ||||
| 
 | ||||
| 	/* initialize internal qc */ | ||||
| 	qc = __ata_qc_from_tag(ap, ATA_TAG_INTERNAL); | ||||
| 
 | ||||
| 	/* XXX: Tag 0 is used for drivers with legacy EH as some
 | ||||
| 	 * drivers choke if any other tag is given.  This breaks | ||||
| 	 * 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->tag = ATA_TAG_INTERNAL; | ||||
| 	qc->hw_tag = 0; | ||||
| 	qc->scsicmd = NULL; | ||||
| 	qc->ap = ap; | ||||
| 	qc->dev = dev; | ||||
|  | @ -5156,7 +5146,7 @@ void ata_qc_free(struct ata_queued_cmd *qc) | |||
| 
 | ||||
| 	qc->flags = 0; | ||||
| 	tag = qc->tag; | ||||
| 	if (likely(ata_tag_valid(tag))) { | ||||
| 	if (ata_tag_valid(tag)) { | ||||
| 		qc->tag = ATA_TAG_POISON; | ||||
| 		if (ap->flags & ATA_FLAG_SAS_HOST) | ||||
| 			ata_sas_free_tag(tag, ap); | ||||
|  | @ -5415,7 +5405,7 @@ void ata_qc_issue(struct ata_queued_cmd *qc) | |||
| 		WARN_ON_ONCE(link->sactive); | ||||
| 
 | ||||
| 		ap->nr_active_links++; | ||||
| 		link->active_tag = qc->hw_tag; | ||||
| 		link->active_tag = qc->tag; | ||||
| 	} | ||||
| 
 | ||||
| 	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 */ | ||||
| 	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); | ||||
| 
 | ||||
| 		if (qc && (!link || qc->dev->link == link)) { | ||||
|  |  | |||
|  | @ -125,9 +125,8 @@ enum { | |||
| 	LIBATA_MAX_PRD		= ATA_MAX_PRD / 2, | ||||
| 	LIBATA_DUMB_MAX_PRD	= ATA_MAX_PRD / 4,	/* Worst case */ | ||||
| 	ATA_DEF_QUEUE		= 1, | ||||
| 	/* tag ATA_MAX_QUEUE - 1 is reserved for internal commands */ | ||||
| 	ATA_MAX_QUEUE		= 32, | ||||
| 	ATA_TAG_INTERNAL	= ATA_MAX_QUEUE - 1, | ||||
| 	ATA_TAG_INTERNAL	= ATA_MAX_QUEUE, | ||||
| 	ATA_SHORT_PAUSE		= 16, | ||||
| 
 | ||||
| 	ATAPI_MAX_DRAIN		= 16 << 10, | ||||
|  | @ -850,7 +849,7 @@ struct ata_port { | |||
| 	unsigned int		udma_mask; | ||||
| 	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 */ | ||||
| 	u64			qc_active; | ||||
| 	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); | ||||
| #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) | ||||
| { | ||||
| 	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 | ||||
|  */ | ||||
|  | @ -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, | ||||
| 						       unsigned int tag) | ||||
| { | ||||
| 	if (likely(ata_tag_valid(tag))) | ||||
| 	if (ata_tag_valid(tag)) | ||||
| 		return &ap->qcmd[tag]; | ||||
| 	return NULL; | ||||
| } | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue
	
	 Jens Axboe
						Jens Axboe