linux-bk/drivers/scsi/qla2xxx/qla_isr.c
<<
>>
Prefs
   1/*
   2 *                  QLOGIC LINUX SOFTWARE
   3 *
   4 * QLogic ISP2x00 device driver for Linux 2.6.x
   5 * Copyright (C) 2003-2004 QLogic Corporation
   6 * (www.qlogic.com)
   7 *
   8 * This program is free software; you can redistribute it and/or modify it
   9 * under the terms of the GNU General Public License as published by the
  10 * Free Software Foundation; either version 2, or (at your option) any
  11 * later version.
  12 *
  13 * This program is distributed in the hope that it will be useful, but
  14 * WITHOUT ANY WARRANTY; without even the implied warranty of
  15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  16 * General Public License for more details.
  17 *
  18 */
  19#include "qla_def.h"
  20
  21static void qla2x00_mbx_completion(scsi_qla_host_t *, uint16_t);
  22static void qla2x00_async_event(scsi_qla_host_t *, uint32_t);
  23static void qla2x00_process_completed_request(struct scsi_qla_host *, uint32_t);
  24void qla2x00_process_response_queue(struct scsi_qla_host *);
  25static void qla2x00_status_entry(scsi_qla_host_t *, sts_entry_t *);
  26static void qla2x00_status_cont_entry(scsi_qla_host_t *, sts_cont_entry_t *);
  27static void qla2x00_error_entry(scsi_qla_host_t *, sts_entry_t *);
  28static void qla2x00_ms_entry(scsi_qla_host_t *, ms_iocb_entry_t *);
  29
  30static int qla2x00_check_sense(struct scsi_cmnd *cp, os_lun_t *);
  31
  32/**
  33 * qla2100_intr_handler() - Process interrupts for the ISP2100 and ISP2200.
  34 * @irq:
  35 * @dev_id: SCSI driver HA context
  36 * @regs:
  37 *
  38 * Called by system whenever the host adapter generates an interrupt.
  39 *
  40 * Returns handled flag.
  41 */
  42irqreturn_t
  43qla2100_intr_handler(int irq, void *dev_id, struct pt_regs *regs)
  44{
  45        scsi_qla_host_t *ha;
  46        device_reg_t __iomem *reg;
  47        int             status;
  48        unsigned long   flags;
  49        unsigned long   iter;
  50        uint32_t        mbx;
  51
  52        ha = (scsi_qla_host_t *) dev_id;
  53        if (!ha) {
  54                printk(KERN_INFO
  55                    "%s(): NULL host pointer\n", __func__);
  56                return (IRQ_NONE);
  57        }
  58
  59        reg = ha->iobase;
  60        status = 0;
  61
  62        spin_lock_irqsave(&ha->hardware_lock, flags);
  63        for (iter = 50; iter--; ) {
  64                if ((RD_REG_WORD(&reg->istatus) & ISR_RISC_INT) == 0)
  65                        break;
  66
  67                if (RD_REG_WORD(&reg->semaphore) & BIT_0) {
  68                        WRT_REG_WORD(&reg->hccr, HCCR_CLR_RISC_INT);
  69                        RD_REG_WORD(&reg->hccr);
  70
  71                        /* Get mailbox data. */
  72                        mbx = RD_MAILBOX_REG(ha, reg, 0);
  73                        if (mbx > 0x3fff && mbx < 0x8000) {
  74                                qla2x00_mbx_completion(ha, (uint16_t)mbx);
  75                                status |= MBX_INTERRUPT;
  76                        } else if (mbx > 0x7fff && mbx < 0xc000) {
  77                                qla2x00_async_event(ha, mbx);
  78                        } else {
  79                                /*EMPTY*/
  80                                DEBUG2(printk("scsi(%ld): Unrecognized "
  81                                    "interrupt type (%d)\n",
  82                                    ha->host_no, mbx));
  83                        }
  84                        /* Release mailbox registers. */
  85                        WRT_REG_WORD(&reg->semaphore, 0);
  86                        RD_REG_WORD(&reg->semaphore);
  87                } else {
  88                        qla2x00_process_response_queue(ha);
  89
  90                        WRT_REG_WORD(&reg->hccr, HCCR_CLR_RISC_INT);
  91                        RD_REG_WORD(&reg->hccr);
  92                }
  93        }
  94        spin_unlock_irqrestore(&ha->hardware_lock, flags);
  95
  96        qla2x00_next(ha);
  97        ha->last_irq_cpu = _smp_processor_id();
  98        ha->total_isr_cnt++;
  99
 100        if (test_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags) &&
 101            (status & MBX_INTERRUPT) && ha->flags.mbox_int) {
 102                spin_lock_irqsave(&ha->mbx_reg_lock, flags);
 103
 104                set_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags);
 105                up(&ha->mbx_intr_sem);
 106
 107                spin_unlock_irqrestore(&ha->mbx_reg_lock, flags);
 108        }
 109
 110        if (!list_empty(&ha->done_queue))
 111                qla2x00_done(ha);
 112
 113        return (IRQ_HANDLED);
 114}
 115
 116/**
 117 * qla2300_intr_handler() - Process interrupts for the ISP23xx and ISP63xx.
 118 * @irq:
 119 * @dev_id: SCSI driver HA context
 120 * @regs:
 121 *
 122 * Called by system whenever the host adapter generates an interrupt.
 123 *
 124 * Returns handled flag.
 125 */
 126irqreturn_t
 127qla2300_intr_handler(int irq, void *dev_id, struct pt_regs *regs)
 128{
 129        scsi_qla_host_t *ha;
 130        device_reg_t __iomem *reg;
 131        int             status;
 132        unsigned long   flags;
 133        unsigned long   iter;
 134        uint32_t        stat;
 135        uint32_t        mbx;
 136        uint16_t        hccr;
 137
 138        ha = (scsi_qla_host_t *) dev_id;
 139        if (!ha) {
 140                printk(KERN_INFO
 141                    "%s(): NULL host pointer\n", __func__);
 142                return (IRQ_NONE);
 143        }
 144
 145        reg = ha->iobase;
 146        status = 0;
 147
 148        spin_lock_irqsave(&ha->hardware_lock, flags);
 149        for (iter = 50; iter--; ) {
 150                stat = RD_REG_DWORD(&reg->u.isp2300.host_status);
 151                if (stat & HSR_RISC_PAUSED) {
 152                        hccr = RD_REG_WORD(&reg->hccr);
 153                        if (hccr & (BIT_15 | BIT_13 | BIT_11 | BIT_8))
 154                                qla_printk(KERN_INFO, ha,
 155                                    "Parity error -- HCCR=%x.\n", hccr);
 156                        else
 157                                qla_printk(KERN_INFO, ha,
 158                                    "RISC paused -- HCCR=%x\n", hccr);
 159
 160                        /*
 161                         * Issue a "HARD" reset in order for the RISC
 162                         * interrupt bit to be cleared.  Schedule a big
 163                         * hammmer to get out of the RISC PAUSED state.
 164                         */
 165                        WRT_REG_WORD(&reg->hccr, HCCR_RESET_RISC);
 166                        RD_REG_WORD(&reg->hccr);
 167                        set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags);
 168                        break;
 169                } else if ((stat & HSR_RISC_INT) == 0)
 170                        break;
 171
 172                mbx = MSW(stat);
 173                switch (stat & 0xff) {
 174                case 0x13:
 175                        qla2x00_process_response_queue(ha);
 176                        break;
 177                case 0x1:
 178                case 0x2:
 179                case 0x10:
 180                case 0x11:
 181                        qla2x00_mbx_completion(ha, (uint16_t)mbx);
 182                        status |= MBX_INTERRUPT;
 183
 184                        /* Release mailbox registers. */
 185                        WRT_REG_WORD(&reg->semaphore, 0);
 186                        break;
 187                case 0x12:
 188                        qla2x00_async_event(ha, mbx);
 189                        break;
 190                case 0x15:
 191                        mbx = mbx << 16 | MBA_CMPLT_1_16BIT;
 192                        qla2x00_async_event(ha, mbx);
 193                        break;
 194                case 0x16:
 195                        mbx = mbx << 16 | MBA_SCSI_COMPLETION;
 196                        qla2x00_async_event(ha, mbx);
 197                        break;
 198                default:
 199                        DEBUG2(printk("scsi(%ld): Unrecognized interrupt type "
 200                            "(%d)\n",
 201                            ha->host_no, stat & 0xff));
 202                        break;
 203                }
 204                WRT_REG_WORD(&reg->hccr, HCCR_CLR_RISC_INT);
 205                RD_REG_WORD_RELAXED(&reg->hccr);
 206        }
 207        spin_unlock_irqrestore(&ha->hardware_lock, flags);
 208
 209        qla2x00_next(ha);
 210        ha->last_irq_cpu = _smp_processor_id();
 211        ha->total_isr_cnt++;
 212
 213        if (test_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags) &&
 214            (status & MBX_INTERRUPT) && ha->flags.mbox_int) {
 215                spin_lock_irqsave(&ha->mbx_reg_lock, flags);
 216
 217                set_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags);
 218                up(&ha->mbx_intr_sem);
 219
 220                spin_unlock_irqrestore(&ha->mbx_reg_lock, flags);
 221        }
 222
 223        if (!list_empty(&ha->done_queue))
 224                qla2x00_done(ha);
 225
 226        return (IRQ_HANDLED);
 227}
 228
 229/**
 230 * qla2x00_mbx_completion() - Process mailbox command completions.
 231 * @ha: SCSI driver HA context
 232 * @mb0: Mailbox0 register
 233 */
 234static void
 235qla2x00_mbx_completion(scsi_qla_host_t *ha, uint16_t mb0)
 236{
 237        uint16_t        cnt;
 238        uint16_t __iomem *wptr;
 239        device_reg_t __iomem *reg = ha->iobase;
 240
 241        /* Load return mailbox registers. */
 242        ha->flags.mbox_int = 1;
 243        ha->mailbox_out[0] = mb0;
 244        wptr = (uint16_t __iomem *)MAILBOX_REG(ha, reg, 1);
 245
 246        for (cnt = 1; cnt < ha->mbx_count; cnt++) {
 247                if (IS_QLA2200(ha) && cnt == 8) 
 248                        wptr = (uint16_t __iomem *)MAILBOX_REG(ha, reg, 8);
 249                if (cnt == 4 || cnt == 5)
 250                        ha->mailbox_out[cnt] = qla2x00_debounce_register(wptr);
 251                else
 252                        ha->mailbox_out[cnt] = RD_REG_WORD(wptr);
 253        
 254                wptr++;
 255        }
 256
 257        if (ha->mcp) {
 258                DEBUG3(printk("%s(%ld): Got mailbox completion. cmd=%x.\n",
 259                    __func__, ha->host_no, ha->mcp->mb[0]));
 260        } else {
 261                DEBUG2_3(printk("%s(%ld): MBX pointer ERROR!\n",
 262                    __func__, ha->host_no));
 263        }
 264}
 265
 266/**
 267 * qla2x00_async_event() - Process aynchronous events.
 268 * @ha: SCSI driver HA context
 269 * @mb0: Mailbox0 register
 270 */
 271static void
 272qla2x00_async_event(scsi_qla_host_t *ha, uint32_t mbx)
 273{
 274        static char     *link_speeds[5] = { "1", "2", "4", "?", "10" };
 275        char            *link_speed;
 276        uint16_t        mb[4];
 277        uint16_t        handle_cnt;
 278        uint16_t        cnt;
 279        uint32_t        handles[5];
 280        device_reg_t __iomem *reg = ha->iobase;
 281        uint32_t        rscn_entry, host_pid;
 282        uint8_t         rscn_queue_index;
 283
 284        /* Setup to process RIO completion. */
 285        handle_cnt = 0;
 286        mb[0] = LSW(mbx);
 287        switch (mb[0]) {
 288        case MBA_SCSI_COMPLETION:
 289                if (IS_QLA2100(ha) || IS_QLA2200(ha))
 290                        handles[0] = le32_to_cpu(
 291                            ((uint32_t)(RD_MAILBOX_REG(ha, reg, 2) << 16)) |
 292                            RD_MAILBOX_REG(ha, reg, 1));
 293                else
 294                        handles[0] = le32_to_cpu(
 295                            ((uint32_t)(RD_MAILBOX_REG(ha, reg, 2) << 16)) |
 296                            MSW(mbx));
 297                handle_cnt = 1;
 298                break;
 299        case MBA_CMPLT_1_16BIT:
 300                if (IS_QLA2100(ha) || IS_QLA2200(ha))
 301                        handles[0] = (uint32_t)RD_MAILBOX_REG(ha, reg, 1);
 302                else
 303                        handles[0] = MSW(mbx);
 304                handle_cnt = 1;
 305                mb[0] = MBA_SCSI_COMPLETION;
 306                break;
 307        case MBA_CMPLT_2_16BIT:
 308                handles[0] = (uint32_t)RD_MAILBOX_REG(ha, reg, 1);
 309                handles[1] = (uint32_t)RD_MAILBOX_REG(ha, reg, 2);
 310                handle_cnt = 2;
 311                mb[0] = MBA_SCSI_COMPLETION;
 312                break;
 313        case MBA_CMPLT_3_16BIT:
 314                handles[0] = (uint32_t)RD_MAILBOX_REG(ha, reg, 1);
 315                handles[1] = (uint32_t)RD_MAILBOX_REG(ha, reg, 2);
 316                handles[2] = (uint32_t)RD_MAILBOX_REG(ha, reg, 3);
 317                handle_cnt = 3;
 318                mb[0] = MBA_SCSI_COMPLETION;
 319                break;
 320        case MBA_CMPLT_4_16BIT:
 321                handles[0] = (uint32_t)RD_MAILBOX_REG(ha, reg, 1);
 322                handles[1] = (uint32_t)RD_MAILBOX_REG(ha, reg, 2);
 323                handles[2] = (uint32_t)RD_MAILBOX_REG(ha, reg, 3);
 324                handles[3] = (uint32_t)RD_MAILBOX_REG(ha, reg, 6);
 325                handle_cnt = 4;
 326                mb[0] = MBA_SCSI_COMPLETION;
 327                break;
 328        case MBA_CMPLT_5_16BIT:
 329                handles[0] = (uint32_t)RD_MAILBOX_REG(ha, reg, 1);
 330                handles[1] = (uint32_t)RD_MAILBOX_REG(ha, reg, 2);
 331                handles[2] = (uint32_t)RD_MAILBOX_REG(ha, reg, 3);
 332                handles[3] = (uint32_t)RD_MAILBOX_REG(ha, reg, 6);
 333                handles[4] = (uint32_t)RD_MAILBOX_REG(ha, reg, 7);
 334                handle_cnt = 5;
 335                mb[0] = MBA_SCSI_COMPLETION;
 336                break;
 337        case MBA_CMPLT_2_32BIT:
 338                handles[0] = le32_to_cpu(
 339                    ((uint32_t)(RD_MAILBOX_REG(ha, reg, 2) << 16)) |
 340                    RD_MAILBOX_REG(ha, reg, 1));
 341                handles[1] = le32_to_cpu(
 342                    ((uint32_t)(RD_MAILBOX_REG(ha, reg, 7) << 16)) |
 343                    RD_MAILBOX_REG(ha, reg, 6));
 344                handle_cnt = 2;
 345                mb[0] = MBA_SCSI_COMPLETION;
 346                break;
 347        default:
 348                break;
 349        }
 350
 351        switch (mb[0]) {
 352        case MBA_SCSI_COMPLETION:       /* Fast Post */
 353                if (!ha->flags.online)
 354                        break;
 355
 356                for (cnt = 0; cnt < handle_cnt; cnt++)
 357                        qla2x00_process_completed_request(ha, handles[cnt]);
 358                break;
 359
 360        case MBA_RESET:                 /* Reset */
 361                DEBUG2(printk("scsi(%ld): Asynchronous RESET.\n", ha->host_no));
 362
 363                set_bit(RESET_MARKER_NEEDED, &ha->dpc_flags);
 364                break;
 365
 366        case MBA_SYSTEM_ERR:            /* System Error */
 367                mb[1] = RD_MAILBOX_REG(ha, reg, 1);
 368                mb[2] = RD_MAILBOX_REG(ha, reg, 2);
 369                mb[3] = RD_MAILBOX_REG(ha, reg, 3);
 370
 371                qla_printk(KERN_INFO, ha,
 372                    "ISP System Error - mbx1=%xh mbx2=%xh mbx3=%xh.\n",
 373                    mb[1], mb[2], mb[3]);
 374
 375                if (IS_QLA2100(ha) || IS_QLA2200(ha))
 376                        qla2100_fw_dump(ha, 1);
 377                else
 378                        qla2300_fw_dump(ha, 1);
 379
 380                if (mb[1] == 0) {
 381                        qla_printk(KERN_INFO, ha,
 382                            "Unrecoverable Hardware Error: adapter marked "
 383                            "OFFLINE!\n");
 384                        ha->flags.online = 0;
 385                } else
 386                        set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags);
 387                break;
 388
 389        case MBA_REQ_TRANSFER_ERR:      /* Request Transfer Error */
 390                DEBUG2(printk("scsi(%ld): ISP Request Transfer Error.\n",
 391                    ha->host_no));
 392                qla_printk(KERN_WARNING, ha, "ISP Request Transfer Error.\n");
 393
 394                set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags);
 395                break;
 396
 397        case MBA_RSP_TRANSFER_ERR:      /* Response Transfer Error */
 398                DEBUG2(printk("scsi(%ld): ISP Response Transfer Error.\n",
 399                    ha->host_no));
 400                qla_printk(KERN_WARNING, ha, "ISP Response Transfer Error.\n");
 401
 402                set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags);
 403                break;
 404
 405        case MBA_WAKEUP_THRES:          /* Request Queue Wake-up */
 406                DEBUG2(printk("scsi(%ld): Asynchronous WAKEUP_THRES.\n",
 407                    ha->host_no));
 408                break;
 409
 410        case MBA_LIP_OCCURRED:          /* Loop Initialization Procedure */
 411                mb[1] = RD_MAILBOX_REG(ha, reg, 1);
 412
 413                DEBUG2(printk("scsi(%ld): LIP occured (%x).\n", ha->host_no,
 414                    mb[1]));
 415                qla_printk(KERN_INFO, ha, "LIP occured (%x).\n", mb[1]);
 416
 417                if (atomic_read(&ha->loop_state) != LOOP_DOWN) {
 418                        atomic_set(&ha->loop_state, LOOP_DOWN);
 419                        atomic_set(&ha->loop_down_timer, LOOP_DOWN_TIME);
 420                        qla2x00_mark_all_devices_lost(ha);
 421                }
 422
 423                set_bit(REGISTER_FC4_NEEDED, &ha->dpc_flags);
 424
 425                ha->flags.management_server_logged_in = 0;
 426
 427                /* Update AEN queue. */
 428                qla2x00_enqueue_aen(ha, MBA_LIP_OCCURRED, NULL);
 429
 430                ha->total_lip_cnt++;
 431                break;
 432
 433        case MBA_LOOP_UP:               /* Loop Up Event */
 434                mb[1] = RD_MAILBOX_REG(ha, reg, 1);
 435
 436                ha->link_data_rate = 0;
 437                if (IS_QLA2100(ha) || IS_QLA2200(ha)) {
 438                        link_speed = link_speeds[0];
 439                } else {
 440                        link_speed = link_speeds[3];
 441                        if (mb[1] < 5)
 442                                link_speed = link_speeds[mb[1]];
 443                        ha->link_data_rate = mb[1];
 444                }
 445
 446                DEBUG2(printk("scsi(%ld): Asynchronous LOOP UP (%s Gbps).\n",
 447                    ha->host_no, link_speed));
 448                qla_printk(KERN_INFO, ha, "LOOP UP detected (%s Gbps).\n",
 449                    link_speed);
 450
 451                ha->flags.management_server_logged_in = 0;
 452
 453                /* Update AEN queue. */
 454                qla2x00_enqueue_aen(ha, MBA_LOOP_UP, NULL);
 455                break;
 456
 457        case MBA_LOOP_DOWN:             /* Loop Down Event */
 458                DEBUG2(printk("scsi(%ld): Asynchronous LOOP DOWN.\n",
 459                    ha->host_no));
 460                qla_printk(KERN_INFO, ha, "LOOP DOWN detected.\n");
 461
 462                if (atomic_read(&ha->loop_state) != LOOP_DOWN) {
 463                        atomic_set(&ha->loop_state, LOOP_DOWN);
 464                        atomic_set(&ha->loop_down_timer, LOOP_DOWN_TIME);
 465                        ha->device_flags |= DFLG_NO_CABLE;
 466                        qla2x00_mark_all_devices_lost(ha);
 467                }
 468
 469                ha->flags.management_server_logged_in = 0;
 470                ha->link_data_rate = 0;
 471
 472                /* Update AEN queue. */
 473                qla2x00_enqueue_aen(ha, MBA_LOOP_DOWN, NULL);
 474                break;
 475
 476        case MBA_LIP_RESET:             /* LIP reset occurred */
 477                mb[1] = RD_MAILBOX_REG(ha, reg, 1);
 478
 479                DEBUG2(printk("scsi(%ld): Asynchronous LIP RESET (%x).\n",
 480                    ha->host_no, mb[1]));
 481                qla_printk(KERN_INFO, ha,
 482                    "LIP reset occured (%x).\n", mb[1]);
 483
 484                if (atomic_read(&ha->loop_state) != LOOP_DOWN) {
 485                        atomic_set(&ha->loop_state, LOOP_DOWN);
 486                        atomic_set(&ha->loop_down_timer, LOOP_DOWN_TIME);
 487                        qla2x00_mark_all_devices_lost(ha);
 488                }
 489
 490                set_bit(RESET_MARKER_NEEDED, &ha->dpc_flags);
 491
 492                ha->operating_mode = LOOP;
 493                ha->flags.management_server_logged_in = 0;
 494
 495                /* Update AEN queue. */
 496                qla2x00_enqueue_aen(ha, MBA_LIP_RESET, NULL);
 497
 498                ha->total_lip_cnt++;
 499                break;
 500
 501        case MBA_POINT_TO_POINT:        /* Point-to-Point */
 502                if (IS_QLA2100(ha))
 503                        break;
 504
 505                DEBUG2(printk("scsi(%ld): Asynchronous P2P MODE received.\n",
 506                    ha->host_no));
 507
 508                /*
 509                 * Until there's a transition from loop down to loop up, treat
 510                 * this as loop down only.
 511                 */
 512                if (atomic_read(&ha->loop_state) != LOOP_DOWN) {
 513                        atomic_set(&ha->loop_state, LOOP_DOWN);
 514                        if (!atomic_read(&ha->loop_down_timer))
 515                                atomic_set(&ha->loop_down_timer,
 516                                    LOOP_DOWN_TIME);
 517                        qla2x00_mark_all_devices_lost(ha);
 518                }
 519
 520                if (!(test_bit(ABORT_ISP_ACTIVE, &ha->dpc_flags))) {
 521                        set_bit(RESET_MARKER_NEEDED, &ha->dpc_flags);
 522                }
 523                set_bit(REGISTER_FC4_NEEDED, &ha->dpc_flags);
 524                break;
 525
 526        case MBA_CHG_IN_CONNECTION:     /* Change in connection mode */
 527                if (IS_QLA2100(ha))
 528                        break;
 529
 530                mb[1] = RD_MAILBOX_REG(ha, reg, 1);
 531
 532                DEBUG2(printk("scsi(%ld): Asynchronous Change In Connection "
 533                    "received.\n",
 534                    ha->host_no));
 535                qla_printk(KERN_INFO, ha,
 536                    "Configuration change detected: value=%x.\n", mb[1]);
 537
 538                if (atomic_read(&ha->loop_state) != LOOP_DOWN) {
 539                        atomic_set(&ha->loop_state, LOOP_DOWN);  
 540                        if (!atomic_read(&ha->loop_down_timer))
 541                                atomic_set(&ha->loop_down_timer,
 542                                    LOOP_DOWN_TIME);
 543                        qla2x00_mark_all_devices_lost(ha);
 544                }
 545
 546                set_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags);
 547                set_bit(LOCAL_LOOP_UPDATE, &ha->dpc_flags);
 548                break;
 549
 550        case MBA_PORT_UPDATE:           /* Port database update */
 551                mb[1] = RD_MAILBOX_REG(ha, reg, 1);
 552                mb[2] = RD_MAILBOX_REG(ha, reg, 2);
 553
 554                /*
 555                 * If a single remote port just logged into (or logged out of)
 556                 * us, create a new entry in our rscn fcports list and handle
 557                 * the event like an RSCN.
 558                 */
 559                if (!IS_QLA2100(ha) && !IS_QLA2200(ha) && !IS_QLA6312(ha) &&
 560                    !IS_QLA6322(ha) && ha->flags.init_done && mb[1] != 0xffff &&
 561                    ((ha->operating_mode == P2P && mb[1] != 0) ||
 562                    (ha->operating_mode != P2P && mb[1] !=
 563                        SNS_FIRST_LOOP_ID)) && (mb[2] == 6 || mb[2] == 7)) {
 564                        int rval;
 565                        fc_port_t *rscn_fcport;
 566
 567                        /* Create new fcport for login. */
 568                        rscn_fcport = qla2x00_alloc_rscn_fcport(ha, GFP_ATOMIC);
 569                        if (rscn_fcport) {
 570                                DEBUG14(printk("scsi(%ld): Port Update -- "
 571                                    "creating RSCN fcport %p for %x/%x.\n",
 572                                    ha->host_no, rscn_fcport, mb[1], mb[2]));
 573
 574                                rscn_fcport->loop_id = mb[1];
 575                                rscn_fcport->d_id.b24 = INVALID_PORT_ID;
 576                                atomic_set(&rscn_fcport->state,
 577                                    FCS_DEVICE_LOST);
 578                                list_add_tail(&rscn_fcport->list,
 579                                    &ha->rscn_fcports);
 580
 581                                rval = qla2x00_handle_port_rscn(ha, 0,
 582                                    rscn_fcport, 1);
 583                                if (rval == QLA_SUCCESS)
 584                                        break;
 585                        } else {
 586                                DEBUG14(printk("scsi(%ld): Port Update -- "
 587                                    "-- unable to allocate RSCN fcport "
 588                                    "login.\n", ha->host_no));
 589                        }
 590                }
 591
 592                /*
 593                 * If PORT UPDATE is global (recieved LIP_OCCURED/LIP_RESET
 594                 * event etc. earlier indicating loop is down) then process
 595                 * it.  Otherwise ignore it and Wait for RSCN to come in.
 596                 */
 597                atomic_set(&ha->loop_down_timer, 0);
 598                if (atomic_read(&ha->loop_state) != LOOP_DOWN &&
 599                    atomic_read(&ha->loop_state) != LOOP_DEAD) {
 600                        DEBUG2(printk("scsi(%ld): Asynchronous PORT UPDATE "
 601                            "ignored.\n", ha->host_no));
 602                        break;
 603                }
 604
 605                DEBUG2(printk("scsi(%ld): Asynchronous PORT UPDATE.\n",
 606                    ha->host_no));
 607                DEBUG(printk(KERN_INFO
 608                    "scsi(%ld): Port database changed %04x %04x.\n",
 609                    ha->host_no, mb[1], mb[2]));
 610
 611                /*
 612                 * Mark all devices as missing so we will login again.
 613                 */
 614                atomic_set(&ha->loop_state, LOOP_UP);
 615
 616                qla2x00_mark_all_devices_lost(ha);
 617
 618                ha->flags.rscn_queue_overflow = 1;
 619
 620                set_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags);
 621                set_bit(LOCAL_LOOP_UPDATE, &ha->dpc_flags);
 622
 623                /* Update AEN queue. */
 624                qla2x00_enqueue_aen(ha, MBA_PORT_UPDATE, NULL);
 625                break;
 626
 627        case MBA_RSCN_UPDATE:           /* State Change Registration */
 628                mb[1] = RD_MAILBOX_REG(ha, reg, 1);
 629                mb[2] = RD_MAILBOX_REG(ha, reg, 2);
 630
 631                DEBUG2(printk("scsi(%ld): Asynchronous RSCR UPDATE.\n",
 632                    ha->host_no));
 633                DEBUG(printk(KERN_INFO
 634                    "scsi(%ld): RSCN database changed -- %04x %04x.\n",
 635                    ha->host_no, mb[1], mb[2]));
 636
 637                rscn_entry = (mb[1] << 16) | mb[2];
 638                host_pid = (ha->d_id.b.domain << 16) | (ha->d_id.b.area << 8) |
 639                    ha->d_id.b.al_pa;
 640                if (rscn_entry == host_pid) {
 641                        DEBUG(printk(KERN_INFO
 642                            "scsi(%ld): Ignoring RSCN update to local host "
 643                            "port ID (%06x)\n",
 644                            ha->host_no, host_pid));
 645                        break;
 646                }
 647
 648                rscn_queue_index = ha->rscn_in_ptr + 1;
 649                if (rscn_queue_index == MAX_RSCN_COUNT)
 650                        rscn_queue_index = 0;
 651                if (rscn_queue_index != ha->rscn_out_ptr) {
 652                        ha->rscn_queue[ha->rscn_in_ptr] = rscn_entry;
 653                        ha->rscn_in_ptr = rscn_queue_index;
 654                } else {
 655                        ha->flags.rscn_queue_overflow = 1;
 656                }
 657
 658                atomic_set(&ha->loop_state, LOOP_UPDATE);
 659                atomic_set(&ha->loop_down_timer, 0);
 660                ha->flags.management_server_logged_in = 0;
 661
 662                set_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags);
 663                set_bit(RSCN_UPDATE, &ha->dpc_flags);
 664
 665                /* Update AEN queue. */
 666                qla2x00_enqueue_aen(ha, MBA_RSCN_UPDATE, &mb[0]);
 667                break;
 668
 669        /* case MBA_RIO_RESPONSE: */
 670        case MBA_ZIO_RESPONSE:
 671                DEBUG2(printk("scsi(%ld): [R|Z]IO update completion.\n",
 672                    ha->host_no));
 673                DEBUG(printk(KERN_INFO
 674                    "scsi(%ld): [R|Z]IO update completion.\n",
 675                    ha->host_no));
 676
 677                qla2x00_process_response_queue(ha);
 678                break;
 679        }
 680}
 681
 682/**
 683 * qla2x00_process_completed_request() - Process a Fast Post response.
 684 * @ha: SCSI driver HA context
 685 * @index: SRB index
 686 */
 687static void
 688qla2x00_process_completed_request(struct scsi_qla_host *ha, uint32_t index)
 689{
 690        srb_t *sp;
 691
 692        /* Validate handle. */
 693        if (index >= MAX_OUTSTANDING_COMMANDS) {
 694                DEBUG2(printk("scsi(%ld): Invalid SCSI completion handle %d.\n",
 695                    ha->host_no, index));
 696                qla_printk(KERN_WARNING, ha,
 697                    "Invalid SCSI completion handle %d.\n", index);
 698
 699                set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags);
 700                return;
 701        }
 702
 703        sp = ha->outstanding_cmds[index];
 704        if (sp) {
 705                /* Free outstanding command slot. */
 706                ha->outstanding_cmds[index] = NULL;
 707
 708                if (ha->actthreads)
 709                        ha->actthreads--;
 710                sp->lun_queue->out_cnt--;
 711                CMD_COMPL_STATUS(sp->cmd) = 0L;
 712                CMD_SCSI_STATUS(sp->cmd) = 0L;
 713
 714                /* Save ISP completion status */
 715                sp->cmd->result = DID_OK << 16;
 716                sp->fo_retry_cnt = 0;
 717                add_to_done_queue(ha, sp);
 718        } else {
 719                DEBUG2(printk("scsi(%ld): Invalid ISP SCSI completion handle\n",
 720                    ha->host_no));
 721                qla_printk(KERN_WARNING, ha,
 722                    "Invalid ISP SCSI completion handle\n");
 723
 724                set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags);
 725        }
 726}
 727
 728/**
 729 * qla2x00_process_response_queue() - Process response queue entries.
 730 * @ha: SCSI driver HA context
 731 */
 732void
 733qla2x00_process_response_queue(struct scsi_qla_host *ha)
 734{
 735        device_reg_t __iomem *reg = ha->iobase;
 736        sts_entry_t     *pkt;
 737        uint16_t        handle_cnt;
 738        uint16_t        cnt;
 739
 740        if (!ha->flags.online)
 741                return;
 742
 743        while (ha->response_ring_ptr->signature != RESPONSE_PROCESSED) {
 744                pkt = (sts_entry_t *)ha->response_ring_ptr;
 745
 746                ha->rsp_ring_index++;
 747                if (ha->rsp_ring_index == ha->response_q_length) {
 748                        ha->rsp_ring_index = 0;
 749                        ha->response_ring_ptr = ha->response_ring;
 750                } else {
 751                        ha->response_ring_ptr++;
 752                }
 753
 754                if (pkt->entry_status != 0) {
 755                        DEBUG3(printk(KERN_INFO
 756                            "scsi(%ld): Process error entry.\n", ha->host_no));
 757
 758                        qla2x00_error_entry(ha, pkt);
 759                        ((response_t *)pkt)->signature = RESPONSE_PROCESSED;
 760                        wmb();
 761                        continue;
 762                }
 763
 764                switch (pkt->entry_type) {
 765                case STATUS_TYPE:
 766                        qla2x00_status_entry(ha, pkt);
 767                        break;
 768                case STATUS_TYPE_21:
 769                        handle_cnt = ((sts21_entry_t *)pkt)->handle_count;
 770                        for (cnt = 0; cnt < handle_cnt; cnt++) {
 771                                qla2x00_process_completed_request(ha,
 772                                    ((sts21_entry_t *)pkt)->handle[cnt]);
 773                        }
 774                        break;
 775                case STATUS_TYPE_22:
 776                        handle_cnt = ((sts22_entry_t *)pkt)->handle_count;
 777                        for (cnt = 0; cnt < handle_cnt; cnt++) {
 778                                qla2x00_process_completed_request(ha,
 779                                    ((sts22_entry_t *)pkt)->handle[cnt]);
 780                        }
 781                        break;
 782                case STATUS_CONT_TYPE:
 783                        qla2x00_status_cont_entry(ha, (sts_cont_entry_t *)pkt);
 784                        break;
 785                case MS_IOCB_TYPE:
 786                        qla2x00_ms_entry(ha, (ms_iocb_entry_t *)pkt);
 787                        break;
 788                case MBX_IOCB_TYPE:
 789                        if (!IS_QLA2100(ha) && !IS_QLA2200(ha) &&
 790                            !IS_QLA6312(ha) && !IS_QLA6322(ha)) {
 791                                if (pkt->sys_define == SOURCE_ASYNC_IOCB) {
 792                                        qla2x00_process_iodesc(ha,
 793                                            (struct mbx_entry *)pkt);
 794                                } else {
 795                                        /* MBX IOCB Type Not Supported. */
 796                                        DEBUG4(printk(KERN_WARNING
 797                                            "scsi(%ld): Received unknown MBX "
 798                                            "IOCB response pkt type=%x "
 799                                            "source=%x entry status=%x.\n",
 800                                            ha->host_no, pkt->entry_type,
 801                                            pkt->sys_define,
 802                                            pkt->entry_status));
 803                                }
 804                                break;
 805                        }
 806                        /* Fallthrough. */
 807                default:
 808                        /* Type Not Supported. */
 809                        DEBUG4(printk(KERN_WARNING
 810                            "scsi(%ld): Received unknown response pkt type %x "
 811                            "entry status=%x.\n",
 812                            ha->host_no, pkt->entry_type, pkt->entry_status));
 813                        break;
 814                }
 815                ((response_t *)pkt)->signature = RESPONSE_PROCESSED;
 816                wmb();
 817        }
 818
 819        /* Adjust ring index */
 820        WRT_REG_WORD(ISP_RSP_Q_OUT(ha, reg), ha->rsp_ring_index);
 821}
 822
 823/**
 824 * qla2x00_status_entry() - Process a Status IOCB entry.
 825 * @ha: SCSI driver HA context
 826 * @pkt: Entry pointer
 827 */
 828static void
 829qla2x00_status_entry(scsi_qla_host_t *ha, sts_entry_t *pkt)
 830{
 831        int             ret;
 832        unsigned        b, t, l;
 833        srb_t           *sp;
 834        os_lun_t        *lq;
 835        os_tgt_t        *tq;
 836        fc_port_t       *fcport;
 837        struct scsi_cmnd *cp;
 838        uint16_t        comp_status;
 839        uint16_t        scsi_status;
 840        uint8_t         lscsi_status;
 841        int32_t         resid;
 842        uint8_t         sense_sz = 0;
 843        uint16_t        rsp_info_len;
 844
 845        /* Fast path completion. */
 846        if (le16_to_cpu(pkt->comp_status) == CS_COMPLETE &&
 847            (le16_to_cpu(pkt->scsi_status) & SS_MASK) == 0) {
 848                qla2x00_process_completed_request(ha, pkt->handle);
 849
 850                return;
 851        }
 852
 853        /* Validate handle. */
 854        if (pkt->handle < MAX_OUTSTANDING_COMMANDS) {
 855                sp = ha->outstanding_cmds[pkt->handle];
 856                ha->outstanding_cmds[pkt->handle] = NULL;
 857        } else
 858                sp = NULL;
 859
 860        if (sp == NULL) {
 861                DEBUG2(printk("scsi(%ld): Status Entry invalid handle.\n",
 862                    ha->host_no));
 863                qla_printk(KERN_WARNING, ha, "Status Entry invalid handle.\n");
 864
 865                set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags);
 866                if (ha->dpc_wait && !ha->dpc_active) 
 867                        up(ha->dpc_wait);
 868
 869                return;
 870        }
 871        cp = sp->cmd;
 872        if (cp == NULL) {
 873                DEBUG2(printk("scsi(%ld): Command already returned back to OS "
 874                    "pkt->handle=%d sp=%p sp->state:%d\n",
 875                    ha->host_no, pkt->handle, sp, sp->state));
 876                qla_printk(KERN_WARNING, ha,
 877                    "Command is NULL: already returned to OS (sp=%p)\n", sp);
 878
 879                return;
 880        }
 881
 882        if (ha->actthreads)
 883                ha->actthreads--;
 884
 885        if (sp->lun_queue == NULL) {
 886                DEBUG2(printk("scsi(%ld): Status Entry invalid lun pointer.\n",
 887                    ha->host_no));
 888                qla_printk(KERN_WARNING, ha,
 889                    "Status Entry invalid lun pointer.\n");
 890
 891                set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags);
 892                if (ha->dpc_wait && !ha->dpc_active) 
 893                        up(ha->dpc_wait);
 894
 895                return;
 896        }
 897
 898        sp->lun_queue->out_cnt--;
 899
 900        comp_status = le16_to_cpu(pkt->comp_status);
 901        /* Mask of reserved bits 12-15, before we examine the scsi status */
 902        scsi_status = le16_to_cpu(pkt->scsi_status) & SS_MASK;
 903        lscsi_status = scsi_status & STATUS_MASK;
 904
 905        CMD_ENTRY_STATUS(cp) = pkt->entry_status;
 906        CMD_COMPL_STATUS(cp) = comp_status;
 907        CMD_SCSI_STATUS(cp) = scsi_status;
 908
 909        /* Generate LU queue on cntrl, target, LUN */
 910        b = cp->device->channel;
 911        t = cp->device->id;
 912        l = cp->device->lun,
 913
 914        tq = sp->tgt_queue;
 915        lq = sp->lun_queue;
 916
 917        /*
 918         * If loop is in transient state Report DID_BUS_BUSY
 919         */
 920        if ((comp_status != CS_COMPLETE || scsi_status != 0)) {
 921                if (!(sp->flags & (SRB_IOCTL | SRB_TAPE)) &&
 922                    (atomic_read(&ha->loop_down_timer) ||
 923                        atomic_read(&ha->loop_state) != LOOP_READY)) {
 924
 925                        DEBUG2(printk("scsi(%ld:%d:%d:%d): Loop Not Ready - "
 926                            "pid=%lx.\n",
 927                            ha->host_no, b, t, l, cp->serial_number));
 928
 929                        qla2x00_extend_timeout(cp, EXTEND_CMD_TIMEOUT);
 930                        add_to_retry_queue(ha, sp);
 931                        return;
 932                }
 933        }
 934
 935        /* Check for any FCP transport errors. */
 936        if (scsi_status & SS_RESPONSE_INFO_LEN_VALID) {
 937                rsp_info_len = le16_to_cpu(pkt->rsp_info_len);
 938                if (rsp_info_len > 3 && pkt->rsp_info[3]) {
 939                        DEBUG2(printk("scsi(%ld:%d:%d:%d) FCP I/O protocol "
 940                            "failure (%x/%02x%02x%02x%02x%02x%02x%02x%02x)..."
 941                            "retrying command\n", ha->host_no, b, t, l,
 942                            rsp_info_len, pkt->rsp_info[0], pkt->rsp_info[1],
 943                            pkt->rsp_info[2], pkt->rsp_info[3],
 944                            pkt->rsp_info[4], pkt->rsp_info[5],
 945                            pkt->rsp_info[6], pkt->rsp_info[7]));
 946
 947                        cp->result = DID_BUS_BUSY << 16;
 948                        add_to_done_queue(ha, sp);
 949                        return;
 950                }
 951        }
 952
 953        /*
 954         * Based on Host and scsi status generate status code for Linux
 955         */
 956        switch (comp_status) {
 957        case CS_COMPLETE:
 958                if (scsi_status == 0) {
 959                        cp->result = DID_OK << 16;
 960                        break;
 961                }
 962                if (scsi_status & (SS_RESIDUAL_UNDER | SS_RESIDUAL_OVER)) {
 963                        resid = le32_to_cpu(pkt->residual_length);
 964                        cp->resid = resid;
 965                        CMD_RESID_LEN(cp) = resid;
 966                }
 967                if (lscsi_status == SS_BUSY_CONDITION) {
 968                        cp->result = DID_BUS_BUSY << 16 | lscsi_status;
 969                        break;
 970                }
 971
 972                cp->result = DID_OK << 16 | lscsi_status;
 973
 974                if (lscsi_status != SS_CHECK_CONDITION)
 975                        break;
 976
 977                /*
 978                 * Copy Sense Data into sense buffer
 979                 */
 980                memset(cp->sense_buffer, 0, sizeof(cp->sense_buffer));
 981
 982                if (!(scsi_status & SS_SENSE_LEN_VALID))
 983                        break;
 984
 985                if (le16_to_cpu(pkt->req_sense_length) <
 986                    sizeof(cp->sense_buffer))
 987                        sense_sz = le16_to_cpu(pkt->req_sense_length);
 988                else
 989                        sense_sz = sizeof(cp->sense_buffer);
 990
 991                CMD_ACTUAL_SNSLEN(cp) = sense_sz;
 992                sp->request_sense_length = sense_sz;
 993                sp->request_sense_ptr = cp->sense_buffer;
 994
 995                if (sp->request_sense_length > 32)
 996                        sense_sz = 32;
 997
 998                memcpy(cp->sense_buffer, pkt->req_sense_data, sense_sz);
 999
1000                sp->request_sense_ptr += sense_sz;
1001                sp->request_sense_length -= sense_sz;
1002                if (sp->request_sense_length != 0)
1003                        ha->status_srb = sp;
1004
1005                if (!(sp->flags & (SRB_IOCTL | SRB_TAPE)) &&
1006                    qla2x00_check_sense(cp, lq) == QLA_SUCCESS) {
1007                        /* Throw away status_cont if any */
1008                        ha->status_srb = NULL;
1009                        add_to_scsi_retry_queue(ha, sp);
1010                        return;
1011                }
1012
1013                DEBUG5(printk("%s(): Check condition Sense data, "
1014                    "scsi(%ld:%d:%d:%d) cmd=%p pid=%ld\n",
1015                    __func__, ha->host_no, b, t, l, cp,
1016                    cp->serial_number));
1017                if (sense_sz)
1018                        DEBUG5(qla2x00_dump_buffer(cp->sense_buffer,
1019                            CMD_ACTUAL_SNSLEN(cp)));
1020                break;
1021
1022        case CS_DATA_UNDERRUN:
1023                DEBUG2(printk(KERN_INFO
1024                    "scsi(%ld:%d:%d) UNDERRUN status detected 0x%x-0x%x.\n",
1025                    ha->host_no, t, l, comp_status, scsi_status));
1026
1027                resid = le32_to_cpu(pkt->residual_length);
1028                if (scsi_status & SS_RESIDUAL_UNDER) {
1029                        cp->resid = resid;
1030                        CMD_RESID_LEN(cp) = resid;
1031                }
1032
1033                /*
1034                 * Check to see if SCSI Status is non zero. If so report SCSI 
1035                 * Status.
1036                 */
1037                if (lscsi_status != 0) {
1038                        if (lscsi_status == SS_BUSY_CONDITION) {
1039                                cp->result = DID_BUS_BUSY << 16 |
1040                                    lscsi_status;
1041                                break;
1042                        }
1043
1044                        cp->result = DID_OK << 16 | lscsi_status;
1045
1046                        if (lscsi_status != SS_CHECK_CONDITION)
1047                                break;
1048
1049                        /* Copy Sense Data into sense buffer */
1050                        memset(cp->sense_buffer, 0, sizeof(cp->sense_buffer));
1051
1052                        if (!(scsi_status & SS_SENSE_LEN_VALID))
1053                                break;
1054
1055                        if (le16_to_cpu(pkt->req_sense_length) <
1056                            sizeof(cp->sense_buffer))
1057                                sense_sz = le16_to_cpu(pkt->req_sense_length);
1058                        else
1059                                sense_sz = sizeof(cp->sense_buffer);
1060
1061                        CMD_ACTUAL_SNSLEN(cp) = sense_sz;
1062                        sp->request_sense_length = sense_sz;
1063                        sp->request_sense_ptr = cp->sense_buffer;
1064
1065                        if (sp->request_sense_length > 32) 
1066                                sense_sz = 32;
1067
1068                        memcpy(cp->sense_buffer, pkt->req_sense_data, sense_sz);
1069
1070                        sp->request_sense_ptr += sense_sz;
1071                        sp->request_sense_length -= sense_sz;
1072                        if (sp->request_sense_length != 0)
1073                                ha->status_srb = sp;
1074
1075                        if (!(sp->flags & (SRB_IOCTL | SRB_TAPE)) &&
1076                            (qla2x00_check_sense(cp, lq) == QLA_SUCCESS)) {
1077                                ha->status_srb = NULL;
1078                                add_to_scsi_retry_queue(ha, sp);
1079                                return;
1080                        }
1081                        DEBUG5(printk("%s(): Check condition Sense data, "
1082                            "scsi(%ld:%d:%d:%d) cmd=%p pid=%ld\n",
1083                            __func__, ha->host_no, b, t, l, cp,
1084                            cp->serial_number));
1085                        if (sense_sz)
1086                                DEBUG5(qla2x00_dump_buffer(cp->sense_buffer,
1087                                    CMD_ACTUAL_SNSLEN(cp)));
1088                } else {
1089                        /*
1090                         * If RISC reports underrun and target does not report
1091                         * it then we must have a lost frame, so tell upper
1092                         * layer to retry it by reporting a bus busy.
1093                         */
1094                        if (!(scsi_status & SS_RESIDUAL_UNDER)) {
1095                                DEBUG2(printk("scsi(%ld:%d:%d:%d) Dropped "
1096                                    "frame(s) detected (%x of %x bytes)..."
1097                                    "retrying command.\n",
1098                                    ha->host_no, b, t, l, resid,
1099                                    cp->request_bufflen));
1100
1101                                cp->result = DID_BUS_BUSY << 16;
1102                                ha->dropped_frame_error_cnt++;
1103                                break;
1104                        }
1105
1106                        /* Handle mid-layer underflow */
1107                        if ((unsigned)(cp->request_bufflen - resid) <
1108                            cp->underflow) {
1109                                qla_printk(KERN_INFO, ha,
1110                                    "scsi(%ld:%d:%d:%d): Mid-layer underflow "
1111                                    "detected (%x of %x bytes)...returning "
1112                                    "error status.\n",
1113                                    ha->host_no, b, t, l, resid,
1114                                    cp->request_bufflen);
1115
1116                                cp->result = DID_ERROR << 16;
1117                                break;
1118                        }
1119
1120                        /* Everybody online, looking good... */
1121                        cp->result = DID_OK << 16;
1122                }
1123                break;
1124
1125        case CS_DATA_OVERRUN:
1126                DEBUG2(printk(KERN_INFO
1127                    "scsi(%ld:%d:%d): OVERRUN status detected 0x%x-0x%x\n",
1128                    ha->host_no, t, l, comp_status, scsi_status));
1129                DEBUG2(printk(KERN_INFO
1130                    "CDB: 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n",
1131                    cp->cmnd[0], cp->cmnd[1], cp->cmnd[2], cp->cmnd[3],
1132                    cp->cmnd[4], cp->cmnd[5]));
1133                DEBUG2(printk(KERN_INFO
1134                    "PID=0x%lx req=0x%x xtra=0x%x -- returning DID_ERROR "
1135                    "status!\n",
1136                    cp->serial_number, cp->request_bufflen,
1137                    le32_to_cpu(pkt->residual_length)));
1138
1139                cp->result = DID_ERROR << 16;
1140                break;
1141
1142        case CS_PORT_LOGGED_OUT:
1143        case CS_PORT_CONFIG_CHG:
1144        case CS_PORT_BUSY:
1145        case CS_INCOMPLETE:
1146        case CS_PORT_UNAVAILABLE:
1147                /*
1148                 * If the port is in Target Down state, return all IOs for this
1149                 * Target with DID_NO_CONNECT ELSE Queue the IOs in the
1150                 * retry_queue.
1151                 */
1152                fcport = sp->fclun->fcport;
1153                DEBUG2(printk("scsi(%ld:%d:%d): status_entry: Port Down "
1154                    "pid=%ld, compl status=0x%x, port state=0x%x\n",
1155                    ha->host_no, t, l, cp->serial_number, comp_status,
1156                    atomic_read(&fcport->state)));
1157
1158                if ((sp->flags & (SRB_IOCTL | SRB_TAPE)) ||
1159                    atomic_read(&fcport->state) == FCS_DEVICE_DEAD) {
1160                        cp->result = DID_NO_CONNECT << 16;
1161                        if (atomic_read(&ha->loop_state) == LOOP_DOWN) 
1162                                sp->err_id = SRB_ERR_LOOP;
1163                        else
1164                                sp->err_id = SRB_ERR_PORT;
1165                        add_to_done_queue(ha, sp);
1166                } else {
1167                        qla2x00_extend_timeout(cp, EXTEND_CMD_TIMEOUT);
1168                        add_to_retry_queue(ha, sp);
1169                }
1170
1171                if (atomic_read(&fcport->state) == FCS_ONLINE) {
1172                        qla2x00_mark_device_lost(ha, fcport, 1);
1173                }
1174
1175                return;
1176                break;
1177
1178        case CS_RESET:
1179                DEBUG2(printk(KERN_INFO
1180                    "scsi(%ld): RESET status detected 0x%x-0x%x.\n",
1181                    ha->host_no, comp_status, scsi_status));
1182
1183                if (sp->flags & (SRB_IOCTL | SRB_TAPE)) {
1184                        cp->result = DID_RESET << 16;
1185                } else {
1186                        qla2x00_extend_timeout(cp, EXTEND_CMD_TIMEOUT);
1187                        add_to_retry_queue(ha, sp);
1188                        return;
1189                }
1190                break;
1191
1192        case CS_ABORTED:
1193                /* 
1194                 * hv2.19.12 - DID_ABORT does not retry the request if we
1195                 * aborted this request then abort otherwise it must be a
1196                 * reset.
1197                 */
1198                DEBUG2(printk(KERN_INFO
1199                    "scsi(%ld): ABORT status detected 0x%x-0x%x.\n",
1200                    ha->host_no, comp_status, scsi_status));
1201
1202                cp->result = DID_RESET << 16;
1203                break;
1204
1205        case CS_TIMEOUT:
1206                DEBUG2(printk(KERN_INFO
1207                    "scsi(%ld:%d:%d:%d): TIMEOUT status detected 0x%x-0x%x "
1208                    "sflags=%x.\n", ha->host_no, b, t, l, comp_status,
1209                    scsi_status, le16_to_cpu(pkt->status_flags)));
1210
1211                cp->result = DID_BUS_BUSY << 16;
1212
1213                fcport = lq->fclun->fcport;
1214
1215                /* Check to see if logout occurred */
1216                if ((le16_to_cpu(pkt->status_flags) & SF_LOGOUT_SENT)) {
1217                        qla2x00_mark_device_lost(ha, fcport, 1);
1218                }
1219                break;
1220
1221        case CS_QUEUE_FULL:
1222                DEBUG2(printk(KERN_INFO
1223                    "scsi(%ld): QUEUE FULL status detected 0x%x-0x%x.\n",
1224                    ha->host_no, comp_status, scsi_status));
1225
1226                /* SCSI Mid-Layer handles device queue full */
1227
1228                cp->result = DID_OK << 16 | lscsi_status; 
1229
1230                /* TODO: ??? */
1231                /* Adjust queue depth */
1232                ret = scsi_track_queue_full(cp->device,
1233                    sp->lun_queue->out_cnt - 1);
1234                if (ret) {
1235                        qla_printk(KERN_INFO, ha,
1236                            "scsi(%ld:%d:%d:%d): Queue depth adjusted to %d.\n",
1237                            ha->host_no, cp->device->channel, cp->device->id,
1238                            cp->device->lun, ret);
1239                }
1240                break;
1241
1242        default:
1243                DEBUG3(printk("scsi(%ld): Error detected (unknown status) "
1244                    "0x%x-0x%x.\n",
1245                    ha->host_no, comp_status, scsi_status));
1246                qla_printk(KERN_INFO, ha,
1247                    "Unknown status detected 0x%x-0x%x.\n",
1248                    comp_status, scsi_status);
1249
1250                cp->result = DID_ERROR << 16;
1251                break;
1252        }
1253
1254        /* Place command on done queue. */
1255        if (ha->status_srb == NULL)
1256                add_to_done_queue(ha, sp);
1257}
1258
1259/**
1260 * qla2x00_status_cont_entry() - Process a Status Continuations entry.
1261 * @ha: SCSI driver HA context
1262 * @pkt: Entry pointer
1263 *
1264 * Extended sense data.
1265 */
1266static void
1267qla2x00_status_cont_entry(scsi_qla_host_t *ha, sts_cont_entry_t *pkt)
1268{
1269        uint8_t         sense_sz = 0;
1270        srb_t           *sp = ha->status_srb;
1271        struct scsi_cmnd *cp;
1272
1273        if (sp != NULL && sp->request_sense_length != 0) {
1274                cp = sp->cmd;
1275                if (cp == NULL) {
1276                        DEBUG2(printk("%s(): Cmd already returned back to OS "
1277                            "sp=%p sp->state:%d\n", __func__, sp, sp->state));
1278                        qla_printk(KERN_INFO, ha,
1279                            "cmd is NULL: already returned to OS (sp=%p)\n",
1280                            sp); 
1281
1282                        ha->status_srb = NULL;
1283                        return;
1284                }
1285
1286                if (sp->request_sense_length > sizeof(pkt->data)) {
1287                        sense_sz = sizeof(pkt->data);
1288                } else {
1289                        sense_sz = sp->request_sense_length;
1290                }
1291
1292                /* Move sense data. */
1293                memcpy(sp->request_sense_ptr, pkt->data, sense_sz);
1294                DEBUG5(qla2x00_dump_buffer(sp->request_sense_ptr, sense_sz));
1295
1296                sp->request_sense_ptr += sense_sz;
1297                sp->request_sense_length -= sense_sz;
1298
1299                /* Place command on done queue. */
1300                if (sp->request_sense_length == 0) {
1301                        add_to_done_queue(ha, sp);
1302                        ha->status_srb = NULL;
1303                }
1304        }
1305}
1306
1307/**
1308 * qla2x00_error_entry() - Process an error entry.
1309 * @ha: SCSI driver HA context
1310 * @pkt: Entry pointer
1311 */
1312static void
1313qla2x00_error_entry(scsi_qla_host_t *ha, sts_entry_t *pkt) 
1314{
1315        srb_t *sp;
1316
1317#if defined(QL_DEBUG_LEVEL_2)
1318        if (pkt->entry_status & RF_INV_E_ORDER)
1319                qla_printk(KERN_ERR, ha, "%s: Invalid Entry Order\n", __func__);
1320        else if (pkt->entry_status & RF_INV_E_COUNT)
1321                qla_printk(KERN_ERR, ha, "%s: Invalid Entry Count\n", __func__);
1322        else if (pkt->entry_status & RF_INV_E_PARAM)
1323                qla_printk(KERN_ERR, ha, 
1324                    "%s: Invalid Entry Parameter\n", __func__);
1325        else if (pkt->entry_status & RF_INV_E_TYPE)
1326                qla_printk(KERN_ERR, ha, "%s: Invalid Entry Type\n", __func__);
1327        else if (pkt->entry_status & RF_BUSY)
1328                qla_printk(KERN_ERR, ha, "%s: Busy\n", __func__);
1329        else
1330                qla_printk(KERN_ERR, ha, "%s: UNKNOWN flag error\n", __func__);
1331#endif
1332
1333        /* Validate handle. */
1334        if (pkt->handle < MAX_OUTSTANDING_COMMANDS)
1335                sp = ha->outstanding_cmds[pkt->handle];
1336        else
1337                sp = NULL;
1338
1339        if (sp) {
1340                /* Free outstanding command slot. */
1341                ha->outstanding_cmds[pkt->handle] = NULL;
1342                if (ha->actthreads)
1343                        ha->actthreads--;
1344                sp->lun_queue->out_cnt--;
1345
1346                /* Bad payload or header */
1347                if (pkt->entry_status &
1348                    (RF_INV_E_ORDER | RF_INV_E_COUNT |
1349                     RF_INV_E_PARAM | RF_INV_E_TYPE)) {
1350                        sp->cmd->result = DID_ERROR << 16;
1351                } else if (pkt->entry_status & RF_BUSY) {
1352                        sp->cmd->result = DID_BUS_BUSY << 16;
1353                } else {
1354                        sp->cmd->result = DID_ERROR << 16;
1355                }
1356                /* Place command on done queue. */
1357                add_to_done_queue(ha, sp);
1358
1359        } else if (pkt->entry_type == COMMAND_A64_TYPE ||
1360            pkt->entry_type == COMMAND_TYPE) {
1361                DEBUG2(printk("scsi(%ld): Error entry - invalid handle\n",
1362                    ha->host_no));
1363                qla_printk(KERN_WARNING, ha,
1364                    "Error entry - invalid handle\n");
1365
1366                set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags);
1367                if (ha->dpc_wait && !ha->dpc_active) 
1368                        up(ha->dpc_wait);
1369        }
1370}
1371
1372/**
1373 * qla2x00_ms_entry() - Process a Management Server entry.
1374 * @ha: SCSI driver HA context
1375 * @index: Response queue out pointer
1376 */
1377static void
1378qla2x00_ms_entry(scsi_qla_host_t *ha, ms_iocb_entry_t *pkt) 
1379{
1380        srb_t          *sp;
1381
1382        DEBUG3(printk("%s(%ld): pkt=%p pkthandle=%d.\n",
1383            __func__, ha->host_no, pkt, pkt->handle1));
1384
1385        /* Validate handle. */
1386        if (pkt->handle1 < MAX_OUTSTANDING_COMMANDS)
1387                sp = ha->outstanding_cmds[pkt->handle1];
1388        else
1389                sp = NULL;
1390
1391        if (sp == NULL) {
1392                DEBUG2(printk("scsi(%ld): MS entry - invalid handle\n",
1393                    ha->host_no));
1394                qla_printk(KERN_WARNING, ha, "MS entry - invalid handle\n");
1395
1396                set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags);
1397                return;
1398        }
1399
1400        CMD_COMPL_STATUS(sp->cmd) = le16_to_cpu(pkt->status);
1401        CMD_ENTRY_STATUS(sp->cmd) = pkt->entry_status;
1402
1403        /* Free outstanding command slot. */
1404        ha->outstanding_cmds[pkt->handle1] = NULL;
1405
1406        add_to_done_queue(ha, sp);
1407}
1408
1409/**
1410 * qla2x00_check_sense() - Perform any sense data interrogation.
1411 * @cp: SCSI Command
1412 * @lq: Lun queue
1413 *
1414 * Returns QLA_SUCCESS if the lun queue is suspended, else
1415 * QLA_FUNCTION_FAILED  (lun queue not suspended).
1416 */
1417static int 
1418qla2x00_check_sense(struct scsi_cmnd *cp, os_lun_t *lq)
1419{
1420        scsi_qla_host_t *ha;
1421        srb_t           *sp;
1422        fc_port_t       *fcport;
1423
1424        ha = (scsi_qla_host_t *) cp->device->host->hostdata;
1425        if ((cp->sense_buffer[0] & 0x70) != 0x70) {
1426                return (QLA_FUNCTION_FAILED);
1427        }
1428
1429        sp = (srb_t * )CMD_SP(cp);
1430        sp->flags |= SRB_GOT_SENSE;
1431
1432        switch (cp->sense_buffer[2] & 0xf) {
1433        case RECOVERED_ERROR:
1434                cp->result = DID_OK << 16;
1435                cp->sense_buffer[0] = 0;
1436                break;
1437
1438        case NOT_READY:
1439                fcport = lq->fclun->fcport;
1440
1441                /*
1442                 * Suspend the lun only for hard disk device type.
1443                 */
1444                if ((fcport->flags & FCF_TAPE_PRESENT) == 0 &&
1445                    lq->q_state != LUN_STATE_TIMEOUT) {
1446                        /*
1447                         * If target is in process of being ready then suspend
1448                         * lun for 6 secs and retry all the commands.
1449                         */
1450                        if (cp->sense_buffer[12] == 0x4 &&
1451                            cp->sense_buffer[13] == 0x1) {
1452
1453                                /* Suspend the lun for 6 secs */
1454                                qla2x00_suspend_lun(ha, lq, 6,
1455                                    ql2xsuspendcount);
1456
1457                                return (QLA_SUCCESS);
1458                        }
1459                }
1460                break;
1461        }
1462
1463        return (QLA_FUNCTION_FAILED);
1464}
1465
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.