@@ -94,74 +94,70 @@ static struct acpi_device *to_acpi_dev(struct acpi_nfit_desc *acpi_desc)
94
94
return to_acpi_device (acpi_desc -> dev );
95
95
}
96
96
97
- static int xlat_status (void * buf , unsigned int cmd )
97
+ static int xlat_status (void * buf , unsigned int cmd , u32 status )
98
98
{
99
99
struct nd_cmd_clear_error * clear_err ;
100
100
struct nd_cmd_ars_status * ars_status ;
101
- struct nd_cmd_ars_start * ars_start ;
102
- struct nd_cmd_ars_cap * ars_cap ;
103
101
u16 flags ;
104
102
105
103
switch (cmd ) {
106
104
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 )
109
106
return - ENOTTY ;
110
107
111
108
/* Command failed */
112
- if (ars_cap -> status & 0xffff )
109
+ if (status & 0xffff )
113
110
return - EIO ;
114
111
115
112
/* No supported scan types for this range */
116
113
flags = ND_ARS_PERSISTENT | ND_ARS_VOLATILE ;
117
- if ((ars_cap -> status >> 16 & flags ) == 0 )
114
+ if ((status >> 16 & flags ) == 0 )
118
115
return - ENOTTY ;
119
116
break ;
120
117
case ND_CMD_ARS_START :
121
- ars_start = buf ;
122
118
/* ARS is in progress */
123
- if ((ars_start -> status & 0xffff ) == NFIT_ARS_START_BUSY )
119
+ if ((status & 0xffff ) == NFIT_ARS_START_BUSY )
124
120
return - EBUSY ;
125
121
126
122
/* Command failed */
127
- if (ars_start -> status & 0xffff )
123
+ if (status & 0xffff )
128
124
return - EIO ;
129
125
break ;
130
126
case ND_CMD_ARS_STATUS :
131
127
ars_status = buf ;
132
128
/* Command failed */
133
- if (ars_status -> status & 0xffff )
129
+ if (status & 0xffff )
134
130
return - EIO ;
135
131
/* Check extended status (Upper two bytes) */
136
- if (ars_status -> status == NFIT_ARS_STATUS_DONE )
132
+ if (status == NFIT_ARS_STATUS_DONE )
137
133
return 0 ;
138
134
139
135
/* ARS is in progress */
140
- if (ars_status -> status == NFIT_ARS_STATUS_BUSY )
136
+ if (status == NFIT_ARS_STATUS_BUSY )
141
137
return - EBUSY ;
142
138
143
139
/* No ARS performed for the current boot */
144
- if (ars_status -> status == NFIT_ARS_STATUS_NONE )
140
+ if (status == NFIT_ARS_STATUS_NONE )
145
141
return - EAGAIN ;
146
142
147
143
/*
148
144
* ARS interrupted, either we overflowed or some other
149
145
* agent wants the scan to stop. If we didn't overflow
150
146
* then just continue with the returned results.
151
147
*/
152
- if (ars_status -> status == NFIT_ARS_STATUS_INTR ) {
148
+ if (status == NFIT_ARS_STATUS_INTR ) {
153
149
if (ars_status -> flags & NFIT_ARS_F_OVERFLOW )
154
150
return - ENOSPC ;
155
151
return 0 ;
156
152
}
157
153
158
154
/* Unknown status */
159
- if (ars_status -> status >> 16 )
155
+ if (status >> 16 )
160
156
return - EIO ;
161
157
break ;
162
158
case ND_CMD_CLEAR_ERROR :
163
159
clear_err = buf ;
164
- if (clear_err -> status & 0xffff )
160
+ if (status & 0xffff )
165
161
return - EIO ;
166
162
if (!clear_err -> cleared )
167
163
return - EIO ;
@@ -172,6 +168,9 @@ static int xlat_status(void *buf, unsigned int cmd)
172
168
break ;
173
169
}
174
170
171
+ /* all other non-zero status results in an error */
172
+ if (status )
173
+ return - EIO ;
175
174
return 0 ;
176
175
}
177
176
@@ -186,10 +185,10 @@ static int acpi_nfit_ctl(struct nvdimm_bus_descriptor *nd_desc,
186
185
struct nd_cmd_pkg * call_pkg = NULL ;
187
186
const char * cmd_name , * dimm_name ;
188
187
unsigned long cmd_mask , dsm_mask ;
188
+ u32 offset , fw_status = 0 ;
189
189
acpi_handle handle ;
190
190
unsigned int func ;
191
191
const u8 * uuid ;
192
- u32 offset ;
193
192
int rc , i ;
194
193
195
194
func = cmd ;
@@ -317,6 +316,15 @@ static int acpi_nfit_ctl(struct nvdimm_bus_descriptor *nd_desc,
317
316
out_obj -> buffer .pointer + offset , out_size );
318
317
offset += out_size ;
319
318
}
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
+
320
328
if (offset + in_buf .buffer .length < buf_len ) {
321
329
if (i >= 1 ) {
322
330
/*
@@ -325,7 +333,7 @@ static int acpi_nfit_ctl(struct nvdimm_bus_descriptor *nd_desc,
325
333
*/
326
334
rc = buf_len - offset - in_buf .buffer .length ;
327
335
if (cmd_rc )
328
- * cmd_rc = xlat_status (buf , cmd );
336
+ * cmd_rc = xlat_status (buf , cmd , fw_status );
329
337
} else {
330
338
dev_err (dev , "%s:%s underrun cmd: %s buf_len: %d out_len: %d\n" ,
331
339
__func__ , dimm_name , cmd_name , buf_len ,
@@ -335,7 +343,7 @@ static int acpi_nfit_ctl(struct nvdimm_bus_descriptor *nd_desc,
335
343
} else {
336
344
rc = 0 ;
337
345
if (cmd_rc )
338
- * cmd_rc = xlat_status (buf , cmd );
346
+ * cmd_rc = xlat_status (buf , cmd , fw_status );
339
347
}
340
348
341
349
out :
0 commit comments