| .. | .. |
|---|
| 19 | 19 | static void __ap_flush_queue(struct ap_queue *aq); |
|---|
| 20 | 20 | |
|---|
| 21 | 21 | /** |
|---|
| 22 | | - * ap_queue_enable_interruption(): Enable interruption on an AP queue. |
|---|
| 22 | + * ap_queue_enable_irq(): Enable interrupt support on this AP queue. |
|---|
| 23 | 23 | * @qid: The AP queue number |
|---|
| 24 | 24 | * @ind: the notification indicator byte |
|---|
| 25 | 25 | * |
|---|
| .. | .. |
|---|
| 27 | 27 | * value it waits a while and tests the AP queue if interrupts |
|---|
| 28 | 28 | * have been switched on using ap_test_queue(). |
|---|
| 29 | 29 | */ |
|---|
| 30 | | -static int ap_queue_enable_interruption(struct ap_queue *aq, void *ind) |
|---|
| 30 | +static int ap_queue_enable_irq(struct ap_queue *aq, void *ind) |
|---|
| 31 | 31 | { |
|---|
| 32 | 32 | struct ap_queue_status status; |
|---|
| 33 | 33 | struct ap_qirq_ctrl qirqctrl = { 0 }; |
|---|
| .. | .. |
|---|
| 69 | 69 | */ |
|---|
| 70 | 70 | static inline struct ap_queue_status |
|---|
| 71 | 71 | __ap_send(ap_qid_t qid, unsigned long long psmid, void *msg, size_t length, |
|---|
| 72 | | - unsigned int special) |
|---|
| 72 | + int special) |
|---|
| 73 | 73 | { |
|---|
| 74 | | - if (special == 1) |
|---|
| 74 | + if (special) |
|---|
| 75 | 75 | qid |= 0x400000UL; |
|---|
| 76 | 76 | return ap_nqap(qid, psmid, msg, length); |
|---|
| 77 | 77 | } |
|---|
| .. | .. |
|---|
| 119 | 119 | |
|---|
| 120 | 120 | /* State machine definitions and helpers */ |
|---|
| 121 | 121 | |
|---|
| 122 | | -static enum ap_wait ap_sm_nop(struct ap_queue *aq) |
|---|
| 122 | +static enum ap_sm_wait ap_sm_nop(struct ap_queue *aq) |
|---|
| 123 | 123 | { |
|---|
| 124 | | - return AP_WAIT_NONE; |
|---|
| 124 | + return AP_SM_WAIT_NONE; |
|---|
| 125 | 125 | } |
|---|
| 126 | 126 | |
|---|
| 127 | 127 | /** |
|---|
| .. | .. |
|---|
| 129 | 129 | * not change the state of the device. |
|---|
| 130 | 130 | * @aq: pointer to the AP queue |
|---|
| 131 | 131 | * |
|---|
| 132 | | - * Returns AP_WAIT_NONE, AP_WAIT_AGAIN, or AP_WAIT_INTERRUPT |
|---|
| 132 | + * Returns AP_SM_WAIT_NONE, AP_SM_WAIT_AGAIN, or AP_SM_WAIT_INTERRUPT |
|---|
| 133 | 133 | */ |
|---|
| 134 | 134 | static struct ap_queue_status ap_sm_recv(struct ap_queue *aq) |
|---|
| 135 | 135 | { |
|---|
| 136 | 136 | struct ap_queue_status status; |
|---|
| 137 | 137 | struct ap_message *ap_msg; |
|---|
| 138 | + bool found = false; |
|---|
| 138 | 139 | |
|---|
| 139 | 140 | status = ap_dqap(aq->qid, &aq->reply->psmid, |
|---|
| 140 | | - aq->reply->message, aq->reply->length); |
|---|
| 141 | + aq->reply->msg, aq->reply->len); |
|---|
| 141 | 142 | switch (status.response_code) { |
|---|
| 142 | 143 | case AP_RESPONSE_NORMAL: |
|---|
| 143 | | - aq->queue_count--; |
|---|
| 144 | + aq->queue_count = max_t(int, 0, aq->queue_count - 1); |
|---|
| 145 | + if (!status.queue_empty && !aq->queue_count) |
|---|
| 146 | + aq->queue_count++; |
|---|
| 144 | 147 | if (aq->queue_count > 0) |
|---|
| 145 | 148 | mod_timer(&aq->timeout, |
|---|
| 146 | 149 | jiffies + aq->request_timeout); |
|---|
| .. | .. |
|---|
| 150 | 153 | list_del_init(&ap_msg->list); |
|---|
| 151 | 154 | aq->pendingq_count--; |
|---|
| 152 | 155 | ap_msg->receive(aq, ap_msg, aq->reply); |
|---|
| 156 | + found = true; |
|---|
| 153 | 157 | break; |
|---|
| 154 | 158 | } |
|---|
| 159 | + if (!found) { |
|---|
| 160 | + AP_DBF_WARN("%s unassociated reply psmid=0x%016llx on 0x%02x.%04x\n", |
|---|
| 161 | + __func__, aq->reply->psmid, |
|---|
| 162 | + AP_QID_CARD(aq->qid), AP_QID_QUEUE(aq->qid)); |
|---|
| 163 | + } |
|---|
| 164 | + fallthrough; |
|---|
| 155 | 165 | case AP_RESPONSE_NO_PENDING_REPLY: |
|---|
| 156 | 166 | if (!status.queue_empty || aq->queue_count <= 0) |
|---|
| 157 | 167 | break; |
|---|
| .. | .. |
|---|
| 171 | 181 | * ap_sm_read(): Receive pending reply messages from an AP queue. |
|---|
| 172 | 182 | * @aq: pointer to the AP queue |
|---|
| 173 | 183 | * |
|---|
| 174 | | - * Returns AP_WAIT_NONE, AP_WAIT_AGAIN, or AP_WAIT_INTERRUPT |
|---|
| 184 | + * Returns AP_SM_WAIT_NONE, AP_SM_WAIT_AGAIN, or AP_SM_WAIT_INTERRUPT |
|---|
| 175 | 185 | */ |
|---|
| 176 | | -static enum ap_wait ap_sm_read(struct ap_queue *aq) |
|---|
| 186 | +static enum ap_sm_wait ap_sm_read(struct ap_queue *aq) |
|---|
| 177 | 187 | { |
|---|
| 178 | 188 | struct ap_queue_status status; |
|---|
| 179 | 189 | |
|---|
| 180 | 190 | if (!aq->reply) |
|---|
| 181 | | - return AP_WAIT_NONE; |
|---|
| 191 | + return AP_SM_WAIT_NONE; |
|---|
| 182 | 192 | status = ap_sm_recv(aq); |
|---|
| 183 | 193 | switch (status.response_code) { |
|---|
| 184 | 194 | case AP_RESPONSE_NORMAL: |
|---|
| 185 | 195 | if (aq->queue_count > 0) { |
|---|
| 186 | | - aq->state = AP_STATE_WORKING; |
|---|
| 187 | | - return AP_WAIT_AGAIN; |
|---|
| 196 | + aq->sm_state = AP_SM_STATE_WORKING; |
|---|
| 197 | + return AP_SM_WAIT_AGAIN; |
|---|
| 188 | 198 | } |
|---|
| 189 | | - aq->state = AP_STATE_IDLE; |
|---|
| 190 | | - return AP_WAIT_NONE; |
|---|
| 199 | + aq->sm_state = AP_SM_STATE_IDLE; |
|---|
| 200 | + return AP_SM_WAIT_NONE; |
|---|
| 191 | 201 | case AP_RESPONSE_NO_PENDING_REPLY: |
|---|
| 192 | 202 | if (aq->queue_count > 0) |
|---|
| 193 | | - return AP_WAIT_INTERRUPT; |
|---|
| 194 | | - aq->state = AP_STATE_IDLE; |
|---|
| 195 | | - return AP_WAIT_NONE; |
|---|
| 203 | + return aq->interrupt ? |
|---|
| 204 | + AP_SM_WAIT_INTERRUPT : AP_SM_WAIT_TIMEOUT; |
|---|
| 205 | + aq->sm_state = AP_SM_STATE_IDLE; |
|---|
| 206 | + return AP_SM_WAIT_NONE; |
|---|
| 196 | 207 | default: |
|---|
| 197 | | - aq->state = AP_STATE_BORKED; |
|---|
| 198 | | - return AP_WAIT_NONE; |
|---|
| 199 | | - } |
|---|
| 200 | | -} |
|---|
| 201 | | - |
|---|
| 202 | | -/** |
|---|
| 203 | | - * ap_sm_suspend_read(): Receive pending reply messages from an AP queue |
|---|
| 204 | | - * without changing the device state in between. In suspend mode we don't |
|---|
| 205 | | - * allow sending new requests, therefore just fetch pending replies. |
|---|
| 206 | | - * @aq: pointer to the AP queue |
|---|
| 207 | | - * |
|---|
| 208 | | - * Returns AP_WAIT_NONE or AP_WAIT_AGAIN |
|---|
| 209 | | - */ |
|---|
| 210 | | -static enum ap_wait ap_sm_suspend_read(struct ap_queue *aq) |
|---|
| 211 | | -{ |
|---|
| 212 | | - struct ap_queue_status status; |
|---|
| 213 | | - |
|---|
| 214 | | - if (!aq->reply) |
|---|
| 215 | | - return AP_WAIT_NONE; |
|---|
| 216 | | - status = ap_sm_recv(aq); |
|---|
| 217 | | - switch (status.response_code) { |
|---|
| 218 | | - case AP_RESPONSE_NORMAL: |
|---|
| 219 | | - if (aq->queue_count > 0) |
|---|
| 220 | | - return AP_WAIT_AGAIN; |
|---|
| 221 | | - /* fall through */ |
|---|
| 222 | | - default: |
|---|
| 223 | | - return AP_WAIT_NONE; |
|---|
| 208 | + aq->dev_state = AP_DEV_STATE_ERROR; |
|---|
| 209 | + aq->last_err_rc = status.response_code; |
|---|
| 210 | + AP_DBF_WARN("%s RC 0x%02x on 0x%02x.%04x -> AP_DEV_STATE_ERROR\n", |
|---|
| 211 | + __func__, status.response_code, |
|---|
| 212 | + AP_QID_CARD(aq->qid), AP_QID_QUEUE(aq->qid)); |
|---|
| 213 | + return AP_SM_WAIT_NONE; |
|---|
| 224 | 214 | } |
|---|
| 225 | 215 | } |
|---|
| 226 | 216 | |
|---|
| .. | .. |
|---|
| 228 | 218 | * ap_sm_write(): Send messages from the request queue to an AP queue. |
|---|
| 229 | 219 | * @aq: pointer to the AP queue |
|---|
| 230 | 220 | * |
|---|
| 231 | | - * Returns AP_WAIT_NONE, AP_WAIT_AGAIN, or AP_WAIT_INTERRUPT |
|---|
| 221 | + * Returns AP_SM_WAIT_NONE, AP_SM_WAIT_AGAIN, or AP_SM_WAIT_INTERRUPT |
|---|
| 232 | 222 | */ |
|---|
| 233 | | -static enum ap_wait ap_sm_write(struct ap_queue *aq) |
|---|
| 223 | +static enum ap_sm_wait ap_sm_write(struct ap_queue *aq) |
|---|
| 234 | 224 | { |
|---|
| 235 | 225 | struct ap_queue_status status; |
|---|
| 236 | 226 | struct ap_message *ap_msg; |
|---|
| 227 | + ap_qid_t qid = aq->qid; |
|---|
| 237 | 228 | |
|---|
| 238 | 229 | if (aq->requestq_count <= 0) |
|---|
| 239 | | - return AP_WAIT_NONE; |
|---|
| 230 | + return AP_SM_WAIT_NONE; |
|---|
| 240 | 231 | /* Start the next request on the queue. */ |
|---|
| 241 | 232 | ap_msg = list_entry(aq->requestq.next, struct ap_message, list); |
|---|
| 242 | | - status = __ap_send(aq->qid, ap_msg->psmid, |
|---|
| 243 | | - ap_msg->message, ap_msg->length, ap_msg->special); |
|---|
| 233 | +#ifdef CONFIG_ZCRYPT_DEBUG |
|---|
| 234 | + if (ap_msg->fi.action == AP_FI_ACTION_NQAP_QID_INVAL) { |
|---|
| 235 | + AP_DBF_WARN("%s fi cmd 0x%04x: forcing invalid qid 0xFF00\n", |
|---|
| 236 | + __func__, ap_msg->fi.cmd); |
|---|
| 237 | + qid = 0xFF00; |
|---|
| 238 | + } |
|---|
| 239 | +#endif |
|---|
| 240 | + status = __ap_send(qid, ap_msg->psmid, |
|---|
| 241 | + ap_msg->msg, ap_msg->len, |
|---|
| 242 | + ap_msg->flags & AP_MSG_FLAG_SPECIAL); |
|---|
| 244 | 243 | switch (status.response_code) { |
|---|
| 245 | 244 | case AP_RESPONSE_NORMAL: |
|---|
| 246 | | - aq->queue_count++; |
|---|
| 245 | + aq->queue_count = max_t(int, 1, aq->queue_count + 1); |
|---|
| 247 | 246 | if (aq->queue_count == 1) |
|---|
| 248 | 247 | mod_timer(&aq->timeout, jiffies + aq->request_timeout); |
|---|
| 249 | 248 | list_move_tail(&ap_msg->list, &aq->pendingq); |
|---|
| 250 | 249 | aq->requestq_count--; |
|---|
| 251 | 250 | aq->pendingq_count++; |
|---|
| 252 | 251 | if (aq->queue_count < aq->card->queue_depth) { |
|---|
| 253 | | - aq->state = AP_STATE_WORKING; |
|---|
| 254 | | - return AP_WAIT_AGAIN; |
|---|
| 252 | + aq->sm_state = AP_SM_STATE_WORKING; |
|---|
| 253 | + return AP_SM_WAIT_AGAIN; |
|---|
| 255 | 254 | } |
|---|
| 256 | | - /* fall through */ |
|---|
| 255 | + fallthrough; |
|---|
| 257 | 256 | case AP_RESPONSE_Q_FULL: |
|---|
| 258 | | - aq->state = AP_STATE_QUEUE_FULL; |
|---|
| 259 | | - return AP_WAIT_INTERRUPT; |
|---|
| 257 | + aq->sm_state = AP_SM_STATE_QUEUE_FULL; |
|---|
| 258 | + return aq->interrupt ? |
|---|
| 259 | + AP_SM_WAIT_INTERRUPT : AP_SM_WAIT_TIMEOUT; |
|---|
| 260 | 260 | case AP_RESPONSE_RESET_IN_PROGRESS: |
|---|
| 261 | | - aq->state = AP_STATE_RESET_WAIT; |
|---|
| 262 | | - return AP_WAIT_TIMEOUT; |
|---|
| 261 | + aq->sm_state = AP_SM_STATE_RESET_WAIT; |
|---|
| 262 | + return AP_SM_WAIT_TIMEOUT; |
|---|
| 263 | + case AP_RESPONSE_INVALID_DOMAIN: |
|---|
| 264 | + AP_DBF(DBF_WARN, "AP_RESPONSE_INVALID_DOMAIN on NQAP\n"); |
|---|
| 265 | + fallthrough; |
|---|
| 263 | 266 | case AP_RESPONSE_MESSAGE_TOO_BIG: |
|---|
| 264 | 267 | case AP_RESPONSE_REQ_FAC_NOT_INST: |
|---|
| 265 | 268 | list_del_init(&ap_msg->list); |
|---|
| 266 | 269 | aq->requestq_count--; |
|---|
| 267 | 270 | ap_msg->rc = -EINVAL; |
|---|
| 268 | 271 | ap_msg->receive(aq, ap_msg, NULL); |
|---|
| 269 | | - return AP_WAIT_AGAIN; |
|---|
| 272 | + return AP_SM_WAIT_AGAIN; |
|---|
| 270 | 273 | default: |
|---|
| 271 | | - aq->state = AP_STATE_BORKED; |
|---|
| 272 | | - return AP_WAIT_NONE; |
|---|
| 274 | + aq->dev_state = AP_DEV_STATE_ERROR; |
|---|
| 275 | + aq->last_err_rc = status.response_code; |
|---|
| 276 | + AP_DBF_WARN("%s RC 0x%02x on 0x%02x.%04x -> AP_DEV_STATE_ERROR\n", |
|---|
| 277 | + __func__, status.response_code, |
|---|
| 278 | + AP_QID_CARD(aq->qid), AP_QID_QUEUE(aq->qid)); |
|---|
| 279 | + return AP_SM_WAIT_NONE; |
|---|
| 273 | 280 | } |
|---|
| 274 | 281 | } |
|---|
| 275 | 282 | |
|---|
| .. | .. |
|---|
| 277 | 284 | * ap_sm_read_write(): Send and receive messages to/from an AP queue. |
|---|
| 278 | 285 | * @aq: pointer to the AP queue |
|---|
| 279 | 286 | * |
|---|
| 280 | | - * Returns AP_WAIT_NONE, AP_WAIT_AGAIN, or AP_WAIT_INTERRUPT |
|---|
| 287 | + * Returns AP_SM_WAIT_NONE, AP_SM_WAIT_AGAIN, or AP_SM_WAIT_INTERRUPT |
|---|
| 281 | 288 | */ |
|---|
| 282 | | -static enum ap_wait ap_sm_read_write(struct ap_queue *aq) |
|---|
| 289 | +static enum ap_sm_wait ap_sm_read_write(struct ap_queue *aq) |
|---|
| 283 | 290 | { |
|---|
| 284 | 291 | return min(ap_sm_read(aq), ap_sm_write(aq)); |
|---|
| 285 | 292 | } |
|---|
| .. | .. |
|---|
| 290 | 297 | * |
|---|
| 291 | 298 | * Submit the Reset command to an AP queue. |
|---|
| 292 | 299 | */ |
|---|
| 293 | | -static enum ap_wait ap_sm_reset(struct ap_queue *aq) |
|---|
| 300 | +static enum ap_sm_wait ap_sm_reset(struct ap_queue *aq) |
|---|
| 294 | 301 | { |
|---|
| 295 | 302 | struct ap_queue_status status; |
|---|
| 296 | 303 | |
|---|
| .. | .. |
|---|
| 298 | 305 | switch (status.response_code) { |
|---|
| 299 | 306 | case AP_RESPONSE_NORMAL: |
|---|
| 300 | 307 | case AP_RESPONSE_RESET_IN_PROGRESS: |
|---|
| 301 | | - aq->state = AP_STATE_RESET_WAIT; |
|---|
| 302 | | - aq->interrupt = AP_INTR_DISABLED; |
|---|
| 303 | | - return AP_WAIT_TIMEOUT; |
|---|
| 304 | | - case AP_RESPONSE_BUSY: |
|---|
| 305 | | - return AP_WAIT_TIMEOUT; |
|---|
| 306 | | - case AP_RESPONSE_Q_NOT_AVAIL: |
|---|
| 307 | | - case AP_RESPONSE_DECONFIGURED: |
|---|
| 308 | | - case AP_RESPONSE_CHECKSTOPPED: |
|---|
| 308 | + aq->sm_state = AP_SM_STATE_RESET_WAIT; |
|---|
| 309 | + aq->interrupt = false; |
|---|
| 310 | + return AP_SM_WAIT_TIMEOUT; |
|---|
| 309 | 311 | default: |
|---|
| 310 | | - aq->state = AP_STATE_BORKED; |
|---|
| 311 | | - return AP_WAIT_NONE; |
|---|
| 312 | + aq->dev_state = AP_DEV_STATE_ERROR; |
|---|
| 313 | + aq->last_err_rc = status.response_code; |
|---|
| 314 | + AP_DBF_WARN("%s RC 0x%02x on 0x%02x.%04x -> AP_DEV_STATE_ERROR\n", |
|---|
| 315 | + __func__, status.response_code, |
|---|
| 316 | + AP_QID_CARD(aq->qid), AP_QID_QUEUE(aq->qid)); |
|---|
| 317 | + return AP_SM_WAIT_NONE; |
|---|
| 312 | 318 | } |
|---|
| 313 | 319 | } |
|---|
| 314 | 320 | |
|---|
| .. | .. |
|---|
| 318 | 324 | * |
|---|
| 319 | 325 | * Returns AP_POLL_IMMEDIATELY, AP_POLL_AFTER_TIMEROUT or 0. |
|---|
| 320 | 326 | */ |
|---|
| 321 | | -static enum ap_wait ap_sm_reset_wait(struct ap_queue *aq) |
|---|
| 327 | +static enum ap_sm_wait ap_sm_reset_wait(struct ap_queue *aq) |
|---|
| 322 | 328 | { |
|---|
| 323 | 329 | struct ap_queue_status status; |
|---|
| 324 | 330 | void *lsi_ptr; |
|---|
| .. | .. |
|---|
| 333 | 339 | switch (status.response_code) { |
|---|
| 334 | 340 | case AP_RESPONSE_NORMAL: |
|---|
| 335 | 341 | lsi_ptr = ap_airq_ptr(); |
|---|
| 336 | | - if (lsi_ptr && ap_queue_enable_interruption(aq, lsi_ptr) == 0) |
|---|
| 337 | | - aq->state = AP_STATE_SETIRQ_WAIT; |
|---|
| 342 | + if (lsi_ptr && ap_queue_enable_irq(aq, lsi_ptr) == 0) |
|---|
| 343 | + aq->sm_state = AP_SM_STATE_SETIRQ_WAIT; |
|---|
| 338 | 344 | else |
|---|
| 339 | | - aq->state = (aq->queue_count > 0) ? |
|---|
| 340 | | - AP_STATE_WORKING : AP_STATE_IDLE; |
|---|
| 341 | | - return AP_WAIT_AGAIN; |
|---|
| 345 | + aq->sm_state = (aq->queue_count > 0) ? |
|---|
| 346 | + AP_SM_STATE_WORKING : AP_SM_STATE_IDLE; |
|---|
| 347 | + return AP_SM_WAIT_AGAIN; |
|---|
| 342 | 348 | case AP_RESPONSE_BUSY: |
|---|
| 343 | 349 | case AP_RESPONSE_RESET_IN_PROGRESS: |
|---|
| 344 | | - return AP_WAIT_TIMEOUT; |
|---|
| 350 | + return AP_SM_WAIT_TIMEOUT; |
|---|
| 345 | 351 | case AP_RESPONSE_Q_NOT_AVAIL: |
|---|
| 346 | 352 | case AP_RESPONSE_DECONFIGURED: |
|---|
| 347 | 353 | case AP_RESPONSE_CHECKSTOPPED: |
|---|
| 348 | 354 | default: |
|---|
| 349 | | - aq->state = AP_STATE_BORKED; |
|---|
| 350 | | - return AP_WAIT_NONE; |
|---|
| 355 | + aq->dev_state = AP_DEV_STATE_ERROR; |
|---|
| 356 | + aq->last_err_rc = status.response_code; |
|---|
| 357 | + AP_DBF_WARN("%s RC 0x%02x on 0x%02x.%04x -> AP_DEV_STATE_ERROR\n", |
|---|
| 358 | + __func__, status.response_code, |
|---|
| 359 | + AP_QID_CARD(aq->qid), AP_QID_QUEUE(aq->qid)); |
|---|
| 360 | + return AP_SM_WAIT_NONE; |
|---|
| 351 | 361 | } |
|---|
| 352 | 362 | } |
|---|
| 353 | 363 | |
|---|
| .. | .. |
|---|
| 357 | 367 | * |
|---|
| 358 | 368 | * Returns AP_POLL_IMMEDIATELY, AP_POLL_AFTER_TIMEROUT or 0. |
|---|
| 359 | 369 | */ |
|---|
| 360 | | -static enum ap_wait ap_sm_setirq_wait(struct ap_queue *aq) |
|---|
| 370 | +static enum ap_sm_wait ap_sm_setirq_wait(struct ap_queue *aq) |
|---|
| 361 | 371 | { |
|---|
| 362 | 372 | struct ap_queue_status status; |
|---|
| 363 | 373 | |
|---|
| .. | .. |
|---|
| 370 | 380 | |
|---|
| 371 | 381 | if (status.irq_enabled == 1) { |
|---|
| 372 | 382 | /* Irqs are now enabled */ |
|---|
| 373 | | - aq->interrupt = AP_INTR_ENABLED; |
|---|
| 374 | | - aq->state = (aq->queue_count > 0) ? |
|---|
| 375 | | - AP_STATE_WORKING : AP_STATE_IDLE; |
|---|
| 383 | + aq->interrupt = true; |
|---|
| 384 | + aq->sm_state = (aq->queue_count > 0) ? |
|---|
| 385 | + AP_SM_STATE_WORKING : AP_SM_STATE_IDLE; |
|---|
| 376 | 386 | } |
|---|
| 377 | 387 | |
|---|
| 378 | 388 | switch (status.response_code) { |
|---|
| 379 | 389 | case AP_RESPONSE_NORMAL: |
|---|
| 380 | 390 | if (aq->queue_count > 0) |
|---|
| 381 | | - return AP_WAIT_AGAIN; |
|---|
| 382 | | - /* fallthrough */ |
|---|
| 391 | + return AP_SM_WAIT_AGAIN; |
|---|
| 392 | + fallthrough; |
|---|
| 383 | 393 | case AP_RESPONSE_NO_PENDING_REPLY: |
|---|
| 384 | | - return AP_WAIT_TIMEOUT; |
|---|
| 394 | + return AP_SM_WAIT_TIMEOUT; |
|---|
| 385 | 395 | default: |
|---|
| 386 | | - aq->state = AP_STATE_BORKED; |
|---|
| 387 | | - return AP_WAIT_NONE; |
|---|
| 396 | + aq->dev_state = AP_DEV_STATE_ERROR; |
|---|
| 397 | + aq->last_err_rc = status.response_code; |
|---|
| 398 | + AP_DBF_WARN("%s RC 0x%02x on 0x%02x.%04x -> AP_DEV_STATE_ERROR\n", |
|---|
| 399 | + __func__, status.response_code, |
|---|
| 400 | + AP_QID_CARD(aq->qid), AP_QID_QUEUE(aq->qid)); |
|---|
| 401 | + return AP_SM_WAIT_NONE; |
|---|
| 388 | 402 | } |
|---|
| 389 | 403 | } |
|---|
| 390 | 404 | |
|---|
| 391 | 405 | /* |
|---|
| 392 | 406 | * AP state machine jump table |
|---|
| 393 | 407 | */ |
|---|
| 394 | | -static ap_func_t *ap_jumptable[NR_AP_STATES][NR_AP_EVENTS] = { |
|---|
| 395 | | - [AP_STATE_RESET_START] = { |
|---|
| 396 | | - [AP_EVENT_POLL] = ap_sm_reset, |
|---|
| 397 | | - [AP_EVENT_TIMEOUT] = ap_sm_nop, |
|---|
| 408 | +static ap_func_t *ap_jumptable[NR_AP_SM_STATES][NR_AP_SM_EVENTS] = { |
|---|
| 409 | + [AP_SM_STATE_RESET_START] = { |
|---|
| 410 | + [AP_SM_EVENT_POLL] = ap_sm_reset, |
|---|
| 411 | + [AP_SM_EVENT_TIMEOUT] = ap_sm_nop, |
|---|
| 398 | 412 | }, |
|---|
| 399 | | - [AP_STATE_RESET_WAIT] = { |
|---|
| 400 | | - [AP_EVENT_POLL] = ap_sm_reset_wait, |
|---|
| 401 | | - [AP_EVENT_TIMEOUT] = ap_sm_nop, |
|---|
| 413 | + [AP_SM_STATE_RESET_WAIT] = { |
|---|
| 414 | + [AP_SM_EVENT_POLL] = ap_sm_reset_wait, |
|---|
| 415 | + [AP_SM_EVENT_TIMEOUT] = ap_sm_nop, |
|---|
| 402 | 416 | }, |
|---|
| 403 | | - [AP_STATE_SETIRQ_WAIT] = { |
|---|
| 404 | | - [AP_EVENT_POLL] = ap_sm_setirq_wait, |
|---|
| 405 | | - [AP_EVENT_TIMEOUT] = ap_sm_nop, |
|---|
| 417 | + [AP_SM_STATE_SETIRQ_WAIT] = { |
|---|
| 418 | + [AP_SM_EVENT_POLL] = ap_sm_setirq_wait, |
|---|
| 419 | + [AP_SM_EVENT_TIMEOUT] = ap_sm_nop, |
|---|
| 406 | 420 | }, |
|---|
| 407 | | - [AP_STATE_IDLE] = { |
|---|
| 408 | | - [AP_EVENT_POLL] = ap_sm_write, |
|---|
| 409 | | - [AP_EVENT_TIMEOUT] = ap_sm_nop, |
|---|
| 421 | + [AP_SM_STATE_IDLE] = { |
|---|
| 422 | + [AP_SM_EVENT_POLL] = ap_sm_write, |
|---|
| 423 | + [AP_SM_EVENT_TIMEOUT] = ap_sm_nop, |
|---|
| 410 | 424 | }, |
|---|
| 411 | | - [AP_STATE_WORKING] = { |
|---|
| 412 | | - [AP_EVENT_POLL] = ap_sm_read_write, |
|---|
| 413 | | - [AP_EVENT_TIMEOUT] = ap_sm_reset, |
|---|
| 425 | + [AP_SM_STATE_WORKING] = { |
|---|
| 426 | + [AP_SM_EVENT_POLL] = ap_sm_read_write, |
|---|
| 427 | + [AP_SM_EVENT_TIMEOUT] = ap_sm_reset, |
|---|
| 414 | 428 | }, |
|---|
| 415 | | - [AP_STATE_QUEUE_FULL] = { |
|---|
| 416 | | - [AP_EVENT_POLL] = ap_sm_read, |
|---|
| 417 | | - [AP_EVENT_TIMEOUT] = ap_sm_reset, |
|---|
| 418 | | - }, |
|---|
| 419 | | - [AP_STATE_SUSPEND_WAIT] = { |
|---|
| 420 | | - [AP_EVENT_POLL] = ap_sm_suspend_read, |
|---|
| 421 | | - [AP_EVENT_TIMEOUT] = ap_sm_nop, |
|---|
| 422 | | - }, |
|---|
| 423 | | - [AP_STATE_BORKED] = { |
|---|
| 424 | | - [AP_EVENT_POLL] = ap_sm_nop, |
|---|
| 425 | | - [AP_EVENT_TIMEOUT] = ap_sm_nop, |
|---|
| 429 | + [AP_SM_STATE_QUEUE_FULL] = { |
|---|
| 430 | + [AP_SM_EVENT_POLL] = ap_sm_read, |
|---|
| 431 | + [AP_SM_EVENT_TIMEOUT] = ap_sm_reset, |
|---|
| 426 | 432 | }, |
|---|
| 427 | 433 | }; |
|---|
| 428 | 434 | |
|---|
| 429 | | -enum ap_wait ap_sm_event(struct ap_queue *aq, enum ap_event event) |
|---|
| 435 | +enum ap_sm_wait ap_sm_event(struct ap_queue *aq, enum ap_sm_event event) |
|---|
| 430 | 436 | { |
|---|
| 431 | | - return ap_jumptable[aq->state][event](aq); |
|---|
| 437 | + if (aq->dev_state > AP_DEV_STATE_UNINITIATED) |
|---|
| 438 | + return ap_jumptable[aq->sm_state][event](aq); |
|---|
| 439 | + else |
|---|
| 440 | + return AP_SM_WAIT_NONE; |
|---|
| 432 | 441 | } |
|---|
| 433 | 442 | |
|---|
| 434 | | -enum ap_wait ap_sm_event_loop(struct ap_queue *aq, enum ap_event event) |
|---|
| 443 | +enum ap_sm_wait ap_sm_event_loop(struct ap_queue *aq, enum ap_sm_event event) |
|---|
| 435 | 444 | { |
|---|
| 436 | | - enum ap_wait wait; |
|---|
| 445 | + enum ap_sm_wait wait; |
|---|
| 437 | 446 | |
|---|
| 438 | | - while ((wait = ap_sm_event(aq, event)) == AP_WAIT_AGAIN) |
|---|
| 447 | + while ((wait = ap_sm_event(aq, event)) == AP_SM_WAIT_AGAIN) |
|---|
| 439 | 448 | ; |
|---|
| 440 | 449 | return wait; |
|---|
| 441 | 450 | } |
|---|
| 442 | | - |
|---|
| 443 | | -/* |
|---|
| 444 | | - * Power management for queue devices |
|---|
| 445 | | - */ |
|---|
| 446 | | -void ap_queue_suspend(struct ap_device *ap_dev) |
|---|
| 447 | | -{ |
|---|
| 448 | | - struct ap_queue *aq = to_ap_queue(&ap_dev->device); |
|---|
| 449 | | - |
|---|
| 450 | | - /* Poll on the device until all requests are finished. */ |
|---|
| 451 | | - spin_lock_bh(&aq->lock); |
|---|
| 452 | | - aq->state = AP_STATE_SUSPEND_WAIT; |
|---|
| 453 | | - while (ap_sm_event(aq, AP_EVENT_POLL) != AP_WAIT_NONE) |
|---|
| 454 | | - ; |
|---|
| 455 | | - aq->state = AP_STATE_BORKED; |
|---|
| 456 | | - spin_unlock_bh(&aq->lock); |
|---|
| 457 | | -} |
|---|
| 458 | | -EXPORT_SYMBOL(ap_queue_suspend); |
|---|
| 459 | | - |
|---|
| 460 | | -void ap_queue_resume(struct ap_device *ap_dev) |
|---|
| 461 | | -{ |
|---|
| 462 | | -} |
|---|
| 463 | | -EXPORT_SYMBOL(ap_queue_resume); |
|---|
| 464 | 451 | |
|---|
| 465 | 452 | /* |
|---|
| 466 | 453 | * AP queue related attributes. |
|---|
| .. | .. |
|---|
| 470 | 457 | char *buf) |
|---|
| 471 | 458 | { |
|---|
| 472 | 459 | struct ap_queue *aq = to_ap_queue(dev); |
|---|
| 460 | + bool valid = false; |
|---|
| 473 | 461 | u64 req_cnt; |
|---|
| 474 | 462 | |
|---|
| 475 | 463 | spin_lock_bh(&aq->lock); |
|---|
| 476 | | - req_cnt = aq->total_request_count; |
|---|
| 464 | + if (aq->dev_state > AP_DEV_STATE_UNINITIATED) { |
|---|
| 465 | + req_cnt = aq->total_request_count; |
|---|
| 466 | + valid = true; |
|---|
| 467 | + } |
|---|
| 477 | 468 | spin_unlock_bh(&aq->lock); |
|---|
| 478 | | - return snprintf(buf, PAGE_SIZE, "%llu\n", req_cnt); |
|---|
| 469 | + |
|---|
| 470 | + if (valid) |
|---|
| 471 | + return scnprintf(buf, PAGE_SIZE, "%llu\n", req_cnt); |
|---|
| 472 | + else |
|---|
| 473 | + return scnprintf(buf, PAGE_SIZE, "-\n"); |
|---|
| 479 | 474 | } |
|---|
| 480 | 475 | |
|---|
| 481 | 476 | static ssize_t request_count_store(struct device *dev, |
|---|
| .. | .. |
|---|
| 500 | 495 | unsigned int reqq_cnt = 0; |
|---|
| 501 | 496 | |
|---|
| 502 | 497 | spin_lock_bh(&aq->lock); |
|---|
| 503 | | - reqq_cnt = aq->requestq_count; |
|---|
| 498 | + if (aq->dev_state > AP_DEV_STATE_UNINITIATED) |
|---|
| 499 | + reqq_cnt = aq->requestq_count; |
|---|
| 504 | 500 | spin_unlock_bh(&aq->lock); |
|---|
| 505 | | - return snprintf(buf, PAGE_SIZE, "%d\n", reqq_cnt); |
|---|
| 501 | + return scnprintf(buf, PAGE_SIZE, "%d\n", reqq_cnt); |
|---|
| 506 | 502 | } |
|---|
| 507 | 503 | |
|---|
| 508 | 504 | static DEVICE_ATTR_RO(requestq_count); |
|---|
| .. | .. |
|---|
| 514 | 510 | unsigned int penq_cnt = 0; |
|---|
| 515 | 511 | |
|---|
| 516 | 512 | spin_lock_bh(&aq->lock); |
|---|
| 517 | | - penq_cnt = aq->pendingq_count; |
|---|
| 513 | + if (aq->dev_state > AP_DEV_STATE_UNINITIATED) |
|---|
| 514 | + penq_cnt = aq->pendingq_count; |
|---|
| 518 | 515 | spin_unlock_bh(&aq->lock); |
|---|
| 519 | | - return snprintf(buf, PAGE_SIZE, "%d\n", penq_cnt); |
|---|
| 516 | + return scnprintf(buf, PAGE_SIZE, "%d\n", penq_cnt); |
|---|
| 520 | 517 | } |
|---|
| 521 | 518 | |
|---|
| 522 | 519 | static DEVICE_ATTR_RO(pendingq_count); |
|---|
| .. | .. |
|---|
| 528 | 525 | int rc = 0; |
|---|
| 529 | 526 | |
|---|
| 530 | 527 | spin_lock_bh(&aq->lock); |
|---|
| 531 | | - switch (aq->state) { |
|---|
| 532 | | - case AP_STATE_RESET_START: |
|---|
| 533 | | - case AP_STATE_RESET_WAIT: |
|---|
| 534 | | - rc = snprintf(buf, PAGE_SIZE, "Reset in progress.\n"); |
|---|
| 528 | + switch (aq->sm_state) { |
|---|
| 529 | + case AP_SM_STATE_RESET_START: |
|---|
| 530 | + case AP_SM_STATE_RESET_WAIT: |
|---|
| 531 | + rc = scnprintf(buf, PAGE_SIZE, "Reset in progress.\n"); |
|---|
| 535 | 532 | break; |
|---|
| 536 | | - case AP_STATE_WORKING: |
|---|
| 537 | | - case AP_STATE_QUEUE_FULL: |
|---|
| 538 | | - rc = snprintf(buf, PAGE_SIZE, "Reset Timer armed.\n"); |
|---|
| 533 | + case AP_SM_STATE_WORKING: |
|---|
| 534 | + case AP_SM_STATE_QUEUE_FULL: |
|---|
| 535 | + rc = scnprintf(buf, PAGE_SIZE, "Reset Timer armed.\n"); |
|---|
| 539 | 536 | break; |
|---|
| 540 | 537 | default: |
|---|
| 541 | | - rc = snprintf(buf, PAGE_SIZE, "No Reset Timer set.\n"); |
|---|
| 538 | + rc = scnprintf(buf, PAGE_SIZE, "No Reset Timer set.\n"); |
|---|
| 542 | 539 | } |
|---|
| 543 | 540 | spin_unlock_bh(&aq->lock); |
|---|
| 544 | 541 | return rc; |
|---|
| .. | .. |
|---|
| 552 | 549 | |
|---|
| 553 | 550 | spin_lock_bh(&aq->lock); |
|---|
| 554 | 551 | __ap_flush_queue(aq); |
|---|
| 555 | | - aq->state = AP_STATE_RESET_START; |
|---|
| 556 | | - ap_wait(ap_sm_event(aq, AP_EVENT_POLL)); |
|---|
| 552 | + aq->sm_state = AP_SM_STATE_RESET_START; |
|---|
| 553 | + ap_wait(ap_sm_event(aq, AP_SM_EVENT_POLL)); |
|---|
| 557 | 554 | spin_unlock_bh(&aq->lock); |
|---|
| 558 | 555 | |
|---|
| 559 | 556 | AP_DBF(DBF_INFO, "reset queue=%02x.%04x triggered by user\n", |
|---|
| .. | .. |
|---|
| 571 | 568 | int rc = 0; |
|---|
| 572 | 569 | |
|---|
| 573 | 570 | spin_lock_bh(&aq->lock); |
|---|
| 574 | | - if (aq->state == AP_STATE_SETIRQ_WAIT) |
|---|
| 575 | | - rc = snprintf(buf, PAGE_SIZE, "Enable Interrupt pending.\n"); |
|---|
| 576 | | - else if (aq->interrupt == AP_INTR_ENABLED) |
|---|
| 577 | | - rc = snprintf(buf, PAGE_SIZE, "Interrupts enabled.\n"); |
|---|
| 571 | + if (aq->sm_state == AP_SM_STATE_SETIRQ_WAIT) |
|---|
| 572 | + rc = scnprintf(buf, PAGE_SIZE, "Enable Interrupt pending.\n"); |
|---|
| 573 | + else if (aq->interrupt) |
|---|
| 574 | + rc = scnprintf(buf, PAGE_SIZE, "Interrupts enabled.\n"); |
|---|
| 578 | 575 | else |
|---|
| 579 | | - rc = snprintf(buf, PAGE_SIZE, "Interrupts disabled.\n"); |
|---|
| 576 | + rc = scnprintf(buf, PAGE_SIZE, "Interrupts disabled.\n"); |
|---|
| 580 | 577 | spin_unlock_bh(&aq->lock); |
|---|
| 581 | 578 | return rc; |
|---|
| 582 | 579 | } |
|---|
| 583 | 580 | |
|---|
| 584 | 581 | static DEVICE_ATTR_RO(interrupt); |
|---|
| 582 | + |
|---|
| 583 | +static ssize_t config_show(struct device *dev, |
|---|
| 584 | + struct device_attribute *attr, char *buf) |
|---|
| 585 | +{ |
|---|
| 586 | + struct ap_queue *aq = to_ap_queue(dev); |
|---|
| 587 | + int rc; |
|---|
| 588 | + |
|---|
| 589 | + spin_lock_bh(&aq->lock); |
|---|
| 590 | + rc = scnprintf(buf, PAGE_SIZE, "%d\n", aq->config ? 1 : 0); |
|---|
| 591 | + spin_unlock_bh(&aq->lock); |
|---|
| 592 | + return rc; |
|---|
| 593 | +} |
|---|
| 594 | + |
|---|
| 595 | +static DEVICE_ATTR_RO(config); |
|---|
| 596 | + |
|---|
| 597 | +#ifdef CONFIG_ZCRYPT_DEBUG |
|---|
| 598 | +static ssize_t states_show(struct device *dev, |
|---|
| 599 | + struct device_attribute *attr, char *buf) |
|---|
| 600 | +{ |
|---|
| 601 | + struct ap_queue *aq = to_ap_queue(dev); |
|---|
| 602 | + int rc = 0; |
|---|
| 603 | + |
|---|
| 604 | + spin_lock_bh(&aq->lock); |
|---|
| 605 | + /* queue device state */ |
|---|
| 606 | + switch (aq->dev_state) { |
|---|
| 607 | + case AP_DEV_STATE_UNINITIATED: |
|---|
| 608 | + rc = scnprintf(buf, PAGE_SIZE, "UNINITIATED\n"); |
|---|
| 609 | + break; |
|---|
| 610 | + case AP_DEV_STATE_OPERATING: |
|---|
| 611 | + rc = scnprintf(buf, PAGE_SIZE, "OPERATING"); |
|---|
| 612 | + break; |
|---|
| 613 | + case AP_DEV_STATE_SHUTDOWN: |
|---|
| 614 | + rc = scnprintf(buf, PAGE_SIZE, "SHUTDOWN"); |
|---|
| 615 | + break; |
|---|
| 616 | + case AP_DEV_STATE_ERROR: |
|---|
| 617 | + rc = scnprintf(buf, PAGE_SIZE, "ERROR"); |
|---|
| 618 | + break; |
|---|
| 619 | + default: |
|---|
| 620 | + rc = scnprintf(buf, PAGE_SIZE, "UNKNOWN"); |
|---|
| 621 | + } |
|---|
| 622 | + /* state machine state */ |
|---|
| 623 | + if (aq->dev_state) { |
|---|
| 624 | + switch (aq->sm_state) { |
|---|
| 625 | + case AP_SM_STATE_RESET_START: |
|---|
| 626 | + rc += scnprintf(buf + rc, PAGE_SIZE - rc, |
|---|
| 627 | + " [RESET_START]\n"); |
|---|
| 628 | + break; |
|---|
| 629 | + case AP_SM_STATE_RESET_WAIT: |
|---|
| 630 | + rc += scnprintf(buf + rc, PAGE_SIZE - rc, |
|---|
| 631 | + " [RESET_WAIT]\n"); |
|---|
| 632 | + break; |
|---|
| 633 | + case AP_SM_STATE_SETIRQ_WAIT: |
|---|
| 634 | + rc += scnprintf(buf + rc, PAGE_SIZE - rc, |
|---|
| 635 | + " [SETIRQ_WAIT]\n"); |
|---|
| 636 | + break; |
|---|
| 637 | + case AP_SM_STATE_IDLE: |
|---|
| 638 | + rc += scnprintf(buf + rc, PAGE_SIZE - rc, |
|---|
| 639 | + " [IDLE]\n"); |
|---|
| 640 | + break; |
|---|
| 641 | + case AP_SM_STATE_WORKING: |
|---|
| 642 | + rc += scnprintf(buf + rc, PAGE_SIZE - rc, |
|---|
| 643 | + " [WORKING]\n"); |
|---|
| 644 | + break; |
|---|
| 645 | + case AP_SM_STATE_QUEUE_FULL: |
|---|
| 646 | + rc += scnprintf(buf + rc, PAGE_SIZE - rc, |
|---|
| 647 | + " [FULL]\n"); |
|---|
| 648 | + break; |
|---|
| 649 | + default: |
|---|
| 650 | + rc += scnprintf(buf + rc, PAGE_SIZE - rc, |
|---|
| 651 | + " [UNKNOWN]\n"); |
|---|
| 652 | + } |
|---|
| 653 | + } |
|---|
| 654 | + spin_unlock_bh(&aq->lock); |
|---|
| 655 | + |
|---|
| 656 | + return rc; |
|---|
| 657 | +} |
|---|
| 658 | +static DEVICE_ATTR_RO(states); |
|---|
| 659 | + |
|---|
| 660 | +static ssize_t last_err_rc_show(struct device *dev, |
|---|
| 661 | + struct device_attribute *attr, char *buf) |
|---|
| 662 | +{ |
|---|
| 663 | + struct ap_queue *aq = to_ap_queue(dev); |
|---|
| 664 | + int rc; |
|---|
| 665 | + |
|---|
| 666 | + spin_lock_bh(&aq->lock); |
|---|
| 667 | + rc = aq->last_err_rc; |
|---|
| 668 | + spin_unlock_bh(&aq->lock); |
|---|
| 669 | + |
|---|
| 670 | + switch (rc) { |
|---|
| 671 | + case AP_RESPONSE_NORMAL: |
|---|
| 672 | + return scnprintf(buf, PAGE_SIZE, "NORMAL\n"); |
|---|
| 673 | + case AP_RESPONSE_Q_NOT_AVAIL: |
|---|
| 674 | + return scnprintf(buf, PAGE_SIZE, "Q_NOT_AVAIL\n"); |
|---|
| 675 | + case AP_RESPONSE_RESET_IN_PROGRESS: |
|---|
| 676 | + return scnprintf(buf, PAGE_SIZE, "RESET_IN_PROGRESS\n"); |
|---|
| 677 | + case AP_RESPONSE_DECONFIGURED: |
|---|
| 678 | + return scnprintf(buf, PAGE_SIZE, "DECONFIGURED\n"); |
|---|
| 679 | + case AP_RESPONSE_CHECKSTOPPED: |
|---|
| 680 | + return scnprintf(buf, PAGE_SIZE, "CHECKSTOPPED\n"); |
|---|
| 681 | + case AP_RESPONSE_BUSY: |
|---|
| 682 | + return scnprintf(buf, PAGE_SIZE, "BUSY\n"); |
|---|
| 683 | + case AP_RESPONSE_INVALID_ADDRESS: |
|---|
| 684 | + return scnprintf(buf, PAGE_SIZE, "INVALID_ADDRESS\n"); |
|---|
| 685 | + case AP_RESPONSE_OTHERWISE_CHANGED: |
|---|
| 686 | + return scnprintf(buf, PAGE_SIZE, "OTHERWISE_CHANGED\n"); |
|---|
| 687 | + case AP_RESPONSE_Q_FULL: |
|---|
| 688 | + return scnprintf(buf, PAGE_SIZE, "Q_FULL/NO_PENDING_REPLY\n"); |
|---|
| 689 | + case AP_RESPONSE_INDEX_TOO_BIG: |
|---|
| 690 | + return scnprintf(buf, PAGE_SIZE, "INDEX_TOO_BIG\n"); |
|---|
| 691 | + case AP_RESPONSE_NO_FIRST_PART: |
|---|
| 692 | + return scnprintf(buf, PAGE_SIZE, "NO_FIRST_PART\n"); |
|---|
| 693 | + case AP_RESPONSE_MESSAGE_TOO_BIG: |
|---|
| 694 | + return scnprintf(buf, PAGE_SIZE, "MESSAGE_TOO_BIG\n"); |
|---|
| 695 | + case AP_RESPONSE_REQ_FAC_NOT_INST: |
|---|
| 696 | + return scnprintf(buf, PAGE_SIZE, "REQ_FAC_NOT_INST\n"); |
|---|
| 697 | + default: |
|---|
| 698 | + return scnprintf(buf, PAGE_SIZE, "response code %d\n", rc); |
|---|
| 699 | + } |
|---|
| 700 | +} |
|---|
| 701 | +static DEVICE_ATTR_RO(last_err_rc); |
|---|
| 702 | +#endif |
|---|
| 585 | 703 | |
|---|
| 586 | 704 | static struct attribute *ap_queue_dev_attrs[] = { |
|---|
| 587 | 705 | &dev_attr_request_count.attr, |
|---|
| .. | .. |
|---|
| 589 | 707 | &dev_attr_pendingq_count.attr, |
|---|
| 590 | 708 | &dev_attr_reset.attr, |
|---|
| 591 | 709 | &dev_attr_interrupt.attr, |
|---|
| 710 | + &dev_attr_config.attr, |
|---|
| 711 | +#ifdef CONFIG_ZCRYPT_DEBUG |
|---|
| 712 | + &dev_attr_states.attr, |
|---|
| 713 | + &dev_attr_last_err_rc.attr, |
|---|
| 714 | +#endif |
|---|
| 592 | 715 | NULL |
|---|
| 593 | 716 | }; |
|---|
| 594 | 717 | |
|---|
| .. | .. |
|---|
| 610 | 733 | { |
|---|
| 611 | 734 | struct ap_queue *aq = to_ap_queue(dev); |
|---|
| 612 | 735 | |
|---|
| 613 | | - if (!list_empty(&aq->list)) { |
|---|
| 614 | | - spin_lock_bh(&ap_list_lock); |
|---|
| 615 | | - list_del_init(&aq->list); |
|---|
| 616 | | - spin_unlock_bh(&ap_list_lock); |
|---|
| 617 | | - } |
|---|
| 736 | + spin_lock_bh(&ap_queues_lock); |
|---|
| 737 | + hash_del(&aq->hnode); |
|---|
| 738 | + spin_unlock_bh(&ap_queues_lock); |
|---|
| 739 | + |
|---|
| 618 | 740 | kfree(aq); |
|---|
| 619 | 741 | } |
|---|
| 620 | 742 | |
|---|
| .. | .. |
|---|
| 629 | 751 | aq->ap_dev.device.type = &ap_queue_type; |
|---|
| 630 | 752 | aq->ap_dev.device_type = device_type; |
|---|
| 631 | 753 | aq->qid = qid; |
|---|
| 632 | | - aq->state = AP_STATE_RESET_START; |
|---|
| 633 | | - aq->interrupt = AP_INTR_DISABLED; |
|---|
| 754 | + aq->interrupt = false; |
|---|
| 634 | 755 | spin_lock_init(&aq->lock); |
|---|
| 635 | | - INIT_LIST_HEAD(&aq->list); |
|---|
| 636 | 756 | INIT_LIST_HEAD(&aq->pendingq); |
|---|
| 637 | 757 | INIT_LIST_HEAD(&aq->requestq); |
|---|
| 638 | 758 | timer_setup(&aq->timeout, ap_request_timeout, 0); |
|---|
| .. | .. |
|---|
| 645 | 765 | aq->reply = reply; |
|---|
| 646 | 766 | |
|---|
| 647 | 767 | spin_lock_bh(&aq->lock); |
|---|
| 648 | | - ap_wait(ap_sm_event(aq, AP_EVENT_POLL)); |
|---|
| 768 | + ap_wait(ap_sm_event(aq, AP_SM_EVENT_POLL)); |
|---|
| 649 | 769 | spin_unlock_bh(&aq->lock); |
|---|
| 650 | 770 | } |
|---|
| 651 | 771 | EXPORT_SYMBOL(ap_queue_init_reply); |
|---|
| .. | .. |
|---|
| 655 | 775 | * @aq: The AP device to queue the message to |
|---|
| 656 | 776 | * @ap_msg: The message that is to be added |
|---|
| 657 | 777 | */ |
|---|
| 658 | | -void ap_queue_message(struct ap_queue *aq, struct ap_message *ap_msg) |
|---|
| 778 | +int ap_queue_message(struct ap_queue *aq, struct ap_message *ap_msg) |
|---|
| 659 | 779 | { |
|---|
| 660 | | - /* For asynchronous message handling a valid receive-callback |
|---|
| 661 | | - * is required. |
|---|
| 662 | | - */ |
|---|
| 780 | + int rc = 0; |
|---|
| 781 | + |
|---|
| 782 | + /* msg needs to have a valid receive-callback */ |
|---|
| 663 | 783 | BUG_ON(!ap_msg->receive); |
|---|
| 664 | 784 | |
|---|
| 665 | 785 | spin_lock_bh(&aq->lock); |
|---|
| 666 | | - /* Queue the message. */ |
|---|
| 667 | | - list_add_tail(&ap_msg->list, &aq->requestq); |
|---|
| 668 | | - aq->requestq_count++; |
|---|
| 669 | | - aq->total_request_count++; |
|---|
| 670 | | - atomic64_inc(&aq->card->total_request_count); |
|---|
| 786 | + |
|---|
| 787 | + /* only allow to queue new messages if device state is ok */ |
|---|
| 788 | + if (aq->dev_state == AP_DEV_STATE_OPERATING) { |
|---|
| 789 | + list_add_tail(&ap_msg->list, &aq->requestq); |
|---|
| 790 | + aq->requestq_count++; |
|---|
| 791 | + aq->total_request_count++; |
|---|
| 792 | + atomic64_inc(&aq->card->total_request_count); |
|---|
| 793 | + } else |
|---|
| 794 | + rc = -ENODEV; |
|---|
| 795 | + |
|---|
| 671 | 796 | /* Send/receive as many request from the queue as possible. */ |
|---|
| 672 | | - ap_wait(ap_sm_event_loop(aq, AP_EVENT_POLL)); |
|---|
| 797 | + ap_wait(ap_sm_event_loop(aq, AP_SM_EVENT_POLL)); |
|---|
| 798 | + |
|---|
| 673 | 799 | spin_unlock_bh(&aq->lock); |
|---|
| 800 | + |
|---|
| 801 | + return rc; |
|---|
| 674 | 802 | } |
|---|
| 675 | 803 | EXPORT_SYMBOL(ap_queue_message); |
|---|
| 676 | 804 | |
|---|
| .. | .. |
|---|
| 725 | 853 | ap_msg->rc = -EAGAIN; |
|---|
| 726 | 854 | ap_msg->receive(aq, ap_msg, NULL); |
|---|
| 727 | 855 | } |
|---|
| 856 | + aq->queue_count = 0; |
|---|
| 728 | 857 | } |
|---|
| 729 | 858 | |
|---|
| 730 | 859 | void ap_flush_queue(struct ap_queue *aq) |
|---|
| .. | .. |
|---|
| 735 | 864 | } |
|---|
| 736 | 865 | EXPORT_SYMBOL(ap_flush_queue); |
|---|
| 737 | 866 | |
|---|
| 867 | +void ap_queue_prepare_remove(struct ap_queue *aq) |
|---|
| 868 | +{ |
|---|
| 869 | + spin_lock_bh(&aq->lock); |
|---|
| 870 | + /* flush queue */ |
|---|
| 871 | + __ap_flush_queue(aq); |
|---|
| 872 | + /* move queue device state to SHUTDOWN in progress */ |
|---|
| 873 | + aq->dev_state = AP_DEV_STATE_SHUTDOWN; |
|---|
| 874 | + spin_unlock_bh(&aq->lock); |
|---|
| 875 | + del_timer_sync(&aq->timeout); |
|---|
| 876 | +} |
|---|
| 877 | + |
|---|
| 738 | 878 | void ap_queue_remove(struct ap_queue *aq) |
|---|
| 739 | 879 | { |
|---|
| 740 | | - ap_flush_queue(aq); |
|---|
| 741 | | - del_timer_sync(&aq->timeout); |
|---|
| 742 | | - |
|---|
| 743 | | - /* reset with zero, also clears irq registration */ |
|---|
| 880 | + /* |
|---|
| 881 | + * all messages have been flushed and the device state |
|---|
| 882 | + * is SHUTDOWN. Now reset with zero which also clears |
|---|
| 883 | + * the irq registration and move the device state |
|---|
| 884 | + * to the initial value AP_DEV_STATE_UNINITIATED. |
|---|
| 885 | + */ |
|---|
| 744 | 886 | spin_lock_bh(&aq->lock); |
|---|
| 745 | 887 | ap_zapq(aq->qid); |
|---|
| 746 | | - aq->state = AP_STATE_BORKED; |
|---|
| 888 | + aq->dev_state = AP_DEV_STATE_UNINITIATED; |
|---|
| 747 | 889 | spin_unlock_bh(&aq->lock); |
|---|
| 748 | 890 | } |
|---|
| 749 | | -EXPORT_SYMBOL(ap_queue_remove); |
|---|
| 750 | 891 | |
|---|
| 751 | | -void ap_queue_reinit_state(struct ap_queue *aq) |
|---|
| 892 | +void ap_queue_init_state(struct ap_queue *aq) |
|---|
| 752 | 893 | { |
|---|
| 753 | 894 | spin_lock_bh(&aq->lock); |
|---|
| 754 | | - aq->state = AP_STATE_RESET_START; |
|---|
| 755 | | - ap_wait(ap_sm_event(aq, AP_EVENT_POLL)); |
|---|
| 895 | + aq->dev_state = AP_DEV_STATE_OPERATING; |
|---|
| 896 | + aq->sm_state = AP_SM_STATE_RESET_START; |
|---|
| 897 | + ap_wait(ap_sm_event(aq, AP_SM_EVENT_POLL)); |
|---|
| 756 | 898 | spin_unlock_bh(&aq->lock); |
|---|
| 757 | 899 | } |
|---|
| 758 | | -EXPORT_SYMBOL(ap_queue_reinit_state); |
|---|
| 900 | +EXPORT_SYMBOL(ap_queue_init_state); |
|---|