Skip to contentSkip to conversation

Introduce new SATA queued commands

PATCH Superseded Marc C 3 participants 23 messages Aug 9, 2013 – Aug 12, 2013 libata

v3 of 5 Superseded Latest is v5 →

lore
Share & tools
lore

Marc C

author
#0 lore raw

v3 cover Introduce new SATA queued commands

From: Marc Carino <[email protected]>

This patch series updates the libata driver with some additional commands which are specified in the more recent versions of the SATA and ATA specifications. These commands are:

SEND FPDMA QUEUED
RECEIVE FPDMA QUEUED.

The new queued commands augment the existing READ and WRITE FPDMA QUEUED commands. The commands are intended to transport non-media data to/from a device in a non-blocking manner.

One application of these commands include a queued-style DSM TRIM operation. The current DSM TRIM command is non-queued, and requires the initiator to empty out the queue before issuance. The new DSM TRIM allows the initiator to keep the queue full.

These patches have been validated on an Intel SATA AHCI controller, on a Micron M500 SSD, using "postmark," "fstrim," and "fsck."

Version history:

v3:
- rebased to libata/for-3.12
- put H2D FIS "auxiliary" field changes in separate patch
- added "auxiliary" field population to all FIS-based SATA drivers

v2:
- rebased to 3.11-rc4
- moved auxiliary field to ata_queued_cmd struct
- updated signoff name

v1:
- initial

Marc Carino (3):
libata: Populate host-to-device FIS "auxiliary" field
libata: Add support for SEND/RECEIVE FPDMA QUEUED
libata: Add support for queued DSM TRIM

 drivers/ata/acard-ahci.c  |  2 +-
 drivers/ata/libahci.c     |  2 +-
 drivers/ata/libata-core.c | 44 ++++++++++++++++++++++++++++++++++++++++++++
 drivers/ata/libata-scsi.c | 27 +++++++++++++++++++++------
 drivers/ata/sata_fsl.c    |  2 +-
 drivers/ata/sata_mv.c     |  2 +-
 drivers/ata/sata_qstor.c  |  2 +-
 drivers/ata/sata_sil24.c  |  2 +-
 include/linux/ata.h       | 23 +++++++++++++++++++++++
 include/linux/libata.h    |  8 ++++++++
 10 files changed, 102 insertions(+), 12 deletions(-)
Signature · 1 line
1.8.1.2
author
#1 lore raw

PATCH v3 1/3 libata: Populate host-to-device FIS "auxiliary" field

From: Marc Carino <[email protected]>

SATA 3.1 added an "auxiliary" field to the host-to-device FIS.

Since there is no analog between the new field and the ATA taskfile, a new element was added to 'struct ata_queued_cmd."

---
 drivers/ata/acard-ahci.c  |  2 +-
 drivers/ata/libahci.c     |  2 +-
 drivers/ata/libata-core.c | 29 +++++++++++++++++++++++++++++
 drivers/ata/sata_fsl.c    |  2 +-
 drivers/ata/sata_mv.c     |  2 +-
 drivers/ata/sata_qstor.c  |  2 +-
 drivers/ata/sata_sil24.c  |  2 +-
 include/linux/libata.h    |  4 ++++
 8 files changed, 39 insertions(+), 6 deletions(-)
drivers/ata/acard-ahci.c +1 -1
index fd665d9..a7bf4c4 100644
@@ -274,7 +274,7 @@ static void acard_ahci_qc_prep(struct ata_queued_cmd *qc)
 	 */
 	cmd_tbl = pp->cmd_tbl + qc->tag * AHCI_CMD_TBL_SZ;
 
-	ata_tf_to_fis(&qc->tf, qc->dev->link->pmp, 1, cmd_tbl);
+	ata_qc_to_fis(qc, qc->dev->link->pmp, 1, cmd_tbl);
 	if (is_atapi) {
 		memset(cmd_tbl + AHCI_CMD_TBL_CDB, 0, 32);
 		memcpy(cmd_tbl + AHCI_CMD_TBL_CDB, qc->cdb, qc->dev->cdb_len);
drivers/ata/libahci.c +1 -1
index acfd0f7..2283ea4 100644
@@ -1498,7 +1498,7 @@ static void ahci_qc_prep(struct ata_queued_cmd *qc)
 	 */
 	cmd_tbl = pp->cmd_tbl + qc->tag * AHCI_CMD_TBL_SZ;
 
-	ata_tf_to_fis(&qc->tf, qc->dev->link->pmp, 1, cmd_tbl);
+	ata_qc_to_fis(qc, qc->dev->link->pmp, 1, cmd_tbl);
 	if (is_atapi) {
 		memset(cmd_tbl + AHCI_CMD_TBL_CDB, 0, 32);
 		memcpy(cmd_tbl + AHCI_CMD_TBL_CDB, qc->cdb, qc->dev->cdb_len);
drivers/ata/libata-core.c +29 -0
index c24354d..9d02c47 100644
@@ -532,6 +532,34 @@ int atapi_cmd_type(u8 opcode)
 }
 
 /**
+ *	ata_qc_to_fis - Convert struct ata_queued_cmd to SATA FIS structure
+ *	@qc: struct ata_queued_cmd to convert
+ *	@pmp: Port multiplier port
+ *	@is_cmd: This FIS is for command
+ *	@fis: Buffer into which data will output
+ *
+ *	Converts a struct ata_queued_cmd to a Serial ATA
+ *	FIS structure (Register - Host to Device).
+ *
+ *	Beginning with SATA 3.1, the ATA taskfile does not completely describe
+ *	all of the fields in a host-to-device FIS. More specifically, the
+ *	'auxiliary' field has no ATA taskfile analog, and thus requires us
+ *	to populate the FIS via the ata_queued_cmd structure.
+ *
+ *	LOCKING:
+ *	Inherited from caller.
+ */
+void ata_qc_to_fis(const struct ata_queued_cmd *qc, u8 pmp, int is_cmd, u8 *fis)
+{
+	ata_tf_to_fis(&qc->tf, pmp, is_cmd, fis);
+
+	fis[16] = qc->auxiliary & 0xff;
+	fis[17] = (qc->auxiliary >> 8) & 0xff;
+	fis[18] = (qc->auxiliary >> 16) & 0xff;
+	fis[19] = (qc->auxiliary >> 24) & 0xff;
+}
+
+/**
  *	ata_tf_to_fis - Convert ATA taskfile to SATA FIS structure
  *	@tf: Taskfile to convert
  *	@pmp: Port multiplier port
@@ -6877,6 +6905,7 @@ EXPORT_SYMBOL_GPL(ata_sg_init);
 EXPORT_SYMBOL_GPL(ata_qc_complete);
 EXPORT_SYMBOL_GPL(ata_qc_complete_multiple);
 EXPORT_SYMBOL_GPL(atapi_cmd_type);
+EXPORT_SYMBOL_GPL(ata_qc_to_fis);
 EXPORT_SYMBOL_GPL(ata_tf_to_fis);
 EXPORT_SYMBOL_GPL(ata_tf_from_fis);
 EXPORT_SYMBOL_GPL(ata_pack_xfermask);
drivers/ata/sata_fsl.c +1 -1
index 19720a0..bbdba01 100644
@@ -525,7 +525,7 @@ static void sata_fsl_qc_prep(struct ata_queued_cmd *qc)
 	cd = (struct command_desc *)pp->cmdentry + tag;
 	cd_paddr = pp->cmdentry_paddr + tag * SATA_FSL_CMD_DESC_SIZE;
 
-	ata_tf_to_fis(&qc->tf, qc->dev->link->pmp, 1, (u8 *) &cd->cfis);
+	ata_qc_to_fis(qc, qc->dev->link->pmp, 1, (u8 *) &cd->cfis);
 
 	VPRINTK("Dumping cfis : 0x%x, 0x%x, 0x%x\n",
 		cd->cfis[0], cd->cfis[1], cd->cfis[2]);
drivers/ata/sata_mv.c +1 -1
index 56be318..96fc238 100644
@@ -2267,7 +2267,7 @@ static unsigned int mv_qc_issue_fis(struct ata_queued_cmd *qc)
 	u32 fis[5];
 	int err = 0;
 
-	ata_tf_to_fis(&qc->tf, link->pmp, 1, (void *)fis);
+	ata_qc_to_fis(qc, link->pmp, 1, (void *)fis);
 	err = mv_send_fis(ap, fis, ARRAY_SIZE(fis));
 	if (err)
 		return err;
drivers/ata/sata_qstor.c +1 -1
index 3b0dd57..e0ce396 100644
@@ -311,7 +311,7 @@ static void qs_qc_prep(struct ata_queued_cmd *qc)
 	buf[28] = dflags;
 
 	/* frame information structure (FIS) */
-	ata_tf_to_fis(&qc->tf, 0, 1, &buf[32]);
+	ata_qc_to_fis(qc, 0, 1, &buf[32]);
 }
 
 static inline void qs_packet_start(struct ata_queued_cmd *qc)
drivers/ata/sata_sil24.c +1 -1
index aa1051b..7e56d48 100644
@@ -877,7 +877,7 @@ static void sil24_qc_prep(struct ata_queued_cmd *qc)
 	}
 
 	prb->ctrl = cpu_to_le16(ctrl);
-	ata_tf_to_fis(&qc->tf, qc->dev->link->pmp, 1, prb->fis);
+	ata_qc_to_fis(qc, qc->dev->link->pmp, 1, prb->fis);
 
 	if (qc->flags & ATA_QCFLAG_DMAMAP)
 		sil24_fill_sg(qc, sge);
include/linux/libata.h +4 -0
index 283d66b..a4601cc 100644
@@ -604,6 +604,7 @@ struct ata_queued_cmd {
 
 	struct ata_taskfile	tf;
 	u8			cdb[ATAPI_CDB_LEN];
+	u32			auxiliary;
 
 	unsigned long		flags;		/* ATA_QCFLAG_xxx */
 	unsigned int		tag;
@@ -1145,6 +1146,8 @@ extern void ata_msleep(struct ata_port *ap, unsigned int msecs);
 extern u32 ata_wait_register(struct ata_port *ap, void __iomem *reg, u32 mask,
 			u32 val, unsigned long interval, unsigned long timeout);
 extern int atapi_cmd_type(u8 opcode);
+extern void ata_qc_to_fis(const struct ata_queued_cmd *qc,
+			  u8 pmp, int is_cmd, u8 *fis);
 extern void ata_tf_to_fis(const struct ata_taskfile *tf,
 			  u8 pmp, int is_cmd, u8 *fis);
 extern void ata_tf_from_fis(const u8 *fis, struct ata_taskfile *tf);
@@ -1658,6 +1661,7 @@ static inline void ata_qc_reinit(struct ata_queued_cmd *qc)
 	qc->n_elem = 0;
 	qc->err_mask = 0;
 	qc->sect_size = ATA_SECT_SIZE;
+	qc->auxiliary = 0;
 
 	ata_tf_init(qc->dev, &qc->tf);
 
Signature · 1 line
1.8.1.2
#2 lore raw

Re: [PATCH v3 1/3] libata: Populate host-to-device FIS "auxiliary" field

Quoted 6 lines · Marc C

From: Marc Carino <[email protected]>

SATA 3.1 added an "auxiliary" field to the host-to-device FIS.

Since there is no analog between the new field and the ATA taskfile, a new element was added to 'struct ata_queued_cmd."

Ummm... I'm sorry but I'm gonna do 180 from Sergei on this one. The auxiliary field is part of ata taskfile for all intents and purposes. FIS is the new command structure anyway and struct ata_taskfile proper should be able to describe the command with ata_queuedcmd providing the surrounding context. The argument that ata_taskfile shouldn't contain anything which wasn't in PATA taskfile is bogus as it already contains ATA_TFLAG_*.

So, please put the aux field into ata_taskfile. That's where it belongs.

Thanks.

Signature · 1 line
tejun
#3 lore raw

Re: [PATCH v3 1/3] libata: Populate host-to-device FIS "auxiliary" field

Quoted 8 lines · Tejun Heo
Quoted 6 lines

From: Marc Carino <[email protected]>

SATA 3.1 added an "auxiliary" field to the host-to-device FIS.

Since there is no analog between the new field and the ATA taskfile, a new element was added to 'struct ata_queued_cmd."

Ummm... I'm sorry but I'm gonna do 180 from Sergei on this one. The

That's very unfortunate for me. :-(

Quoted 6 lines

auxiliary field is part of ata taskfile for all intents and purposes. FIS is the new command structure anyway and struct ata_taskfile proper should be able to describe the command with ata_queuedcmd providing the surrounding context. The argument that ata_taskfile shouldn't contain anything which wasn't in PATA taskfile is bogus as it already contains ATA_TFLAG_*.

That's what make 'struct ata_taskfile' bogus. I'm going to remove
'protocol', 'flags', and 'ctl' fields from there (at least to save a space in 'struct ata_queued_cmd' because they're not used in 'result_tf').

Quoted 2 lines

So, please put the aux field into ata_taskfile. That's where it belongs.

Can't agree to that. I was going to make 'struct ata_taskfile' reflect the
historical notion and remove from it all not belonging to that notion. Alas, libata has a bad history of mistreating the historical terms...

Quoted 1 line

Thanks.

WBR, Sergei

#4 lore raw

Re: [PATCH v3 1/3] libata: Populate host-to-device FIS "auxiliary" field

Quoted 3 lines · Sergei Shtylyov
Quoted 1 line

Ummm... I'm sorry but I'm gonna do 180 from Sergei on this one. The

   That's very unfortunate for me. :-(

Hehe, sorry. :)

Quoted 7 lines
Quoted 2 lines

So, please put the aux field into ata_taskfile. That's where it belongs.

Can't agree to that. I was going to make 'struct ata_taskfile'
reflect the historical notion and remove from it all not belonging to that notion. Alas, libata has a bad history of mistreating the historical terms...

But what does sticking to the historical definition give us when the whole concept of TF is no longer maintained in new specs. The distinction between "command proper" and "supporting / plumbing information" is still useful so I think it's natural to assign the former to ata_taskfile and the latter to ata_queuedcmd. After all, there are cases where we want to describe command without all the plumbing stuff libata imposes and given that the aux field is part of FIS proper it might even get used for command results too in the future. I mean, FIS is the new TF. We can rename ata_taskfile to ata_fis and map things the other way but that'd just be extra churn.

Thanks.

Signature · 1 line
tejun
#5 lore raw

Re: [PATCH v3 1/3] libata: Populate host-to-device FIS "auxiliary" field

Hello.

Quoted 5 lines · Tejun Heo
Quoted 3 lines
Quoted 1 line

Ummm... I'm sorry but I'm gonna do 180 from Sergei on this one. The

    That's very unfortunate for me. :-(

Hehe, sorry. :)

I've started to work on my taskfile patchset about a year ago (while being
in hospital) and worked on it on my copious free time (perhaps, not actively enough until I realized I don't have much time anymore), so it doesn't sound funny for me. If you're going to reject my patches once submitted outright, just tell me now, and with some regret for the wasted time, I'll find a better use for my free time, making a note to myself that the taskfile support in libata is hopeless and the maintainer doesn't care a bit about that. (In case you want an example of better taskfile support, look at IDE).

Quoted 10 lines
Quoted 7 lines
Quoted 2 lines

So, please put the aux field into ata_taskfile. That's where it belongs.

Can't agree to that. I was going to make 'struct ata_taskfile'
reflect the historical notion and remove from it all not belonging to that notion. Alas, libata has a bad history of mistreating the historical terms...

But what does sticking to the historical definition give us when the whole concept of TF is no longer maintained in new specs.

It predated even the old specs, so what?

Quoted 3 lines

The
distinction between "command proper" and "supporting / plumbing information" is still useful

Yes, it's just the border was drawn incorrectly from the start IMO.
Jeff even placed the structure and friends into ata.h for no apparent reason (part of those *enum* friends eventually got shared by IDE).

Quoted 2 lines

so I think it's natural to assign the
former to ata_taskfile and the latter to ata_queuedcmd.

That's exactly what I want to do.

Quoted 2 lines

After all, there are cases where we want to describe command without all the plumbing stuff libata imposes

Exactly what I want to achieve.

Quoted 3 lines

and given that the aux field is part of
FIS proper it might even get used for command results too in the future.

If and when this happens, we'll see. So far, the structure of H2D and D2H
FIS is different enough that libata doesn't have a stucture defined for FISes, and just treats them as array of u8.

Quoted 1 line

I mean, FIS is the new TF.

FISes are used by what, handful of controllers? While the others, even
SATA are still taskfile based and can't transfer FISes directly (especially true for the embedded world where not everybody wants to use AHCI). So that's kind of wishful thinking for now. And don't forget about the PATA legacy you'll have to drag around forever.

Quoted 2 lines

We can rename ata_taskfile to
ata_fis and map things the other way but that'd just be extra churn.

Indeed. And totally stupid move concerning the amount of direct FIS
support in different hardware.

Quoted 1 line

Thanks.

WBR, Sergei

#6 lore raw

Re: [PATCH v3 1/3] libata: Populate host-to-device FIS "auxiliary" field

Hello, Sergei.

Quoted 10 lines · Sergei Shtylyov

I've started to work on my taskfile patchset about a year ago
(while being in hospital) and worked on it on my copious free time (perhaps, not actively enough until I realized I don't have much time anymore), so it doesn't sound funny for me. If you're going to reject my patches once submitted outright, just tell me now, and with some regret for the wasted time, I'll find a better use for my free time, making a note to myself that the taskfile support in libata is hopeless and the maintainer doesn't care a bit about that. (In case you want an example of better taskfile support, look at IDE).

Can you explain why following the traditional TF definition matters so much? What practical difference does that make? The new field is part of command code definition, so it belongs with the rest of them regardless of what the structure it's contained in is named. If the only reason for strictly separating TF regs into a separate struct is because the spec says so, I indeed don't give a flying hoot.

Also, the only controller interface which would continue to be relevant is ahci and that's it. There will be no new development whatsoever happening with TF based interface, ever. I don't see why you're getting all passive agressive about it. If you have technical arguments, dish them out.

Thanks.

Signature · 1 line
tejun
#7 lore raw

Re: [PATCH v3 1/3] libata: Populate host-to-device FIS "auxiliary" field

Hello.

Quoted 11 lines · Tejun Heo
Quoted 10 lines

I've started to work on my taskfile patchset about a year ago
(while being in hospital) and worked on it on my copious free time (perhaps, not actively enough until I realized I don't have much time anymore), so it doesn't sound funny for me. If you're going to reject my patches once submitted outright, just tell me now, and with some regret for the wasted time, I'll find a better use for my free time, making a note to myself that the taskfile support in libata is hopeless and the maintainer doesn't care a bit about that. (In case you want an example of better taskfile support, look at IDE).

Quoted 2 lines

Can you explain why following the traditional TF definition matters so much?

Because it's more clear, saves some memory and matches the (rather poor)
capabilities of the libata's driver taskfile interface (which you can't throw out however you wanted).

Quoted 3 lines

What practical difference does that make? The new field is part of command code definition, so it belongs with the rest of them regardless of what the structure it's contained in is named.

So why not place it to 'struct ata_queued_cmd' then? If it doesn't really
matter where to put it if it serves to describe a command, and additionally will save you some memory?

Quoted 2 lines

If the only reason for strictly separating TF regs into a separate struct is because the spec says so,

No. Besides, as I told you, taskfile isn't in any spec, it's pre-ATA term.

Quoted 1 line

I indeed don't give a flying hoot.

Excellent reply from a maintainer. :-D

Quoted 3 lines

Also, the only controller interface which would continue to be relevant is ahci and that's it. There will be no new development whatsoever happening with TF based interface, ever.

In x86 world maybe but how much does it help you with the legacy stuff you
have to drag around?
Tell about AHCI to my embedded customer, Renesas. Remember the most recent
sata_rcar driver I have submitted? It's taskfile based (there's also SATA driver we at MontaVista did write but didn't submit). And it's used in their top-notch R-Car SoCs.

Quoted 1 line

I don't see why you're getting all passive agressive about it.

Don't intimidate me with psychological terms. :-)

Quoted 1 line

If you have technical arguments, dish them out.

I have. It seems you intentionally ignore them, and reply to non-technical
passage only.

Quoted 1 line

Thanks.

WBR, Sergei

#8 lore raw

Re: [PATCH v3 1/3] libata: Populate host-to-device FIS "auxiliary" field

Hey,

Quoted 3 lines · Sergei Shtylyov

So why not place it to 'struct ata_queued_cmd' then? If it
doesn't really matter where to put it if it serves to describe a command, and additionally will save you some memory?

Because it's just more churn? Now TF basically matches what goes into FIS. Adding aux to qc break that for no good reason (no, 4 bytes isn't a good reason).

Quoted 6 lines

In x86 world maybe but how much does it help you with the legacy
stuff you have to drag around?
Tell about AHCI to my embedded customer, Renesas. Remember the
most recent sata_rcar driver I have submitted? It's taskfile based (there's also SATA driver we at MontaVista did write but didn't submit). And it's used in their top-notch R-Car SoCs.

Oh sure, we'll carry the existing ones and there will be new drivers for sure. I'm saying that in terms of command protocol and standard, it is and has long been a dead end. Nothing can happen there anymore. There's no point in putting TF based interface in the center of attention.

Quoted 3 lines
Quoted 1 line

I don't see why you're getting all passive agressive about it.

Don't intimidate me with psychological terms. :-)

Please adjust your tone then because your original reply was very easily escalatable. If you want to escalate things, I'm game but if you don't want that, please make that clear too.

Quoted 4 lines
Quoted 1 line

If you have technical arguments, dish them out.

I have. It seems you intentionally ignore them, and reply to
non-technical passage only.

The only concrete thing I got upto this point is saving 4 bytes, which is a bit difficult to consider seriously. Other parts, I don't get at all. Sure there are TF drivers, but how does adding aux field to TF make it worse for them?

Thanks.

Signature · 1 line
tejun
#9 lore raw

Re: [PATCH v3 1/3] libata: Populate host-to-device FIS "auxiliary" field

Hello.

Quoted 7 lines · Tejun Heo
Quoted 3 lines

So why not place it to 'struct ata_queued_cmd' then? If it
doesn't really matter where to put it if it serves to describe a command, and additionally will save you some memory?

Because it's just more churn? Now TF basically matches what goes into FIS. Adding aux to qc break that for no good reason (no, 4 bytes isn't a good reason).

Funny to remember, when I was just starting my Linux IDE development back
in 2006, I published a patch that added 4-byte field to 'ide_hwif_t' and some people started complaining about memory waste, so that I had to promise I'd send a next patch that would remove another 40bte field. Clearly, they didn't expect an explosion in IDE development that stated happening the next year. :-) That time however is gone, and I probably can't promise as stable stream of patches as it was back then, especially given my one-year development period for the mentioned taskfile patches (which I still can't publish due to completely unexpected issue guaranteeing several debugging sessions).

Quoted 7 lines
Quoted 6 lines

In x86 world maybe but how much does it help you with the legacy
stuff you have to drag around?
Tell about AHCI to my embedded customer, Renesas. Remember the
most recent sata_rcar driver I have submitted? It's taskfile based (there's also SATA driver we at MontaVista did write but didn't submit). And it's used in their top-notch R-Car SoCs.

Quoted 5 lines

Oh sure, we'll carry the existing ones and there will be new drivers for sure. I'm saying that in terms of command protocol and standard, it is and has long been a dead end. Nothing can happen there anymore. There's no point in putting TF based interface in the center of attention.

I still would like it improved regardless how old the issues there are,
I'm just not sure I can do it. Being engaged in the embedded area, I feel more comfortable with the old stuff than the new, hence my interest.

Quoted 7 lines
Quoted 3 lines
Quoted 1 line

I don't see why you're getting all passive agressive about it.

Don't intimidate me with psychological terms. :-)

Please adjust your tone then because your original reply was very easily escalatable. If you want to escalate things, I'm game but if you don't want that, please make that clear too.

No, I don't want to escalate to Linus, if you meant it. I was just feeling
somewhat bitter. However, I would like to hear a clear answer to my question about the taskfile patches currnetly in the works (although they seem to make less sence now that the taskfile "purity" is out of question): is there a chance you apply them or will you reject them as a needless churn?

Quoted 9 lines
Quoted 4 lines
Quoted 1 line

If you have technical arguments, dish them out.

I have. It seems you intentionally ignore them, and reply to
non-technical passage only.

The only concrete thing I got upto this point is saving 4 bytes, which is a bit difficult to consider seriously. Other parts, I don't get at all. Sure there are TF drivers, but how does adding aux field to TF make it worse for them?

Well, it seems I'm just out of arguments at this point. It seems just
aesthetically unpleasing and not right to me to have a field in taskfile which can't be delivered via the taskfile interface, if you want.
To be honest, I also have a patch that makes the taskfile lose it's 'hob_'
fields, and so the '[result_]tf' variables in the 'struct ata_queued_cmd' becoming arrays of 2 elements but I was somewhat afraid of publishing it because it's not exactly a memory saver (and a candidate of being labelled a pointless churn). Adding the new field to struct ata_taskfile just would make this patch completely impractical...

Quoted 1 line

Thanks.

Not at all.

WBR, Sergei

#10 lore raw

Re: [PATCH v3 1/3] libata: Populate host-to-device FIS "auxiliary" field

Hello, Sergei.

Quoted 10 lines · Sergei Shtylyov
Quoted 5 lines

Oh sure, we'll carry the existing ones and there will be new drivers for sure. I'm saying that in terms of command protocol and standard, it is and has long been a dead end. Nothing can happen there anymore. There's no point in putting TF based interface in the center of attention.

I still would like it improved regardless how old the issues
there are, I'm just not sure I can do it. Being engaged in the embedded area, I feel more comfortable with the old stuff than the new, hence my interest.

Sure, improvements are always welcome. My point is that when making trade-offs, it'd make more sense to prioritize design concerns for FIS based ones rather than the other way around. Here, the only concrete downside for TF based ones is 4 extra bytes in ata_taskfile, which I don't think matters at all.

Quoted 6 lines

No, I don't want to escalate to Linus, if you meant it. I was
just feeling somewhat bitter. However, I would like to hear a clear answer to my question about the taskfile patches currnetly in the works (although they seem to make less sence now that the taskfile "purity" is out of question): is there a chance you apply them or will you reject them as a needless churn?

I can't say for sure before actually looking at the patch but I'm likely to nack it if the only reason behind it is saving some bytes and conformance to the traditional definition of taskfile, especially as I'd much prefer to be able to put all fields of a FIS into ata_taskfile. If the moving out the prot and flags out of ata_tf makes the code generally cleaner, sure, but I'm a bit skeptical it would. Why don't you post the patch as-is? Let's see how the whole thing looks like.

Quoted 11 lines

Well, it seems I'm just out of arguments at this point. It seems
just aesthetically unpleasing and not right to me to have a field in taskfile which can't be delivered via the taskfile interface, if you want.
To be honest, I also have a patch that makes the taskfile lose
it's 'hob_' fields, and so the '[result_]tf' variables in the 'struct ata_queued_cmd' becoming arrays of 2 elements but I was somewhat afraid of publishing it because it's not exactly a memory saver (and a candidate of being labelled a pointless churn). Adding the new field to struct ata_taskfile just would make this patch completely impractical...

So, two things. Code cleanup is always a good idea; however, "aesthetically unpleasing" is pretty subjective and I'm not too likely to be fond of changes which are puristic in its nature without any practical cleanup value.

Secondly, optimization is good but it has to matter. There's no point in saving some bytes in a struct which aren't allocated in massive numbers. Likewise, there's no point in optimizing some cycles in paths which aren't hot. Straight-forwardness and maintainability should be the prime concerns in most cases.

Thanks.

Signature · 1 line
tejun
#11 lore raw

Re: [PATCH v3 1/3] libata: Populate host-to-device FIS "auxiliary" field

In reply to Tejun Heo
Quoted 9 lines · Tejun Heo
Quoted 6 lines

From: Marc Carino <[email protected]>

SATA 3.1 added an "auxiliary" field to the host-to-device FIS.

Since there is no analog between the new field and the ATA taskfile, a new element was added to 'struct ata_queued_cmd."

Ummm... I'm sorry but I'm gonna do 180 from Sergei on this one. The auxiliary field is part of ata taskfile for all intents and purposes.

Which would be another abuse of the ATA taskfile term (reminds me of SFF
abuse wehre everybody hushed me down saying that it's too late to change anything and for all intenets and purposes SFF means "taskfile based" for everybody). As Marc rightly said, this field won't be deliverable by the usual taskfile methods. Moreover, it won't be used in qc->result_tf' and so will waste 4 bytes for no reason.

Quoted 3 lines

FIS is the new command structure anyway and struct ata_taskfile proper should be able to describe the command with ata_queuedcmd providing the surrounding context.

It depends on your definition of surrounding context. In my definition,
'flags' and 'protocol' fields should be a part of surrounding context. 'ctl' too sicen the device control register was never considered a part of the ATA taskfile and it's not used in 'qc->result_tf' (as well as the other two fields), hence just wasting memory for no reason.

Quoted 3 lines

The argument that ata_taskfile shouldn't
contain anything which wasn't in PATA taskfile is bogus as it already contains ATA_TFLAG_*.

I regret that I haven't done my patches earlier to get rid of this example
of abuse of the ATA taskfile before.

Quoted 2 lines

So, please put the aux field into ata_taskfile. That's where it belongs.

Sigh.

Quoted 1 line

Thanks.

WBR, Sergei

#12 lore raw

Re: [PATCH v3 1/3] libata: Populate host-to-device FIS "auxiliary" field

In reply to Marc C

Hello.

Quoted 8 lines · Marc C

From: Marc Carino <[email protected]>

SATA 3.1 added an "auxiliary" field to the host-to-device FIS.

Since there is no analog between the new field and the ATA taskfile, a new element was added to 'struct ata_queued_cmd."

[...]

Quoted 40 lines
drivers/ata/libata-core.c +28 -0
index c24354d..9d02c47 100644
@@ -532,6 +532,34 @@ int atapi_cmd_type(u8 opcode)
  }
 
  /**
+ *	ata_qc_to_fis - Convert struct ata_queued_cmd to SATA FIS structure
+ *	@qc: struct ata_queued_cmd to convert
+ *	@pmp: Port multiplier port
+ *	@is_cmd: This FIS is for command
+ *	@fis: Buffer into which data will output
+ *
+ *	Converts a struct ata_queued_cmd to a Serial ATA
+ *	FIS structure (Register - Host to Device).
+ *
+ *	Beginning with SATA 3.1, the ATA taskfile does not completely describe
+ *	all of the fields in a host-to-device FIS. More specifically, the
+ *	'auxiliary' field has no ATA taskfile analog, and thus requires us
+ *	to populate the FIS via the ata_queued_cmd structure.
+ *
+ *	LOCKING:
+ *	Inherited from caller.
+ */
+void ata_qc_to_fis(const struct ata_queued_cmd *qc, u8 pmp, int is_cmd, u8 *fis)
+{
+	ata_tf_to_fis(&qc->tf, pmp, is_cmd, fis);
+
+	fis[16] = qc->auxiliary & 0xff;
+	fis[17] = (qc->auxiliary >> 8) & 0xff;
+	fis[18] = (qc->auxiliary >> 16) & 0xff;
+	fis[19] = (qc->auxiliary >> 24) & 0xff;
+}
+
+/**
   *	ata_tf_to_fis - Convert ATA taskfile to SATA FIS structure
   *	@tf: Taskfile to convert
   *	@pmp: Port multiplier port

drivers/ata/libata-core.c EXPORT_SYMBOL_GPL(ata_sg_init); · line 6909

Quoted 5 lines
drivers/ata/libata-core.c +1 -0
@@ -6877,6 +6905,7 @@ EXPORT_SYMBOL_GPL(ata_sg_init);
  EXPORT_SYMBOL_GPL(ata_qc_complete);
  EXPORT_SYMBOL_GPL(ata_qc_complete_multiple);
  EXPORT_SYMBOL_GPL(atapi_cmd_type);
+EXPORT_SYMBOL_GPL(ata_qc_to_fis);
  EXPORT_SYMBOL_GPL(ata_tf_to_fis);

I think we should now unexport this function and make it static since it
would be no longer valid to call it from the drivers...

WBR, Sergei

#13 lore raw

Re: [PATCH v3 1/3] libata: Populate host-to-device FIS "auxiliary" field

Quoted 52 lines · Sergei Shtylyov
Quoted 8 lines

From: Marc Carino <[email protected]>

SATA 3.1 added an "auxiliary" field to the host-to-device FIS.

Since there is no analog between the new field and the ATA taskfile, a new element was added to 'struct ata_queued_cmd."

[...]

Quoted 41 lines
drivers/ata/libata-core.c +28 -0
index c24354d..9d02c47 100644
@@ -532,6 +532,34 @@ int atapi_cmd_type(u8 opcode)
  }
 
  /**
+ *    ata_qc_to_fis - Convert struct ata_queued_cmd to SATA FIS structure
+ *    @qc: struct ata_queued_cmd to convert
+ *    @pmp: Port multiplier port
+ *    @is_cmd: This FIS is for command
+ *    @fis: Buffer into which data will output
+ *
+ *    Converts a struct ata_queued_cmd to a Serial ATA
+ *    FIS structure (Register - Host to Device).
+ *
+ *    Beginning with SATA 3.1, the ATA taskfile does not completely describe
+ *    all of the fields in a host-to-device FIS. More specifically, the
+ *    'auxiliary' field has no ATA taskfile analog, and thus requires us
+ *    to populate the FIS via the ata_queued_cmd structure.
+ *
+ *    LOCKING:
+ *    Inherited from caller.
+ */
+void ata_qc_to_fis(const struct ata_queued_cmd *qc, u8 pmp, int is_cmd, u8
 *fis)
+{
+    ata_tf_to_fis(&qc->tf, pmp, is_cmd, fis);
+
+    fis[16] = qc->auxiliary & 0xff;
+    fis[17] = (qc->auxiliary >> 8) & 0xff;
+    fis[18] = (qc->auxiliary >> 16) & 0xff;
+    fis[19] = (qc->auxiliary >> 24) & 0xff;
+}
+
+/**
   *    ata_tf_to_fis - Convert ATA taskfile to SATA FIS structure
   *    @tf: Taskfile to convert

* @pmp: Port multiplier port

drivers/ata/libata-core.c +0 -0
@@ -6877,6 +6905,7 @@ EXPORT_SYMBOL_GPL(ata_sg_init);
Quoted 8 lines

drivers/ata/libata-core.c EXPORT_SYMBOL_GPL(ata_sg_init); · line 6909

Quoted 5 lines
drivers/ata/libata-core.c +1 -0
  EXPORT_SYMBOL_GPL(ata_qc_complete);
  EXPORT_SYMBOL_GPL(ata_qc_complete_multiple);
  EXPORT_SYMBOL_GPL(atapi_cmd_type);
+EXPORT_SYMBOL_GPL(ata_qc_to_fis);
  EXPORT_SYMBOL_GPL(ata_tf_to_fis);

I think we should now unexport this function and make it static since it
would be no longer valid to call it from the drivers...

I was somewhat rash in this conclusion: drivers use this function not only
to issue commands but also to fake D2H FIS and not only that...

WBR, Sergei

#14 lore raw

Re: [PATCH v3 1/3] libata: Populate host-to-device FIS "auxiliary" field

In reply to Marc C

Hello.

Quoted 8 lines · Marc C

From: Marc Carino <[email protected]>

SATA 3.1 added an "auxiliary" field to the host-to-device FIS.

Since there is no analog between the new field and the ATA taskfile, a new element was added to 'struct ata_queued_cmd."

Quoted 10 lines
---
  drivers/ata/acard-ahci.c  |  2 +-
  drivers/ata/libahci.c     |  2 +-
  drivers/ata/libata-core.c | 29 +++++++++++++++++++++++++++++
  drivers/ata/sata_fsl.c    |  2 +-
  drivers/ata/sata_mv.c     |  2 +-
  drivers/ata/sata_qstor.c  |  2 +-
  drivers/ata/sata_sil24.c  |  2 +-
  include/linux/libata.h    |  4 ++++
  8 files changed, 39 insertions(+), 6 deletions(-)

Looks like you missed drivers/scsi/libsas/sas_ata.c...

WBR, Sergei

author
#15 lore raw

PATCH v3 2/3 libata: Add support for SEND/RECEIVE FPDMA QUEUED

In reply to Marc C

From: Marc Carino <[email protected]>

Add support for the following ATA opcodes, which are present in SATA 3.1 and T13 ATA ACS-3:

SEND FPDMA QUEUED
RECEIVE FPDMA QUEUED

---
 drivers/ata/libata-core.c | 15 +++++++++++++++
 include/linux/ata.h       | 23 +++++++++++++++++++++++
 include/linux/libata.h    |  4 ++++
 3 files changed, 42 insertions(+)
drivers/ata/libata-core.c +15 -0
index 9d02c47..9fd8d92 100644
@@ -2131,6 +2131,7 @@ static int ata_dev_config_ncq(struct ata_device *dev,
 	int hdepth = 0, ddepth = ata_id_queue_depth(dev->id);
 	unsigned int err_mask;
 	char *aa_desc = "";
+	u8 sata_setting[ATA_SECT_SIZE];
 
 	if (!ata_id_has_ncq(dev->id)) {
 		desc[0] = '\0';
@@ -2167,6 +2168,20 @@ static int ata_dev_config_ncq(struct ata_device *dev,
 	else
 		snprintf(desc, desc_sz, "NCQ (depth %d/%d)%s", hdepth,
 			ddepth, aa_desc);
+
+	if (ata_id_has_ncq_send_and_recv(dev->id)) {
+		err_mask = ata_read_log_page(dev,
+					     ATA_LOG_NCQ_SEND_RECV,
+					     0,
+					     sata_setting,
+					     1);
+		if (!err_mask) {
+			dev->flags |= ATA_DFLAG_NCQ_SEND_RECV;
+			memcpy(dev->ncq_send_recv_cmds, sata_setting,
+				ATA_LOG_NCQ_SEND_RECV_SIZE);
+		}
+	}
+
 	return 0;
 }
 
include/linux/ata.h +23 -0
index f63fb1a..f9a0465 100644
@@ -239,6 +239,8 @@ enum {
 	ATA_CMD_WRITE_QUEUED_FUA_EXT = 0x3E,
 	ATA_CMD_FPDMA_READ	= 0x60,
 	ATA_CMD_FPDMA_WRITE	= 0x61,
+	ATA_CMD_FPDMA_SEND	= 0x64,
+	ATA_CMD_FPDMA_RECV	= 0x65,
 	ATA_CMD_PIO_READ	= 0x20,
 	ATA_CMD_PIO_READ_EXT	= 0x24,
 	ATA_CMD_PIO_WRITE	= 0x30,
@@ -293,8 +295,13 @@ enum {
 	/* marked obsolete in the ATA/ATAPI-7 spec */
 	ATA_CMD_RESTORE		= 0x10,
 
+	/* Subcmds for ATA_CMD_FPDMA_SEND */
+	ATA_SUBCMD_FPDMA_SEND_DSM            = 0x00,
+	ATA_SUBCMD_FPDMA_SEND_WR_LOG_DMA_EXT = 0x02,
+
 	/* READ_LOG_EXT pages */
 	ATA_LOG_SATA_NCQ	= 0x10,
+	ATA_LOG_NCQ_SEND_RECV	  = 0x13,
 	ATA_LOG_SATA_ID_DEV_DATA  = 0x30,
 	ATA_LOG_SATA_SETTINGS	  = 0x08,
 	ATA_LOG_DEVSLP_OFFSET	  = 0x30,
@@ -305,6 +312,15 @@ enum {
 	ATA_LOG_DEVSLP_VALID	  = 0x07,
 	ATA_LOG_DEVSLP_VALID_MASK = 0x80,
 
+	/* NCQ send and receive log */
+	ATA_LOG_NCQ_SEND_RECV_SUBCMDS_OFFSET	= 0x00,
+	ATA_LOG_NCQ_SEND_RECV_SUBCMDS_DSM	= (1 << 0),
+	ATA_LOG_NCQ_SEND_RECV_DSM_OFFSET	= 0x04,
+	ATA_LOG_NCQ_SEND_RECV_DSM_TRIM		= (1 << 0),
+	ATA_LOG_NCQ_SEND_RECV_RD_LOG_OFFSET	= 0x08,
+	ATA_LOG_NCQ_SEND_RECV_WR_LOG_OFFSET	= 0x0C,
+	ATA_LOG_NCQ_SEND_RECV_SIZE		= 0x10,
+
 	/* READ/WRITE LONG (obsolete) */
 	ATA_CMD_READ_LONG	= 0x22,
 	ATA_CMD_READ_LONG_ONCE	= 0x23,
@@ -772,6 +788,13 @@ static inline int ata_id_rotation_rate(const u16 *id)
 	return val;
 }
 
+static inline bool ata_id_has_ncq_send_and_recv(const u16 *id)
+{
+	if (id[ATA_ID_SATA_CAPABILITY_2] & BIT(6))
+		return true;
+	return false;
+}
+
 static inline bool ata_id_has_trim(const u16 *id)
 {
 	if (ata_id_major_version(id) >= 7 &&
include/linux/libata.h +4 -0
index a4601cc..9eed812 100644
@@ -180,6 +180,7 @@ enum {
 	ATA_DFLAG_DA		= (1 << 26), /* device supports Device Attention */
 	ATA_DFLAG_DEVSLP	= (1 << 27), /* device supports Device Sleep */
 	ATA_DFLAG_ACPI_DISABLED = (1 << 28), /* ACPI for the device is disabled */
+	ATA_DFLAG_NCQ_SEND_RECV = (1 << 29), /* device supports NCQ SEND and RECV */
 
 	ATA_DEV_UNKNOWN		= 0,	/* unknown device */
 	ATA_DEV_ATA		= 1,	/* ATA device */
@@ -700,6 +701,9 @@ struct ata_device {
 	/* DEVSLP Timing Variables from Identify Device Data Log */
 	u8			devslp_timing[ATA_LOG_DEVSLP_SIZE];
 
+	/* NCQ send and receive log subcommand support */
+	u8			ncq_send_recv_cmds[ATA_LOG_NCQ_SEND_RECV_SIZE];
+
 	/* error history */
 	int			spdn_cnt;
 	/* ering is CLEAR_END, read comment above CLEAR_END */
Signature · 1 line
1.8.1.2
#16 lore raw

Re: [PATCH v3 2/3] libata: Add support for SEND/RECEIVE FPDMA QUEUED

drivers/ata/libata-core.c static int ata_dev_config_ncq(struct ata_device *dev, · line 2134

Quoted 5 lines · Marc C
drivers/ata/libata-core.c +1 -0
@@ -2131,6 +2131,7 @@ static int ata_dev_config_ncq(struct ata_device *dev,
 	int hdepth = 0, ddepth = ata_id_queue_depth(dev->id);
 	unsigned int err_mask;
 	char *aa_desc = "";
+	u8 sata_setting[ATA_SECT_SIZE];

Nope. Please don't do this. Can't you use ap->sector_buf?

Signature · 1 line
tejun
author
#17 lore raw

Re: [PATCH v3 2/3] libata: Add support for SEND/RECEIVE FPDMA QUEUED

Hello,

Quoted 9 lines · Tejun Heo

drivers/ata/libata-core.c static int ata_dev_config_ncq(struct ata_device *dev, · line 2134

Quoted 5 lines · Marc C
drivers/ata/libata-core.c +1 -0
@@ -2131,6 +2131,7 @@ static int ata_dev_config_ncq(struct ata_device *dev,
 	int hdepth = 0, ddepth = ata_id_queue_depth(dev->id);
 	unsigned int err_mask;
 	char *aa_desc = "";
+	u8 sata_setting[ATA_SECT_SIZE];

Nope. Please don't do this. Can't you use ap->sector_buf?

Yup, I should be able to use that instead.

Thanks,
Marc

author
#18 lore raw

PATCH v3 3/3 libata: Add support for queued DSM TRIM

In reply to Marc C

From: Marc Carino <[email protected]>

Some new SSDs support the queued version of the DSM TRIM command. Let the driver use the new command if supported.

---
 drivers/ata/libata-scsi.c | 27 +++++++++++++++++++++------
 1 file changed, 21 insertions(+), 6 deletions(-)
drivers/ata/libata-scsi.c +21 -6
index 83c0890..1605ffc 100644
@@ -3098,12 +3098,27 @@ static unsigned int ata_scsi_write_same_xlat(struct ata_queued_cmd *qc)
 	buf = page_address(sg_page(scsi_sglist(scmd)));
 	size = ata_set_lba_range_entries(buf, 512, block, n_block);
 
-	tf->protocol = ATA_PROT_DMA;
-	tf->hob_feature = 0;
-	tf->feature = ATA_DSM_TRIM;
-	tf->hob_nsect = (size / 512) >> 8;
-	tf->nsect = size / 512;
-	tf->command = ATA_CMD_DSM;
+	if (ata_ncq_enabled(dev) &&
+	    (dev->ncq_send_recv_cmds[ATA_LOG_NCQ_SEND_RECV_DSM_OFFSET] &
+	     ATA_LOG_NCQ_SEND_RECV_DSM_TRIM)) {
+		/* Newer devices support queued TRIM commands */
+		tf->protocol = ATA_PROT_NCQ;
+		tf->command = ATA_CMD_FPDMA_SEND;
+		tf->hob_nsect = ATA_SUBCMD_FPDMA_SEND_DSM & 0x1f;
+		tf->nsect = qc->tag << 3;
+		tf->hob_feature = (size / 512) >> 8;
+		tf->feature = size / 512;
+
+		qc->auxiliary = 1;
+	} else {
+		tf->protocol = ATA_PROT_DMA;
+		tf->hob_feature = 0;
+		tf->feature = ATA_DSM_TRIM;
+		tf->hob_nsect = (size / 512) >> 8;
+		tf->nsect = size / 512;
+		tf->command = ATA_CMD_DSM;
+	}
+
 	tf->flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE | ATA_TFLAG_LBA48 |
 		     ATA_TFLAG_WRITE;
 
Signature · 1 line
1.8.1.2
#19 lore raw

Re: [PATCH v3 3/3] libata: Add support for queued DSM TRIM

Hello.

Quoted 35 lines · Marc C

From: Marc Carino <[email protected]>

Some new SSDs support the queued version of the DSM TRIM command. Let the driver use the new command if supported.

---
  drivers/ata/libata-scsi.c | 27 +++++++++++++++++++++------
  1 file changed, 21 insertions(+), 6 deletions(-)
drivers/ata/libata-scsi.c +11 -6
index 83c0890..1605ffc 100644
@@ -3098,12 +3098,27 @@ static unsigned int ata_scsi_write_same_xlat(struct ata_queued_cmd *qc)
  	buf = page_address(sg_page(scsi_sglist(scmd)));
  	size = ata_set_lba_range_entries(buf, 512, block, n_block);
 
-	tf->protocol = ATA_PROT_DMA;
-	tf->hob_feature = 0;
-	tf->feature = ATA_DSM_TRIM;
-	tf->hob_nsect = (size / 512) >> 8;
-	tf->nsect = size / 512;
-	tf->command = ATA_CMD_DSM;
+	if (ata_ncq_enabled(dev) &&
+	    (dev->ncq_send_recv_cmds[ATA_LOG_NCQ_SEND_RECV_DSM_OFFSET] &
+	     ATA_LOG_NCQ_SEND_RECV_DSM_TRIM)) {
+		/* Newer devices support queued TRIM commands */
+		tf->protocol = ATA_PROT_NCQ;
+		tf->command = ATA_CMD_FPDMA_SEND;
+		tf->hob_nsect = ATA_SUBCMD_FPDMA_SEND_DSM & 0x1f;
+		tf->nsect = qc->tag << 3;
+		tf->hob_feature = (size / 512) >> 8;
+		tf->feature = size / 512;
+

drivers/ata/libata-scsi.c static unsigned int ata_scsi_write_same_xlat(struct ata_queued_cmd *qc) · line 3121

Quoted 10 lines
drivers/ata/libata-scsi.c +10 -0
+		qc->auxiliary = 1;
+	} else {
+		tf->protocol = ATA_PROT_DMA;
+		tf->hob_feature = 0;
+		tf->feature = ATA_DSM_TRIM;
+		tf->hob_nsect = (size / 512) >> 8;
+		tf->nsect = size / 512;
+		tf->command = ATA_CMD_DSM;
+	}
+

The remaining issue I see with this is that we don't check whether the
controller/driver is capable of transferring the new commands to device, i.e. that it's FIS-based.

WBR, Sergei

#20 lore raw

Re: [PATCH v3 3/3] libata: Add support for queued DSM TRIM

In reply to Marc C

Hello,

drivers/ata/libata-scsi.c static unsigned int ata_scsi_write_same_xlat(struct ata_queued_cmd *qc) · line 3103

Quoted 3 lines · Marc C
drivers/ata/libata-scsi.c +3 -0
+	if (ata_ncq_enabled(dev) &&
+	    (dev->ncq_send_recv_cmds[ATA_LOG_NCQ_SEND_RECV_DSM_OFFSET] &
+	     ATA_LOG_NCQ_SEND_RECV_DSM_TRIM)) {

Can you add a feature test macro for this?

Quoted 6 lines
drivers/ata/libata-scsi.c +6 -0
+		/* Newer devices support queued TRIM commands */
+		tf->protocol = ATA_PROT_NCQ;
+		tf->command = ATA_CMD_FPDMA_SEND;
+		tf->hob_nsect = ATA_SUBCMD_FPDMA_SEND_DSM & 0x1f;
+		tf->nsect = qc->tag << 3;
+		tf->hob_feature = (size / 512) >> 8;

drivers/ata/libata-scsi.c static unsigned int ata_scsi_write_same_xlat(struct ata_queued_cmd *qc) · line 3119

Quoted 10 lines
drivers/ata/libata-scsi.c +10 -0
+		tf->feature = size / 512;
+
+		qc->auxiliary = 1;
+	} else {
+		tf->protocol = ATA_PROT_DMA;
+		tf->hob_feature = 0;
+		tf->feature = ATA_DSM_TRIM;
+		tf->hob_nsect = (size / 512) >> 8;
+		tf->nsect = size / 512;
+		tf->command = ATA_CMD_DSM;

So, there are controllers which actually look at the command code and thus will choke on new commands and just looking at whether the device supports the new commands is likely to be insufficient. Have you tested this? If so, on which controllers / devices? We're likely to need whitelisting on controller side, I think.

Thanks.

Signature · 1 line
tejun
author
#21 lore raw

Re: [PATCH v3 3/3] libata: Add support for queued DSM TRIM

Hello,

Quoted 5 lines · Tejun Heo

So, there are controllers which actually look at the command code and thus will choke on new commands and just looking at whether the device supports the new commands is likely to be insufficient. Have you tested this? If so, on which controllers / devices? We're likely to need whitelisting on controller side, I think.

Not entirely sure. Non-AHCI controllers scare me since they typically don't come along with specs, or are just finicky. This is especially true since this is a new NCQ command. Anyway, I'll use a flag (as suggested in the other thread) to differentiate between controllers that _should_ be able to handle this properly (AHCI) and other vendor-specific SATA controllers.

Thanks,
Marc

#22 lore raw

Re: [PATCH v3 3/3] libata: Add support for queued DSM TRIM

Hello,

Quoted 6 lines · Marc C

Not entirely sure. Non-AHCI controllers scare me since they typically don't come along with specs, or are just finicky. This is especially true since this is a new NCQ command. Anyway, I'll use a flag (as suggested in the other thread) to differentiate between controllers that _should_ be able to handle this properly (AHCI) and other vendor-specific SATA controllers.

I'm fine with making it only available on ahci's, at least for now, but can you please make the flag distinguish the specific feature rather than the controller is AHCI or not?

Thanks.

Signature · 1 line
tejun