1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45#include "esas2r.h"
46
47
48static void esas2r_doorbell_interrupt(struct esas2r_adapter *a, u32 doorbell);
49static void esas2r_get_outbound_responses(struct esas2r_adapter *a);
50static void esas2r_process_bus_reset(struct esas2r_adapter *a);
51
52
53
54
55
56void esas2r_polled_interrupt(struct esas2r_adapter *a)
57{
58 u32 intstat;
59 u32 doorbell;
60
61 esas2r_disable_chip_interrupts(a);
62
63 intstat = esas2r_read_register_dword(a, MU_INT_STATUS_OUT);
64
65 if (intstat & MU_INTSTAT_POST_OUT) {
66
67
68 esas2r_write_register_dword(a, MU_OUT_LIST_INT_STAT,
69 MU_OLIS_INT);
70 esas2r_flush_register_dword(a, MU_OUT_LIST_INT_STAT);
71
72 esas2r_get_outbound_responses(a);
73 }
74
75 if (intstat & MU_INTSTAT_DRBL) {
76 doorbell = esas2r_read_register_dword(a, MU_DOORBELL_OUT);
77 if (doorbell != 0)
78 esas2r_doorbell_interrupt(a, doorbell);
79 }
80
81 esas2r_enable_chip_interrupts(a);
82
83 if (atomic_read(&a->disable_cnt) == 0)
84 esas2r_do_deferred_processes(a);
85}
86
87
88
89
90
91
92irqreturn_t esas2r_interrupt(int irq, void *dev_id)
93{
94 struct esas2r_adapter *a = (struct esas2r_adapter *)dev_id;
95
96 if (!esas2r_adapter_interrupt_pending(a))
97 return IRQ_NONE;
98
99 set_bit(AF2_INT_PENDING, &a->flags2);
100 esas2r_schedule_tasklet(a);
101
102 return IRQ_HANDLED;
103}
104
105void esas2r_adapter_interrupt(struct esas2r_adapter *a)
106{
107 u32 doorbell;
108
109 if (likely(a->int_stat & MU_INTSTAT_POST_OUT)) {
110
111 esas2r_write_register_dword(a, MU_OUT_LIST_INT_STAT,
112 MU_OLIS_INT);
113 esas2r_flush_register_dword(a, MU_OUT_LIST_INT_STAT);
114 esas2r_get_outbound_responses(a);
115 }
116
117 if (unlikely(a->int_stat & MU_INTSTAT_DRBL)) {
118 doorbell = esas2r_read_register_dword(a, MU_DOORBELL_OUT);
119 if (doorbell != 0)
120 esas2r_doorbell_interrupt(a, doorbell);
121 }
122
123 a->int_mask = ESAS2R_INT_STS_MASK;
124
125 esas2r_enable_chip_interrupts(a);
126
127 if (likely(atomic_read(&a->disable_cnt) == 0))
128 esas2r_do_deferred_processes(a);
129}
130
131irqreturn_t esas2r_msi_interrupt(int irq, void *dev_id)
132{
133 struct esas2r_adapter *a = (struct esas2r_adapter *)dev_id;
134 u32 intstat;
135 u32 doorbell;
136
137 intstat = esas2r_read_register_dword(a, MU_INT_STATUS_OUT);
138
139 if (likely(intstat & MU_INTSTAT_POST_OUT)) {
140
141
142 esas2r_write_register_dword(a, MU_OUT_LIST_INT_STAT,
143 MU_OLIS_INT);
144 esas2r_flush_register_dword(a, MU_OUT_LIST_INT_STAT);
145
146 esas2r_get_outbound_responses(a);
147 }
148
149 if (unlikely(intstat & MU_INTSTAT_DRBL)) {
150 doorbell = esas2r_read_register_dword(a, MU_DOORBELL_OUT);
151 if (doorbell != 0)
152 esas2r_doorbell_interrupt(a, doorbell);
153 }
154
155
156
157
158
159 esas2r_disable_chip_interrupts(a);
160 esas2r_enable_chip_interrupts(a);
161
162 if (likely(atomic_read(&a->disable_cnt) == 0))
163 esas2r_do_deferred_processes(a);
164
165 esas2r_do_tasklet_tasks(a);
166
167 return 1;
168}
169
170
171
172static void esas2r_handle_outbound_rsp_err(struct esas2r_adapter *a,
173 struct esas2r_request *rq,
174 struct atto_vda_ob_rsp *rsp)
175{
176
177
178
179
180
181 if (unlikely(rq->req_stat != RS_SUCCESS)) {
182 memcpy(&rq->func_rsp, &rsp->func_rsp, sizeof(rsp->func_rsp));
183
184 if (rq->req_stat == RS_ABORTED) {
185 if (rq->timeout > RQ_MAX_TIMEOUT)
186 rq->req_stat = RS_TIMEOUT;
187 } else if (rq->req_stat == RS_SCSI_ERROR) {
188 u8 scsistatus = rq->func_rsp.scsi_rsp.scsi_stat;
189
190 esas2r_trace("scsistatus: %x", scsistatus);
191
192
193 if (scsistatus == SAM_STAT_GOOD || scsistatus ==
194 SAM_STAT_CONDITION_MET || scsistatus ==
195 SAM_STAT_INTERMEDIATE || scsistatus ==
196 SAM_STAT_INTERMEDIATE_CONDITION_MET) {
197 rq->req_stat = RS_SUCCESS;
198 rq->func_rsp.scsi_rsp.scsi_stat =
199 SAM_STAT_GOOD;
200 }
201 }
202 }
203}
204
205static void esas2r_get_outbound_responses(struct esas2r_adapter *a)
206{
207 struct atto_vda_ob_rsp *rsp;
208 u32 rspput_ptr;
209 u32 rspget_ptr;
210 struct esas2r_request *rq;
211 u32 handle;
212 unsigned long flags;
213
214 LIST_HEAD(comp_list);
215
216 esas2r_trace_enter();
217
218 spin_lock_irqsave(&a->queue_lock, flags);
219
220
221 rspput_ptr = le32_to_cpu(*a->outbound_copy) & MU_OLC_WRT_PTR;
222 rspget_ptr = a->last_read;
223
224 esas2r_trace("rspput_ptr: %x, rspget_ptr: %x", rspput_ptr, rspget_ptr);
225
226
227 if (unlikely(rspget_ptr == rspput_ptr)) {
228 spin_unlock_irqrestore(&a->queue_lock, flags);
229 esas2r_trace_exit();
230 return;
231 }
232
233
234 if (unlikely(rspput_ptr >= a->list_size)) {
235 spin_unlock_irqrestore(&a->queue_lock, flags);
236 esas2r_bugon();
237 esas2r_local_reset_adapter(a);
238 esas2r_trace_exit();
239 return;
240 }
241
242 do {
243 rspget_ptr++;
244
245 if (rspget_ptr >= a->list_size)
246 rspget_ptr = 0;
247
248 rsp = (struct atto_vda_ob_rsp *)a->outbound_list_md.virt_addr
249 + rspget_ptr;
250
251 handle = rsp->handle;
252
253
254 if (unlikely(LOWORD(handle) == 0
255 || LOWORD(handle) > num_requests +
256 num_ae_requests + 1)) {
257 esas2r_bugon();
258 continue;
259 }
260
261
262 rq = a->req_table[LOWORD(handle)];
263
264 if (unlikely(rq == NULL || rq->vrq->scsi.handle != handle)) {
265 esas2r_bugon();
266 continue;
267 }
268
269 list_del(&rq->req_list);
270
271
272 rq->req_stat = rsp->req_stat;
273
274 esas2r_trace("handle: %x", handle);
275 esas2r_trace("rq: %p", rq);
276 esas2r_trace("req_status: %x", rq->req_stat);
277
278 if (likely(rq->vrq->scsi.function == VDA_FUNC_SCSI)) {
279 esas2r_handle_outbound_rsp_err(a, rq, rsp);
280 } else {
281
282
283
284
285 memcpy(&rq->func_rsp, &rsp->func_rsp,
286 sizeof(rsp->func_rsp));
287 }
288
289
290 list_add_tail(&rq->comp_list, &comp_list);
291
292 } while (rspget_ptr != rspput_ptr);
293
294 a->last_read = rspget_ptr;
295 spin_unlock_irqrestore(&a->queue_lock, flags);
296
297 esas2r_comp_list_drain(a, &comp_list);
298 esas2r_trace_exit();
299}
300
301
302
303
304
305
306void esas2r_do_deferred_processes(struct esas2r_adapter *a)
307{
308 int startreqs = 2;
309 struct esas2r_request *rq;
310 unsigned long flags;
311
312
313
314
315
316
317
318
319
320 if (test_bit(AF_CHPRST_PENDING, &a->flags) ||
321 test_bit(AF_FLASHING, &a->flags))
322 startreqs = 0;
323 else if (test_bit(AF_DISC_PENDING, &a->flags))
324 startreqs = 1;
325
326 atomic_inc(&a->disable_cnt);
327
328
329
330 if (esas2r_is_tasklet_pending(a)) {
331 esas2r_schedule_tasklet(a);
332
333 startreqs = 0;
334 }
335
336
337
338
339
340 if (startreqs && !list_empty(&a->defer_list)) {
341 LIST_HEAD(comp_list);
342 struct list_head *element, *next;
343
344 spin_lock_irqsave(&a->queue_lock, flags);
345
346 list_for_each_safe(element, next, &a->defer_list) {
347 rq = list_entry(element, struct esas2r_request,
348 req_list);
349
350 if (rq->req_stat != RS_PENDING) {
351 list_del(element);
352 list_add_tail(&rq->comp_list, &comp_list);
353 }
354
355
356
357
358
359
360 else if (rq->req_type == RT_DISC_REQ) {
361 list_del(element);
362 esas2r_disc_local_start_request(a, rq);
363 } else if (startreqs == 2) {
364 list_del(element);
365 esas2r_local_start_request(a, rq);
366
367
368
369
370
371 if (test_bit(AF_FLASHING, &a->flags))
372 break;
373 }
374 }
375
376 spin_unlock_irqrestore(&a->queue_lock, flags);
377 esas2r_comp_list_drain(a, &comp_list);
378 }
379
380 atomic_dec(&a->disable_cnt);
381}
382
383
384
385
386
387
388void esas2r_process_adapter_reset(struct esas2r_adapter *a)
389{
390 struct esas2r_request *rq = &a->general_req;
391 unsigned long flags;
392 struct esas2r_disc_context *dc;
393
394 LIST_HEAD(comp_list);
395 struct list_head *element;
396
397 esas2r_trace_enter();
398
399 spin_lock_irqsave(&a->queue_lock, flags);
400
401
402
403 if (rq->interrupt_cx) {
404 dc = (struct esas2r_disc_context *)rq->interrupt_cx;
405
406 dc->disc_evt = 0;
407
408 clear_bit(AF_DISC_IN_PROG, &a->flags);
409 }
410
411
412
413
414
415
416
417
418 rq->interrupt_cx = NULL;
419 rq->interrupt_cb = NULL;
420
421 rq->comp_cb = esas2r_dummy_complete;
422
423
424
425 *a->outbound_copy =
426 a->last_write =
427 a->last_read = a->list_size - 1;
428
429 set_bit(AF_COMM_LIST_TOGGLE, &a->flags);
430
431
432 list_for_each(element, &a->defer_list) {
433 rq = list_entry(element, struct esas2r_request, req_list);
434
435 if (rq->req_stat == RS_STARTED)
436 if (esas2r_ioreq_aborted(a, rq, RS_ABORTED))
437 list_add_tail(&rq->comp_list, &comp_list);
438 }
439
440 spin_unlock_irqrestore(&a->queue_lock, flags);
441 esas2r_comp_list_drain(a, &comp_list);
442 esas2r_process_bus_reset(a);
443 esas2r_trace_exit();
444}
445
446static void esas2r_process_bus_reset(struct esas2r_adapter *a)
447{
448 struct esas2r_request *rq;
449 struct list_head *element;
450 unsigned long flags;
451
452 LIST_HEAD(comp_list);
453
454 esas2r_trace_enter();
455
456 esas2r_hdebug("reset detected");
457
458 spin_lock_irqsave(&a->queue_lock, flags);
459
460
461 list_for_each(element, &a->defer_list) {
462 rq = list_entry(element, struct esas2r_request, req_list);
463 if (esas2r_ioreq_aborted(a, rq, RS_ABORTED))
464 list_add_tail(&rq->comp_list, &comp_list);
465 }
466
467 spin_unlock_irqrestore(&a->queue_lock, flags);
468
469 esas2r_comp_list_drain(a, &comp_list);
470
471 if (atomic_read(&a->disable_cnt) == 0)
472 esas2r_do_deferred_processes(a);
473
474 clear_bit(AF_OS_RESET, &a->flags);
475
476 esas2r_trace_exit();
477}
478
479static void esas2r_chip_rst_needed_during_tasklet(struct esas2r_adapter *a)
480{
481
482 clear_bit(AF_CHPRST_NEEDED, &a->flags);
483 clear_bit(AF_BUSRST_NEEDED, &a->flags);
484 clear_bit(AF_BUSRST_DETECTED, &a->flags);
485 clear_bit(AF_BUSRST_PENDING, &a->flags);
486
487
488
489
490
491
492
493
494
495
496
497
498
499 if (!esas2r_is_adapter_present(a) || (a->chip_uptime >=
500 ESAS2R_CHP_UPTIME_MAX)) {
501 esas2r_hdebug("*** adapter disabled ***");
502
503
504
505
506
507
508
509
510
511 set_bit(AF_DEGRADED_MODE, &a->flags);
512 set_bit(AF_DISABLED, &a->flags);
513 clear_bit(AF_CHPRST_PENDING, &a->flags);
514 clear_bit(AF_DISC_PENDING, &a->flags);
515
516 esas2r_disable_chip_interrupts(a);
517 a->int_mask = 0;
518 esas2r_process_adapter_reset(a);
519
520 esas2r_log(ESAS2R_LOG_CRIT,
521 "Adapter disabled because of hardware failure");
522 } else {
523 bool alrdyrst = test_and_set_bit(AF_CHPRST_STARTED, &a->flags);
524
525 if (!alrdyrst)
526
527
528
529
530 esas2r_disable_chip_interrupts(a);
531
532 if ((test_bit(AF_POWER_MGT, &a->flags)) &&
533 !test_bit(AF_FIRST_INIT, &a->flags) && !alrdyrst) {
534
535
536
537
538 } else {
539 esas2r_hdebug("*** resetting chip ***");
540 esas2r_reset_chip(a);
541 }
542
543
544 a->chip_uptime += ESAS2R_CHP_UPTIME_CNT;
545 a->chip_init_time = jiffies_to_msecs(jiffies);
546 if (!test_bit(AF_POWER_MGT, &a->flags)) {
547 esas2r_process_adapter_reset(a);
548
549 if (!alrdyrst) {
550
551 a->prev_dev_cnt =
552 esas2r_targ_db_get_tgt_cnt(a);
553 esas2r_targ_db_remove_all(a, false);
554 }
555 }
556
557 a->int_mask = 0;
558 }
559}
560
561static void esas2r_handle_chip_rst_during_tasklet(struct esas2r_adapter *a)
562{
563 while (test_bit(AF_CHPRST_DETECTED, &a->flags)) {
564
565
566
567
568
569 if (!test_bit(AF_DEGRADED_MODE, &a->flags) &&
570 !test_bit(AF_POWER_MGT, &a->flags))
571 esas2r_disable_chip_interrupts(a);
572
573
574 esas2r_check_adapter(a);
575 esas2r_init_adapter_hw(a, 0);
576
577 if (test_bit(AF_CHPRST_NEEDED, &a->flags))
578 break;
579
580 if (test_bit(AF_POWER_MGT, &a->flags)) {
581
582 if (test_bit(AF_FIRST_INIT, &a->flags)) {
583
584 esas2r_log(ESAS2R_LOG_CRIT,
585 "The firmware was reset during a normal power-up sequence");
586 } else {
587
588 clear_bit(AF_POWER_MGT, &a->flags);
589 esas2r_send_reset_ae(a, true);
590 }
591 } else {
592
593 if (test_bit(AF_FIRST_INIT, &a->flags)) {
594
595 } else {
596
597 esas2r_send_reset_ae(a, false);
598 }
599
600 esas2r_log(ESAS2R_LOG_CRIT,
601 "Recovering from a chip reset while the chip was online");
602 }
603
604 clear_bit(AF_CHPRST_STARTED, &a->flags);
605 esas2r_enable_chip_interrupts(a);
606
607
608
609
610
611 clear_bit(AF_CHPRST_DETECTED, &a->flags);
612 }
613}
614
615
616
617void esas2r_do_tasklet_tasks(struct esas2r_adapter *a)
618{
619
620 if (test_bit(AF_CHPRST_NEEDED, &a->flags) ||
621 test_bit(AF_CHPRST_DETECTED, &a->flags)) {
622 if (test_bit(AF_CHPRST_NEEDED, &a->flags))
623 esas2r_chip_rst_needed_during_tasklet(a);
624
625 esas2r_handle_chip_rst_during_tasklet(a);
626 }
627
628 if (test_bit(AF_BUSRST_NEEDED, &a->flags)) {
629 esas2r_hdebug("hard resetting bus");
630
631 clear_bit(AF_BUSRST_NEEDED, &a->flags);
632
633 if (test_bit(AF_FLASHING, &a->flags))
634 set_bit(AF_BUSRST_DETECTED, &a->flags);
635 else
636 esas2r_write_register_dword(a, MU_DOORBELL_IN,
637 DRBL_RESET_BUS);
638 }
639
640 if (test_bit(AF_BUSRST_DETECTED, &a->flags)) {
641 esas2r_process_bus_reset(a);
642
643 esas2r_log_dev(ESAS2R_LOG_WARN,
644 &(a->host->shost_gendev),
645 "scsi_report_bus_reset() called");
646
647 scsi_report_bus_reset(a->host, 0);
648
649 clear_bit(AF_BUSRST_DETECTED, &a->flags);
650 clear_bit(AF_BUSRST_PENDING, &a->flags);
651
652 esas2r_log(ESAS2R_LOG_WARN, "Bus reset complete");
653 }
654
655 if (test_bit(AF_PORT_CHANGE, &a->flags)) {
656 clear_bit(AF_PORT_CHANGE, &a->flags);
657
658 esas2r_targ_db_report_changes(a);
659 }
660
661 if (atomic_read(&a->disable_cnt) == 0)
662 esas2r_do_deferred_processes(a);
663}
664
665static void esas2r_doorbell_interrupt(struct esas2r_adapter *a, u32 doorbell)
666{
667 if (!(doorbell & DRBL_FORCE_INT)) {
668 esas2r_trace_enter();
669 esas2r_trace("doorbell: %x", doorbell);
670 }
671
672
673 esas2r_write_register_dword(a, MU_DOORBELL_OUT, doorbell);
674
675 if (doorbell & DRBL_RESET_BUS)
676 set_bit(AF_BUSRST_DETECTED, &a->flags);
677
678 if (doorbell & DRBL_FORCE_INT)
679 clear_bit(AF_HEARTBEAT, &a->flags);
680
681 if (doorbell & DRBL_PANIC_REASON_MASK) {
682 esas2r_hdebug("*** Firmware Panic ***");
683 esas2r_log(ESAS2R_LOG_CRIT, "The firmware has panicked");
684 }
685
686 if (doorbell & DRBL_FW_RESET) {
687 set_bit(AF2_COREDUMP_AVAIL, &a->flags2);
688 esas2r_local_reset_adapter(a);
689 }
690
691 if (!(doorbell & DRBL_FORCE_INT))
692 esas2r_trace_exit();
693}
694
695void esas2r_force_interrupt(struct esas2r_adapter *a)
696{
697 esas2r_write_register_dword(a, MU_DOORBELL_IN, DRBL_FORCE_INT |
698 DRBL_DRV_VER);
699}
700
701
702static void esas2r_lun_event(struct esas2r_adapter *a, union atto_vda_ae *ae,
703 u16 target, u32 length)
704{
705 struct esas2r_target *t = a->targetdb + target;
706 u32 cplen = length;
707 unsigned long flags;
708
709 if (cplen > sizeof(t->lu_event))
710 cplen = sizeof(t->lu_event);
711
712 esas2r_trace("ae->lu.dwevent: %x", ae->lu.dwevent);
713 esas2r_trace("ae->lu.bystate: %x", ae->lu.bystate);
714
715 spin_lock_irqsave(&a->mem_lock, flags);
716
717 t->new_target_state = TS_INVALID;
718
719 if (ae->lu.dwevent & VDAAE_LU_LOST) {
720 t->new_target_state = TS_NOT_PRESENT;
721 } else {
722 switch (ae->lu.bystate) {
723 case VDAAE_LU_NOT_PRESENT:
724 case VDAAE_LU_OFFLINE:
725 case VDAAE_LU_DELETED:
726 case VDAAE_LU_FACTORY_DISABLED:
727 t->new_target_state = TS_NOT_PRESENT;
728 break;
729
730 case VDAAE_LU_ONLINE:
731 case VDAAE_LU_DEGRADED:
732 t->new_target_state = TS_PRESENT;
733 break;
734 }
735 }
736
737 if (t->new_target_state != TS_INVALID) {
738 memcpy(&t->lu_event, &ae->lu, cplen);
739
740 esas2r_disc_queue_event(a, DCDE_DEV_CHANGE);
741 }
742
743 spin_unlock_irqrestore(&a->mem_lock, flags);
744}
745
746
747
748void esas2r_ae_complete(struct esas2r_adapter *a, struct esas2r_request *rq)
749{
750 union atto_vda_ae *ae =
751 (union atto_vda_ae *)rq->vda_rsp_data->ae_data.event_data;
752 u32 length = le32_to_cpu(rq->func_rsp.ae_rsp.length);
753 union atto_vda_ae *last =
754 (union atto_vda_ae *)(rq->vda_rsp_data->ae_data.event_data
755 + length);
756
757 esas2r_trace_enter();
758 esas2r_trace("length: %d", length);
759
760 if (length > sizeof(struct atto_vda_ae_data)
761 || (length & 3) != 0
762 || length == 0) {
763 esas2r_log(ESAS2R_LOG_WARN,
764 "The AE request response length (%p) is too long: %d",
765 rq, length);
766
767 esas2r_hdebug("aereq->length (0x%x) too long", length);
768 esas2r_bugon();
769
770 last = ae;
771 }
772
773 while (ae < last) {
774 u16 target;
775
776 esas2r_trace("ae: %p", ae);
777 esas2r_trace("ae->hdr: %p", &(ae->hdr));
778
779 length = ae->hdr.bylength;
780
781 if (length > (u32)((u8 *)last - (u8 *)ae)
782 || (length & 3) != 0
783 || length == 0) {
784 esas2r_log(ESAS2R_LOG_CRIT,
785 "the async event length is invalid (%p): %d",
786 ae, length);
787
788 esas2r_hdebug("ae->hdr.length (0x%x) invalid", length);
789 esas2r_bugon();
790
791 break;
792 }
793
794 esas2r_nuxi_ae_data(ae);
795
796 esas2r_queue_fw_event(a, fw_event_vda_ae, ae,
797 sizeof(union atto_vda_ae));
798
799 switch (ae->hdr.bytype) {
800 case VDAAE_HDR_TYPE_RAID:
801
802 if (ae->raid.dwflags & (VDAAE_GROUP_STATE
803 | VDAAE_RBLD_STATE
804 | VDAAE_MEMBER_CHG
805 | VDAAE_PART_CHG)) {
806 esas2r_log(ESAS2R_LOG_INFO,
807 "RAID event received - name:%s rebuild_state:%d group_state:%d",
808 ae->raid.acname,
809 ae->raid.byrebuild_state,
810 ae->raid.bygroup_state);
811 }
812
813 break;
814
815 case VDAAE_HDR_TYPE_LU:
816 esas2r_log(ESAS2R_LOG_INFO,
817 "LUN event received: event:%d target_id:%d LUN:%d state:%d",
818 ae->lu.dwevent,
819 ae->lu.id.tgtlun.wtarget_id,
820 ae->lu.id.tgtlun.bylun,
821 ae->lu.bystate);
822
823 target = ae->lu.id.tgtlun.wtarget_id;
824
825 if (target < ESAS2R_MAX_TARGETS)
826 esas2r_lun_event(a, ae, target, length);
827
828 break;
829
830 case VDAAE_HDR_TYPE_DISK:
831 esas2r_log(ESAS2R_LOG_INFO, "Disk event received");
832 break;
833
834 default:
835
836
837
838
839
840 break;
841 }
842
843 ae = (union atto_vda_ae *)((u8 *)ae + length);
844 }
845
846
847 esas2r_start_ae_request(a, rq);
848 esas2r_trace_exit();
849}
850
851
852void esas2r_send_reset_ae(struct esas2r_adapter *a, bool pwr_mgt)
853{
854 struct atto_vda_ae_hdr ae;
855
856 if (pwr_mgt)
857 ae.bytype = VDAAE_HDR_TYPE_PWRMGT;
858 else
859 ae.bytype = VDAAE_HDR_TYPE_RESET;
860
861 ae.byversion = VDAAE_HDR_VER_0;
862 ae.byflags = 0;
863 ae.bylength = (u8)sizeof(struct atto_vda_ae_hdr);
864
865 if (pwr_mgt)
866 esas2r_hdebug("*** sending power management AE ***");
867 else
868 esas2r_hdebug("*** sending reset AE ***");
869
870 esas2r_queue_fw_event(a, fw_event_vda_ae, &ae,
871 sizeof(union atto_vda_ae));
872}
873
874void esas2r_dummy_complete(struct esas2r_adapter *a, struct esas2r_request *rq)
875{}
876
877static void esas2r_check_req_rsp_sense(struct esas2r_adapter *a,
878 struct esas2r_request *rq)
879{
880 u8 snslen, snslen2;
881
882 snslen = snslen2 = rq->func_rsp.scsi_rsp.sense_len;
883
884 if (snslen > rq->sense_len)
885 snslen = rq->sense_len;
886
887 if (snslen) {
888 if (rq->sense_buf)
889 memcpy(rq->sense_buf, rq->data_buf, snslen);
890 else
891 rq->sense_buf = (u8 *)rq->data_buf;
892
893
894 if (snslen2 > 0x0c) {
895 u8 *s = (u8 *)rq->data_buf;
896
897 esas2r_trace_enter();
898
899
900 if (s[0x0c] == 0x3f && s[0x0d] == 0x0E) {
901 esas2r_trace("rq->target_id: %d",
902 rq->target_id);
903 esas2r_target_state_changed(a, rq->target_id,
904 TS_LUN_CHANGE);
905 }
906
907 esas2r_trace("add_sense_key=%x", s[0x0c]);
908 esas2r_trace("add_sense_qual=%x", s[0x0d]);
909 esas2r_trace_exit();
910 }
911 }
912
913 rq->sense_len = snslen;
914}
915
916
917void esas2r_complete_request(struct esas2r_adapter *a,
918 struct esas2r_request *rq)
919{
920 if (rq->vrq->scsi.function == VDA_FUNC_FLASH
921 && rq->vrq->flash.sub_func == VDA_FLASH_COMMIT)
922 clear_bit(AF_FLASHING, &a->flags);
923
924
925
926 if (rq->interrupt_cb) {
927 (*rq->interrupt_cb)(a, rq);
928
929 if (rq->req_stat == RS_PENDING) {
930 esas2r_start_request(a, rq);
931 return;
932 }
933 }
934
935 if (likely(rq->vrq->scsi.function == VDA_FUNC_SCSI)
936 && unlikely(rq->req_stat != RS_SUCCESS)) {
937 esas2r_check_req_rsp_sense(a, rq);
938 esas2r_log_request_failure(a, rq);
939 }
940
941 (*rq->comp_cb)(a, rq);
942}
943