diff options
author | <andrew.vasquez@qlogic.com> | 2005-04-17 16:02:26 -0400 |
---|---|---|
committer | James Bottomley <jejb@titanic> | 2005-04-18 14:46:53 -0400 |
commit | f4f051ebb40e74ad0ba02d2cb3a6c16b0393472b (patch) | |
tree | cc5b5267465d833d36037bd717cef9368f6c9472 /drivers/scsi/qla2xxx/qla_os.c | |
parent | c46f2ffb9e7fce7208c2639790e1ade42e00b146 (diff) |
[PATCH] qla2xxx: remove internal queuing...
Remove internal command queuing from the driver. As is, this
driver cannot tolerate cable-pulls as I/Os will begin to fail
by the upper layers.
o Should be used in conjuction with the
11-fc_rport_adds_2.diff patch.
o Removes qla_listops.h file -- no longer needed.
Signed-off-by: Andrew Vasquez <andrew.vasquez@qlogic.com>
Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
Diffstat (limited to 'drivers/scsi/qla2xxx/qla_os.c')
-rw-r--r-- | drivers/scsi/qla2xxx/qla_os.c | 1900 |
1 files changed, 258 insertions, 1642 deletions
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index b5863d8769e0..0e7e51db470c 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c | |||
@@ -151,6 +151,8 @@ static void qla2x00_config_dma_addressing(scsi_qla_host_t *ha); | |||
151 | * SCSI host template entry points | 151 | * SCSI host template entry points |
152 | */ | 152 | */ |
153 | static int qla2xxx_slave_configure(struct scsi_device * device); | 153 | static int qla2xxx_slave_configure(struct scsi_device * device); |
154 | static int qla2xxx_slave_alloc(struct scsi_device *); | ||
155 | static void qla2xxx_slave_destroy(struct scsi_device *); | ||
154 | static int qla2x00_queuecommand(struct scsi_cmnd *cmd, | 156 | static int qla2x00_queuecommand(struct scsi_cmnd *cmd, |
155 | void (*fn)(struct scsi_cmnd *)); | 157 | void (*fn)(struct scsi_cmnd *)); |
156 | static int qla2xxx_eh_abort(struct scsi_cmnd *); | 158 | static int qla2xxx_eh_abort(struct scsi_cmnd *); |
@@ -177,6 +179,8 @@ static struct scsi_host_template qla2x00_driver_template = { | |||
177 | 179 | ||
178 | .slave_configure = qla2xxx_slave_configure, | 180 | .slave_configure = qla2xxx_slave_configure, |
179 | 181 | ||
182 | .slave_alloc = qla2xxx_slave_alloc, | ||
183 | .slave_destroy = qla2xxx_slave_destroy, | ||
180 | .this_id = -1, | 184 | .this_id = -1, |
181 | .cmd_per_lun = 3, | 185 | .cmd_per_lun = 3, |
182 | .use_clustering = ENABLE_CLUSTERING, | 186 | .use_clustering = ENABLE_CLUSTERING, |
@@ -230,168 +234,6 @@ qla2x00_stop_timer(scsi_qla_host_t *ha) | |||
230 | ha->timer_active = 0; | 234 | ha->timer_active = 0; |
231 | } | 235 | } |
232 | 236 | ||
233 | void qla2x00_cmd_timeout(srb_t *); | ||
234 | |||
235 | static __inline__ void qla2x00_callback(scsi_qla_host_t *, struct scsi_cmnd *); | ||
236 | static __inline__ void sp_put(struct scsi_qla_host * ha, srb_t *sp); | ||
237 | static __inline__ void sp_get(struct scsi_qla_host * ha, srb_t *sp); | ||
238 | static __inline__ void | ||
239 | qla2x00_delete_from_done_queue(scsi_qla_host_t *, srb_t *); | ||
240 | |||
241 | /* | ||
242 | * qla2x00_callback | ||
243 | * Returns the completed SCSI command to LINUX. | ||
244 | * | ||
245 | * Input: | ||
246 | * ha -- Host adapter structure | ||
247 | * cmd -- SCSI mid-level command structure. | ||
248 | * Returns: | ||
249 | * None | ||
250 | * Note:From failover point of view we always get the sp | ||
251 | * from vis_ha pool in queuecommand.So when we put it | ||
252 | * back to the pool it has to be the vis_ha. | ||
253 | * So rely on struct scsi_cmnd to get the vis_ha and not on sp. | ||
254 | */ | ||
255 | static inline void | ||
256 | qla2x00_callback(scsi_qla_host_t *ha, struct scsi_cmnd *cmd) | ||
257 | { | ||
258 | srb_t *sp = (srb_t *) CMD_SP(cmd); | ||
259 | scsi_qla_host_t *vis_ha; | ||
260 | os_lun_t *lq; | ||
261 | int got_sense; | ||
262 | unsigned long cpu_flags = 0; | ||
263 | |||
264 | cmd->host_scribble = (unsigned char *) NULL; | ||
265 | vis_ha = (scsi_qla_host_t *) cmd->device->host->hostdata; | ||
266 | |||
267 | if (sp == NULL) { | ||
268 | qla_printk(KERN_INFO, ha, | ||
269 | "%s(): **** CMD derives a NULL SP\n", | ||
270 | __func__); | ||
271 | DEBUG2(BUG();) | ||
272 | return; | ||
273 | } | ||
274 | |||
275 | /* | ||
276 | * If command status is not DID_BUS_BUSY then go ahead and freed sp. | ||
277 | */ | ||
278 | /* | ||
279 | * Cancel command timeout | ||
280 | */ | ||
281 | qla2x00_delete_timer_from_cmd(sp); | ||
282 | |||
283 | /* | ||
284 | * Put SP back in the free queue | ||
285 | */ | ||
286 | sp->cmd = NULL; | ||
287 | CMD_SP(cmd) = NULL; | ||
288 | lq = sp->lun_queue; | ||
289 | got_sense = (sp->flags & SRB_GOT_SENSE)? 1: 0; | ||
290 | add_to_free_queue(vis_ha, sp); | ||
291 | |||
292 | if (host_byte(cmd->result) == DID_OK) { | ||
293 | /* device ok */ | ||
294 | ha->total_bytes += cmd->bufflen; | ||
295 | if (!got_sense) { | ||
296 | /* If lun was suspended then clear retry count */ | ||
297 | spin_lock_irqsave(&lq->q_lock, cpu_flags); | ||
298 | if (!test_bit(LUN_EXEC_DELAYED, &lq->q_flag)) | ||
299 | lq->q_state = LUN_STATE_READY; | ||
300 | spin_unlock_irqrestore(&lq->q_lock, cpu_flags); | ||
301 | } | ||
302 | } else if (host_byte(cmd->result) == DID_ERROR) { | ||
303 | /* device error */ | ||
304 | ha->total_dev_errs++; | ||
305 | } | ||
306 | |||
307 | /* Call the mid-level driver interrupt handler */ | ||
308 | (*(cmd)->scsi_done)(cmd); | ||
309 | } | ||
310 | |||
311 | /************************************************************************** | ||
312 | * sp_put | ||
313 | * | ||
314 | * Description: | ||
315 | * Decrement reference count and call the callback if we're the last | ||
316 | * owner of the specified sp. Will get the host_lock before calling | ||
317 | * the callback. | ||
318 | * | ||
319 | * Input: | ||
320 | * ha - pointer to the scsi_qla_host_t where the callback is to occur. | ||
321 | * sp - pointer to srb_t structure to use. | ||
322 | * | ||
323 | * Returns: | ||
324 | * | ||
325 | **************************************************************************/ | ||
326 | static inline void | ||
327 | sp_put(struct scsi_qla_host * ha, srb_t *sp) | ||
328 | { | ||
329 | if (atomic_read(&sp->ref_count) == 0) { | ||
330 | qla_printk(KERN_INFO, ha, | ||
331 | "%s(): **** SP->ref_count not zero\n", | ||
332 | __func__); | ||
333 | DEBUG2(BUG();) | ||
334 | |||
335 | return; | ||
336 | } | ||
337 | |||
338 | if (!atomic_dec_and_test(&sp->ref_count)) { | ||
339 | return; | ||
340 | } | ||
341 | |||
342 | qla2x00_callback(ha, sp->cmd); | ||
343 | } | ||
344 | |||
345 | /************************************************************************** | ||
346 | * sp_get | ||
347 | * | ||
348 | * Description: | ||
349 | * Increment reference count of the specified sp. | ||
350 | * | ||
351 | * Input: | ||
352 | * sp - pointer to srb_t structure to use. | ||
353 | * | ||
354 | * Returns: | ||
355 | * | ||
356 | **************************************************************************/ | ||
357 | static inline void | ||
358 | sp_get(struct scsi_qla_host * ha, srb_t *sp) | ||
359 | { | ||
360 | atomic_inc(&sp->ref_count); | ||
361 | |||
362 | if (atomic_read(&sp->ref_count) > 2) { | ||
363 | qla_printk(KERN_INFO, ha, | ||
364 | "%s(): **** SP->ref_count greater than two\n", | ||
365 | __func__); | ||
366 | DEBUG2(BUG();) | ||
367 | |||
368 | return; | ||
369 | } | ||
370 | } | ||
371 | |||
372 | static inline void | ||
373 | qla2x00_delete_from_done_queue(scsi_qla_host_t *dest_ha, srb_t *sp) | ||
374 | { | ||
375 | /* remove command from done list */ | ||
376 | list_del_init(&sp->list); | ||
377 | dest_ha->done_q_cnt--; | ||
378 | sp->state = SRB_NO_QUEUE_STATE; | ||
379 | |||
380 | if (sp->flags & SRB_DMA_VALID) { | ||
381 | sp->flags &= ~SRB_DMA_VALID; | ||
382 | |||
383 | /* Release memory used for this I/O */ | ||
384 | if (sp->cmd->use_sg) { | ||
385 | pci_unmap_sg(dest_ha->pdev, sp->cmd->request_buffer, | ||
386 | sp->cmd->use_sg, sp->cmd->sc_data_direction); | ||
387 | } else if (sp->cmd->request_bufflen) { | ||
388 | pci_unmap_page(dest_ha->pdev, sp->dma_handle, | ||
389 | sp->cmd->request_bufflen, | ||
390 | sp->cmd->sc_data_direction); | ||
391 | } | ||
392 | } | ||
393 | } | ||
394 | |||
395 | static int qla2x00_do_dpc(void *data); | 237 | static int qla2x00_do_dpc(void *data); |
396 | 238 | ||
397 | static void qla2x00_rst_aen(scsi_qla_host_t *); | 239 | static void qla2x00_rst_aen(scsi_qla_host_t *); |
@@ -400,7 +242,9 @@ static uint8_t qla2x00_mem_alloc(scsi_qla_host_t *); | |||
400 | static void qla2x00_mem_free(scsi_qla_host_t *ha); | 242 | static void qla2x00_mem_free(scsi_qla_host_t *ha); |
401 | static int qla2x00_allocate_sp_pool( scsi_qla_host_t *ha); | 243 | static int qla2x00_allocate_sp_pool( scsi_qla_host_t *ha); |
402 | static void qla2x00_free_sp_pool(scsi_qla_host_t *ha); | 244 | static void qla2x00_free_sp_pool(scsi_qla_host_t *ha); |
403 | static srb_t *qla2x00_get_new_sp(scsi_qla_host_t *ha); | 245 | static srb_t *qla2x00_get_new_sp(scsi_qla_host_t *); |
246 | static void qla2x00_sp_free_dma(scsi_qla_host_t *, srb_t *); | ||
247 | void qla2x00_sp_compl(scsi_qla_host_t *ha, srb_t *); | ||
404 | 248 | ||
405 | static ssize_t qla2x00_sysfs_read_fw_dump(struct kobject *, char *, loff_t, | 249 | static ssize_t qla2x00_sysfs_read_fw_dump(struct kobject *, char *, loff_t, |
406 | size_t); | 250 | size_t); |
@@ -661,210 +505,84 @@ qla2x00_get_fw_version_str(struct scsi_qla_host *ha, char *str) | |||
661 | * handling). | 505 | * handling). |
662 | **************************************************************************/ | 506 | **************************************************************************/ |
663 | static int | 507 | static int |
664 | qla2x00_queuecommand(struct scsi_cmnd *cmd, void (*fn)(struct scsi_cmnd *)) | 508 | qla2x00_queuecommand(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *)) |
665 | { | 509 | { |
666 | fc_port_t *fcport; | 510 | scsi_qla_host_t *ha = to_qla_host(cmd->device->host); |
667 | os_lun_t *lq; | 511 | os_tgt_t *tq = (os_tgt_t *) cmd->device->hostdata; |
668 | os_tgt_t *tq; | 512 | fc_port_t *fcport = tq->fcport; |
669 | scsi_qla_host_t *ha, *ha2; | 513 | os_lun_t *lq; |
670 | srb_t *sp; | 514 | srb_t *sp; |
671 | struct Scsi_Host *host; | 515 | int rval; |
672 | unsigned int b, t, l; | ||
673 | unsigned long handle; | ||
674 | int was_empty; | ||
675 | |||
676 | 516 | ||
677 | host = cmd->device->host; | 517 | lq = GET_LU_Q(ha, cmd->device->id, cmd->device->lun); |
678 | ha = (scsi_qla_host_t *) host->hostdata; | 518 | if (!fcport || !lq) { |
679 | was_empty = 1; | 519 | cmd->result = DID_NO_CONNECT << 16; |
520 | goto qc_fail_command; | ||
521 | } | ||
680 | 522 | ||
681 | cmd->scsi_done = fn; | 523 | if (atomic_read(&fcport->state) != FCS_ONLINE) { |
524 | if (atomic_read(&fcport->state) == FCS_DEVICE_DEAD || | ||
525 | atomic_read(&ha->loop_state) == LOOP_DEAD) { | ||
526 | cmd->result = DID_NO_CONNECT << 16; | ||
527 | goto qc_fail_command; | ||
528 | } | ||
529 | goto qc_host_busy; | ||
530 | } | ||
682 | 531 | ||
683 | spin_unlock_irq(ha->host->host_lock); | 532 | spin_unlock_irq(ha->host->host_lock); |
684 | 533 | ||
685 | /* | 534 | /* Allocate a command packet from the "sp" pool. */ |
686 | * Allocate a command packet from the "sp" pool. If we cant get back | ||
687 | * one then let scsi layer come back later. | ||
688 | */ | ||
689 | if ((sp = qla2x00_get_new_sp(ha)) == NULL) { | 535 | if ((sp = qla2x00_get_new_sp(ha)) == NULL) { |
690 | qla_printk(KERN_WARNING, ha, | 536 | goto qc_host_busy_lock; |
691 | "Couldn't allocate memory for sp - retried.\n"); | ||
692 | |||
693 | spin_lock_irq(ha->host->host_lock); | ||
694 | |||
695 | return (1); | ||
696 | } | 537 | } |
697 | 538 | ||
539 | sp->ha = ha; | ||
698 | sp->cmd = cmd; | 540 | sp->cmd = cmd; |
699 | CMD_SP(cmd) = (void *)sp; | ||
700 | |||
701 | sp->flags = 0; | ||
702 | if (CMD_RESID_LEN(cmd) & SRB_IOCTL) { | ||
703 | /* Need to set sp->flags */ | ||
704 | sp->flags |= SRB_IOCTL; | ||
705 | CMD_RESID_LEN(cmd) = 0; /* Clear it since no more use. */ | ||
706 | } | ||
707 | |||
708 | sp->fo_retry_cnt = 0; | ||
709 | sp->err_id = 0; | ||
710 | |||
711 | /* Generate LU queue on bus, target, LUN */ | ||
712 | b = cmd->device->channel; | ||
713 | t = cmd->device->id; | ||
714 | l = cmd->device->lun; | ||
715 | |||
716 | /* | ||
717 | * Start Command Timer. Typically it will be 2 seconds less than what | ||
718 | * is requested by the Host such that we can return the IO before | ||
719 | * aborts are called. | ||
720 | */ | ||
721 | if ((cmd->timeout_per_command / HZ) > QLA_CMD_TIMER_DELTA) | ||
722 | qla2x00_add_timer_to_cmd(sp, | ||
723 | (cmd->timeout_per_command / HZ) - QLA_CMD_TIMER_DELTA); | ||
724 | else | ||
725 | qla2x00_add_timer_to_cmd(sp, cmd->timeout_per_command / HZ); | ||
726 | |||
727 | if (l >= ha->max_luns) { | ||
728 | cmd->result = DID_NO_CONNECT << 16; | ||
729 | sp->err_id = SRB_ERR_PORT; | ||
730 | |||
731 | spin_lock_irq(ha->host->host_lock); | ||
732 | |||
733 | sp_put(ha, sp); | ||
734 | |||
735 | return (0); | ||
736 | } | ||
737 | |||
738 | if ((tq = (os_tgt_t *) TGT_Q(ha, t)) != NULL && | ||
739 | (lq = (os_lun_t *) LUN_Q(ha, t, l)) != NULL) { | ||
740 | fcport = lq->fclun->fcport; | ||
741 | ha2 = fcport->ha; | ||
742 | } else { | ||
743 | lq = NULL; | ||
744 | fcport = NULL; | ||
745 | ha2 = ha; | ||
746 | } | ||
747 | |||
748 | /* Set an invalid handle until we issue the command to ISP */ | ||
749 | /* then we will set the real handle value. */ | ||
750 | handle = INVALID_HANDLE; | ||
751 | cmd->host_scribble = (unsigned char *)handle; | ||
752 | |||
753 | /* Bookkeeping information */ | ||
754 | sp->r_start = jiffies; /* Time the request was recieved. */ | ||
755 | sp->u_start = 0; | ||
756 | |||
757 | /* Setup device queue pointers. */ | ||
758 | sp->tgt_queue = tq; | 541 | sp->tgt_queue = tq; |
759 | sp->lun_queue = lq; | ||
760 | |||
761 | /* | ||
762 | * NOTE : q is NULL | ||
763 | * | ||
764 | * 1. When device is added from persistent binding but has not been | ||
765 | * discovered yet.The state of loopid == PORT_AVAIL. | ||
766 | * 2. When device is never found on the bus.(loopid == UNUSED) | ||
767 | * | ||
768 | * IF Device Queue is not created, or device is not in a valid state | ||
769 | * and link down error reporting is enabled, reject IO. | ||
770 | */ | ||
771 | if (fcport == NULL) { | ||
772 | DEBUG3(printk("scsi(%ld:%2d:%2d): port unavailable\n", | ||
773 | ha->host_no,t,l)); | ||
774 | 542 | ||
775 | cmd->result = DID_NO_CONNECT << 16; | 543 | sp->lun_queue = lq; |
776 | sp->err_id = SRB_ERR_PORT; | 544 | lq->io_cnt++; |
777 | 545 | sp->fclun = lq->fclun; | |
778 | spin_lock_irq(ha->host->host_lock); | ||
779 | |||
780 | sp_put(ha, sp); | ||
781 | |||
782 | return (0); | ||
783 | } | ||
784 | 546 | ||
785 | /* Only modify the allowed count if the target is a *non* tape device */ | 547 | sp->flags = 0; |
786 | if ((fcport->flags & FCF_TAPE_PRESENT) == 0) { | 548 | sp->err_id = 0; |
787 | sp->flags &= ~SRB_TAPE; | ||
788 | if (cmd->allowed < ql2xretrycount) { | ||
789 | cmd->allowed = ql2xretrycount; | ||
790 | } | ||
791 | } else | ||
792 | sp->flags |= SRB_TAPE; | ||
793 | 549 | ||
794 | DEBUG5(printk("scsi(%ld:%2d:%2d): (queuecmd) queue sp = %p, " | 550 | CMD_SP(cmd) = (void *)sp; |
795 | "flags=0x%x fo retry=%d, pid=%ld\n", | 551 | cmd->scsi_done = done; |
796 | ha->host_no, t, l, sp, sp->flags, sp->fo_retry_cnt, | ||
797 | cmd->serial_number)); | ||
798 | DEBUG5(qla2x00_print_scsi_cmd(cmd)); | ||
799 | 552 | ||
800 | sp->fclun = lq->fclun; | 553 | rval = qla2x00_start_scsi(sp); |
801 | sp->ha = ha2; | 554 | if (rval != QLA_SUCCESS) |
555 | goto qc_host_busy_free_sp; | ||
802 | 556 | ||
803 | if (cmd->sc_data_direction == DMA_BIDIRECTIONAL && | 557 | /* Manage unprocessed RIO/ZIO commands in response queue. */ |
804 | cmd->request_bufflen != 0) { | 558 | if (ha->flags.online && ha->flags.process_response_queue && |
559 | ha->response_ring_ptr->signature != RESPONSE_PROCESSED) { | ||
560 | unsigned long flags; | ||
805 | 561 | ||
806 | DEBUG2(printk(KERN_WARNING | 562 | spin_lock_irqsave(&ha->hardware_lock, flags); |
807 | "scsi(%ld): Incorrect data direction - transfer " | 563 | qla2x00_process_response_queue(ha); |
808 | "length=%d, direction=%d, pid=%ld, opcode=%x\n", | 564 | spin_unlock_irqrestore(&ha->hardware_lock, flags); |
809 | ha->host_no, cmd->request_bufflen, cmd->sc_data_direction, | ||
810 | cmd->serial_number, cmd->cmnd[0])); | ||
811 | } | 565 | } |
812 | 566 | ||
813 | /* Final pre-check : | 567 | spin_lock_irq(ha->host->host_lock); |
814 | * | ||
815 | * Either PORT_DOWN_TIMER OR LINK_DOWN_TIMER Expired. | ||
816 | */ | ||
817 | if (atomic_read(&fcport->state) == FCS_DEVICE_DEAD || | ||
818 | atomic_read(&ha2->loop_state) == LOOP_DEAD) { | ||
819 | /* | ||
820 | * Add the command to the done-queue for later failover | ||
821 | * processing. | ||
822 | */ | ||
823 | cmd->result = DID_NO_CONNECT << 16; | ||
824 | if (atomic_read(&ha2->loop_state) == LOOP_DOWN) | ||
825 | sp->err_id = SRB_ERR_LOOP; | ||
826 | else | ||
827 | sp->err_id = SRB_ERR_PORT; | ||
828 | 568 | ||
829 | add_to_done_queue(ha, sp); | 569 | return 0; |
830 | qla2x00_done(ha); | ||
831 | 570 | ||
832 | spin_lock_irq(ha->host->host_lock); | 571 | qc_host_busy_free_sp: |
833 | return (0); | 572 | qla2x00_sp_free_dma(ha, sp); |
834 | } | 573 | CMD_SP(cmd) = NULL; |
574 | mempool_free(sp, ha->srb_mempool); | ||
835 | 575 | ||
836 | if (tq && test_bit(TQF_SUSPENDED, &tq->flags) && | 576 | qc_host_busy_lock: |
837 | (sp->flags & SRB_TAPE) == 0) { | 577 | spin_lock_irq(ha->host->host_lock); |
838 | /* If target suspended put incoming I/O in retry_q. */ | ||
839 | qla2x00_extend_timeout(sp->cmd, 10); | ||
840 | add_to_scsi_retry_queue(ha, sp); | ||
841 | } else | ||
842 | was_empty = add_to_pending_queue(ha, sp); | ||
843 | |||
844 | if ((IS_QLA2100(ha) || IS_QLA2200(ha)) && ha->flags.online) { | ||
845 | if (ha->response_ring_ptr->signature != RESPONSE_PROCESSED) { | ||
846 | unsigned long flags; | ||
847 | |||
848 | spin_lock_irqsave(&ha->hardware_lock, flags); | ||
849 | qla2x00_process_response_queue(ha); | ||
850 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | ||
851 | } | ||
852 | } | ||
853 | 578 | ||
854 | /* We submit to the hardware if: | 579 | qc_host_busy: |
855 | * | 580 | return SCSI_MLQUEUE_HOST_BUSY; |
856 | * 1) we're on the cpu the irq's arrive on or | ||
857 | * 2) there are very few io's outstanding. | ||
858 | * | ||
859 | * In all other cases we'll let an irq pick up our IO and submit it | ||
860 | * to the controller to improve affinity. | ||
861 | */ | ||
862 | if (_smp_processor_id() == ha->last_irq_cpu || was_empty) | ||
863 | qla2x00_next(ha); | ||
864 | 581 | ||
865 | spin_lock_irq(ha->host->host_lock); | 582 | qc_fail_command: |
583 | done(cmd); | ||
866 | 584 | ||
867 | return (0); | 585 | return 0; |
868 | } | 586 | } |
869 | 587 | ||
870 | /* | 588 | /* |
@@ -886,54 +604,21 @@ static int | |||
886 | qla2x00_eh_wait_on_command(scsi_qla_host_t *ha, struct scsi_cmnd *cmd) | 604 | qla2x00_eh_wait_on_command(scsi_qla_host_t *ha, struct scsi_cmnd *cmd) |
887 | { | 605 | { |
888 | #define ABORT_POLLING_PERIOD HZ | 606 | #define ABORT_POLLING_PERIOD HZ |
889 | #define ABORT_WAIT_TIME ((10 * HZ) / (ABORT_POLLING_PERIOD)) | 607 | #define ABORT_WAIT_ITER ((10 * HZ) / (ABORT_POLLING_PERIOD)) |
890 | 608 | unsigned long wait_iter = ABORT_WAIT_ITER; | |
891 | int found = 0; | 609 | int ret = QLA_SUCCESS; |
892 | int done = 0; | ||
893 | srb_t *rp = NULL; | ||
894 | struct list_head *list, *temp; | ||
895 | u_long max_wait_time = ABORT_WAIT_TIME; | ||
896 | |||
897 | do { | ||
898 | /* Check on done queue */ | ||
899 | spin_lock(&ha->list_lock); | ||
900 | list_for_each_safe(list, temp, &ha->done_queue) { | ||
901 | rp = list_entry(list, srb_t, list); | ||
902 | |||
903 | /* | ||
904 | * Found command. Just exit and wait for the cmd sent | ||
905 | * to OS. | ||
906 | */ | ||
907 | if (cmd == rp->cmd) { | ||
908 | found++; | ||
909 | DEBUG3(printk("%s: found in done queue.\n", | ||
910 | __func__);) | ||
911 | break; | ||
912 | } | ||
913 | } | ||
914 | spin_unlock(&ha->list_lock); | ||
915 | |||
916 | /* Complete the cmd right away. */ | ||
917 | if (found) { | ||
918 | qla2x00_delete_from_done_queue(ha, rp); | ||
919 | sp_put(ha, rp); | ||
920 | done++; | ||
921 | break; | ||
922 | } | ||
923 | |||
924 | spin_unlock_irq(ha->host->host_lock); | ||
925 | 610 | ||
611 | while (CMD_SP(cmd)) { | ||
926 | set_current_state(TASK_UNINTERRUPTIBLE); | 612 | set_current_state(TASK_UNINTERRUPTIBLE); |
927 | schedule_timeout(ABORT_POLLING_PERIOD); | 613 | schedule_timeout(ABORT_POLLING_PERIOD); |
928 | 614 | ||
929 | spin_lock_irq(ha->host->host_lock); | 615 | if (--wait_iter) |
930 | 616 | break; | |
931 | } while ((max_wait_time--)); | 617 | } |
932 | 618 | if (CMD_SP(cmd)) | |
933 | if (done) | 619 | ret = QLA_FUNCTION_FAILED; |
934 | DEBUG2(printk(KERN_INFO "%s: found cmd=%p.\n", __func__, cmd)); | ||
935 | 620 | ||
936 | return (done); | 621 | return ret; |
937 | } | 622 | } |
938 | 623 | ||
939 | /* | 624 | /* |
@@ -1032,245 +717,69 @@ qla2x00_wait_for_loop_ready(scsi_qla_host_t *ha) | |||
1032 | int | 717 | int |
1033 | qla2xxx_eh_abort(struct scsi_cmnd *cmd) | 718 | qla2xxx_eh_abort(struct scsi_cmnd *cmd) |
1034 | { | 719 | { |
1035 | int i; | 720 | scsi_qla_host_t *ha = to_qla_host(cmd->device->host); |
1036 | int return_status = FAILED; | 721 | srb_t *sp; |
1037 | os_lun_t *q; | 722 | int ret, i; |
1038 | scsi_qla_host_t *ha; | 723 | unsigned int id, lun; |
1039 | scsi_qla_host_t *vis_ha; | 724 | unsigned long serial; |
1040 | srb_t *sp; | ||
1041 | srb_t *rp; | ||
1042 | struct list_head *list, *temp; | ||
1043 | struct Scsi_Host *host; | ||
1044 | uint8_t found = 0; | ||
1045 | unsigned int b, t, l; | ||
1046 | |||
1047 | /* Get the SCSI request ptr */ | ||
1048 | sp = (srb_t *) CMD_SP(cmd); | ||
1049 | |||
1050 | /* | ||
1051 | * If sp is NULL, command is already returned. | ||
1052 | * sp is NULLED just before we call back scsi_done | ||
1053 | * | ||
1054 | */ | ||
1055 | if ((sp == NULL)) { | ||
1056 | /* no action - we don't have command */ | ||
1057 | qla_printk(KERN_INFO, to_qla_host(cmd->device->host), | ||
1058 | "qla2xxx_eh_abort: cmd already done sp=%p\n", sp); | ||
1059 | DEBUG(printk("qla2xxx_eh_abort: cmd already done sp=%p\n", sp);) | ||
1060 | return SUCCESS; | ||
1061 | } | ||
1062 | if (sp) { | ||
1063 | DEBUG(printk("qla2xxx_eh_abort: refcount %i \n", | ||
1064 | atomic_read(&sp->ref_count));) | ||
1065 | } | ||
1066 | |||
1067 | vis_ha = (scsi_qla_host_t *) cmd->device->host->hostdata; | ||
1068 | ha = (scsi_qla_host_t *)cmd->device->host->hostdata; | ||
1069 | |||
1070 | host = ha->host; | ||
1071 | |||
1072 | /* Generate LU queue on bus, target, LUN */ | ||
1073 | b = cmd->device->channel; | ||
1074 | t = cmd->device->id; | ||
1075 | l = cmd->device->lun; | ||
1076 | q = GET_LU_Q(vis_ha, t, l); | ||
1077 | |||
1078 | qla_printk(KERN_INFO, ha, | ||
1079 | "%s scsi(%ld:%d:%d:%d): cmd_timeout_in_sec=0x%x.\n", __func__, | ||
1080 | ha->host_no, (int)b, (int)t, (int)l, | ||
1081 | cmd->timeout_per_command / HZ); | ||
1082 | |||
1083 | /* | ||
1084 | * if no LUN queue then something is very wrong!!! | ||
1085 | */ | ||
1086 | if (q == NULL) { | ||
1087 | qla_printk(KERN_WARNING, ha, | ||
1088 | "qla2x00: (%x:%x:%x) No LUN queue.\n", b, t, l); | ||
1089 | 725 | ||
1090 | /* no action - we don't have command */ | 726 | if (!CMD_SP(cmd)) |
1091 | return FAILED; | 727 | return FAILED; |
1092 | } | ||
1093 | 728 | ||
1094 | DEBUG2(printk("scsi(%ld): ABORTing cmd=%p sp=%p jiffies = 0x%lx, " | 729 | ret = FAILED; |
1095 | "timeout=%x, dpc_flags=%lx, vis_ha->dpc_flags=%lx q->flag=%lx\n", | ||
1096 | ha->host_no, cmd, sp, jiffies, cmd->timeout_per_command / HZ, | ||
1097 | ha->dpc_flags, vis_ha->dpc_flags, q->q_flag)); | ||
1098 | DEBUG2(qla2x00_print_scsi_cmd(cmd)); | ||
1099 | 730 | ||
1100 | spin_unlock_irq(ha->host->host_lock); | 731 | id = cmd->device->id; |
1101 | if (qla2x00_wait_for_hba_online(ha) != QLA_SUCCESS) { | 732 | lun = cmd->device->lun; |
1102 | DEBUG2(printk("%s failed:board disabled\n", __func__);) | 733 | serial = cmd->serial_number; |
1103 | spin_lock_irq(ha->host->host_lock); | ||
1104 | return FAILED; | ||
1105 | } | ||
1106 | spin_lock_irq(ha->host->host_lock); | ||
1107 | 734 | ||
1108 | /* Search done queue */ | 735 | /* Check active list for command command. */ |
1109 | spin_lock(&ha->list_lock); | 736 | spin_unlock_irq(ha->host->host_lock); |
1110 | list_for_each_safe(list, temp, &ha->done_queue) { | 737 | spin_lock(&ha->hardware_lock); |
1111 | rp = list_entry(list, srb_t, list); | 738 | for (i = 1; i < MAX_OUTSTANDING_COMMANDS; i++) { |
739 | sp = ha->outstanding_cmds[i]; | ||
1112 | 740 | ||
1113 | if (cmd != rp->cmd) | 741 | if (sp == NULL) |
1114 | continue; | 742 | continue; |
1115 | 743 | ||
1116 | /* | 744 | if (sp->cmd != cmd) |
1117 | * Found command.Remove it from done list. | ||
1118 | * And proceed to post completion to scsi mid layer. | ||
1119 | */ | ||
1120 | return_status = SUCCESS; | ||
1121 | found++; | ||
1122 | qla2x00_delete_from_done_queue(ha, sp); | ||
1123 | |||
1124 | break; | ||
1125 | } /* list_for_each_safe() */ | ||
1126 | spin_unlock(&ha->list_lock); | ||
1127 | |||
1128 | /* | ||
1129 | * Return immediately if the aborted command was already in the done | ||
1130 | * queue | ||
1131 | */ | ||
1132 | if (found) { | ||
1133 | qla_printk(KERN_INFO, ha, | ||
1134 | "qla2xxx_eh_abort: Returning completed command=%p sp=%p\n", | ||
1135 | cmd, sp); | ||
1136 | sp_put(ha, sp); | ||
1137 | return (return_status); | ||
1138 | } | ||
1139 | |||
1140 | |||
1141 | /* | ||
1142 | * See if this command is in the retry queue | ||
1143 | */ | ||
1144 | DEBUG3(printk("qla2xxx_eh_abort: searching sp %p in retry " | ||
1145 | "queue.\n", sp);) | ||
1146 | |||
1147 | spin_lock(&ha->list_lock); | ||
1148 | list_for_each_safe(list, temp, &ha->retry_queue) { | ||
1149 | rp = list_entry(list, srb_t, list); | ||
1150 | |||
1151 | if (cmd != rp->cmd) | ||
1152 | continue; | 745 | continue; |
1153 | 746 | ||
747 | DEBUG2(printk("%s(%ld): aborting sp %p from RISC. pid=%ld " | ||
748 | "sp->state=%x\n", __func__, ha->host_no, sp, serial, | ||
749 | sp->state)); | ||
750 | DEBUG3(qla2x00_print_scsi_cmd(cmd);) | ||
1154 | 751 | ||
1155 | DEBUG2(printk("qla2xxx_eh_abort: found " | ||
1156 | "in retry queue. SP=%p\n", sp);) | ||
1157 | |||
1158 | __del_from_retry_queue(ha, rp); | ||
1159 | cmd->result = DID_ABORT << 16; | ||
1160 | __add_to_done_queue(ha, rp); | ||
1161 | |||
1162 | return_status = SUCCESS; | ||
1163 | found++; | ||
1164 | |||
1165 | break; | ||
1166 | |||
1167 | } | ||
1168 | spin_unlock(&ha->list_lock); | ||
1169 | |||
1170 | |||
1171 | /* | ||
1172 | * Our SP pointer points at the command we want to remove from the | ||
1173 | * pending queue providing we haven't already sent it to the adapter. | ||
1174 | */ | ||
1175 | if (!found) { | ||
1176 | DEBUG3(printk("qla2xxx_eh_abort: searching sp %p " | ||
1177 | "in pending queue.\n", sp);) | ||
1178 | |||
1179 | spin_lock(&vis_ha->list_lock); | ||
1180 | list_for_each_safe(list, temp, &vis_ha->pending_queue) { | ||
1181 | rp = list_entry(list, srb_t, list); | ||
1182 | |||
1183 | if (rp->cmd != cmd) | ||
1184 | continue; | ||
1185 | |||
1186 | /* Remove srb from LUN queue. */ | ||
1187 | rp->flags |= SRB_ABORTED; | ||
1188 | |||
1189 | DEBUG2(printk("qla2xxx_eh_abort: Cmd in pending queue." | ||
1190 | " serial_number %ld.\n", | ||
1191 | sp->cmd->serial_number);) | ||
1192 | |||
1193 | __del_from_pending_queue(vis_ha, rp); | ||
1194 | cmd->result = DID_ABORT << 16; | ||
1195 | |||
1196 | __add_to_done_queue(vis_ha, rp); | ||
1197 | |||
1198 | return_status = SUCCESS; | ||
1199 | |||
1200 | found++; | ||
1201 | break; | ||
1202 | } /* list_for_each_safe() */ | ||
1203 | spin_unlock(&vis_ha->list_lock); | ||
1204 | } /*End of if !found */ | ||
1205 | |||
1206 | if (!found) { /* find the command in our active list */ | ||
1207 | DEBUG3(printk("qla2xxx_eh_abort: searching sp %p " | ||
1208 | "in outstanding queue.\n", sp);) | ||
1209 | |||
1210 | spin_lock(&ha->hardware_lock); | ||
1211 | for (i = 1; i < MAX_OUTSTANDING_COMMANDS; i++) { | ||
1212 | sp = ha->outstanding_cmds[i]; | ||
1213 | |||
1214 | if (sp == NULL) | ||
1215 | continue; | ||
1216 | |||
1217 | if (sp->cmd != cmd) | ||
1218 | continue; | ||
1219 | |||
1220 | DEBUG2(printk("qla2xxx_eh_abort(%ld): aborting sp %p " | ||
1221 | "from RISC. pid=%ld sp->state=%x q->q_flag=%lx\n", | ||
1222 | ha->host_no, sp, sp->cmd->serial_number, | ||
1223 | sp->state, q->q_flag);) | ||
1224 | DEBUG(qla2x00_print_scsi_cmd(cmd);) | ||
1225 | |||
1226 | /* Get a reference to the sp and drop the lock.*/ | ||
1227 | sp_get(ha, sp); | ||
1228 | |||
1229 | spin_unlock(&ha->hardware_lock); | ||
1230 | spin_unlock_irq(ha->host->host_lock); | ||
1231 | |||
1232 | if (qla2x00_abort_command(ha, sp)) { | ||
1233 | DEBUG2(printk("qla2xxx_eh_abort: abort_command " | ||
1234 | "mbx failed.\n");) | ||
1235 | return_status = FAILED; | ||
1236 | } else { | ||
1237 | DEBUG3(printk("qla2xxx_eh_abort: abort_command " | ||
1238 | " mbx success.\n");) | ||
1239 | return_status = SUCCESS; | ||
1240 | } | ||
1241 | |||
1242 | sp_put(ha,sp); | ||
1243 | |||
1244 | spin_lock_irq(ha->host->host_lock); | ||
1245 | spin_lock(&ha->hardware_lock); | ||
1246 | |||
1247 | /* | ||
1248 | * Regardless of mailbox command status, go check on | ||
1249 | * done queue just in case the sp is already done. | ||
1250 | */ | ||
1251 | break; | ||
1252 | |||
1253 | }/*End of for loop */ | ||
1254 | spin_unlock(&ha->hardware_lock); | 752 | spin_unlock(&ha->hardware_lock); |
753 | if (qla2x00_abort_command(ha, sp)) { | ||
754 | DEBUG2(printk("%s(%ld): abort_command " | ||
755 | "mbx failed.\n", __func__, ha->host_no)); | ||
756 | } else { | ||
757 | DEBUG3(printk("%s(%ld): abort_command " | ||
758 | "mbx success.\n", __func__, ha->host_no)); | ||
759 | ret = SUCCESS; | ||
760 | } | ||
761 | spin_lock(&ha->hardware_lock); | ||
1255 | 762 | ||
1256 | } /*End of if !found */ | 763 | break; |
1257 | |||
1258 | /* Waiting for our command in done_queue to be returned to OS.*/ | ||
1259 | if (qla2x00_eh_wait_on_command(ha, cmd) != 0) { | ||
1260 | DEBUG2(printk("qla2xxx_eh_abort: cmd returned back to OS.\n");) | ||
1261 | return_status = SUCCESS; | ||
1262 | } | 764 | } |
1263 | 765 | ||
1264 | if (return_status == FAILED) { | 766 | /* Wait for the command to be returned. */ |
1265 | qla_printk(KERN_INFO, ha, | 767 | if (ret == SUCCESS) { |
1266 | "qla2xxx_eh_abort Exiting: status=Failed\n"); | 768 | spin_unlock(&ha->hardware_lock); |
1267 | return FAILED; | 769 | if (qla2x00_eh_wait_on_command(ha, cmd) != QLA_SUCCESS) { |
770 | qla_printk(KERN_ERR, ha, | ||
771 | "scsi(%ld:%d:%d): Abort handler timed out -- %lx " | ||
772 | "%x.\n", ha->host_no, id, lun, serial, ret); | ||
773 | } | ||
774 | spin_lock(&ha->hardware_lock); | ||
1268 | } | 775 | } |
776 | spin_lock_irq(ha->host->host_lock); | ||
1269 | 777 | ||
1270 | DEBUG2(printk("qla2xxx_eh_abort: Exiting. return_status=0x%x.\n", | 778 | qla_printk(KERN_INFO, ha, |
1271 | return_status)); | 779 | "scsi(%ld:%d:%d): Abort command issued -- %lx %x.\n", ha->host_no, |
780 | id, lun, serial, ret); | ||
1272 | 781 | ||
1273 | return return_status; | 782 | return ret; |
1274 | } | 783 | } |
1275 | 784 | ||
1276 | /************************************************************************** | 785 | /************************************************************************** |
@@ -1313,8 +822,7 @@ qla2x00_eh_wait_for_pending_target_commands(scsi_qla_host_t *ha, unsigned int t) | |||
1313 | break; | 822 | break; |
1314 | } | 823 | } |
1315 | } | 824 | } |
1316 | } | 825 | } else { |
1317 | else { | ||
1318 | spin_unlock(&ha->hardware_lock); | 826 | spin_unlock(&ha->hardware_lock); |
1319 | } | 827 | } |
1320 | } | 828 | } |
@@ -1344,96 +852,45 @@ qla2x00_eh_wait_for_pending_target_commands(scsi_qla_host_t *ha, unsigned int t) | |||
1344 | int | 852 | int |
1345 | qla2xxx_eh_device_reset(struct scsi_cmnd *cmd) | 853 | qla2xxx_eh_device_reset(struct scsi_cmnd *cmd) |
1346 | { | 854 | { |
1347 | int return_status; | 855 | scsi_qla_host_t *ha = to_qla_host(cmd->device->host); |
1348 | unsigned int b, t, l; | 856 | os_tgt_t *tq = (os_tgt_t *) cmd->device->hostdata; |
1349 | scsi_qla_host_t *ha; | 857 | fc_port_t *fcport = tq->fcport; |
1350 | os_tgt_t *tq; | 858 | os_lun_t *lq; |
1351 | os_lun_t *lq; | 859 | srb_t *sp; |
1352 | fc_port_t *fcport_to_reset; | 860 | int ret; |
1353 | srb_t *rp; | 861 | unsigned int id, lun; |
1354 | struct list_head *list, *temp; | 862 | unsigned long serial; |
1355 | |||
1356 | return_status = FAILED; | ||
1357 | if (cmd == NULL) { | ||
1358 | printk(KERN_INFO | ||
1359 | "%s(): **** SCSI mid-layer passing in NULL cmd\n", | ||
1360 | __func__); | ||
1361 | |||
1362 | return (return_status); | ||
1363 | } | ||
1364 | |||
1365 | b = cmd->device->channel; | ||
1366 | t = cmd->device->id; | ||
1367 | l = cmd->device->lun; | ||
1368 | ha = (scsi_qla_host_t *)cmd->device->host->hostdata; | ||
1369 | |||
1370 | tq = TGT_Q(ha, t); | ||
1371 | if (tq == NULL) { | ||
1372 | qla_printk(KERN_INFO, ha, | ||
1373 | "%s(): **** CMD derives a NULL TGT_Q\n", __func__); | ||
1374 | 863 | ||
1375 | return (return_status); | 864 | ret = FAILED; |
1376 | } | ||
1377 | lq = (os_lun_t *)LUN_Q(ha, t, l); | ||
1378 | if (lq == NULL) { | ||
1379 | printk(KERN_INFO | ||
1380 | "%s(): **** CMD derives a NULL LUN_Q\n", __func__); | ||
1381 | 865 | ||
1382 | return (return_status); | 866 | id = cmd->device->id; |
1383 | } | 867 | lun = cmd->device->lun; |
1384 | fcport_to_reset = lq->fclun->fcport; | 868 | serial = cmd->serial_number; |
1385 | 869 | ||
1386 | /* If we are coming in from the back-door, stall I/O until complete. */ | 870 | sp = (srb_t *) CMD_SP(cmd); |
1387 | if (!cmd->device->host->eh_active) | 871 | lq = GET_LU_Q(ha, id, lun); |
1388 | set_bit(TQF_SUSPENDED, &tq->flags); | 872 | if (!sp || !fcport || !lq) |
873 | return ret; | ||
1389 | 874 | ||
1390 | qla_printk(KERN_INFO, ha, | 875 | qla_printk(KERN_INFO, ha, |
1391 | "scsi(%ld:%d:%d:%d): DEVICE RESET ISSUED.\n", ha->host_no, b, t, l); | 876 | "scsi(%ld:%d:%d): DEVICE RESET ISSUED.\n", ha->host_no, id, lun); |
1392 | |||
1393 | DEBUG2(printk(KERN_INFO | ||
1394 | "scsi(%ld): DEVICE_RESET cmd=%p jiffies = 0x%lx, timeout=%x, " | ||
1395 | "dpc_flags=%lx, status=%x allowed=%d cmd.state=%x\n", | ||
1396 | ha->host_no, cmd, jiffies, cmd->timeout_per_command / HZ, | ||
1397 | ha->dpc_flags, cmd->result, cmd->allowed, cmd->state)); | ||
1398 | |||
1399 | /* Clear commands from the retry queue. */ | ||
1400 | spin_lock(&ha->list_lock); | ||
1401 | list_for_each_safe(list, temp, &ha->retry_queue) { | ||
1402 | rp = list_entry(list, srb_t, list); | ||
1403 | |||
1404 | if (t != rp->cmd->device->id) | ||
1405 | continue; | ||
1406 | |||
1407 | DEBUG2(printk(KERN_INFO | ||
1408 | "qla2xxx_eh_reset: found in retry queue. SP=%p\n", rp)); | ||
1409 | |||
1410 | __del_from_retry_queue(ha, rp); | ||
1411 | rp->cmd->result = DID_RESET << 16; | ||
1412 | __add_to_done_queue(ha, rp); | ||
1413 | } | ||
1414 | spin_unlock(&ha->list_lock); | ||
1415 | 877 | ||
1416 | spin_unlock_irq(ha->host->host_lock); | 878 | spin_unlock_irq(ha->host->host_lock); |
1417 | 879 | ||
1418 | if (qla2x00_wait_for_hba_online(ha) != QLA_SUCCESS) { | 880 | if (qla2x00_wait_for_hba_online(ha) != QLA_SUCCESS) { |
1419 | DEBUG2(printk(KERN_INFO | ||
1420 | "%s failed:board disabled\n",__func__)); | ||
1421 | |||
1422 | spin_lock_irq(ha->host->host_lock); | 881 | spin_lock_irq(ha->host->host_lock); |
1423 | goto eh_dev_reset_done; | 882 | goto eh_dev_reset_done; |
1424 | } | 883 | } |
1425 | 884 | ||
1426 | if (qla2x00_wait_for_loop_ready(ha) == QLA_SUCCESS) { | 885 | if (qla2x00_wait_for_loop_ready(ha) == QLA_SUCCESS) { |
1427 | if (qla2x00_device_reset(ha, fcport_to_reset) == 0) { | 886 | if (qla2x00_device_reset(ha, fcport) == 0) |
1428 | return_status = SUCCESS; | 887 | ret = SUCCESS; |
1429 | } | ||
1430 | 888 | ||
1431 | #if defined(LOGOUT_AFTER_DEVICE_RESET) | 889 | #if defined(LOGOUT_AFTER_DEVICE_RESET) |
1432 | if (return_status == SUCCESS) { | 890 | if (ret == SUCCESS) { |
1433 | if (fcport_to_reset->flags & FC_FABRIC_DEVICE) { | 891 | if (fcport->flags & FC_FABRIC_DEVICE) { |
1434 | qla2x00_fabric_logout(ha, | 892 | qla2x00_fabric_logout(ha, fcport->loop_id); |
1435 | fcport_to_reset->loop_id); | 893 | qla2x00_mark_device_lost(ha, fcport); |
1436 | qla2x00_mark_device_lost(ha, fcport_to_reset); | ||
1437 | } | 894 | } |
1438 | } | 895 | } |
1439 | #endif | 896 | #endif |
@@ -1442,9 +899,7 @@ qla2xxx_eh_device_reset(struct scsi_cmnd *cmd) | |||
1442 | "%s failed: loop not ready\n",__func__);) | 899 | "%s failed: loop not ready\n",__func__);) |
1443 | } | 900 | } |
1444 | 901 | ||
1445 | spin_lock_irq(ha->host->host_lock); | 902 | if (ret == FAILED) { |
1446 | |||
1447 | if (return_status == FAILED) { | ||
1448 | DEBUG3(printk("%s(%ld): device reset failed\n", | 903 | DEBUG3(printk("%s(%ld): device reset failed\n", |
1449 | __func__, ha->host_no)); | 904 | __func__, ha->host_no)); |
1450 | qla_printk(KERN_INFO, ha, "%s: device reset failed\n", | 905 | qla_printk(KERN_INFO, ha, "%s: device reset failed\n", |
@@ -1458,10 +913,10 @@ qla2xxx_eh_device_reset(struct scsi_cmnd *cmd) | |||
1458 | * complete for the device. | 913 | * complete for the device. |
1459 | */ | 914 | */ |
1460 | if (cmd->device->host->eh_active) { | 915 | if (cmd->device->host->eh_active) { |
1461 | if (qla2x00_eh_wait_for_pending_target_commands(ha, t)) | 916 | if (qla2x00_eh_wait_for_pending_target_commands(ha, id)) |
1462 | return_status = FAILED; | 917 | ret = FAILED; |
1463 | 918 | ||
1464 | if (return_status == FAILED) { | 919 | if (ret == FAILED) { |
1465 | DEBUG3(printk("%s(%ld): failed while waiting for " | 920 | DEBUG3(printk("%s(%ld): failed while waiting for " |
1466 | "commands\n", __func__, ha->host_no)); | 921 | "commands\n", __func__, ha->host_no)); |
1467 | qla_printk(KERN_INFO, ha, | 922 | qla_printk(KERN_INFO, ha, |
@@ -1473,15 +928,12 @@ qla2xxx_eh_device_reset(struct scsi_cmnd *cmd) | |||
1473 | } | 928 | } |
1474 | 929 | ||
1475 | qla_printk(KERN_INFO, ha, | 930 | qla_printk(KERN_INFO, ha, |
1476 | "scsi(%ld:%d:%d:%d): DEVICE RESET SUCCEEDED.\n", | 931 | "scsi(%ld:%d:%d): DEVICE RESET SUCCEEDED.\n", ha->host_no, id, lun); |
1477 | ha->host_no, b, t, l); | ||
1478 | 932 | ||
1479 | eh_dev_reset_done: | 933 | eh_dev_reset_done: |
934 | spin_lock_irq(ha->host->host_lock); | ||
1480 | 935 | ||
1481 | if (!cmd->device->host->eh_active) | 936 | return ret; |
1482 | clear_bit(TQF_SUSPENDED, &tq->flags); | ||
1483 | |||
1484 | return (return_status); | ||
1485 | } | 937 | } |
1486 | 938 | ||
1487 | /************************************************************************** | 939 | /************************************************************************** |
@@ -1549,44 +1001,55 @@ qla2x00_eh_wait_for_pending_commands(scsi_qla_host_t *ha) | |||
1549 | int | 1001 | int |
1550 | qla2xxx_eh_bus_reset(struct scsi_cmnd *cmd) | 1002 | qla2xxx_eh_bus_reset(struct scsi_cmnd *cmd) |
1551 | { | 1003 | { |
1552 | scsi_qla_host_t *ha; | 1004 | scsi_qla_host_t *ha = to_qla_host(cmd->device->host); |
1005 | os_tgt_t *tq = (os_tgt_t *) cmd->device->hostdata; | ||
1006 | fc_port_t *fcport = tq->fcport; | ||
1007 | os_lun_t *lq; | ||
1553 | srb_t *sp; | 1008 | srb_t *sp; |
1554 | int rval = FAILED; | 1009 | int ret; |
1010 | unsigned int id, lun; | ||
1011 | unsigned long serial; | ||
1012 | |||
1013 | ret = FAILED; | ||
1014 | |||
1015 | id = cmd->device->id; | ||
1016 | lun = cmd->device->lun; | ||
1017 | serial = cmd->serial_number; | ||
1555 | 1018 | ||
1556 | ha = (scsi_qla_host_t *) cmd->device->host->hostdata; | ||
1557 | sp = (srb_t *) CMD_SP(cmd); | 1019 | sp = (srb_t *) CMD_SP(cmd); |
1020 | lq = GET_LU_Q(ha, id, lun); | ||
1021 | if (!sp || !fcport || !lq) | ||
1022 | return ret; | ||
1558 | 1023 | ||
1559 | qla_printk(KERN_INFO, ha, | 1024 | qla_printk(KERN_INFO, ha, |
1560 | "scsi(%ld:%d:%d:%d): LOOP RESET ISSUED.\n", ha->host_no, | 1025 | "scsi(%ld:%d:%d): LOOP RESET ISSUED.\n", ha->host_no, id, lun); |
1561 | cmd->device->channel, cmd->device->id, cmd->device->lun); | ||
1562 | 1026 | ||
1563 | spin_unlock_irq(ha->host->host_lock); | 1027 | spin_unlock_irq(ha->host->host_lock); |
1564 | 1028 | ||
1565 | if (qla2x00_wait_for_hba_online(ha) != QLA_SUCCESS) { | 1029 | if (qla2x00_wait_for_hba_online(ha) != QLA_SUCCESS) { |
1566 | DEBUG2(printk("%s failed:board disabled\n",__func__)); | 1030 | DEBUG2(printk("%s failed:board disabled\n",__func__)); |
1567 | spin_lock_irq(ha->host->host_lock); | 1031 | goto eh_bus_reset_done; |
1568 | return FAILED; | ||
1569 | } | 1032 | } |
1570 | 1033 | ||
1571 | if (qla2x00_wait_for_loop_ready(ha) == QLA_SUCCESS) { | 1034 | if (qla2x00_wait_for_loop_ready(ha) == QLA_SUCCESS) { |
1572 | if (qla2x00_loop_reset(ha) == QLA_SUCCESS) | 1035 | if (qla2x00_loop_reset(ha) == QLA_SUCCESS) |
1573 | rval = SUCCESS; | 1036 | ret = SUCCESS; |
1574 | } | 1037 | } |
1575 | 1038 | if (ret == FAILED) | |
1576 | spin_lock_irq(ha->host->host_lock); | 1039 | goto eh_bus_reset_done; |
1577 | if (rval == FAILED) | ||
1578 | goto out; | ||
1579 | 1040 | ||
1580 | /* Waiting for our command in done_queue to be returned to OS.*/ | 1041 | /* Waiting for our command in done_queue to be returned to OS.*/ |
1581 | if (cmd->device->host->eh_active) | 1042 | if (cmd->device->host->eh_active) |
1582 | if (!qla2x00_eh_wait_for_pending_commands(ha)) | 1043 | if (!qla2x00_eh_wait_for_pending_commands(ha)) |
1583 | rval = FAILED; | 1044 | ret = FAILED; |
1584 | 1045 | ||
1585 | out: | 1046 | eh_bus_reset_done: |
1586 | qla_printk(KERN_INFO, ha, "%s: reset %s\n", __func__, | 1047 | qla_printk(KERN_INFO, ha, "%s: reset %s\n", __func__, |
1587 | (rval == FAILED) ? "failed" : "succeded"); | 1048 | (ret == FAILED) ? "failed" : "succeded"); |
1588 | 1049 | ||
1589 | return rval; | 1050 | spin_lock_irq(ha->host->host_lock); |
1051 | |||
1052 | return ret; | ||
1590 | } | 1053 | } |
1591 | 1054 | ||
1592 | /************************************************************************** | 1055 | /************************************************************************** |
@@ -1607,24 +1070,33 @@ qla2xxx_eh_bus_reset(struct scsi_cmnd *cmd) | |||
1607 | int | 1070 | int |
1608 | qla2xxx_eh_host_reset(struct scsi_cmnd *cmd) | 1071 | qla2xxx_eh_host_reset(struct scsi_cmnd *cmd) |
1609 | { | 1072 | { |
1610 | scsi_qla_host_t *ha = (scsi_qla_host_t *)cmd->device->host->hostdata; | 1073 | scsi_qla_host_t *ha = to_qla_host(cmd->device->host); |
1611 | int rval = SUCCESS; | 1074 | os_tgt_t *tq = (os_tgt_t *) cmd->device->hostdata; |
1075 | fc_port_t *fcport = tq->fcport; | ||
1076 | os_lun_t *lq; | ||
1077 | srb_t *sp; | ||
1078 | int ret; | ||
1079 | unsigned int id, lun; | ||
1080 | unsigned long serial; | ||
1612 | 1081 | ||
1613 | /* Display which one we're actually resetting for debug. */ | 1082 | ret = FAILED; |
1614 | DEBUG(printk("qla2xxx_eh_host_reset:Resetting scsi(%ld).\n", | 1083 | |
1615 | ha->host_no)); | 1084 | id = cmd->device->id; |
1085 | lun = cmd->device->lun; | ||
1086 | serial = cmd->serial_number; | ||
1087 | |||
1088 | sp = (srb_t *) CMD_SP(cmd); | ||
1089 | lq = GET_LU_Q(ha, id, lun); | ||
1090 | if (!sp || !fcport || !lq) | ||
1091 | return ret; | ||
1616 | 1092 | ||
1617 | /* | ||
1618 | * Now issue reset. | ||
1619 | */ | ||
1620 | qla_printk(KERN_INFO, ha, | 1093 | qla_printk(KERN_INFO, ha, |
1621 | "scsi(%ld:%d:%d:%d): ADAPTER RESET issued.\n", ha->host_no, | 1094 | "scsi(%ld:%d:%d): ADAPTER RESET ISSUED.\n", ha->host_no, id, lun); |
1622 | cmd->device->channel, cmd->device->id, cmd->device->lun); | ||
1623 | 1095 | ||
1624 | spin_unlock_irq(ha->host->host_lock); | 1096 | spin_unlock_irq(ha->host->host_lock); |
1625 | 1097 | ||
1626 | if (qla2x00_wait_for_hba_online(ha) != QLA_SUCCESS) | 1098 | if (qla2x00_wait_for_hba_online(ha) != QLA_SUCCESS) |
1627 | goto board_disabled; | 1099 | goto eh_host_reset_lock; |
1628 | 1100 | ||
1629 | /* | 1101 | /* |
1630 | * Fixme-may be dpc thread is active and processing | 1102 | * Fixme-may be dpc thread is active and processing |
@@ -1634,7 +1106,6 @@ qla2xxx_eh_host_reset(struct scsi_cmnd *cmd) | |||
1634 | * devices as lost kicking of the port_down_timer | 1106 | * devices as lost kicking of the port_down_timer |
1635 | * while dpc is stuck for the mailbox to complete. | 1107 | * while dpc is stuck for the mailbox to complete. |
1636 | */ | 1108 | */ |
1637 | /* Blocking call-Does context switching if loop is Not Ready */ | ||
1638 | qla2x00_wait_for_loop_ready(ha); | 1109 | qla2x00_wait_for_loop_ready(ha); |
1639 | set_bit(ABORT_ISP_ACTIVE, &ha->dpc_flags); | 1110 | set_bit(ABORT_ISP_ACTIVE, &ha->dpc_flags); |
1640 | if (qla2x00_abort_isp(ha)) { | 1111 | if (qla2x00_abort_isp(ha)) { |
@@ -1643,32 +1114,22 @@ qla2xxx_eh_host_reset(struct scsi_cmnd *cmd) | |||
1643 | set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags); | 1114 | set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags); |
1644 | 1115 | ||
1645 | if (qla2x00_wait_for_hba_online(ha) != QLA_SUCCESS) | 1116 | if (qla2x00_wait_for_hba_online(ha) != QLA_SUCCESS) |
1646 | goto board_disabled; | 1117 | goto eh_host_reset_lock; |
1647 | } | 1118 | } |
1648 | |||
1649 | clear_bit(ABORT_ISP_ACTIVE, &ha->dpc_flags); | 1119 | clear_bit(ABORT_ISP_ACTIVE, &ha->dpc_flags); |
1650 | 1120 | ||
1651 | spin_lock_irq(ha->host->host_lock); | ||
1652 | if (rval == FAILED) | ||
1653 | goto out; | ||
1654 | |||
1655 | /* Waiting for our command in done_queue to be returned to OS.*/ | 1121 | /* Waiting for our command in done_queue to be returned to OS.*/ |
1656 | if (!qla2x00_eh_wait_for_pending_commands(ha)) | 1122 | if (qla2x00_eh_wait_for_pending_commands(ha)) |
1657 | rval = FAILED; | 1123 | ret = SUCCESS; |
1658 | |||
1659 | out: | ||
1660 | qla_printk(KERN_INFO, ha, "%s: reset %s\n", __func__, | ||
1661 | (rval == FAILED) ? "failed" : "succeded"); | ||
1662 | |||
1663 | return rval; | ||
1664 | 1124 | ||
1665 | board_disabled: | 1125 | eh_host_reset_lock: |
1666 | spin_lock_irq(ha->host->host_lock); | 1126 | spin_lock_irq(ha->host->host_lock); |
1667 | 1127 | ||
1668 | qla_printk(KERN_INFO, ha, "%s: failed:board disabled\n", __func__); | 1128 | qla_printk(KERN_INFO, ha, "%s: reset %s\n", __func__, |
1669 | return FAILED; | 1129 | (ret == FAILED) ? "failed" : "succeded"); |
1670 | } | ||
1671 | 1130 | ||
1131 | return ret; | ||
1132 | } | ||
1672 | 1133 | ||
1673 | /* | 1134 | /* |
1674 | * qla2x00_loop_reset | 1135 | * qla2x00_loop_reset |
@@ -1752,41 +1213,38 @@ qla2x00_device_reset(scsi_qla_host_t *ha, fc_port_t *reset_fcport) | |||
1752 | return qla2x00_abort_target(reset_fcport); | 1213 | return qla2x00_abort_target(reset_fcport); |
1753 | } | 1214 | } |
1754 | 1215 | ||
1755 | /************************************************************************** | 1216 | static int |
1756 | * qla2xxx_slave_configure | 1217 | qla2xxx_slave_alloc(struct scsi_device *sdev) |
1757 | * | ||
1758 | * Description: | ||
1759 | **************************************************************************/ | ||
1760 | int | ||
1761 | qla2xxx_slave_configure(struct scsi_device *sdev) | ||
1762 | { | 1218 | { |
1763 | scsi_qla_host_t *ha = to_qla_host(sdev->host); | 1219 | scsi_qla_host_t *ha = to_qla_host(sdev->host); |
1764 | int queue_depth; | 1220 | os_tgt_t *tq; |
1765 | 1221 | ||
1766 | if (IS_QLA2100(ha) || IS_QLA2200(ha)) | 1222 | tq = (os_tgt_t *) TGT_Q(ha, sdev->id); |
1767 | queue_depth = 16; | 1223 | if (!tq) |
1768 | else | 1224 | return -ENXIO; |
1769 | queue_depth = 32; | 1225 | if (!tq->fcport) |
1226 | return -ENXIO; | ||
1770 | 1227 | ||
1771 | if (sdev->tagged_supported) { | 1228 | sdev->hostdata = tq; |
1772 | if (ql2xmaxqdepth != 0 && ql2xmaxqdepth <= 0xffffU) | ||
1773 | queue_depth = ql2xmaxqdepth; | ||
1774 | 1229 | ||
1775 | ql2xmaxqdepth = queue_depth; | 1230 | return 0; |
1231 | } | ||
1776 | 1232 | ||
1777 | scsi_activate_tcq(sdev, queue_depth); | 1233 | static int |
1234 | qla2xxx_slave_configure(struct scsi_device *sdev) | ||
1235 | { | ||
1236 | if (sdev->tagged_supported) | ||
1237 | scsi_activate_tcq(sdev, 32); | ||
1238 | else | ||
1239 | scsi_deactivate_tcq(sdev, 32); | ||
1778 | 1240 | ||
1779 | qla_printk(KERN_INFO, ha, | 1241 | return 0; |
1780 | "scsi(%d:%d:%d:%d): Enabled tagged queuing, queue " | 1242 | } |
1781 | "depth %d.\n", | ||
1782 | sdev->host->host_no, sdev->channel, sdev->id, sdev->lun, | ||
1783 | sdev->queue_depth); | ||
1784 | } else { | ||
1785 | scsi_adjust_queue_depth(sdev, 0 /* TCQ off */, | ||
1786 | sdev->host->hostt->cmd_per_lun /* 3 */); | ||
1787 | } | ||
1788 | 1243 | ||
1789 | return (0); | 1244 | static void |
1245 | qla2xxx_slave_destroy(struct scsi_device *sdev) | ||
1246 | { | ||
1247 | sdev->hostdata = NULL; | ||
1790 | } | 1248 | } |
1791 | 1249 | ||
1792 | /** | 1250 | /** |
@@ -1993,10 +1451,6 @@ int qla2x00_probe_one(struct pci_dev *pdev, struct qla_board_info *brd_info) | |||
1993 | INIT_LIST_HEAD(&ha->list); | 1451 | INIT_LIST_HEAD(&ha->list); |
1994 | INIT_LIST_HEAD(&ha->fcports); | 1452 | INIT_LIST_HEAD(&ha->fcports); |
1995 | INIT_LIST_HEAD(&ha->rscn_fcports); | 1453 | INIT_LIST_HEAD(&ha->rscn_fcports); |
1996 | INIT_LIST_HEAD(&ha->done_queue); | ||
1997 | INIT_LIST_HEAD(&ha->retry_queue); | ||
1998 | INIT_LIST_HEAD(&ha->scsi_retry_queue); | ||
1999 | INIT_LIST_HEAD(&ha->pending_queue); | ||
2000 | 1454 | ||
2001 | /* | 1455 | /* |
2002 | * These locks are used to prevent more than one CPU | 1456 | * These locks are used to prevent more than one CPU |
@@ -2005,7 +1459,6 @@ int qla2x00_probe_one(struct pci_dev *pdev, struct qla_board_info *brd_info) | |||
2005 | * contention for these locks. | 1459 | * contention for these locks. |
2006 | */ | 1460 | */ |
2007 | spin_lock_init(&ha->mbx_reg_lock); | 1461 | spin_lock_init(&ha->mbx_reg_lock); |
2008 | spin_lock_init(&ha->list_lock); | ||
2009 | 1462 | ||
2010 | ha->dpc_pid = -1; | 1463 | ha->dpc_pid = -1; |
2011 | init_completion(&ha->dpc_inited); | 1464 | init_completion(&ha->dpc_inited); |
@@ -2381,13 +1834,6 @@ qla2x00_proc_info(struct Scsi_Host *shost, char *buffer, | |||
2381 | "Number of retries for empty slots = %ld\n", | 1834 | "Number of retries for empty slots = %ld\n", |
2382 | qla2x00_stats.outarray_full); | 1835 | qla2x00_stats.outarray_full); |
2383 | 1836 | ||
2384 | copy_info(&info, | ||
2385 | "Number of reqs in pending_q= %ld, retry_q= %d, " | ||
2386 | "done_q= %ld, scsi_retry_q= %d\n", | ||
2387 | ha->qthreads, ha->retry_q_cnt, | ||
2388 | ha->done_q_cnt, ha->scsi_retry_q_cnt); | ||
2389 | |||
2390 | |||
2391 | flags = (uint32_t *) &ha->flags; | 1837 | flags = (uint32_t *) &ha->flags; |
2392 | 1838 | ||
2393 | if (atomic_read(&ha->loop_state) == LOOP_DOWN) { | 1839 | if (atomic_read(&ha->loop_state) == LOOP_DOWN) { |
@@ -2631,93 +2077,6 @@ qla2x00_display_fc_names(scsi_qla_host_t *ha) | |||
2631 | } | 2077 | } |
2632 | } | 2078 | } |
2633 | 2079 | ||
2634 | /* | ||
2635 | * qla2x00_suspend_lun | ||
2636 | * Suspend lun and start port down timer | ||
2637 | * | ||
2638 | * Input: | ||
2639 | * ha = visable adapter block pointer. | ||
2640 | * lq = lun queue | ||
2641 | * cp = Scsi command pointer | ||
2642 | * time = time in seconds | ||
2643 | * count = number of times to let time expire | ||
2644 | * delay_lun = non-zero, if lun should be delayed rather than suspended | ||
2645 | * | ||
2646 | * Return: | ||
2647 | * QLA_SUCCESS -- suspended lun | ||
2648 | * QLA_FUNCTION_FAILED -- Didn't suspend lun | ||
2649 | * | ||
2650 | * Context: | ||
2651 | * Interrupt context. | ||
2652 | */ | ||
2653 | int | ||
2654 | __qla2x00_suspend_lun(scsi_qla_host_t *ha, | ||
2655 | os_lun_t *lq, int time, int count, int delay_lun) | ||
2656 | { | ||
2657 | int rval; | ||
2658 | srb_t *sp; | ||
2659 | struct list_head *list, *temp; | ||
2660 | unsigned long flags; | ||
2661 | |||
2662 | rval = QLA_SUCCESS; | ||
2663 | |||
2664 | /* if the lun_q is already suspended then don't do it again */ | ||
2665 | if (lq->q_state == LUN_STATE_READY ||lq->q_state == LUN_STATE_RUN) { | ||
2666 | |||
2667 | spin_lock_irqsave(&lq->q_lock, flags); | ||
2668 | if (lq->q_state == LUN_STATE_READY) { | ||
2669 | lq->q_max = count; | ||
2670 | lq->q_count = 0; | ||
2671 | } | ||
2672 | /* Set the suspend time usually 6 secs */ | ||
2673 | atomic_set(&lq->q_timer, time); | ||
2674 | |||
2675 | /* now suspend the lun */ | ||
2676 | lq->q_state = LUN_STATE_WAIT; | ||
2677 | |||
2678 | if (delay_lun) { | ||
2679 | set_bit(LUN_EXEC_DELAYED, &lq->q_flag); | ||
2680 | DEBUG(printk(KERN_INFO | ||
2681 | "scsi(%ld): Delay lun execution for %d secs, " | ||
2682 | "count=%d, max count=%d, state=%d\n", | ||
2683 | ha->host_no, | ||
2684 | time, | ||
2685 | lq->q_count, lq->q_max, lq->q_state)); | ||
2686 | } else { | ||
2687 | DEBUG(printk(KERN_INFO | ||
2688 | "scsi(%ld): Suspend lun for %d secs, count=%d, " | ||
2689 | "max count=%d, state=%d\n", | ||
2690 | ha->host_no, | ||
2691 | time, | ||
2692 | lq->q_count, lq->q_max, lq->q_state)); | ||
2693 | } | ||
2694 | spin_unlock_irqrestore(&lq->q_lock, flags); | ||
2695 | |||
2696 | /* | ||
2697 | * Remove all pending commands from request queue and put them | ||
2698 | * in the scsi_retry queue. | ||
2699 | */ | ||
2700 | spin_lock_irqsave(&ha->list_lock, flags); | ||
2701 | list_for_each_safe(list, temp, &ha->pending_queue) { | ||
2702 | sp = list_entry(list, srb_t, list); | ||
2703 | if (sp->lun_queue != lq) | ||
2704 | continue; | ||
2705 | |||
2706 | __del_from_pending_queue(ha, sp); | ||
2707 | |||
2708 | if (sp->cmd->allowed < count) | ||
2709 | sp->cmd->allowed = count; | ||
2710 | __add_to_scsi_retry_queue(ha, sp); | ||
2711 | |||
2712 | } /* list_for_each_safe */ | ||
2713 | spin_unlock_irqrestore(&ha->list_lock, flags); | ||
2714 | rval = QLA_SUCCESS; | ||
2715 | } else { | ||
2716 | rval = QLA_FUNCTION_FAILED; | ||
2717 | } | ||
2718 | |||
2719 | return (rval); | ||
2720 | } | ||
2721 | 2080 | ||
2722 | /* | 2081 | /* |
2723 | * qla2x00_mark_device_lost Updates fcport state when device goes offline. | 2082 | * qla2x00_mark_device_lost Updates fcport state when device goes offline. |
@@ -3188,16 +2547,8 @@ qla2x00_do_dpc(void *data) | |||
3188 | DECLARE_MUTEX_LOCKED(sem); | 2547 | DECLARE_MUTEX_LOCKED(sem); |
3189 | scsi_qla_host_t *ha; | 2548 | scsi_qla_host_t *ha; |
3190 | fc_port_t *fcport; | 2549 | fc_port_t *fcport; |
3191 | os_lun_t *q; | ||
3192 | srb_t *sp; | ||
3193 | uint8_t status; | 2550 | uint8_t status; |
3194 | unsigned long flags = 0; | ||
3195 | struct list_head *list, *templist; | ||
3196 | int dead_cnt, online_cnt; | ||
3197 | int retry_cmds = 0; | ||
3198 | uint16_t next_loopid; | 2551 | uint16_t next_loopid; |
3199 | int t; | ||
3200 | os_tgt_t *tq; | ||
3201 | 2552 | ||
3202 | ha = (scsi_qla_host_t *)data; | 2553 | ha = (scsi_qla_host_t *)data; |
3203 | 2554 | ||
@@ -3233,139 +2584,7 @@ qla2x00_do_dpc(void *data) | |||
3233 | 2584 | ||
3234 | ha->dpc_active = 1; | 2585 | ha->dpc_active = 1; |
3235 | 2586 | ||
3236 | if (!list_empty(&ha->done_queue)) | ||
3237 | qla2x00_done(ha); | ||
3238 | |||
3239 | /* Process commands in retry queue */ | ||
3240 | if (test_and_clear_bit(PORT_RESTART_NEEDED, &ha->dpc_flags)) { | ||
3241 | DEBUG(printk("scsi(%ld): DPC checking retry_q. " | ||
3242 | "total=%d\n", | ||
3243 | ha->host_no, ha->retry_q_cnt)); | ||
3244 | |||
3245 | spin_lock_irqsave(&ha->list_lock, flags); | ||
3246 | dead_cnt = online_cnt = 0; | ||
3247 | list_for_each_safe(list, templist, &ha->retry_queue) { | ||
3248 | sp = list_entry(list, srb_t, list); | ||
3249 | q = sp->lun_queue; | ||
3250 | DEBUG3(printk("scsi(%ld): pid=%ld sp=%p, " | ||
3251 | "spflags=0x%x, q_flag= 0x%lx\n", | ||
3252 | ha->host_no, sp->cmd->serial_number, sp, | ||
3253 | sp->flags, q->q_flag)); | ||
3254 | |||
3255 | if (q == NULL) | ||
3256 | continue; | ||
3257 | fcport = q->fclun->fcport; | ||
3258 | |||
3259 | if (atomic_read(&fcport->state) == | ||
3260 | FCS_DEVICE_DEAD || | ||
3261 | atomic_read(&fcport->ha->loop_state) == LOOP_DEAD) { | ||
3262 | |||
3263 | __del_from_retry_queue(ha, sp); | ||
3264 | sp->cmd->result = DID_NO_CONNECT << 16; | ||
3265 | if (atomic_read(&fcport->ha->loop_state) == | ||
3266 | LOOP_DOWN) | ||
3267 | sp->err_id = SRB_ERR_LOOP; | ||
3268 | else | ||
3269 | sp->err_id = SRB_ERR_PORT; | ||
3270 | sp->cmd->host_scribble = | ||
3271 | (unsigned char *) NULL; | ||
3272 | __add_to_done_queue(ha, sp); | ||
3273 | dead_cnt++; | ||
3274 | } else if (atomic_read(&fcport->state) != | ||
3275 | FCS_DEVICE_LOST) { | ||
3276 | |||
3277 | __del_from_retry_queue(ha, sp); | ||
3278 | sp->cmd->result = DID_BUS_BUSY << 16; | ||
3279 | sp->cmd->host_scribble = | ||
3280 | (unsigned char *) NULL; | ||
3281 | __add_to_done_queue(ha, sp); | ||
3282 | online_cnt++; | ||
3283 | } | ||
3284 | } /* list_for_each_safe() */ | ||
3285 | spin_unlock_irqrestore(&ha->list_lock, flags); | ||
3286 | |||
3287 | DEBUG(printk("scsi(%ld): done processing retry queue " | ||
3288 | "- dead=%d, online=%d\n ", | ||
3289 | ha->host_no, dead_cnt, online_cnt)); | ||
3290 | } | ||
3291 | |||
3292 | /* Process commands in scsi retry queue */ | ||
3293 | if (test_and_clear_bit(SCSI_RESTART_NEEDED, &ha->dpc_flags)) { | ||
3294 | /* | ||
3295 | * Any requests we want to delay for some period is put | ||
3296 | * in the scsi retry queue with a delay added. The | ||
3297 | * timer will schedule a "scsi_restart_needed" every | ||
3298 | * second as long as there are requests in the scsi | ||
3299 | * queue. | ||
3300 | */ | ||
3301 | DEBUG(printk("scsi(%ld): DPC checking scsi " | ||
3302 | "retry_q.total=%d\n", | ||
3303 | ha->host_no, ha->scsi_retry_q_cnt)); | ||
3304 | |||
3305 | online_cnt = 0; | ||
3306 | spin_lock_irqsave(&ha->list_lock, flags); | ||
3307 | list_for_each_safe(list, templist, | ||
3308 | &ha->scsi_retry_queue) { | ||
3309 | |||
3310 | sp = list_entry(list, srb_t, list); | ||
3311 | q = sp->lun_queue; | ||
3312 | tq = sp->tgt_queue; | ||
3313 | |||
3314 | DEBUG3(printk("scsi(%ld): scsi_retry_q: " | ||
3315 | "pid=%ld sp=%p, spflags=0x%x, " | ||
3316 | "q_flag= 0x%lx,q_state=%d\n", | ||
3317 | ha->host_no, sp->cmd->serial_number, | ||
3318 | sp, sp->flags, q->q_flag, q->q_state)); | ||
3319 | |||
3320 | /* Was this lun suspended */ | ||
3321 | if (q->q_state != LUN_STATE_WAIT) { | ||
3322 | online_cnt++; | ||
3323 | __del_from_scsi_retry_queue(ha, sp); | ||
3324 | |||
3325 | if (test_bit(TQF_RETRY_CMDS, | ||
3326 | &tq->flags)) { | ||
3327 | qla2x00_extend_timeout(sp->cmd, | ||
3328 | (sp->cmd->timeout_per_command / HZ) - QLA_CMD_TIMER_DELTA); | ||
3329 | __add_to_pending_queue(ha, sp); | ||
3330 | retry_cmds++; | ||
3331 | } else | ||
3332 | __add_to_retry_queue(ha, sp); | ||
3333 | } | ||
3334 | |||
3335 | /* Was this command suspended for N secs */ | ||
3336 | if (sp->delay != 0) { | ||
3337 | sp->delay--; | ||
3338 | if (sp->delay == 0) { | ||
3339 | online_cnt++; | ||
3340 | __del_from_scsi_retry_queue( | ||
3341 | ha, sp); | ||
3342 | __add_to_retry_queue(ha,sp); | ||
3343 | } | ||
3344 | } | ||
3345 | } | ||
3346 | spin_unlock_irqrestore(&ha->list_lock, flags); | ||
3347 | |||
3348 | /* Clear all Target Unsuspended bits */ | ||
3349 | for (t = 0; t < ha->max_targets; t++) { | ||
3350 | if ((tq = ha->otgt[t]) == NULL) | ||
3351 | continue; | ||
3352 | |||
3353 | if (test_bit(TQF_RETRY_CMDS, &tq->flags)) | ||
3354 | clear_bit(TQF_RETRY_CMDS, &tq->flags); | ||
3355 | } | ||
3356 | if (retry_cmds) | ||
3357 | qla2x00_next(ha); | ||
3358 | |||
3359 | DEBUG(if (online_cnt > 0)) | ||
3360 | DEBUG(printk("scsi(%ld): dpc() found scsi reqs to " | ||
3361 | "restart= %d\n", | ||
3362 | ha->host_no, online_cnt)); | ||
3363 | } | ||
3364 | |||
3365 | if (ha->flags.mbox_busy) { | 2587 | if (ha->flags.mbox_busy) { |
3366 | if (!list_empty(&ha->done_queue)) | ||
3367 | qla2x00_done(ha); | ||
3368 | |||
3369 | ha->dpc_active = 0; | 2588 | ha->dpc_active = 0; |
3370 | continue; | 2589 | continue; |
3371 | } | 2590 | } |
@@ -3493,28 +2712,6 @@ qla2x00_do_dpc(void *data) | |||
3493 | ha->host_no)); | 2712 | ha->host_no)); |
3494 | } | 2713 | } |
3495 | 2714 | ||
3496 | |||
3497 | if (test_bit(RESTART_QUEUES_NEEDED, &ha->dpc_flags)) { | ||
3498 | DEBUG(printk("scsi(%ld): qla2x00_restart_queues()\n", | ||
3499 | ha->host_no)); | ||
3500 | |||
3501 | qla2x00_restart_queues(ha, 0); | ||
3502 | |||
3503 | DEBUG(printk("scsi(%ld): qla2x00_restart_queues - end\n", | ||
3504 | ha->host_no)); | ||
3505 | } | ||
3506 | |||
3507 | if (test_bit(ABORT_QUEUES_NEEDED, &ha->dpc_flags)) { | ||
3508 | |||
3509 | DEBUG(printk("scsi(%ld): qla2x00_abort_queues()\n", | ||
3510 | ha->host_no)); | ||
3511 | |||
3512 | qla2x00_abort_queues(ha, 0); | ||
3513 | |||
3514 | DEBUG(printk("scsi(%ld): qla2x00_abort_queues - end\n", | ||
3515 | ha->host_no)); | ||
3516 | } | ||
3517 | |||
3518 | if (test_and_clear_bit(FCPORT_RESCAN_NEEDED, &ha->dpc_flags)) { | 2715 | if (test_and_clear_bit(FCPORT_RESCAN_NEEDED, &ha->dpc_flags)) { |
3519 | 2716 | ||
3520 | DEBUG(printk("scsi(%ld): Rescan flagged fcports...\n", | 2717 | DEBUG(printk("scsi(%ld): Rescan flagged fcports...\n", |
@@ -3527,13 +2724,9 @@ qla2x00_do_dpc(void *data) | |||
3527 | ha->host_no)); | 2724 | ha->host_no)); |
3528 | } | 2725 | } |
3529 | 2726 | ||
3530 | |||
3531 | if (!ha->interrupts_on) | 2727 | if (!ha->interrupts_on) |
3532 | qla2x00_enable_intrs(ha); | 2728 | qla2x00_enable_intrs(ha); |
3533 | 2729 | ||
3534 | if (!list_empty(&ha->done_queue)) | ||
3535 | qla2x00_done(ha); | ||
3536 | |||
3537 | ha->dpc_active = 0; | 2730 | ha->dpc_active = 0; |
3538 | } /* End of while(1) */ | 2731 | } /* End of while(1) */ |
3539 | 2732 | ||
@@ -3549,45 +2742,6 @@ qla2x00_do_dpc(void *data) | |||
3549 | } | 2742 | } |
3550 | 2743 | ||
3551 | /* | 2744 | /* |
3552 | * qla2x00_abort_queues | ||
3553 | * Abort all commands on queues on device | ||
3554 | * | ||
3555 | * Input: | ||
3556 | * ha = adapter block pointer. | ||
3557 | * | ||
3558 | * Context: | ||
3559 | * Interrupt context. | ||
3560 | */ | ||
3561 | void | ||
3562 | qla2x00_abort_queues(scsi_qla_host_t *ha, uint8_t doneqflg) | ||
3563 | { | ||
3564 | |||
3565 | srb_t *sp; | ||
3566 | struct list_head *list, *temp; | ||
3567 | unsigned long flags; | ||
3568 | |||
3569 | clear_bit(ABORT_QUEUES_NEEDED, &ha->dpc_flags); | ||
3570 | |||
3571 | /* Return all commands device queues. */ | ||
3572 | spin_lock_irqsave(&ha->list_lock,flags); | ||
3573 | list_for_each_safe(list, temp, &ha->pending_queue) { | ||
3574 | sp = list_entry(list, srb_t, list); | ||
3575 | |||
3576 | if (sp->flags & SRB_ABORTED) | ||
3577 | continue; | ||
3578 | |||
3579 | /* Remove srb from LUN queue. */ | ||
3580 | __del_from_pending_queue(ha, sp); | ||
3581 | |||
3582 | /* Set ending status. */ | ||
3583 | sp->cmd->result = DID_BUS_BUSY << 16; | ||
3584 | |||
3585 | __add_to_done_queue(ha, sp); | ||
3586 | } | ||
3587 | spin_unlock_irqrestore(&ha->list_lock, flags); | ||
3588 | } | ||
3589 | |||
3590 | /* | ||
3591 | * qla2x00_rst_aen | 2745 | * qla2x00_rst_aen |
3592 | * Processes asynchronous reset. | 2746 | * Processes asynchronous reset. |
3593 | * | 2747 | * |
@@ -3632,6 +2786,36 @@ qla2x00_get_new_sp(scsi_qla_host_t *ha) | |||
3632 | return (sp); | 2786 | return (sp); |
3633 | } | 2787 | } |
3634 | 2788 | ||
2789 | static void | ||
2790 | qla2x00_sp_free_dma(scsi_qla_host_t *ha, srb_t *sp) | ||
2791 | { | ||
2792 | struct scsi_cmnd *cmd = sp->cmd; | ||
2793 | |||
2794 | if (sp->flags & SRB_DMA_VALID) { | ||
2795 | if (cmd->use_sg) { | ||
2796 | dma_unmap_sg(&ha->pdev->dev, cmd->request_buffer, | ||
2797 | cmd->use_sg, cmd->sc_data_direction); | ||
2798 | } else if (cmd->request_bufflen) { | ||
2799 | dma_unmap_single(&ha->pdev->dev, sp->dma_handle, | ||
2800 | cmd->request_bufflen, cmd->sc_data_direction); | ||
2801 | } | ||
2802 | sp->flags &= ~SRB_DMA_VALID; | ||
2803 | } | ||
2804 | } | ||
2805 | |||
2806 | void | ||
2807 | qla2x00_sp_compl(scsi_qla_host_t *ha, srb_t *sp) | ||
2808 | { | ||
2809 | struct scsi_cmnd *cmd = sp->cmd; | ||
2810 | |||
2811 | qla2x00_sp_free_dma(ha, sp); | ||
2812 | |||
2813 | CMD_SP(cmd) = NULL; | ||
2814 | mempool_free(sp, ha->srb_mempool); | ||
2815 | |||
2816 | cmd->scsi_done(cmd); | ||
2817 | } | ||
2818 | |||
3635 | /************************************************************************** | 2819 | /************************************************************************** |
3636 | * qla2x00_timer | 2820 | * qla2x00_timer |
3637 | * | 2821 | * |
@@ -3643,30 +2827,12 @@ qla2x00_get_new_sp(scsi_qla_host_t *ha) | |||
3643 | static void | 2827 | static void |
3644 | qla2x00_timer(scsi_qla_host_t *ha) | 2828 | qla2x00_timer(scsi_qla_host_t *ha) |
3645 | { | 2829 | { |
3646 | int t,l; | ||
3647 | unsigned long cpu_flags = 0; | 2830 | unsigned long cpu_flags = 0; |
3648 | fc_port_t *fcport; | 2831 | fc_port_t *fcport; |
3649 | os_lun_t *lq; | ||
3650 | os_tgt_t *tq; | ||
3651 | int start_dpc = 0; | 2832 | int start_dpc = 0; |
3652 | int index; | 2833 | int index; |
3653 | srb_t *sp; | 2834 | srb_t *sp; |
3654 | 2835 | int t; | |
3655 | /* | ||
3656 | * We try and restart any request in the retry queue every second. | ||
3657 | */ | ||
3658 | if (!list_empty(&ha->retry_queue)) { | ||
3659 | set_bit(PORT_RESTART_NEEDED, &ha->dpc_flags); | ||
3660 | start_dpc++; | ||
3661 | } | ||
3662 | |||
3663 | /* | ||
3664 | * We try and restart any request in the scsi_retry queue every second. | ||
3665 | */ | ||
3666 | if (!list_empty(&ha->scsi_retry_queue)) { | ||
3667 | set_bit(SCSI_RESTART_NEEDED, &ha->dpc_flags); | ||
3668 | start_dpc++; | ||
3669 | } | ||
3670 | 2836 | ||
3671 | /* | 2837 | /* |
3672 | * Ports - Port down timer. | 2838 | * Ports - Port down timer. |
@@ -3696,59 +2862,6 @@ qla2x00_timer(scsi_qla_host_t *ha) | |||
3696 | t++; | 2862 | t++; |
3697 | } /* End of for fcport */ | 2863 | } /* End of for fcport */ |
3698 | 2864 | ||
3699 | /* | ||
3700 | * LUNS - lun suspend timer. | ||
3701 | * | ||
3702 | * Whenever, a lun is suspended the timer starts decrementing its | ||
3703 | * suspend timer every second until it reaches zero. Once it reaches | ||
3704 | * zero the lun retry count is decremented. | ||
3705 | */ | ||
3706 | |||
3707 | /* | ||
3708 | * FIXME(dg) - Need to convert this linear search of luns into a search | ||
3709 | * of a list of suspended luns. | ||
3710 | */ | ||
3711 | for (t = 0; t < ha->max_targets; t++) { | ||
3712 | if ((tq = ha->otgt[t]) == NULL) | ||
3713 | continue; | ||
3714 | |||
3715 | for (l = 0; l < ha->max_luns; l++) { | ||
3716 | if ((lq = (os_lun_t *) tq->olun[l]) == NULL) | ||
3717 | continue; | ||
3718 | |||
3719 | spin_lock_irqsave(&lq->q_lock, cpu_flags); | ||
3720 | if (lq->q_state == LUN_STATE_WAIT && | ||
3721 | atomic_read(&lq->q_timer) != 0) { | ||
3722 | |||
3723 | if (atomic_dec_and_test(&lq->q_timer) != 0) { | ||
3724 | /* | ||
3725 | * A delay should immediately | ||
3726 | * transition to a READY state | ||
3727 | */ | ||
3728 | if (test_and_clear_bit(LUN_EXEC_DELAYED, | ||
3729 | &lq->q_flag)) { | ||
3730 | lq->q_state = LUN_STATE_READY; | ||
3731 | } | ||
3732 | else { | ||
3733 | lq->q_count++; | ||
3734 | if (lq->q_count == lq->q_max) | ||
3735 | lq->q_state = | ||
3736 | LUN_STATE_TIMEOUT; | ||
3737 | else | ||
3738 | lq->q_state = | ||
3739 | LUN_STATE_RUN; | ||
3740 | } | ||
3741 | } | ||
3742 | DEBUG3(printk("scsi(%ld): lun%d - timer %d, " | ||
3743 | "count=%d, max=%d, state=%d\n", | ||
3744 | ha->host_no, | ||
3745 | l, | ||
3746 | atomic_read(&lq->q_timer), | ||
3747 | lq->q_count, lq->q_max, lq->q_state)); | ||
3748 | } | ||
3749 | spin_unlock_irqrestore(&lq->q_lock, cpu_flags); | ||
3750 | } /* End of for luns */ | ||
3751 | } /* End of for targets */ | ||
3752 | 2865 | ||
3753 | /* Loop down handler. */ | 2866 | /* Loop down handler. */ |
3754 | if (atomic_read(&ha->loop_down_timer) > 0 && | 2867 | if (atomic_read(&ha->loop_down_timer) > 0 && |
@@ -3808,19 +2921,12 @@ qla2x00_timer(scsi_qla_host_t *ha) | |||
3808 | atomic_read(&ha->loop_down_timer))); | 2921 | atomic_read(&ha->loop_down_timer))); |
3809 | } | 2922 | } |
3810 | 2923 | ||
3811 | /* | ||
3812 | * Done Q Handler -- dgFIXME This handler will kick off doneq if we | ||
3813 | * haven't process it in 2 seconds. | ||
3814 | */ | ||
3815 | if (!list_empty(&ha->done_queue)) | ||
3816 | qla2x00_done(ha); | ||
3817 | |||
3818 | |||
3819 | /* Schedule the DPC routine if needed */ | 2924 | /* Schedule the DPC routine if needed */ |
3820 | if ((test_bit(ISP_ABORT_NEEDED, &ha->dpc_flags) || | 2925 | if ((test_bit(ISP_ABORT_NEEDED, &ha->dpc_flags) || |
3821 | test_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags) || | 2926 | test_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags) || |
3822 | start_dpc || | 2927 | start_dpc || |
3823 | test_bit(LOGIN_RETRY_NEEDED, &ha->dpc_flags) || | 2928 | test_bit(LOGIN_RETRY_NEEDED, &ha->dpc_flags) || |
2929 | test_bit(RESET_MARKER_NEEDED, &ha->dpc_flags) || | ||
3824 | test_bit(RELOGIN_NEEDED, &ha->dpc_flags)) && | 2930 | test_bit(RELOGIN_NEEDED, &ha->dpc_flags)) && |
3825 | ha->dpc_wait && !ha->dpc_active) { | 2931 | ha->dpc_wait && !ha->dpc_active) { |
3826 | 2932 | ||
@@ -3830,496 +2936,6 @@ qla2x00_timer(scsi_qla_host_t *ha) | |||
3830 | qla2x00_restart_timer(ha, WATCH_INTERVAL); | 2936 | qla2x00_restart_timer(ha, WATCH_INTERVAL); |
3831 | } | 2937 | } |
3832 | 2938 | ||
3833 | /* | ||
3834 | * qla2x00_extend_timeout | ||
3835 | * This routine will extend the timeout to the specified value. | ||
3836 | * | ||
3837 | * Input: | ||
3838 | * cmd = SCSI command structure | ||
3839 | * | ||
3840 | * Returns: | ||
3841 | * None. | ||
3842 | */ | ||
3843 | void | ||
3844 | qla2x00_extend_timeout(struct scsi_cmnd *cmd, int timeout) | ||
3845 | { | ||
3846 | srb_t *sp = (srb_t *) CMD_SP(cmd); | ||
3847 | u_long our_jiffies = (timeout * HZ) + jiffies; | ||
3848 | |||
3849 | sp->ext_history= 0; | ||
3850 | sp->e_start = jiffies; | ||
3851 | if (cmd->eh_timeout.function) { | ||
3852 | mod_timer(&cmd->eh_timeout,our_jiffies); | ||
3853 | sp->ext_history |= 1; | ||
3854 | } | ||
3855 | if (sp->timer.function != NULL) { | ||
3856 | /* | ||
3857 | * Our internal timer should timeout before the midlayer has a | ||
3858 | * chance begin the abort process | ||
3859 | */ | ||
3860 | mod_timer(&sp->timer,our_jiffies - (QLA_CMD_TIMER_DELTA * HZ)); | ||
3861 | |||
3862 | sp->ext_history |= 2; | ||
3863 | } | ||
3864 | } | ||
3865 | |||
3866 | /************************************************************************** | ||
3867 | * qla2x00_cmd_timeout | ||
3868 | * | ||
3869 | * Description: | ||
3870 | * Handles the command if it times out in any state. | ||
3871 | * | ||
3872 | * Input: | ||
3873 | * sp - pointer to validate | ||
3874 | * | ||
3875 | * Returns: | ||
3876 | * None. | ||
3877 | * Note:Need to add the support for if( sp->state == SRB_FAILOVER_STATE). | ||
3878 | **************************************************************************/ | ||
3879 | void | ||
3880 | qla2x00_cmd_timeout(srb_t *sp) | ||
3881 | { | ||
3882 | int t, l; | ||
3883 | int processed; | ||
3884 | scsi_qla_host_t *vis_ha, *dest_ha; | ||
3885 | struct scsi_cmnd *cmd; | ||
3886 | unsigned long flags, cpu_flags; | ||
3887 | fc_port_t *fcport; | ||
3888 | |||
3889 | cmd = sp->cmd; | ||
3890 | vis_ha = (scsi_qla_host_t *)cmd->device->host->hostdata; | ||
3891 | |||
3892 | DEBUG3(printk("cmd_timeout: Entering sp->state = %x\n", sp->state)); | ||
3893 | |||
3894 | t = cmd->device->id; | ||
3895 | l = cmd->device->lun; | ||
3896 | fcport = sp->fclun->fcport; | ||
3897 | dest_ha = sp->ha; | ||
3898 | |||
3899 | /* | ||
3900 | * If IO is found either in retry Queue | ||
3901 | * OR in Lun Queue | ||
3902 | * Return this IO back to host | ||
3903 | */ | ||
3904 | spin_lock_irqsave(&vis_ha->list_lock, flags); | ||
3905 | processed = 0; | ||
3906 | if (sp->state == SRB_PENDING_STATE) { | ||
3907 | __del_from_pending_queue(vis_ha, sp); | ||
3908 | DEBUG2(printk("scsi(%ld): Found in Pending queue pid %ld, " | ||
3909 | "State = %x., fcport state=%d sjiffs=%lx njiffs=%lx\n", | ||
3910 | vis_ha->host_no, cmd->serial_number, sp->state, | ||
3911 | atomic_read(&fcport->state), sp->r_start, jiffies)); | ||
3912 | |||
3913 | /* | ||
3914 | * If FC_DEVICE is marked as dead return the cmd with | ||
3915 | * DID_NO_CONNECT status. Otherwise set the host_byte to | ||
3916 | * DID_BUS_BUSY to let the OS retry this cmd. | ||
3917 | */ | ||
3918 | if (atomic_read(&fcport->state) == FCS_DEVICE_DEAD || | ||
3919 | atomic_read(&fcport->ha->loop_state) == LOOP_DEAD) { | ||
3920 | cmd->result = DID_NO_CONNECT << 16; | ||
3921 | if (atomic_read(&fcport->ha->loop_state) == LOOP_DOWN) | ||
3922 | sp->err_id = SRB_ERR_LOOP; | ||
3923 | else | ||
3924 | sp->err_id = SRB_ERR_PORT; | ||
3925 | } else { | ||
3926 | cmd->result = DID_BUS_BUSY << 16; | ||
3927 | } | ||
3928 | __add_to_done_queue(vis_ha, sp); | ||
3929 | processed++; | ||
3930 | } | ||
3931 | spin_unlock_irqrestore(&vis_ha->list_lock, flags); | ||
3932 | |||
3933 | if (processed) { | ||
3934 | qla2x00_done(vis_ha); | ||
3935 | return; | ||
3936 | } | ||
3937 | |||
3938 | spin_lock_irqsave(&dest_ha->list_lock, flags); | ||
3939 | if ((sp->state == SRB_RETRY_STATE) || | ||
3940 | (sp->state == SRB_SCSI_RETRY_STATE)) { | ||
3941 | |||
3942 | DEBUG2(printk("scsi(%ld): Found in (Scsi) Retry queue or " | ||
3943 | "failover Q pid %ld, State = %x., fcport state=%d " | ||
3944 | "jiffies=%lx retried=%d\n", | ||
3945 | dest_ha->host_no, cmd->serial_number, sp->state, | ||
3946 | atomic_read(&fcport->state), jiffies, cmd->retries)); | ||
3947 | |||
3948 | if ((sp->state == SRB_RETRY_STATE)) { | ||
3949 | __del_from_retry_queue(dest_ha, sp); | ||
3950 | } else if ((sp->state == SRB_SCSI_RETRY_STATE)) { | ||
3951 | __del_from_scsi_retry_queue(dest_ha, sp); | ||
3952 | } | ||
3953 | |||
3954 | /* | ||
3955 | * If FC_DEVICE is marked as dead return the cmd with | ||
3956 | * DID_NO_CONNECT status. Otherwise set the host_byte to | ||
3957 | * DID_BUS_BUSY to let the OS retry this cmd. | ||
3958 | */ | ||
3959 | if ((atomic_read(&fcport->state) == FCS_DEVICE_DEAD) || | ||
3960 | atomic_read(&dest_ha->loop_state) == LOOP_DEAD) { | ||
3961 | qla2x00_extend_timeout(cmd, EXTEND_CMD_TIMEOUT); | ||
3962 | cmd->result = DID_NO_CONNECT << 16; | ||
3963 | if (atomic_read(&dest_ha->loop_state) == LOOP_DOWN) | ||
3964 | sp->err_id = SRB_ERR_LOOP; | ||
3965 | else | ||
3966 | sp->err_id = SRB_ERR_PORT; | ||
3967 | } else { | ||
3968 | cmd->result = DID_BUS_BUSY << 16; | ||
3969 | } | ||
3970 | |||
3971 | __add_to_done_queue(dest_ha, sp); | ||
3972 | processed++; | ||
3973 | } | ||
3974 | spin_unlock_irqrestore(&dest_ha->list_lock, flags); | ||
3975 | |||
3976 | if (processed) { | ||
3977 | qla2x00_done(dest_ha); | ||
3978 | return; | ||
3979 | } | ||
3980 | |||
3981 | spin_lock_irqsave(&dest_ha->list_lock, cpu_flags); | ||
3982 | if (sp->state == SRB_DONE_STATE) { | ||
3983 | /* IO in done_q -- leave it */ | ||
3984 | DEBUG(printk("scsi(%ld): Found in Done queue pid %ld sp=%p.\n", | ||
3985 | dest_ha->host_no, cmd->serial_number, sp)); | ||
3986 | } else if (sp->state == SRB_SUSPENDED_STATE) { | ||
3987 | DEBUG(printk("scsi(%ld): Found SP %p in suspended state " | ||
3988 | "- pid %ld:\n", | ||
3989 | dest_ha->host_no, sp, cmd->serial_number)); | ||
3990 | DEBUG(qla2x00_dump_buffer((uint8_t *)sp, sizeof(srb_t));) | ||
3991 | } else if (sp->state == SRB_ACTIVE_STATE) { | ||
3992 | /* | ||
3993 | * IO is with ISP find the command in our active list. | ||
3994 | */ | ||
3995 | spin_unlock_irqrestore(&dest_ha->list_lock, cpu_flags); | ||
3996 | spin_lock_irqsave(&dest_ha->hardware_lock, flags); | ||
3997 | if (sp == dest_ha->outstanding_cmds[ | ||
3998 | (unsigned long)sp->cmd->host_scribble]) { | ||
3999 | |||
4000 | DEBUG(printk("cmd_timeout: Found in ISP \n")); | ||
4001 | |||
4002 | if (sp->flags & SRB_TAPE) { | ||
4003 | /* | ||
4004 | * We cannot allow the midlayer error handler | ||
4005 | * to wakeup and begin the abort process. | ||
4006 | * Extend the timer so that the firmware can | ||
4007 | * properly return the IOCB. | ||
4008 | */ | ||
4009 | DEBUG(printk("cmd_timeout: Extending timeout " | ||
4010 | "of FCP2 tape command!\n")); | ||
4011 | qla2x00_extend_timeout(sp->cmd, | ||
4012 | EXTEND_CMD_TIMEOUT); | ||
4013 | } | ||
4014 | sp->state = SRB_ACTIVE_TIMEOUT_STATE; | ||
4015 | spin_unlock_irqrestore(&dest_ha->hardware_lock, flags); | ||
4016 | } else { | ||
4017 | spin_unlock_irqrestore(&dest_ha->hardware_lock, flags); | ||
4018 | printk(KERN_INFO | ||
4019 | "qla_cmd_timeout: State indicates it is with " | ||
4020 | "ISP, But not in active array\n"); | ||
4021 | } | ||
4022 | spin_lock_irqsave(&dest_ha->list_lock, cpu_flags); | ||
4023 | } else if (sp->state == SRB_ACTIVE_TIMEOUT_STATE) { | ||
4024 | DEBUG(printk("qla2100%ld: Found in Active timeout state" | ||
4025 | "pid %ld, State = %x., \n", | ||
4026 | dest_ha->host_no, | ||
4027 | sp->cmd->serial_number, sp->state);) | ||
4028 | } else { | ||
4029 | /* EMPTY */ | ||
4030 | DEBUG2(printk("cmd_timeout%ld: LOST command state = " | ||
4031 | "0x%x, sp=%p\n", | ||
4032 | vis_ha->host_no, sp->state,sp);) | ||
4033 | |||
4034 | qla_printk(KERN_INFO, vis_ha, | ||
4035 | "cmd_timeout: LOST command state = 0x%x\n", sp->state); | ||
4036 | } | ||
4037 | spin_unlock_irqrestore(&dest_ha->list_lock, cpu_flags); | ||
4038 | |||
4039 | DEBUG3(printk("cmd_timeout: Leaving\n");) | ||
4040 | } | ||
4041 | |||
4042 | /************************************************************************** | ||
4043 | * qla2x00_done | ||
4044 | * Process completed commands. | ||
4045 | * | ||
4046 | * Input: | ||
4047 | * old_ha = adapter block pointer. | ||
4048 | * | ||
4049 | **************************************************************************/ | ||
4050 | void | ||
4051 | qla2x00_done(scsi_qla_host_t *old_ha) | ||
4052 | { | ||
4053 | os_lun_t *lq; | ||
4054 | struct scsi_cmnd *cmd; | ||
4055 | unsigned long flags = 0; | ||
4056 | scsi_qla_host_t *ha; | ||
4057 | scsi_qla_host_t *vis_ha; | ||
4058 | int send_marker_once = 0; | ||
4059 | srb_t *sp, *sptemp; | ||
4060 | LIST_HEAD(local_sp_list); | ||
4061 | |||
4062 | /* | ||
4063 | * Get into local queue such that we do not wind up calling done queue | ||
4064 | * tasklet for the same IOs from DPC or any other place. | ||
4065 | */ | ||
4066 | spin_lock_irqsave(&old_ha->list_lock, flags); | ||
4067 | list_splice_init(&old_ha->done_queue, &local_sp_list); | ||
4068 | spin_unlock_irqrestore(&old_ha->list_lock, flags); | ||
4069 | |||
4070 | /* | ||
4071 | * All done commands are in the local queue, now do the call back. | ||
4072 | */ | ||
4073 | list_for_each_entry_safe(sp, sptemp, &local_sp_list, list) { | ||
4074 | old_ha->done_q_cnt--; | ||
4075 | sp->state = SRB_NO_QUEUE_STATE; | ||
4076 | |||
4077 | /* remove command from local list */ | ||
4078 | list_del_init(&sp->list); | ||
4079 | |||
4080 | cmd = sp->cmd; | ||
4081 | if (cmd == NULL) | ||
4082 | continue; | ||
4083 | |||
4084 | vis_ha = (scsi_qla_host_t *)cmd->device->host->hostdata; | ||
4085 | lq = sp->lun_queue; | ||
4086 | ha = sp->ha; | ||
4087 | |||
4088 | if (sp->flags & SRB_DMA_VALID) { | ||
4089 | sp->flags &= ~SRB_DMA_VALID; | ||
4090 | |||
4091 | /* Release memory used for this I/O */ | ||
4092 | if (cmd->use_sg) { | ||
4093 | pci_unmap_sg(ha->pdev, cmd->request_buffer, | ||
4094 | cmd->use_sg, cmd->sc_data_direction); | ||
4095 | } else if (cmd->request_bufflen) { | ||
4096 | pci_unmap_page(ha->pdev, sp->dma_handle, | ||
4097 | cmd->request_bufflen, | ||
4098 | cmd->sc_data_direction); | ||
4099 | } | ||
4100 | } | ||
4101 | |||
4102 | |||
4103 | switch (host_byte(cmd->result)) { | ||
4104 | case DID_OK: | ||
4105 | case DID_ERROR: | ||
4106 | break; | ||
4107 | |||
4108 | case DID_RESET: | ||
4109 | /* | ||
4110 | * Set marker needed, so we don't have to | ||
4111 | * send multiple markers | ||
4112 | */ | ||
4113 | if (!send_marker_once) { | ||
4114 | ha->marker_needed = 1; | ||
4115 | send_marker_once++; | ||
4116 | } | ||
4117 | |||
4118 | /* | ||
4119 | * WORKAROUND | ||
4120 | * | ||
4121 | * A backdoor device-reset requires different | ||
4122 | * error handling. This code differentiates | ||
4123 | * between normal error handling and the | ||
4124 | * backdoor method. | ||
4125 | * | ||
4126 | */ | ||
4127 | if (ha->host->eh_active != EH_ACTIVE) | ||
4128 | cmd->result = DID_BUS_BUSY << 16; | ||
4129 | break; | ||
4130 | |||
4131 | |||
4132 | case DID_ABORT: | ||
4133 | sp->flags &= ~SRB_ABORT_PENDING; | ||
4134 | sp->flags |= SRB_ABORTED; | ||
4135 | |||
4136 | if (sp->flags & SRB_TIMEOUT) | ||
4137 | cmd->result = DID_TIME_OUT << 16; | ||
4138 | |||
4139 | break; | ||
4140 | |||
4141 | default: | ||
4142 | DEBUG2(printk("scsi(%ld:%d:%d) %s: did_error " | ||
4143 | "= %d, comp-scsi= 0x%x-0x%x pid=%ld.\n", | ||
4144 | vis_ha->host_no, | ||
4145 | cmd->device->id, cmd->device->lun, | ||
4146 | __func__, | ||
4147 | host_byte(cmd->result), | ||
4148 | CMD_COMPL_STATUS(cmd), | ||
4149 | CMD_SCSI_STATUS(cmd), cmd->serial_number)); | ||
4150 | break; | ||
4151 | } | ||
4152 | |||
4153 | /* | ||
4154 | * Call the mid-level driver interrupt handler -- via sp_put() | ||
4155 | */ | ||
4156 | sp_put(ha, sp); | ||
4157 | } /* end of while */ | ||
4158 | } | ||
4159 | |||
4160 | /* | ||
4161 | * qla2x00_process_response_queue_in_zio_mode | ||
4162 | * Process response queue completion as fast as possible | ||
4163 | * to achieve Zero Interrupt Opertions-ZIO | ||
4164 | * | ||
4165 | * Input: | ||
4166 | * ha = adapter block pointer. | ||
4167 | * | ||
4168 | * Context: | ||
4169 | * Kernel context. | ||
4170 | */ | ||
4171 | static inline void | ||
4172 | qla2x00_process_response_queue_in_zio_mode(scsi_qla_host_t *ha) | ||
4173 | { | ||
4174 | unsigned long flags; | ||
4175 | |||
4176 | /* Check for unprocessed commands in response queue. */ | ||
4177 | if (!ha->flags.process_response_queue) | ||
4178 | return; | ||
4179 | if (!ha->flags.online) | ||
4180 | return; | ||
4181 | if (ha->response_ring_ptr->signature == RESPONSE_PROCESSED) | ||
4182 | return; | ||
4183 | |||
4184 | spin_lock_irqsave(&ha->hardware_lock,flags); | ||
4185 | qla2x00_process_response_queue(ha); | ||
4186 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | ||
4187 | } | ||
4188 | |||
4189 | /* | ||
4190 | * qla2x00_next | ||
4191 | * Retrieve and process next job in the LUN queue. | ||
4192 | * | ||
4193 | * Input: | ||
4194 | * tq = SCSI target queue pointer. | ||
4195 | * lq = SCSI LUN queue pointer. | ||
4196 | * TGT_LOCK must be already obtained. | ||
4197 | * | ||
4198 | * Output: | ||
4199 | * Releases TGT_LOCK upon exit. | ||
4200 | * | ||
4201 | * Context: | ||
4202 | * Kernel/Interrupt context. | ||
4203 | * | ||
4204 | * Note: This routine will always try to start I/O from visible HBA. | ||
4205 | */ | ||
4206 | void | ||
4207 | qla2x00_next(scsi_qla_host_t *vis_ha) | ||
4208 | { | ||
4209 | int rval; | ||
4210 | unsigned long flags; | ||
4211 | scsi_qla_host_t *dest_ha; | ||
4212 | fc_port_t *fcport; | ||
4213 | srb_t *sp, *sptemp; | ||
4214 | LIST_HEAD(local_sp_list); | ||
4215 | |||
4216 | dest_ha = NULL; | ||
4217 | |||
4218 | spin_lock_irqsave(&vis_ha->list_lock, flags); | ||
4219 | list_splice_init(&vis_ha->pending_queue, &local_sp_list); | ||
4220 | vis_ha->qthreads = 0; | ||
4221 | spin_unlock_irqrestore(&vis_ha->list_lock, flags); | ||
4222 | |||
4223 | list_for_each_entry_safe(sp, sptemp, &local_sp_list, list) { | ||
4224 | list_del_init(&sp->list); | ||
4225 | sp->state = SRB_NO_QUEUE_STATE; | ||
4226 | |||
4227 | fcport = sp->fclun->fcport; | ||
4228 | dest_ha = fcport->ha; | ||
4229 | |||
4230 | /* If device is dead then send request back to OS */ | ||
4231 | if (atomic_read(&fcport->state) == FCS_DEVICE_DEAD) { | ||
4232 | sp->cmd->result = DID_NO_CONNECT << 16; | ||
4233 | if (atomic_read(&dest_ha->loop_state) == LOOP_DOWN) | ||
4234 | sp->err_id = SRB_ERR_LOOP; | ||
4235 | else | ||
4236 | sp->err_id = SRB_ERR_PORT; | ||
4237 | |||
4238 | DEBUG3(printk("scsi(%ld): loop/port is down - pid=%ld, " | ||
4239 | "sp=%p err_id=%d loopid=0x%x queued to dest HBA " | ||
4240 | "scsi%ld.\n", dest_ha->host_no, | ||
4241 | sp->cmd->serial_number, sp, sp->err_id, | ||
4242 | fcport->loop_id, dest_ha->host_no)); | ||
4243 | /* | ||
4244 | * Initiate a failover - done routine will initiate. | ||
4245 | */ | ||
4246 | add_to_done_queue(vis_ha, sp); | ||
4247 | |||
4248 | continue; | ||
4249 | } | ||
4250 | |||
4251 | /* | ||
4252 | * SCSI Kluge: Whenever, we need to wait for an event such as | ||
4253 | * loop down (i.e. loop_down_timer ) or port down (i.e. LUN | ||
4254 | * request qeueue is suspended) then we will recycle new | ||
4255 | * commands back to the SCSI layer. We do this because this is | ||
4256 | * normally a temporary condition and we don't want the | ||
4257 | * mid-level scsi.c driver to get upset and start aborting | ||
4258 | * commands. The timeout value is extracted from the command | ||
4259 | * minus 1-second and put on a retry queue (watchdog). Once the | ||
4260 | * command timeout it is returned to the mid-level with a BUSY | ||
4261 | * status, so the mid-level will retry it. This process | ||
4262 | * continues until the LOOP DOWN time expires or the condition | ||
4263 | * goes away. | ||
4264 | */ | ||
4265 | if (!(sp->flags & (SRB_IOCTL | SRB_TAPE)) && | ||
4266 | (atomic_read(&fcport->state) != FCS_ONLINE || | ||
4267 | test_bit(ABORT_ISP_ACTIVE, &dest_ha->dpc_flags) || | ||
4268 | atomic_read(&dest_ha->loop_state) != LOOP_READY)) { | ||
4269 | |||
4270 | DEBUG3(printk("scsi(%ld): pid=%ld port=0x%x state=%d " | ||
4271 | "loop state=%d, loop counter=0x%x " | ||
4272 | "dpc_flags=0x%lx\n", sp->cmd->serial_number, | ||
4273 | dest_ha->host_no, fcport->loop_id, | ||
4274 | atomic_read(&fcport->state), | ||
4275 | atomic_read(&dest_ha->loop_state), | ||
4276 | atomic_read(&dest_ha->loop_down_timer), | ||
4277 | dest_ha->dpc_flags)); | ||
4278 | |||
4279 | qla2x00_extend_timeout(sp->cmd, EXTEND_CMD_TIMEOUT); | ||
4280 | add_to_retry_queue(vis_ha, sp); | ||
4281 | |||
4282 | continue; | ||
4283 | } | ||
4284 | |||
4285 | /* | ||
4286 | * If this request's lun is suspended then put the request on | ||
4287 | * the scsi_retry queue. | ||
4288 | */ | ||
4289 | if (!(sp->flags & (SRB_IOCTL | SRB_TAPE)) && | ||
4290 | sp->lun_queue->q_state == LUN_STATE_WAIT) { | ||
4291 | DEBUG3(printk("scsi(%ld): lun wait state - pid=%ld, " | ||
4292 | "opcode=%d, allowed=%d, retries=%d\n", | ||
4293 | dest_ha->host_no, | ||
4294 | sp->cmd->serial_number, | ||
4295 | sp->cmd->cmnd[0], | ||
4296 | sp->cmd->allowed, | ||
4297 | sp->cmd->retries)); | ||
4298 | |||
4299 | add_to_scsi_retry_queue(vis_ha, sp); | ||
4300 | |||
4301 | continue; | ||
4302 | } | ||
4303 | |||
4304 | sp->lun_queue->io_cnt++; | ||
4305 | |||
4306 | rval = qla2x00_start_scsi(sp); | ||
4307 | if (rval != QLA_SUCCESS) { | ||
4308 | /* Place request back on top of device queue */ | ||
4309 | /* add to the top of queue */ | ||
4310 | add_to_pending_queue_head(vis_ha, sp); | ||
4311 | |||
4312 | sp->lun_queue->io_cnt--; | ||
4313 | } | ||
4314 | } | ||
4315 | |||
4316 | if (!IS_QLA2100(vis_ha) && !IS_QLA2200(vis_ha)) { | ||
4317 | /* Process response_queue if ZIO support is enabled*/ | ||
4318 | qla2x00_process_response_queue_in_zio_mode(vis_ha); | ||
4319 | |||
4320 | } | ||
4321 | } | ||
4322 | |||
4323 | /* XXX(hch): crude hack to emulate a down_timeout() */ | 2939 | /* XXX(hch): crude hack to emulate a down_timeout() */ |
4324 | int | 2940 | int |
4325 | qla2x00_down_timeout(struct semaphore *sema, unsigned long timeout) | 2941 | qla2x00_down_timeout(struct semaphore *sema, unsigned long timeout) |