diff options
author | Hannes Reinecke <hare@suse.de> | 2016-04-25 06:45:54 -0400 |
---|---|---|
committer | Tejun Heo <tj@kernel.org> | 2016-05-09 12:36:46 -0400 |
commit | 284b3b77ea883234dadb2cbf97b145c3c30fe4bd (patch) | |
tree | 2faa832ef21a350e2d6b5e4c238f70e38e0e6502 /drivers/ata | |
parent | 27708a9579ee069c6e0ebb6e61ac1114ed1d546c (diff) |
libata: NCQ encapsulation for ZAC MANAGEMENT OUT
Add NCQ encapsulation for ZAC MANAGEMENT OUT and evaluate
NCQ Non-Data log pages to figure out if NCQ encapsulation
is supported.
Signed-off-by: Hannes Reinecke <hare@suse.com>
Signed-off-by: Tejun Heo <tj@kernel.org>
Diffstat (limited to 'drivers/ata')
-rw-r--r-- | drivers/ata/libata-core.c | 43 | ||||
-rw-r--r-- | drivers/ata/libata-scsi.c | 18 | ||||
-rw-r--r-- | drivers/ata/libata-trace.c | 3 |
3 files changed, 56 insertions, 8 deletions
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index b2bd7c499653..1528c7cc0089 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c | |||
@@ -2121,6 +2121,40 @@ static void ata_dev_config_ncq_send_recv(struct ata_device *dev) | |||
2121 | } | 2121 | } |
2122 | } | 2122 | } |
2123 | 2123 | ||
2124 | static void ata_dev_config_ncq_non_data(struct ata_device *dev) | ||
2125 | { | ||
2126 | struct ata_port *ap = dev->link->ap; | ||
2127 | unsigned int err_mask; | ||
2128 | int log_index = ATA_LOG_NCQ_NON_DATA * 2; | ||
2129 | u16 log_pages; | ||
2130 | |||
2131 | err_mask = ata_read_log_page(dev, ATA_LOG_DIRECTORY, | ||
2132 | 0, ap->sector_buf, 1); | ||
2133 | if (err_mask) { | ||
2134 | ata_dev_dbg(dev, | ||
2135 | "failed to get Log Directory Emask 0x%x\n", | ||
2136 | err_mask); | ||
2137 | return; | ||
2138 | } | ||
2139 | log_pages = get_unaligned_le16(&ap->sector_buf[log_index]); | ||
2140 | if (!log_pages) { | ||
2141 | ata_dev_warn(dev, | ||
2142 | "NCQ Send/Recv Log not supported\n"); | ||
2143 | return; | ||
2144 | } | ||
2145 | err_mask = ata_read_log_page(dev, ATA_LOG_NCQ_NON_DATA, | ||
2146 | 0, ap->sector_buf, 1); | ||
2147 | if (err_mask) { | ||
2148 | ata_dev_dbg(dev, | ||
2149 | "failed to get NCQ Non-Data Log Emask 0x%x\n", | ||
2150 | err_mask); | ||
2151 | } else { | ||
2152 | u8 *cmds = dev->ncq_non_data_cmds; | ||
2153 | |||
2154 | memcpy(cmds, ap->sector_buf, ATA_LOG_NCQ_NON_DATA_SIZE); | ||
2155 | } | ||
2156 | } | ||
2157 | |||
2124 | static int ata_dev_config_ncq(struct ata_device *dev, | 2158 | static int ata_dev_config_ncq(struct ata_device *dev, |
2125 | char *desc, size_t desc_sz) | 2159 | char *desc, size_t desc_sz) |
2126 | { | 2160 | { |
@@ -2165,9 +2199,12 @@ static int ata_dev_config_ncq(struct ata_device *dev, | |||
2165 | snprintf(desc, desc_sz, "NCQ (depth %d/%d)%s", hdepth, | 2199 | snprintf(desc, desc_sz, "NCQ (depth %d/%d)%s", hdepth, |
2166 | ddepth, aa_desc); | 2200 | ddepth, aa_desc); |
2167 | 2201 | ||
2168 | if ((ap->flags & ATA_FLAG_FPDMA_AUX) && | 2202 | if ((ap->flags & ATA_FLAG_FPDMA_AUX)) { |
2169 | ata_id_has_ncq_send_and_recv(dev->id)) | 2203 | if (ata_id_has_ncq_send_and_recv(dev->id)) |
2170 | ata_dev_config_ncq_send_recv(dev); | 2204 | ata_dev_config_ncq_send_recv(dev); |
2205 | if (ata_id_has_ncq_non_data(dev->id)) | ||
2206 | ata_dev_config_ncq_non_data(dev); | ||
2207 | } | ||
2171 | 2208 | ||
2172 | return 0; | 2209 | return 0; |
2173 | } | 2210 | } |
diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index 6afd0840ebbe..43403aa0801f 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c | |||
@@ -3506,11 +3506,19 @@ static unsigned int ata_scsi_zbc_out_xlat(struct ata_queued_cmd *qc) | |||
3506 | 3506 | ||
3507 | reset_all = cdb[14] & 0x1; | 3507 | reset_all = cdb[14] & 0x1; |
3508 | 3508 | ||
3509 | tf->protocol = ATA_PROT_NODATA; | 3509 | if (ata_ncq_enabled(qc->dev) && |
3510 | tf->command = ATA_CMD_ZAC_MGMT_OUT; | 3510 | ata_fpdma_zac_mgmt_out_supported(qc->dev)) { |
3511 | tf->feature = sa; | 3511 | tf->protocol = ATA_PROT_NCQ; |
3512 | tf->hob_feature = reset_all & 0x1; | 3512 | tf->command = ATA_CMD_NCQ_NON_DATA; |
3513 | 3513 | tf->hob_nsect = ATA_SUBCMD_NCQ_NON_DATA_ZAC_MGMT_OUT; | |
3514 | tf->nsect = qc->tag << 3; | ||
3515 | tf->auxiliary = sa | (reset_all & 0x1) << 8; | ||
3516 | } else { | ||
3517 | tf->protocol = ATA_PROT_NODATA; | ||
3518 | tf->command = ATA_CMD_ZAC_MGMT_OUT; | ||
3519 | tf->feature = sa; | ||
3520 | tf->hob_feature = reset_all & 0x1; | ||
3521 | } | ||
3514 | tf->lbah = (block >> 16) & 0xff; | 3522 | tf->lbah = (block >> 16) & 0xff; |
3515 | tf->lbam = (block >> 8) & 0xff; | 3523 | tf->lbam = (block >> 8) & 0xff; |
3516 | tf->lbal = block & 0xff; | 3524 | tf->lbal = block & 0xff; |
diff --git a/drivers/ata/libata-trace.c b/drivers/ata/libata-trace.c index 1111ba7db5b3..f8c550df0615 100644 --- a/drivers/ata/libata-trace.c +++ b/drivers/ata/libata-trace.c | |||
@@ -188,6 +188,9 @@ libata_trace_parse_subcmd(struct trace_seq *p, unsigned char cmd, | |||
188 | case ATA_SUBCMD_NCQ_NON_DATA_ZERO_EXT: | 188 | case ATA_SUBCMD_NCQ_NON_DATA_ZERO_EXT: |
189 | trace_seq_printf(p, " ZERO_EXT"); | 189 | trace_seq_printf(p, " ZERO_EXT"); |
190 | break; | 190 | break; |
191 | case ATA_SUBCMD_NCQ_NON_DATA_ZAC_MGMT_OUT: | ||
192 | trace_seq_printf(p, " ZAC_MGMT_OUT"); | ||
193 | break; | ||
191 | } | 194 | } |
192 | break; | 195 | break; |
193 | case ATA_CMD_ZAC_MGMT_IN: | 196 | case ATA_CMD_ZAC_MGMT_IN: |