@@ -94,74 +94,70 @@ static struct acpi_device *to_acpi_dev(struct acpi_nfit_desc *acpi_desc)
9494 return to_acpi_device (acpi_desc -> dev );
9595}
9696
97- static int xlat_status (void * buf , unsigned int cmd )
97+ static int xlat_status (void * buf , unsigned int cmd , u32 status )
9898{
9999 struct nd_cmd_clear_error * clear_err ;
100100 struct nd_cmd_ars_status * ars_status ;
101- struct nd_cmd_ars_start * ars_start ;
102- struct nd_cmd_ars_cap * ars_cap ;
103101 u16 flags ;
104102
105103 switch (cmd ) {
106104 case ND_CMD_ARS_CAP :
107- ars_cap = buf ;
108- if ((ars_cap -> status & 0xffff ) == NFIT_ARS_CAP_NONE )
105+ if ((status & 0xffff ) == NFIT_ARS_CAP_NONE )
109106 return - ENOTTY ;
110107
111108 /* Command failed */
112- if (ars_cap -> status & 0xffff )
109+ if (status & 0xffff )
113110 return - EIO ;
114111
115112 /* No supported scan types for this range */
116113 flags = ND_ARS_PERSISTENT | ND_ARS_VOLATILE ;
117- if ((ars_cap -> status >> 16 & flags ) == 0 )
114+ if ((status >> 16 & flags ) == 0 )
118115 return - ENOTTY ;
119116 break ;
120117 case ND_CMD_ARS_START :
121- ars_start = buf ;
122118 /* ARS is in progress */
123- if ((ars_start -> status & 0xffff ) == NFIT_ARS_START_BUSY )
119+ if ((status & 0xffff ) == NFIT_ARS_START_BUSY )
124120 return - EBUSY ;
125121
126122 /* Command failed */
127- if (ars_start -> status & 0xffff )
123+ if (status & 0xffff )
128124 return - EIO ;
129125 break ;
130126 case ND_CMD_ARS_STATUS :
131127 ars_status = buf ;
132128 /* Command failed */
133- if (ars_status -> status & 0xffff )
129+ if (status & 0xffff )
134130 return - EIO ;
135131 /* Check extended status (Upper two bytes) */
136- if (ars_status -> status == NFIT_ARS_STATUS_DONE )
132+ if (status == NFIT_ARS_STATUS_DONE )
137133 return 0 ;
138134
139135 /* ARS is in progress */
140- if (ars_status -> status == NFIT_ARS_STATUS_BUSY )
136+ if (status == NFIT_ARS_STATUS_BUSY )
141137 return - EBUSY ;
142138
143139 /* No ARS performed for the current boot */
144- if (ars_status -> status == NFIT_ARS_STATUS_NONE )
140+ if (status == NFIT_ARS_STATUS_NONE )
145141 return - EAGAIN ;
146142
147143 /*
148144 * ARS interrupted, either we overflowed or some other
149145 * agent wants the scan to stop. If we didn't overflow
150146 * then just continue with the returned results.
151147 */
152- if (ars_status -> status == NFIT_ARS_STATUS_INTR ) {
148+ if (status == NFIT_ARS_STATUS_INTR ) {
153149 if (ars_status -> flags & NFIT_ARS_F_OVERFLOW )
154150 return - ENOSPC ;
155151 return 0 ;
156152 }
157153
158154 /* Unknown status */
159- if (ars_status -> status >> 16 )
155+ if (status >> 16 )
160156 return - EIO ;
161157 break ;
162158 case ND_CMD_CLEAR_ERROR :
163159 clear_err = buf ;
164- if (clear_err -> status & 0xffff )
160+ if (status & 0xffff )
165161 return - EIO ;
166162 if (!clear_err -> cleared )
167163 return - EIO ;
@@ -172,6 +168,9 @@ static int xlat_status(void *buf, unsigned int cmd)
172168 break ;
173169 }
174170
171+ /* all other non-zero status results in an error */
172+ if (status )
173+ return - EIO ;
175174 return 0 ;
176175}
177176
@@ -186,10 +185,10 @@ static int acpi_nfit_ctl(struct nvdimm_bus_descriptor *nd_desc,
186185 struct nd_cmd_pkg * call_pkg = NULL ;
187186 const char * cmd_name , * dimm_name ;
188187 unsigned long cmd_mask , dsm_mask ;
188+ u32 offset , fw_status = 0 ;
189189 acpi_handle handle ;
190190 unsigned int func ;
191191 const u8 * uuid ;
192- u32 offset ;
193192 int rc , i ;
194193
195194 func = cmd ;
@@ -317,6 +316,15 @@ static int acpi_nfit_ctl(struct nvdimm_bus_descriptor *nd_desc,
317316 out_obj -> buffer .pointer + offset , out_size );
318317 offset += out_size ;
319318 }
319+
320+ /*
321+ * Set fw_status for all the commands with a known format to be
322+ * later interpreted by xlat_status().
323+ */
324+ if (i >= 1 && ((cmd >= ND_CMD_ARS_CAP && cmd <= ND_CMD_CLEAR_ERROR )
325+ || (cmd >= ND_CMD_SMART && cmd <= ND_CMD_VENDOR )))
326+ fw_status = * (u32 * ) out_obj -> buffer .pointer ;
327+
320328 if (offset + in_buf .buffer .length < buf_len ) {
321329 if (i >= 1 ) {
322330 /*
@@ -325,7 +333,7 @@ static int acpi_nfit_ctl(struct nvdimm_bus_descriptor *nd_desc,
325333 */
326334 rc = buf_len - offset - in_buf .buffer .length ;
327335 if (cmd_rc )
328- * cmd_rc = xlat_status (buf , cmd );
336+ * cmd_rc = xlat_status (buf , cmd , fw_status );
329337 } else {
330338 dev_err (dev , "%s:%s underrun cmd: %s buf_len: %d out_len: %d\n" ,
331339 __func__ , dimm_name , cmd_name , buf_len ,
@@ -335,7 +343,7 @@ static int acpi_nfit_ctl(struct nvdimm_bus_descriptor *nd_desc,
335343 } else {
336344 rc = 0 ;
337345 if (cmd_rc )
338- * cmd_rc = xlat_status (buf , cmd );
346+ * cmd_rc = xlat_status (buf , cmd , fw_status );
339347 }
340348
341349 out :
0 commit comments