[SCSI] qla2xxx: fix bad locking during eh_abort


Correct incorrect locking order in qla2xxx_eh_abort() handler which
would case a hang during certain code-paths.

With extra pieces to fix the irq state in the locks.

Signed-off-by: Andrew Vasquez <andrew.vasquez@qlogic.com>
Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>

authored by Andrew Vasquez and committed by James Bottomley 18e144d3 cdbbde14

+13 -11
+13 -11
drivers/scsi/qla2xxx/qla_os.c
··· 507 507 int ret, i; 508 508 unsigned int id, lun; 509 509 unsigned long serial; 510 + unsigned long flags; 510 511 511 512 if (!CMD_SP(cmd)) 512 513 return FAILED; ··· 520 519 521 520 /* Check active list for command command. */ 522 521 spin_unlock_irq(ha->host->host_lock); 523 - spin_lock(&ha->hardware_lock); 522 + spin_lock_irqsave(&ha->hardware_lock, flags); 524 523 for (i = 1; i < MAX_OUTSTANDING_COMMANDS; i++) { 525 524 sp = ha->outstanding_cmds[i]; 526 525 ··· 535 534 sp->state)); 536 535 DEBUG3(qla2x00_print_scsi_cmd(cmd);) 537 536 538 - spin_unlock(&ha->hardware_lock); 537 + spin_unlock_irqrestore(&ha->hardware_lock, flags); 539 538 if (qla2x00_abort_command(ha, sp)) { 540 539 DEBUG2(printk("%s(%ld): abort_command " 541 540 "mbx failed.\n", __func__, ha->host_no)); ··· 544 543 "mbx success.\n", __func__, ha->host_no)); 545 544 ret = SUCCESS; 546 545 } 547 - spin_lock(&ha->hardware_lock); 546 + spin_lock_irqsave(&ha->hardware_lock, flags); 548 547 549 548 break; 550 549 } 550 + spin_unlock_irqrestore(&ha->hardware_lock, flags); 551 551 552 552 /* Wait for the command to be returned. */ 553 553 if (ret == SUCCESS) { 554 - spin_unlock(&ha->hardware_lock); 555 554 if (qla2x00_eh_wait_on_command(ha, cmd) != QLA_SUCCESS) { 556 555 qla_printk(KERN_ERR, ha, 557 556 "scsi(%ld:%d:%d): Abort handler timed out -- %lx " 558 557 "%x.\n", ha->host_no, id, lun, serial, ret); 559 558 } 560 - spin_lock(&ha->hardware_lock); 561 559 } 562 560 spin_lock_irq(ha->host->host_lock); 563 561 ··· 588 588 int status; 589 589 srb_t *sp; 590 590 struct scsi_cmnd *cmd; 591 + unsigned long flags; 591 592 592 593 status = 0; 593 594 ··· 597 596 * array 598 597 */ 599 598 for (cnt = 1; cnt < MAX_OUTSTANDING_COMMANDS; cnt++) { 600 - spin_lock(&ha->hardware_lock); 599 + spin_lock_irqsave(&ha->hardware_lock, flags); 601 600 sp = ha->outstanding_cmds[cnt]; 602 601 if (sp) { 603 602 cmd = sp->cmd; 604 - spin_unlock(&ha->hardware_lock); 603 + spin_unlock_irqrestore(&ha->hardware_lock, flags); 605 604 if (cmd->device->id == t) { 606 605 if (!qla2x00_eh_wait_on_command(ha, cmd)) { 607 606 status = 1; ··· 609 608 } 610 609 } 611 610 } else { 612 - spin_unlock(&ha->hardware_lock); 611 + spin_unlock_irqrestore(&ha->hardware_lock, flags); 613 612 } 614 613 } 615 614 return (status); ··· 741 740 int status; 742 741 srb_t *sp; 743 742 struct scsi_cmnd *cmd; 743 + unsigned long flags; 744 744 745 745 status = 1; 746 746 ··· 750 748 * array 751 749 */ 752 750 for (cnt = 1; cnt < MAX_OUTSTANDING_COMMANDS; cnt++) { 753 - spin_lock(&ha->hardware_lock); 751 + spin_lock_irqsave(&ha->hardware_lock, flags); 754 752 sp = ha->outstanding_cmds[cnt]; 755 753 if (sp) { 756 754 cmd = sp->cmd; 757 - spin_unlock(&ha->hardware_lock); 755 + spin_unlock_irqrestore(&ha->hardware_lock, flags); 758 756 status = qla2x00_eh_wait_on_command(ha, cmd); 759 757 if (status == 0) 760 758 break; 761 759 } 762 760 else { 763 - spin_unlock(&ha->hardware_lock); 761 + spin_unlock_irqrestore(&ha->hardware_lock, flags); 764 762 } 765 763 } 766 764 return (status);