- return (rval);
-}
-
-/*
- * qla2x00_cfg_lun
- * Configures LUN into fcport LUN list.
- *
- * Input:
- * fcport: FC port structure pointer.
- * lun: LUN number.
- *
- * Context:
- * Kernel context.
- */
-static fc_lun_t *
-qla2x00_cfg_lun(scsi_qla_host_t *ha, fc_port_t *fcport, uint16_t lun,
- inq_cmd_rsp_t *inq, dma_addr_t inq_dma)
-{
- fc_lun_t *fclun;
-
- /* Bypass LUNs that failed. */
- if (qla2x00_inquiry(ha, fcport, lun, inq, inq_dma) != QLA_SUCCESS) {
- DEBUG2(printk("scsi(%ld): Failed inquiry - loop id=0x%04x "
- "lun=%d\n", ha->host_no, fcport->loop_id, lun));
-
- return (NULL);
- }
-
- switch (inq->inq[0]) {
- case TYPE_DISK:
- case TYPE_PROCESSOR:
- case TYPE_WORM:
- case TYPE_ROM:
- case TYPE_SCANNER:
- case TYPE_MOD:
- case TYPE_MEDIUM_CHANGER:
- case TYPE_ENCLOSURE:
- case 0x20:
- case 0x0C:
- break;
- case TYPE_TAPE:
- fcport->flags |= FCF_TAPE_PRESENT;
- break;
- default:
- DEBUG2(printk("scsi(%ld): Unsupported lun type -- "
- "loop id=0x%04x lun=%d type=%x\n",
- ha->host_no, fcport->loop_id, lun, inq->inq[0]));
- return (NULL);
- }
-
- fcport->device_type = inq->inq[0];
- fclun = qla2x00_add_lun(fcport, lun);
-
- if (fclun != NULL) {
- atomic_set(&fcport->state, FCS_ONLINE);
- }
-
- return (fclun);
-}
-
-/*
- * qla2x00_add_lun
- * Adds LUN to database
- *
- * Input:
- * fcport: FC port structure pointer.
- * lun: LUN number.
- *
- * Context:
- * Kernel context.
- */
-static fc_lun_t *
-qla2x00_add_lun(fc_port_t *fcport, uint16_t lun)
-{
- int found;
- fc_lun_t *fclun;
-
- if (fcport == NULL) {
- DEBUG(printk("scsi: Unable to add lun to NULL port\n"));
- return (NULL);
- }
-
- /* Allocate LUN if not already allocated. */
- found = 0;
- list_for_each_entry(fclun, &fcport->fcluns, list) {
- if (fclun->lun == lun) {
- found++;
- break;
- }
- }
- if (found)
- return (NULL);
-
- fclun = kmalloc(sizeof(fc_lun_t), GFP_ATOMIC);
- if (fclun == NULL) {
- printk(KERN_WARNING
- "%s(): Memory Allocation failed - FCLUN\n",
- __func__);
- return (NULL);
- }
-
- /* Setup LUN structure. */
- memset(fclun, 0, sizeof(fc_lun_t));
- fclun->lun = lun;
- fclun->fcport = fcport;
- fclun->o_fcport = fcport;
- fclun->device_type = fcport->device_type;
- atomic_set(&fcport->state, FCS_UNCONFIGURED);
-
- list_add_tail(&fclun->list, &fcport->fcluns);
-
- return (fclun);
-}
-
-/*
- * qla2x00_inquiry
- * Issue SCSI inquiry command.
- *
- * Input:
- * ha = adapter block pointer.
- * fcport = FC port structure pointer.
- *
- * Return:
- * 0 - Success
- * BIT_0 - error
- *
- * Context:
- * Kernel context.
- */
-static int
-qla2x00_inquiry(scsi_qla_host_t *ha,
- fc_port_t *fcport, uint16_t lun, inq_cmd_rsp_t *inq, dma_addr_t inq_dma)
-{
- int rval;
- uint16_t retries;
- uint16_t comp_status;
- uint16_t scsi_status;
-
- rval = QLA_FUNCTION_FAILED;
-
- for (retries = 3; retries; retries--) {
- memset(inq, 0, sizeof(inq_cmd_rsp_t));
- inq->p.cmd.entry_type = COMMAND_A64_TYPE;
- inq->p.cmd.entry_count = 1;
- inq->p.cmd.lun = cpu_to_le16(lun);
- SET_TARGET_ID(ha, inq->p.cmd.target, fcport->loop_id);
- inq->p.cmd.control_flags =
- __constant_cpu_to_le16(CF_READ | CF_SIMPLE_TAG);
- inq->p.cmd.scsi_cdb[0] = INQUIRY;
- inq->p.cmd.scsi_cdb[4] = INQ_DATA_SIZE;
- inq->p.cmd.dseg_count = __constant_cpu_to_le16(1);
- inq->p.cmd.timeout = __constant_cpu_to_le16(10);
- inq->p.cmd.byte_count =
- __constant_cpu_to_le32(INQ_DATA_SIZE);
- inq->p.cmd.dseg_0_address[0] = cpu_to_le32(
- LSD(inq_dma + sizeof(sts_entry_t)));
- inq->p.cmd.dseg_0_address[1] = cpu_to_le32(
- MSD(inq_dma + sizeof(sts_entry_t)));
- inq->p.cmd.dseg_0_length =
- __constant_cpu_to_le32(INQ_DATA_SIZE);
-
- DEBUG5(printk("scsi(%ld): Lun Inquiry - fcport=[%04x/%p],"
- " lun (%d)\n",
- ha->host_no, fcport->loop_id, fcport, lun));
-
- rval = qla2x00_issue_iocb(ha, inq, inq_dma,
- sizeof(inq_cmd_rsp_t));
-
- comp_status = le16_to_cpu(inq->p.rsp.comp_status);
- scsi_status = le16_to_cpu(inq->p.rsp.scsi_status);
-
- DEBUG5(printk("scsi(%ld): lun (%d) inquiry - "
- "inq[0]= 0x%x, comp status 0x%x, scsi status 0x%x, "
- "rval=%d\n",
- ha->host_no, lun, inq->inq[0], comp_status, scsi_status,
- rval));
-
- if (rval != QLA_SUCCESS || comp_status != CS_COMPLETE ||
- scsi_status & SS_CHECK_CONDITION) {
-
- DEBUG(printk("scsi(%ld): INQ failed to issue iocb! "
- "fcport=[%04x/%p] rval=%x cs=%x ss=%x\n",
- ha->host_no, fcport->loop_id, fcport, rval,
- comp_status, scsi_status));
-
- if (rval == QLA_SUCCESS)
- rval = QLA_FUNCTION_FAILED;
-
- if (scsi_status & SS_CHECK_CONDITION) {
- DEBUG2(printk("scsi(%ld): INQ "
- "SS_CHECK_CONDITION Sense Data "
- "%02x %02x %02x %02x %02x %02x %02x %02x\n",
- ha->host_no,
- inq->p.rsp.req_sense_data[0],
- inq->p.rsp.req_sense_data[1],
- inq->p.rsp.req_sense_data[2],
- inq->p.rsp.req_sense_data[3],
- inq->p.rsp.req_sense_data[4],
- inq->p.rsp.req_sense_data[5],
- inq->p.rsp.req_sense_data[6],
- inq->p.rsp.req_sense_data[7]));
- }
-
- /* Device underrun drop LUN. */
- if (comp_status == CS_DATA_UNDERRUN &&
- scsi_status & SS_RESIDUAL_UNDER) {
- break;
- }
- } else {
- break;
- }
- }
-
- return (rval);
-}
-
-
-/*
- * qla2x00_configure_fabric
- * Setup SNS devices with loop ID's.
- *
- * Input:
- * ha = adapter block pointer.
- *
- * Returns:
- * 0 = success.
- * BIT_0 = error
- */
-static int
-qla2x00_configure_fabric(scsi_qla_host_t *ha)
-{
- int rval, rval2;
- fc_port_t *fcport, *fcptemp;
- uint16_t next_loopid;
- uint16_t mb[MAILBOX_REGISTER_COUNT];
- LIST_HEAD(new_fcports);
-
- /* If FL port exists, then SNS is present */
- rval = qla2x00_get_port_name(ha, SNS_FL_PORT, NULL, 0);
- if (rval != QLA_SUCCESS) {
- DEBUG2(printk("scsi(%ld): MBC_GET_PORT_NAME Failed, No FL "
- "Port\n", ha->host_no));
-
- ha->device_flags &= ~SWITCH_FOUND;
- return (QLA_SUCCESS);
- }
-
- /* Mark devices that need re-synchronization. */
- rval2 = qla2x00_device_resync(ha);
- if (rval2 == QLA_RSCNS_HANDLED) {
- /* No point doing the scan, just continue. */
- return (QLA_SUCCESS);
- }
- do {
- /* Ensure we are logged into the SNS. */
- qla2x00_login_fabric(ha, SIMPLE_NAME_SERVER, 0xff, 0xff, 0xfc,
- mb, BIT_1 | BIT_0);
- if (mb[0] != MBS_COMMAND_COMPLETE) {
- DEBUG2(qla_printk(KERN_INFO, ha,
- "Failed SNS login: loop_id=%x mb[0]=%x mb[1]=%x "
- "mb[2]=%x mb[6]=%x mb[7]=%x\n", SIMPLE_NAME_SERVER,
- mb[0], mb[1], mb[2], mb[6], mb[7]));
- return (QLA_SUCCESS);
- }
-
- if (test_and_clear_bit(REGISTER_FC4_NEEDED, &ha->dpc_flags)) {
- if (qla2x00_rft_id(ha)) {
- /* EMPTY */
- DEBUG2(printk("scsi(%ld): Register FC-4 "
- "TYPE failed.\n", ha->host_no));
- }
- if (qla2x00_rff_id(ha)) {
- /* EMPTY */
- DEBUG2(printk("scsi(%ld): Register FC-4 "
- "Features failed.\n", ha->host_no));
- }
- if (qla2x00_rnn_id(ha)) {
- /* EMPTY */
- DEBUG2(printk("scsi(%ld): Register Node Name "
- "failed.\n", ha->host_no));
- } else if (qla2x00_rsnn_nn(ha)) {
- /* EMPTY */
- DEBUG2(printk("scsi(%ld): Register Symbolic "
- "Node Name failed.\n", ha->host_no));
- }
- }
-
- rval = qla2x00_find_all_fabric_devs(ha, &new_fcports);
- if (rval != QLA_SUCCESS)
- break;
-
- /*
- * Logout all previous fabric devices marked lost, except
- * tape devices.
- */
- list_for_each_entry(fcport, &ha->fcports, list) {
- if (test_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags))
- break;
-
- if ((fcport->flags & FCF_FABRIC_DEVICE) == 0)
- continue;
-
- if (atomic_read(&fcport->state) == FCS_DEVICE_LOST) {
- qla2x00_mark_device_lost(ha, fcport,
- ql2xplogiabsentdevice);
- if (fcport->loop_id != FC_NO_LOOP_ID &&
- (fcport->flags & FCF_TAPE_PRESENT) == 0 &&
- fcport->port_type != FCT_INITIATOR &&
- fcport->port_type != FCT_BROADCAST) {
-
- qla2x00_fabric_logout(ha,
- fcport->loop_id);
- fcport->loop_id = FC_NO_LOOP_ID;
- }
- }
- }
-
- /* Starting free loop ID. */
- next_loopid = ha->min_external_loopid;