Index: head/sys/dev/smartpqi/smartpqi_cam.c =================================================================== --- head/sys/dev/smartpqi/smartpqi_cam.c +++ head/sys/dev/smartpqi/smartpqi_cam.c @@ -137,7 +137,6 @@ xpt_async(AC_LOST_DEVICE, tmppath, NULL); xpt_free_path(tmppath); pqisrc_free_device(softs, device); - OS_SLEEP(10000); } DBG_FUNC("OUT\n"); @@ -1199,3 +1198,7 @@ DBG_FUNC("OUT\n"); } + +static void smartpqi_cam_action(struct cam_sim *, union ccb *); +static void smartpqi_poll(struct cam_sim *); + Index: head/sys/dev/smartpqi/smartpqi_defines.h =================================================================== --- head/sys/dev/smartpqi/smartpqi_defines.h +++ head/sys/dev/smartpqi/smartpqi_defines.h @@ -35,9 +35,8 @@ #define PQI_STATUS_SUCCESS 0 #define PQISRC_CMD_TIMEOUT_CNT 1200000 /* 500usec * 1200000 = 5 min */ +#define PQI_CMND_COMPLETE_TMO 1000 /* in millisecond */ -/* #define SHARE_EVENT_QUEUE_FOR_IO 1 */ - #define INVALID_ELEM 0xffff #ifndef MIN #define MIN(a,b) ((a) < (b) ? (a) : (b)) @@ -94,10 +93,13 @@ #define LOCKNAME_SIZE 32 +#define INTR_TYPE_NONE 0x0 #define INTR_TYPE_FIXED 0x1 #define INTR_TYPE_MSI 0x2 #define INTR_TYPE_MSIX 0x4 #define SIS_ENABLE_MSIX 0x40 +#define SIS_ENABLE_INTX 0x80 +#define PQISRC_LEGACY_INTX_MASK 0x1 #define DMA_TO_VIRT(mem) ((mem)->virt_addr) #define DMA_PHYS_LOW(mem) (((mem)->dma_addr) & 0x00000000ffffffff) @@ -120,7 +122,9 @@ DISK_DEVICE, TAPE_DEVICE, ROM_DEVICE = 5, - MEDIUM_CHANGER_DEVICE = 8, + SES_DEVICE, + CONTROLLER_DEVICE, + MEDIUM_CHANGER_DEVICE, RAID_DEVICE = 0x0c, ENCLOSURE_DEVICE, ZBC_DEVICE = 0x14 @@ -549,8 +553,8 @@ #define PQI_MAX_LOGICALS 64 #define PQI_MAX_PHYSICALS 1024 #define PQI_MAX_DEVICES (PQI_MAX_LOGICALS + PQI_MAX_PHYSICALS + 1) /* 1 for controller device entry */ +#define PQI_MAX_EXT_TARGETS 32 - #define PQI_CTLR_INDEX (PQI_MAX_DEVICES - 1) #define PQI_PD_INDEX(t) (t + PQI_MAX_LOGICALS) @@ -700,8 +704,8 @@ #define PQISRC_DRIVER_MAJOR 1 #define PQISRC_DRIVER_MINOR 0 -#define PQISRC_DRIVER_RELEASE 1 -# define PQISRC_DRIVER_REVISION 239 +#define PQISRC_DRIVER_RELEASE 3 +#define PQISRC_DRIVER_REVISION 239 #define STR(s) # s #define PQISRC_VERSION(a, b, c, d) STR(a.b.c-d) @@ -892,15 +896,17 @@ typedef struct mtx OS_LOCK_T; typedef struct sema OS_SEMA_LOCK_T; +#define OS_PQILOCK_T OS_LOCK_T + #define OS_ACQUIRE_SPINLOCK(_lock) mtx_lock_spin(_lock) #define OS_RELEASE_SPINLOCK(_lock) mtx_unlock_spin(_lock) -#define PQI_LOCK(_lock) OS_ACQUIRE_SPINLOCK(_lock) -#define PQI_UNLOCK(_lock) OS_RELEASE_SPINLOCK(_lock) - #define OS_INIT_PQILOCK(_softs,_lock,_lockname) os_init_spinlock(_softs,_lock,_lockname) #define OS_UNINIT_PQILOCK(_lock) os_uninit_spinlock(_lock) +#define PQI_LOCK(_lock) OS_ACQUIRE_SPINLOCK(_lock) +#define PQI_UNLOCK(_lock) OS_RELEASE_SPINLOCK(_lock) + #define OS_GET_CDBP(rcb) ((rcb->cm_ccb->ccb_h.flags & CAM_CDB_POINTER) ? rcb->cm_ccb->csio.cdb_io.cdb_ptr : rcb->cm_ccb->csio.cdb_io.cdb_bytes) #define GET_SCSI_BUFFLEN(rcb) (rcb->cm_ccb->csio.dxfer_len) @@ -909,6 +915,10 @@ #define OS_GET_IO_REQ_QINDEX(softs,rcb) OS_GET_IO_QINDEX(softs,rcb) #define OS_GET_TMF_RESP_QID OS_GET_IO_RESP_QID #define OS_GET_TMF_REQ_QINDEX OS_GET_IO_REQ_QINDEX + +/* check request type */ +#define is_internal_req(rcb) (!(rcb)->cm_ccb) + /* sg elements addr, len, flags */ #define OS_GET_IO_SG_COUNT(rcb) rcb->nseg #define OS_GET_IO_SG_ADDR(rcb,i) rcb->sgt[i].addr @@ -926,7 +936,7 @@ /* Debug facility */ -#define PQISRC_LOG_LEVEL 0x30 +#define PQISRC_LOG_LEVEL 0x60 static int logging_level = PQISRC_LOG_LEVEL; @@ -935,8 +945,9 @@ #define PQISRC_FLAGS_INFO 0x00000002 #define PQISRC_FLAGS_FUNC 0x00000004 #define PQISRC_FLAGS_TRACEIO 0x00000008 -#define PQISRC_FLAGS_WARN 0x00000010 -#define PQISRC_FLAGS_ERROR 0x00000020 +#define PQISRC_FLAGS_DISC 0x00000010 +#define PQISRC_FLAGS_WARN 0x00000020 +#define PQISRC_FLAGS_ERROR 0x00000040 #define DBG_INIT(fmt,args...) \ @@ -964,6 +975,13 @@ do { \ if (logging_level & PQISRC_FLAGS_TRACEIO) { \ printf("[TRACEIO]:[ %s ] [ %d ]"fmt,__func__,__LINE__,##args); \ + } \ + }while(0); + +#define DBG_DISC(fmt,args...) \ + do { \ + if (logging_level & PQISRC_FLAGS_DISC) { \ + printf("[DISC]:[ %s ] [ %d ]"fmt,__func__,__LINE__,##args); \ } \ }while(0); Index: head/sys/dev/smartpqi/smartpqi_discovery.c =================================================================== --- head/sys/dev/smartpqi/smartpqi_discovery.c +++ head/sys/dev/smartpqi/smartpqi_discovery.c @@ -41,6 +41,38 @@ return (sshdr->response_code & 0x70) == 0x70; } +/* Initialize target ID pool for HBA/PDs */ +void pqisrc_init_targetid_pool(pqisrc_softstate_t *softs) +{ + int i, tid = PQI_MAX_PHYSICALS + PQI_MAX_LOGICALS - 1; + + for(i = 0; i < PQI_MAX_PHYSICALS; i++) { + softs->tid_pool.tid[i] = tid--; + } + softs->tid_pool.index = i - 1; +} + +int pqisrc_alloc_tid(pqisrc_softstate_t *softs) +{ + if(softs->tid_pool.index <= -1) { + DBG_ERR("Target ID exhausted\n"); + return INVALID_ELEM; + } + + return softs->tid_pool.tid[softs->tid_pool.index--]; +} + +void pqisrc_free_tid(pqisrc_softstate_t *softs, int tid) +{ + if(softs->tid_pool.index >= PQI_MAX_PHYSICALS) { + DBG_ERR("Target ID queue is full\n"); + return; + } + + softs->tid_pool.index++; + softs->tid_pool.tid[softs->tid_pool.index] = tid; +} + /* Update scsi sense info to a local buffer*/ boolean_t pqisrc_update_scsi_sense(const uint8_t *buff, int len, struct sense_header_scsi *header) @@ -176,6 +208,7 @@ break; case SA_CACHE_FLUSH: request->data_direction = SOP_DATA_DIR_FROM_DEVICE; + memcpy(device_mem.virt_addr, buff, datasize); cdb[0] = BMIC_WRITE; cdb[6] = BMIC_CACHE_FLUSH; cdb[7] = (uint8_t)((datasize) << 8); @@ -258,7 +291,7 @@ ret = PQI_STATUS_SUCCESS; } else{ - DBG_INFO("Error!! Bus=%u Target=%u, Cmd=0x%x," + DBG_DISC("Error!! Bus=%u Target=%u, Cmd=0x%x," "Ret=%d\n", BMIC_GET_LEVEL_2_BUS(scsi3addr), BMIC_GET_LEVEL_TWO_TARGET(scsi3addr), cmd, ret); @@ -342,7 +375,7 @@ } if (list_len == 0) { - DBG_INFO("list_len is 0\n"); + DBG_DISC("list_len is 0\n"); memcpy(lun_data, &report_lun_header, sizeof(report_lun_header)); goto out; } @@ -491,7 +524,7 @@ if (pqisrc_is_logical_device(device)) { if (pqisrc_is_external_raid_device(device)) { - DBG_INFO("External Raid Device!!!"); + DBG_DISC("External Raid Device!!!"); bus = PQI_EXTERNAL_RAID_VOLUME_BUS; target = (lunid >> 16) & 0x3fff; lun = lunid & 0xff; @@ -505,9 +538,6 @@ return; } - /* physical device */ - pqisrc_set_btl(device, PQI_PHYSICAL_DEVICE_BUS, PQI_PD_INDEX(scsi3addr[6]), 0); - DBG_FUNC("OUT\n"); } @@ -547,7 +577,7 @@ *ascq = header.ascq; } - DBG_INFO("sense_key: %x asc: %x ascq: %x\n", *sense_key, *asc, *ascq); + DBG_DISC("sense_key: %x asc: %x ascq: %x\n", *sense_key, *asc, *ascq); DBG_FUNC("OUT\n"); } @@ -636,7 +666,7 @@ /* Determine the reason for not ready state. */ off_status = pqisrc_get_volume_offline_status(softs, scsi3addr); - DBG_INFO("offline_status 0x%x\n", off_status); + DBG_DISC("offline_status 0x%x\n", off_status); /* Keep volume offline in certain cases. */ switch (off_status) { @@ -806,7 +836,7 @@ device->offload_enabled_pending = false; } - DBG_INFO("offload_config: 0x%x offload_enabled_pending: 0x%x \n", + DBG_DISC("offload_config: 0x%x offload_enabled_pending: 0x%x \n", device->offload_config, device->offload_enabled_pending); err_out: @@ -839,7 +869,7 @@ } device->raid_level = raid_level; - DBG_INFO("RAID LEVEL: %x \n", raid_level); + DBG_DISC("RAID LEVEL: %x \n", raid_level); DBG_FUNC("OUT\n"); } @@ -869,7 +899,7 @@ sizeof(device->vendor)); memcpy(device->model, &inq_buff[16], sizeof(device->model)); - DBG_INFO("DEV_TYPE: %x VENDOR: %s MODEL: %s\n", device->devtype, device->vendor, device->model); + DBG_DISC("DEV_TYPE: %x VENDOR: %s MODEL: %s\n", device->devtype, device->vendor, device->model); if (pqisrc_is_logical_device(device) && device->devtype == DISK_DEVICE) { if (pqisrc_is_external_raid_device(device)) { @@ -950,7 +980,7 @@ "-%u", identify_ctrl->fw_build_number); out: os_mem_free(softs, (char *)identify_ctrl, sizeof(*identify_ctrl)); - DBG_INFO("Firmware version: %s Firmware build number: %d\n", softs->fw_version, softs->fw_build_number); + DBG_INIT("Firmware version: %s Firmware build number: %d\n", softs->fw_version, softs->fw_build_number); DBG_FUNC("OUT\n"); return ret; } @@ -1012,7 +1042,7 @@ sizeof(device->phys_connector)); device->bay = id_phys->phys_bay_in_box; - DBG_INFO("BMIC DEV_TYPE: %x QUEUE DEPTH: 0x%x \n", device->device_type, device->queue_depth); + DBG_DISC("BMIC DEV_TYPE: %x QUEUE DEPTH: 0x%x \n", device->device_type, device->queue_depth); DBG_FUNC("OUT\n"); } @@ -1126,7 +1156,8 @@ raidmap_data_t *dev_data; pqi_scsi_dev_t *phys_disk; unsigned j; - + unsigned k; + DBG_FUNC("IN\n"); for(i = 0; i < PQI_MAX_DEVICES; i++) { @@ -1152,9 +1183,9 @@ LE_16(raid_map->row_cnt); queue_depth = 0; - for (i = 0; i < num_raidmap_entries; i++) { + for (k = 0; k < num_raidmap_entries; k++) { phys_disk = pqisrc_identify_device_via_ioaccel(softs, - dev_data[i].ioaccel_handle); + dev_data[k].ioaccel_handle); if (!phys_disk) { DBG_WARN( @@ -1182,7 +1213,7 @@ pqi_scsi_dev_t *device) { DBG_FUNC("IN\n"); - DBG_INFO("vendor: %s model: %s bus:%d target:%d lun:%d is_physical_device:0x%x expose_device:0x%x volume_offline 0x%x volume_status 0x%x \n", + DBG_WARN("vendor: %s model: %s bus:%d target:%d lun:%d is_physical_device:0x%x expose_device:0x%x volume_offline 0x%x volume_status 0x%x \n", device->vendor, device->model, device->bus, device->target, device->lun, device->is_physical_device, device->expose_device, device->volume_offline, device->volume_status); device->invalid = false; @@ -1201,7 +1232,7 @@ pqi_scsi_dev_t *device) { DBG_FUNC("IN\n"); - DBG_INFO("vendor: %s model: %s bus:%d target:%d lun:%d is_physical_device:0x%x expose_device:0x%x volume_offline 0x%x volume_status 0x%x \n", + DBG_DISC("vendor: %s model: %s bus:%d target:%d lun:%d is_physical_device:0x%x expose_device:0x%x volume_offline 0x%x volume_status 0x%x \n", device->vendor, device->model, device->bus, device->target, device->lun, device->is_physical_device, device->expose_device, device->volume_offline, device->volume_status); /* TBD: Call OS upper layer function to remove the device entry */ @@ -1285,21 +1316,21 @@ break; } - DBG_INFO("scsi BTL %d:%d:%d %s\n", + DBG_DISC("scsi BTL %d:%d:%d %s\n", device->bus, device->target, device->lun, status); DBG_FUNC("OUT\n"); } void pqisrc_device_mem_free(pqisrc_softstate_t *softs, pqi_scsi_dev_t *device) { - DBG_INFO("IN\n"); + DBG_FUNC("IN\n"); if (!device) return; if (device->raid_map) { os_mem_free(softs, (char *)device->raid_map, sizeof(pqisrc_raid_map_t)); } os_mem_free(softs, (char *)device,sizeof(*device)); - DBG_INFO("OUT\n"); + DBG_FUNC("OUT\n"); } @@ -1308,6 +1339,9 @@ { OS_ACQUIRE_SPINLOCK(&softs->devlist_lock); + if (!pqisrc_is_logical_device(device)) { + pqisrc_free_tid(softs,device->target); + } pqisrc_device_mem_free(softs, device); OS_RELEASE_SPINLOCK(&softs->devlist_lock); @@ -1327,8 +1361,10 @@ pqi_scsi_dev_t **removed = NULL; int nadded = 0, nremoved = 0; int j; - DBG_INFO("IN\n"); + int tid = 0; + DBG_FUNC("IN\n"); + added = os_mem_alloc(softs, sizeof(*added) * PQI_MAX_DEVICES); removed = os_mem_alloc(softs, sizeof(*removed) * PQI_MAX_DEVICES); @@ -1395,8 +1431,15 @@ if (device->volume_offline) continue; + /* physical device */ + if (!pqisrc_is_logical_device(device)) { + tid = pqisrc_alloc_tid(softs); + if(INVALID_ELEM != tid) + pqisrc_set_btl(device, PQI_PHYSICAL_DEVICE_BUS, tid, 0); + } + softs->device_list[device->target][device->lun] = device; - DBG_INFO("Added device %p at B : %d T : %d L : %d\n",device, + DBG_DISC("Added device %p at B : %d T : %d L : %d\n",device, device->bus,device->target,device->lun); /* To prevent this entry from being freed later. */ new_device_list[i] = NULL; @@ -1479,7 +1522,7 @@ os_mem_free(softs, (char *)removed, sizeof(*removed) * PQI_MAX_DEVICES); - DBG_INFO("OUT\n"); + DBG_FUNC("OUT\n"); } /* @@ -1517,7 +1560,7 @@ strncpy(host_wellness_driver_ver->driver_version + strlen(softs->os_name), PQISRC_DRIVER_VERSION, sizeof(host_wellness_driver_ver->driver_version) - strlen(softs->os_name)); } else { - DBG_INFO("OS name length(%lu) is longer than buffer of driver_version\n", + DBG_DISC("OS name length(%lu) is longer than buffer of driver_version\n", strlen(softs->os_name)); } host_wellness_driver_ver->driver_version[sizeof(host_wellness_driver_ver->driver_version) - 1] = '\0'; @@ -1618,7 +1661,7 @@ logical_cnt = BE_32(logical_dev_list->header.list_length) / sizeof(logical_dev_list->lun_entries[0]); - DBG_INFO("physical_cnt %d logical_cnt %d\n", physical_cnt, logical_cnt); + DBG_DISC("physical_cnt %d logical_cnt %d\n", physical_cnt, logical_cnt); if (physical_cnt) { bmic_phy_info = os_mem_alloc(softs, sizeof(*bmic_phy_info)); @@ -1663,9 +1706,15 @@ } scsi3addr = lun_ext_entry->lunid; + /* Save the target sas adderess for external raid device */ + if(lun_ext_entry->device_type == CONTROLLER_DEVICE) { + int target = lun_ext_entry->lunid[3] & 0x3f; + softs->target_sas_addr[target] = BE_64(lun_ext_entry->wwid); + } /* Skip masked physical non-disk devices. */ - if (MASKED_DEVICE(scsi3addr) && is_physical_device) + if (MASKED_DEVICE(scsi3addr) && is_physical_device + && (lun_ext_entry->ioaccel_handle == 0)) continue; device = new_device_list[new_dev_cnt]; @@ -1683,7 +1732,7 @@ if (ret) { DBG_WARN("Inquiry failed, skipping device %016llx\n", (unsigned long long)BE_64(device->scsi3addr[0])); - DBG_INFO("INQUIRY FAILED \n"); + DBG_DISC("INQUIRY FAILED \n"); continue; } pqisrc_assign_btl(device); @@ -1724,11 +1773,6 @@ pqisrc_get_physical_device_info(softs, device, bmic_phy_info); } - /* Logical device doesn't have SAS address - * so requires target SAS address for MSA. - */ - if(device->is_external_raid_device) - device->sas_address = BE_64((uint64_t)lun_ext_entry->lunid); new_dev_cnt++; break; case ENCLOSURE_DEVICE: @@ -1751,9 +1795,12 @@ if (pqisrc_is_hba_lunid(scsi3addr)) new_dev_cnt++; break; + case SES_DEVICE: + case CONTROLLER_DEVICE: + break; } } - DBG_INFO("new_dev_cnt %d\n", new_dev_cnt); + DBG_DISC("new_dev_cnt %d\n", new_dev_cnt); pqisrc_update_device_list(softs, new_device_list, new_dev_cnt); Index: head/sys/dev/smartpqi/smartpqi_event.c =================================================================== --- head/sys/dev/smartpqi/smartpqi_event.c +++ head/sys/dev/smartpqi/smartpqi_event.c @@ -49,6 +49,12 @@ return ret; } +void pqisrc_wait_for_rescan_complete(pqisrc_softstate_t *softs) +{ + os_sema_lock(&softs->scan_lock); + os_sema_unlock(&softs->scan_lock); +} + /* * Subroutine to acknowledge the events processed by the driver to the adapter. */ Index: head/sys/dev/smartpqi/smartpqi_helper.c =================================================================== --- head/sys/dev/smartpqi/smartpqi_helper.c +++ head/sys/dev/smartpqi/smartpqi_helper.c @@ -40,6 +40,28 @@ return !softs->ctrl_online; } +/* Function used set/clear legacy INTx bit in Legacy Interrupt INTx + * mask clear pqi register + */ +void pqisrc_configure_legacy_intx(pqisrc_softstate_t *softs, boolean_t enable_intx) +{ + uint32_t intx_mask; + uint32_t *reg_addr = NULL; + + DBG_FUNC("IN\n"); + + if (enable_intx) + reg_addr = &softs->pqi_reg->legacy_intr_mask_clr; + else + reg_addr = &softs->pqi_reg->legacy_intr_mask_set; + + intx_mask = PCI_MEM_GET32(softs, reg_addr, PQI_LEGACY_INTR_MASK_CLR); + intx_mask |= PQISRC_LEGACY_INTX_MASK; + PCI_MEM_PUT32(softs, reg_addr, PQI_LEGACY_INTR_MASK_CLR ,intx_mask); + + DBG_FUNC("OUT\n"); +} + /* * Function used to take exposed devices to OS as offline. */ @@ -213,7 +235,6 @@ "RAID 5+1", "RAID ADG", "RAID 1(ADM)", - "RAID 6", }; /* Get the RAID level from the index */ Index: head/sys/dev/smartpqi/smartpqi_init.c =================================================================== --- head/sys/dev/smartpqi/smartpqi_init.c +++ head/sys/dev/smartpqi/smartpqi_init.c @@ -96,17 +96,17 @@ softs->ib_spanning_supported = iu_layer_desc->ib_spanning_supported; softs->ob_spanning_supported = iu_layer_desc->ob_spanning_supported; - DBG_INFO("softs->pqi_dev_cap.max_iqs: %d\n", softs->pqi_dev_cap.max_iqs); - DBG_INFO("softs->pqi_dev_cap.max_iq_elements: %d\n", softs->pqi_dev_cap.max_iq_elements); - DBG_INFO("softs->pqi_dev_cap.max_iq_elem_len: %d\n", softs->pqi_dev_cap.max_iq_elem_len); - DBG_INFO("softs->pqi_dev_cap.min_iq_elem_len: %d\n", softs->pqi_dev_cap.min_iq_elem_len); - DBG_INFO("softs->pqi_dev_cap.max_oqs: %d\n", softs->pqi_dev_cap.max_oqs); - DBG_INFO("softs->pqi_dev_cap.max_oq_elements: %d\n", softs->pqi_dev_cap.max_oq_elements); - DBG_INFO("softs->pqi_dev_cap.max_oq_elem_len: %d\n", softs->pqi_dev_cap.max_oq_elem_len); - DBG_INFO("softs->pqi_dev_cap.intr_coales_time_granularity: %d\n", softs->pqi_dev_cap.intr_coales_time_granularity); - DBG_INFO("softs->max_ib_iu_length_per_fw: %d\n", softs->max_ib_iu_length_per_fw); - DBG_INFO("softs->ib_spanning_supported: %d\n", softs->ib_spanning_supported); - DBG_INFO("softs->ob_spanning_supported: %d\n", softs->ob_spanning_supported); + DBG_INIT("softs->pqi_dev_cap.max_iqs: %d\n", softs->pqi_dev_cap.max_iqs); + DBG_INIT("softs->pqi_dev_cap.max_iq_elements: %d\n", softs->pqi_dev_cap.max_iq_elements); + DBG_INIT("softs->pqi_dev_cap.max_iq_elem_len: %d\n", softs->pqi_dev_cap.max_iq_elem_len); + DBG_INIT("softs->pqi_dev_cap.min_iq_elem_len: %d\n", softs->pqi_dev_cap.min_iq_elem_len); + DBG_INIT("softs->pqi_dev_cap.max_oqs: %d\n", softs->pqi_dev_cap.max_oqs); + DBG_INIT("softs->pqi_dev_cap.max_oq_elements: %d\n", softs->pqi_dev_cap.max_oq_elements); + DBG_INIT("softs->pqi_dev_cap.max_oq_elem_len: %d\n", softs->pqi_dev_cap.max_oq_elem_len); + DBG_INIT("softs->pqi_dev_cap.intr_coales_time_granularity: %d\n", softs->pqi_dev_cap.intr_coales_time_granularity); + DBG_INIT("softs->max_ib_iu_length_per_fw: %d\n", softs->max_ib_iu_length_per_fw); + DBG_INIT("softs->ib_spanning_supported: %d\n", softs->ib_spanning_supported); + DBG_INIT("softs->ob_spanning_supported: %d\n", softs->ob_spanning_supported); os_mem_free(softs, (void *)capability, @@ -165,11 +165,11 @@ /* Set maximum outstanding requests */ /* The valid tag values are from 1, 2, ..., softs->max_outstanding_io * The rcb will be accessed by using the tag as index - * As 0 tag index is not used, we need to allocate one extra. + * * As 0 tag index is not used, we need to allocate one extra. */ softs->max_outstanding_io = softs->pqi_cap.max_outstanding_io; num_req = softs->max_outstanding_io + 1; - DBG_INFO("Max Outstanding IO reset to %d\n", num_req); + DBG_INIT("Max Outstanding IO reset to %d\n", num_req); alloc_size = num_req * sizeof(rcb_t); @@ -225,7 +225,7 @@ DBG_FUNC("IN\n"); - DBG_INFO("softs->intr_count : %d softs->num_cpus_online : %d", + DBG_INIT("softs->intr_count : %d softs->num_cpus_online : %d", softs->intr_count, softs->num_cpus_online); if (softs->intr_count == 1 || softs->num_cpus_online == 1) { @@ -241,16 +241,14 @@ softs->share_opq_and_eventq = false; } -#ifdef MULTIPLE_MSIX /* * softs->num_cpus_online is set as number of physical CPUs, * So we can have more queues/interrupts . */ if (softs->intr_count > 1) softs->share_opq_and_eventq = false; -#endif - DBG_INFO("softs->num_op_obq : %d\n",softs->num_op_obq); + DBG_INIT("softs->num_op_obq : %d\n",softs->num_op_obq); softs->num_op_raid_ibq = softs->num_op_obq; softs->num_op_aio_ibq = softs->num_op_raid_ibq; @@ -286,10 +284,10 @@ sizeof(sgt_t)) + MAX_EMBEDDED_SG_IN_FIRST_IU; - DBG_INFO("softs->max_ib_iu_length: %d\n", softs->max_ib_iu_length); - DBG_INFO("softs->num_elem_per_op_ibq: %d\n", softs->num_elem_per_op_ibq); - DBG_INFO("softs->num_elem_per_op_obq: %d\n", softs->num_elem_per_op_obq); - DBG_INFO("softs->max_sg_per_iu: %d\n", softs->max_sg_per_iu); + DBG_INIT("softs->max_ib_iu_length: %d\n", softs->max_ib_iu_length); + DBG_INIT("softs->num_elem_per_op_ibq: %d\n", softs->num_elem_per_op_ibq); + DBG_INIT("softs->num_elem_per_op_obq: %d\n", softs->num_elem_per_op_obq); + DBG_INIT("softs->max_sg_per_iu: %d\n", softs->max_sg_per_iu); DBG_FUNC("OUT\n"); } @@ -479,7 +477,7 @@ max_timeout = (val & 0xFFFF00000000) >> 32; - DBG_INFO("max_timeout for PQI reset completion in 100 msec units = %u\n", max_timeout); + DBG_INIT("max_timeout for PQI reset completion in 100 msec units = %u\n", max_timeout); while(1) { if (pqi_reset_timeout++ == max_timeout) { @@ -566,6 +564,8 @@ goto err_out; } + softs->intr_type = INTR_TYPE_NONE; + /* Get the interrupt count, type, priority available from OS */ ret = os_get_intr_config(softs); if (ret) { @@ -573,7 +573,15 @@ ret); goto err_out; } - + + /*Enable/Set Legacy INTx Interrupt mask clear pqi register, + *if allocated interrupt is legacy type. + */ + if (INTR_TYPE_FIXED == softs->intr_type) { + pqisrc_configure_legacy_intx(softs, true); + sis_enable_intx(softs); + } + /* Create Admin Queue pair*/ ret = pqisrc_create_admin_queue(softs); if(ret) { @@ -639,7 +647,7 @@ int ret = PQI_STATUS_SUCCESS; if (SIS_IS_KERNEL_PANIC(softs)) { - DBG_INFO("Controller FW is not runnning"); + DBG_INIT("Controller FW is not runnning"); return PQI_STATUS_FAILURE; } @@ -652,7 +660,7 @@ return ret; } /* Disable interrupts ? */ - sis_disable_msix(softs); + sis_disable_interrupt(softs); /* reset pqi, this will delete queues */ ret = pqi_reset(softs); @@ -670,14 +678,54 @@ return ret; } +int pqisrc_wait_for_cmnd_complete(pqisrc_softstate_t *softs) +{ + int ret = PQI_STATUS_SUCCESS; + int tmo = PQI_CMND_COMPLETE_TMO; + + COND_WAIT((softs->taglist.num_elem == softs->max_outstanding_io), tmo); + if (!tmo) { + DBG_ERR("Pending commands %x!!!",softs->taglist.num_elem); + ret = PQI_STATUS_TIMEOUT; + } + return ret; +} + +void pqisrc_complete_internal_cmds(pqisrc_softstate_t *softs) +{ + int tag = 0; + rcb_t *rcb; + + for (tag = 1; tag <= softs->max_outstanding_io; tag++) { + rcb = &softs->rcb[tag]; + if(rcb->req_pending && is_internal_req(rcb)) { + rcb->status = REQUEST_FAILED; + rcb->req_pending = false; + } + } +} + /* * Uninitialize the resources used during PQI initialization. */ void pqisrc_pqi_uninit(pqisrc_softstate_t *softs) { - int i; + int i, ret; + DBG_FUNC("IN\n"); - + + /* Wait for any rescan to finish */ + pqisrc_wait_for_rescan_complete(softs); + + /* Wait for commands to complete */ + ret = pqisrc_wait_for_cmnd_complete(softs); + + /* Complete all pending commands. */ + if(ret != PQI_STATUS_SUCCESS) { + pqisrc_complete_internal_cmds(softs); + os_complete_outstanding_cmds_nodevice(softs); + } + if(softs->devlist_lockcreated==true){ os_uninit_spinlock(&softs->devlist_lock); softs->devlist_lockcreated = false; @@ -701,9 +749,6 @@ os_dma_mem_free(softs, &softs->op_ibq_dma_mem); os_dma_mem_free(softs, &softs->op_obq_dma_mem); os_dma_mem_free(softs, &softs->event_q_dma_mem); - - /* Complete all pending commands. */ - os_complete_outstanding_cmds_nodevice(softs); /* Free rcb */ pqisrc_free_rcb(softs, softs->max_outstanding_io + 1); @@ -711,10 +756,10 @@ /* Free request id lists */ pqisrc_destroy_taglist(softs,&softs->taglist); - if(softs->admin_ib_queue.lockcreated==true){ - OS_UNINIT_PQILOCK(&softs->admin_ib_queue.lock); - softs->admin_ib_queue.lockcreated = false; - } + if(softs->admin_ib_queue.lockcreated==true){ + OS_UNINIT_PQILOCK(&softs->admin_ib_queue.lock); + softs->admin_ib_queue.lockcreated = false; + } /* Free Admin Queue */ os_dma_mem_free(softs, &softs->admin_queue_dma_mem); @@ -746,6 +791,12 @@ goto err_out; } + ret = os_create_semaphore("scan_lock", 1, &softs->scan_lock); + if(ret != PQI_STATUS_SUCCESS){ + DBG_ERR(" Failed to initialize scan lock\n"); + goto err_scan_lock; + } + /* Init the PQI interface */ ret = pqisrc_pqi_init(softs); if (ret) { @@ -798,12 +849,6 @@ } softs->devlist_lockcreated = true; - ret = os_create_semaphore("scan_lock", 1, &softs->scan_lock); - if(ret != PQI_STATUS_SUCCESS){ - DBG_ERR(" Failed to initialize scan lock\n"); - goto err_scan_lock; - } - OS_ATOMIC64_SET(softs, num_intrs, 0); softs->prev_num_intrs = softs->num_intrs; @@ -825,12 +870,12 @@ for(j = 0; j < PQI_MAX_MULTILUN; j++) softs->device_list[i][j] = NULL; + pqisrc_init_targetid_pool(softs); + DBG_FUNC("OUT\n"); return ret; err_config_tab: - os_destroy_semaphore(&softs->scan_lock); -err_scan_lock: if(softs->devlist_lockcreated==true){ os_uninit_spinlock(&softs->devlist_lock); softs->devlist_lockcreated = false; @@ -843,6 +888,8 @@ err_intr: pqisrc_pqi_uninit(softs); err_pqi: + os_destroy_semaphore(&softs->scan_lock); +err_scan_lock: pqisrc_sis_uninit(softs); err_out: DBG_FUNC("OUT failed\n"); @@ -899,13 +946,13 @@ { DBG_FUNC("IN\n"); - os_destroy_intr(softs); - - os_destroy_semaphore(&softs->scan_lock); - pqisrc_pqi_uninit(softs); pqisrc_sis_uninit(softs); + + os_destroy_semaphore(&softs->scan_lock); + + os_destroy_intr(softs); pqisrc_cleanup_devices(softs); Index: head/sys/dev/smartpqi/smartpqi_intr.c =================================================================== --- head/sys/dev/smartpqi/smartpqi_intr.c +++ head/sys/dev/smartpqi/smartpqi_intr.c @@ -181,7 +181,7 @@ return PQI_STATUS_FAILURE; } softs->os_specific.msi_ctx[0].pqi_dev = dev; - softs->os_specific.msi_ctx[0].oq_id = 0; + softs->os_specific.msi_ctx[0].oq_id = 1; error = bus_setup_intr(dev, softs->os_specific.pqi_irq[0], INTR_TYPE_CAM | INTR_MPSAFE, \ @@ -227,7 +227,7 @@ } softs->os_specific.msi_ctx[i].pqi_dev = dev; - softs->os_specific.msi_ctx[i].oq_id = i; + softs->os_specific.msi_ctx[i].oq_id = i+1; error = bus_setup_intr(dev,softs->os_specific.pqi_irq[i], INTR_TYPE_CAM | INTR_MPSAFE,\ Index: head/sys/dev/smartpqi/smartpqi_ioctl.c =================================================================== --- head/sys/dev/smartpqi/smartpqi_ioctl.c +++ head/sys/dev/smartpqi/smartpqi_ioctl.c @@ -166,6 +166,10 @@ return error; } +static d_open_t smartpqi_open; +static d_ioctl_t smartpqi_ioctl; +static d_close_t smartpqi_close; + static struct cdevsw smartpqi_cdevsw = { .d_version = D_VERSION, @@ -312,6 +316,11 @@ request.sg_descriptors[0].flags = SG_FLAG_LAST; } tag = pqisrc_get_tag(&softs->taglist); + if (INVALID_ELEM == tag) { + DBG_ERR("Tag not available\n"); + ret = PQI_STATUS_FAILURE; + goto free_mem; + } request.request_id = tag; request.response_queue_id = ob_q->q_id; request.error_index = request.request_id; Index: head/sys/dev/smartpqi/smartpqi_main.c =================================================================== --- head/sys/dev/smartpqi/smartpqi_main.c +++ head/sys/dev/smartpqi/smartpqi_main.c @@ -75,6 +75,10 @@ {0x9005, 0x028f, 0x9005, 0x806, PQI_HWIF_SRCV, "SmartRAID 3100"}, {0x9005, 0x028f, 0x9005, 0x807, PQI_HWIF_SRCV, "SmartRAID 3162-8i"}, {0x9005, 0x028f, 0x152d, 0x8a22, PQI_HWIF_SRCV, "QS-8204-8i"}, + {0x9005, 0x028f, 0x193d, 0xf460, PQI_HWIF_SRCV, "UN RAID P460-M4"}, + {0x9005, 0x028f, 0x193d, 0xf461, PQI_HWIF_SRCV, "UN RAID P460-B4"}, + {0x9005, 0x028f, 0x1bd4, 0x004b, PQI_HWIF_SRCV, "INSPUR RAID PM8204-2GB"}, + {0x9005, 0x028f, 0x1bd4, 0x004c, PQI_HWIF_SRCV, "INSPUR RAID PM8204-4GB"}, /* (MSCC PM8222 8x12G based) */ {0x9005, 0x028f, 0x9005, 0x900, PQI_HWIF_SRCV, "SmartHBA 2100-8i"}, @@ -87,6 +91,10 @@ {0x9005, 0x028f, 0x9005, 0x907, PQI_HWIF_SRCV, "HBA 1100"}, {0x9005, 0x028f, 0x9005, 0x908, PQI_HWIF_SRCV, "SmartHBA 2100"}, {0x9005, 0x028f, 0x9005, 0x90a, PQI_HWIF_SRCV, "SmartHBA 2100A-8i"}, + {0x9005, 0x028f, 0x193d, 0x8460, PQI_HWIF_SRCV, "UN HBA H460-M1"}, + {0x9005, 0x028f, 0x193d, 0x8461, PQI_HWIF_SRCV, "UN HBA H460-B1"}, + {0x9005, 0x028f, 0x1bd4, 0x004a, PQI_HWIF_SRCV, "INSPUR SMART-HBA PM8222-SHBA"}, + {0x9005, 0x028f, 0x13fe, 0x8312, PQI_HWIF_SRCV, "MIC-8312BridgeB"}, /* (SRCx MSCC FVB 24x12G based) */ {0x9005, 0x028f, 0x103c, 0x1001, PQI_HWIF_SRCV, "MSCC FVB"}, @@ -99,10 +107,13 @@ {0x9005, 0x028f, 0x9005, 0x1301, PQI_HWIF_SRCV, "HBA 1100-24i"}, {0x9005, 0x028f, 0x9005, 0x1302, PQI_HWIF_SRCV, "SmartHBA 2100-8i8e"}, {0x9005, 0x028f, 0x9005, 0x1303, PQI_HWIF_SRCV, "SmartHBA 2100-24i"}, + {0x9005, 0x028f, 0x105b, 0x1321, PQI_HWIF_SRCV, "8242-24i"}, + {0x9005, 0x028f, 0x1bd4, 0x0045, PQI_HWIF_SRCV, "INSPUR SMART-HBA 8242-24i"}, /* (MSCC PM8236 16x12G based) */ {0x9005, 0x028f, 0x152d, 0x8a24, PQI_HWIF_SRCV, "QS-8236-16i"}, {0x9005, 0x028f, 0x9005, 0x1380, PQI_HWIF_SRCV, "SmartRAID 3154-16i"}, + {0x9005, 0x028f, 0x1bd4, 0x0046, PQI_HWIF_SRCV, "INSPUR RAID 8236-16i"}, /* (MSCC PM8237 24x12G based) */ {0x9005, 0x028f, 0x103c, 0x1100, PQI_HWIF_SRCV, "P816i-a SR Gen10"}, @@ -112,12 +123,16 @@ {0x9005, 0x028f, 0x152d, 0x8a23, PQI_HWIF_SRCV, "QS-8238-16i"}, {0x9005, 0x028f, 0x9005, 0x1280, PQI_HWIF_SRCV, "HBA 1100-16i"}, {0x9005, 0x028f, 0x9005, 0x1281, PQI_HWIF_SRCV, "HBA 1100-16e"}, + {0x9005, 0x028f, 0x105b, 0x1211, PQI_HWIF_SRCV, "8238-16i"}, + {0x9005, 0x028f, 0x1bd4, 0x0048, PQI_HWIF_SRCV, "INSPUR SMART-HBA 8238-16i"}, + {0x9005, 0x028f, 0x9005, 0x1282, PQI_HWIF_SRCV, "SmartHBA 2100-16i"}, /* (MSCC PM8240 24x12G based) */ {0x9005, 0x028f, 0x152d, 0x8a36, PQI_HWIF_SRCV, "QS-8240-24i"}, {0x9005, 0x028f, 0x9005, 0x1200, PQI_HWIF_SRCV, "SmartRAID 3154-24i"}, {0x9005, 0x028f, 0x9005, 0x1201, PQI_HWIF_SRCV, "SmartRAID 3154-8i16e"}, {0x9005, 0x028f, 0x9005, 0x1202, PQI_HWIF_SRCV, "SmartRAID 3154-8i8e"}, + {0x9005, 0x028f, 0x1bd4, 0x0047, PQI_HWIF_SRCV, "INSPUR RAID 8240-24i"}, {0, 0, 0, 0, 0, 0} }; @@ -466,6 +481,12 @@ return rval; } + +static int smartpqi_probe(device_t dev); +static int smartpqi_attach(device_t dev); +static int smartpqi_detach(device_t dev); +static int smartpqi_suspend(device_t dev); +static int smartpqi_resume(device_t dev); /* * PCI bus interface. Index: head/sys/dev/smartpqi/smartpqi_mem.c =================================================================== --- head/sys/dev/smartpqi/smartpqi_mem.c +++ head/sys/dev/smartpqi/smartpqi_mem.c @@ -40,20 +40,6 @@ *paddr = segs[0].ds_addr; } -int os_dma_setup(pqisrc_softstate_t *softs) -{ - DBG_FUNC("IN\n"); - DBG_FUNC("OUT\n"); - return PQI_STATUS_SUCCESS; -} - -int os_dma_destroy(pqisrc_softstate_t *softs) -{ - DBG_FUNC("IN\n"); - DBG_FUNC("OUT\n"); - return PQI_STATUS_SUCCESS; -} - /* * DMA mem resource allocation wrapper function */ Index: head/sys/dev/smartpqi/smartpqi_prototypes.h =================================================================== --- head/sys/dev/smartpqi/smartpqi_prototypes.h +++ head/sys/dev/smartpqi/smartpqi_prototypes.h @@ -38,6 +38,8 @@ int pqisrc_process_config_table(pqisrc_softstate_t *); int pqisrc_flush_cache(pqisrc_softstate_t *, enum pqisrc_flush_cache_event_type); int pqisrc_wait_for_pqi_reset_completion(pqisrc_softstate_t *); +int pqisrc_wait_for_cmnd_complete(pqisrc_softstate_t *); +void pqisrc_complete_internal_cmds(pqisrc_softstate_t *); /* pqi_sis.c*/ int pqisrc_sis_init(pqisrc_softstate_t *); @@ -45,8 +47,11 @@ int pqisrc_reenable_sis(pqisrc_softstate_t *); void pqisrc_trigger_nmi_sis(pqisrc_softstate_t *); void sis_disable_msix(pqisrc_softstate_t *); +void sis_enable_intx(pqisrc_softstate_t *); +void sis_disable_intx(pqisrc_softstate_t *softs); int pqisrc_force_sis(pqisrc_softstate_t *); int pqisrc_sis_wait_for_db_bit_to_clear(pqisrc_softstate_t *, uint32_t); +void sis_disable_interrupt(pqisrc_softstate_t*); /* pqi_queue.c */ int pqisrc_submit_admin_req(pqisrc_softstate_t *, @@ -82,6 +87,9 @@ void pqisrc_device_mem_free(pqisrc_softstate_t *, pqi_scsi_dev_t *); boolean_t pqisrc_is_external_raid_device(pqi_scsi_dev_t *device); void pqisrc_free_device(pqisrc_softstate_t * softs,pqi_scsi_dev_t *device); +void pqisrc_init_targetid_pool(pqisrc_softstate_t *softs); +int pqisrc_alloc_tid(pqisrc_softstate_t *softs); +void pqisrc_free_tid(pqisrc_softstate_t *softs, int); /* pqi_helper.c */ boolean_t pqisrc_ctrl_offline(pqisrc_softstate_t *); @@ -95,6 +103,7 @@ boolean_t pqisrc_scsi3addr_equal(uint8_t *, uint8_t *); void check_struct_sizes(void); char *pqisrc_raidlevel_to_string(uint8_t); +void pqisrc_configure_legacy_intx(pqisrc_softstate_t*, boolean_t); /* pqi_response.c */ void pqisrc_signal_event(pqisrc_softstate_t *softs, rcb_t *rcb); @@ -131,6 +140,9 @@ void pqisrc_ack_all_events(void *arg); +void pqisrc_event_worker(void *, int); +int pqisrc_scsi_setup(struct pqisrc_softstate *); +void pqisrc_scsi_cleanup(struct pqisrc_softstate *); boolean_t pqisrc_update_scsi_sense(const uint8_t *, int, struct sense_header_scsi *); int pqisrc_build_send_raid_request(pqisrc_softstate_t *, pqisrc_raid_req_t *, @@ -180,6 +192,7 @@ int pqisrc_alloc_and_create_ob_queues(pqisrc_softstate_t *); int pqisrc_process_task_management_response(pqisrc_softstate_t *, pqi_tmf_resp_t *); +void pqisrc_wait_for_rescan_complete(pqisrc_softstate_t *softs); /* pqi_ioctl.c*/ @@ -195,8 +208,6 @@ void *os_mem_alloc(pqisrc_softstate_t *,size_t); void os_mem_free(pqisrc_softstate_t *,char *,size_t); void os_resource_free(pqisrc_softstate_t *); -int os_dma_setup(pqisrc_softstate_t *); -int os_dma_destroy(pqisrc_softstate_t *); /* FreeBSD intr.c */ int os_get_intr_config(pqisrc_softstate_t *); @@ -227,7 +238,10 @@ void os_start_heartbeat_timer(void *); /* FreeBSD_cam.c */ +int pqisrc_scsi_setup(struct pqisrc_softstate *); +void pqisrc_scsi_cleanup(struct pqisrc_softstate *); uint8_t os_get_task_attr(rcb_t *); +void os_wellness_periodic(void *); void smartpqi_target_rescan(struct pqisrc_softstate *); /* FreeBSD_intr.c FreeBSD_main.c */ Index: head/sys/dev/smartpqi/smartpqi_queue.c =================================================================== --- head/sys/dev/smartpqi/smartpqi_queue.c +++ head/sys/dev/smartpqi/smartpqi_queue.c @@ -200,7 +200,7 @@ (dma_addr_t)((uint8_t*)(softs->admin_ib_queue.ci_dma_addr) + PQI_ADDR_ALIGN_MASK_64 + 1); - DBG_INFO("softs->admin_ib_queue.ci_dma_addr : %p,softs->admin_ob_queue.pi_dma_addr :%p\n", + DBG_INIT("softs->admin_ib_queue.ci_dma_addr : %p,softs->admin_ob_queue.pi_dma_addr :%p\n", (void*)softs->admin_ib_queue.ci_dma_addr, (void*)softs->admin_ob_queue.pi_dma_addr ); /* Verify alignment */ @@ -354,7 +354,7 @@ if(ret){ DBG_ERR("Admin spinlock initialization failed\n"); softs->admin_ib_queue.lockcreated = false; - goto err_out; + goto err_lock; } softs->admin_ib_queue.lockcreated = true; @@ -364,6 +364,7 @@ DBG_FUNC("OUT\n"); return ret; +err_lock: err_q_create: os_dma_mem_free(softs, &softs->admin_queue_dma_mem); err_out: Index: head/sys/dev/smartpqi/smartpqi_request.c =================================================================== --- head/sys/dev/smartpqi/smartpqi_request.c +++ head/sys/dev/smartpqi/smartpqi_request.c @@ -268,6 +268,8 @@ aio_req->res3 = 0; aio_req->err_idx = aio_req->req_id; aio_req->cdb_len = rcb->cmdlen; + if(rcb->cmdlen > sizeof(aio_req->cdb)) + rcb->cmdlen = sizeof(aio_req->cdb); memcpy(aio_req->cdb, rcb->cdbp, rcb->cmdlen); #if 0 DBG_IO("CDB : \n"); @@ -565,7 +567,8 @@ /* Calculate stripe information for the request. */ blks_per_row = data_disks_per_row * strip_sz; - + if (!blks_per_row) + return PQI_STATUS_FAILURE; /* use __udivdi3 ? */ fst_row = fst_blk / blks_per_row; lst_row = lst_blk / blks_per_row; Index: head/sys/dev/smartpqi/smartpqi_sis.c =================================================================== --- head/sys/dev/smartpqi/smartpqi_sis.c +++ head/sys/dev/smartpqi/smartpqi_sis.c @@ -44,6 +44,60 @@ DBG_FUNC("OUT\n"); } +void sis_enable_intx(pqisrc_softstate_t *softs) +{ + uint32_t db_reg; + + DBG_FUNC("IN\n"); + + db_reg = PCI_MEM_GET32(softs, &softs->ioa_reg->host_to_ioa_db, + LEGACY_SIS_IDBR); + db_reg |= SIS_ENABLE_INTX; + PCI_MEM_PUT32(softs, &softs->ioa_reg->host_to_ioa_db, + LEGACY_SIS_IDBR, db_reg); + if (pqisrc_sis_wait_for_db_bit_to_clear(softs,SIS_ENABLE_INTX) + != PQI_STATUS_SUCCESS) { + DBG_ERR("Failed to wait for enable intx db bit to clear\n"); + } + DBG_FUNC("OUT\n"); +} + +void sis_disable_intx(pqisrc_softstate_t *softs) +{ + uint32_t db_reg; + + DBG_FUNC("IN\n"); + + db_reg = PCI_MEM_GET32(softs, &softs->ioa_reg->host_to_ioa_db, + LEGACY_SIS_IDBR); + db_reg &= ~SIS_ENABLE_INTX; + PCI_MEM_PUT32(softs, &softs->ioa_reg->host_to_ioa_db, + LEGACY_SIS_IDBR, db_reg); + + DBG_FUNC("OUT\n"); +} + +void sis_disable_interrupt(pqisrc_softstate_t *softs) +{ + DBG_FUNC("IN"); + + switch(softs->intr_type) { + case INTR_TYPE_FIXED: + pqisrc_configure_legacy_intx(softs,false); + sis_disable_intx(softs); + break; + case INTR_TYPE_MSI: + case INTR_TYPE_MSIX: + sis_disable_msix(softs); + break; + default: + DBG_ERR("Inerrupt mode none!\n"); + break; + } + + DBG_FUNC("OUT"); +} + /* Trigger a NMI as part of taking controller offline procedure */ void pqisrc_trigger_nmi_sis(pqisrc_softstate_t *softs) { @@ -172,7 +226,7 @@ mb[0] = SIS_CMD_GET_ADAPTER_PROPERTIES; ret = pqisrc_send_sis_cmd(softs, mb); if (!ret) { - DBG_INFO("GET_PROPERTIES prop = %x, ext_prop = %x\n", + DBG_INIT("GET_PROPERTIES prop = %x, ext_prop = %x\n", mb[1], mb[4]); *prop = mb[1]; *ext_prop = mb[4]; @@ -197,7 +251,7 @@ softs->pref_settings.max_cmd_size = mb[1] >> 16; /* 15:00: Maximum FIB size in bytes */ softs->pref_settings.max_fib_size = mb[1] & 0x0000FFFF; - DBG_INFO("cmd size = %x, fib size = %x\n", + DBG_INIT("cmd size = %x, fib size = %x\n", softs->pref_settings.max_cmd_size, softs->pref_settings.max_fib_size); } @@ -220,23 +274,14 @@ softs->pqi_cap.max_sg_elem = mb[1]; softs->pqi_cap.max_transfer_size = mb[2]; softs->pqi_cap.max_outstanding_io = mb[3]; -#ifdef DMA_ATTR - softs->os_specific.buf_dma_attr.dma_attr_sgllen = - softs->pqi_cap.max_sg_elem; - softs->os_specific.buf_dma_attr.dma_attr_maxxfer = - softs->pqi_cap.max_transfer_size; - softs->os_specific.buf_dma_attr.dma_attr_count_max = - softs->pqi_cap.max_transfer_size - 1; -#endif softs->pqi_cap.conf_tab_off = mb[4]; - softs->pqi_cap.conf_tab_sz = mb[5]; - DBG_INFO("max_sg_elem = %x\n", + DBG_INIT("max_sg_elem = %x\n", softs->pqi_cap.max_sg_elem); - DBG_INFO("max_transfer_size = %x\n", + DBG_INIT("max_transfer_size = %x\n", softs->pqi_cap.max_transfer_size); - DBG_INFO("max_outstanding_io = %x\n", + DBG_INIT("max_outstanding_io = %x\n", softs->pqi_cap.max_outstanding_io); } @@ -377,28 +422,16 @@ goto err_out; } - /* We need to allocate DMA memory here , - * Do any os specific DMA setup. - */ - ret = os_dma_setup(softs); - if (ret) { - DBG_ERR("Failed to Setup DMA\n"); - goto err_out; - } - /* Init struct base addr */ ret = pqisrc_init_struct_base(softs); if (ret) { DBG_ERR("Failed to set init struct base addr\n"); - goto err_dma; + goto err_out; } - DBG_FUNC("OUT\n"); return ret; -err_dma: - os_dma_destroy(softs); err_out: DBG_FUNC("OUT failed\n"); return ret; @@ -410,11 +443,8 @@ DBG_FUNC("IN\n"); os_dma_mem_free(softs, &softs->err_buf_dma_mem); - - os_dma_destroy(softs); os_resource_free(softs); pqi_reset(softs); - DBG_FUNC("OUT\n"); } Index: head/sys/dev/smartpqi/smartpqi_structures.h =================================================================== --- head/sys/dev/smartpqi/smartpqi_structures.h +++ head/sys/dev/smartpqi/smartpqi_structures.h @@ -512,7 +512,7 @@ boolean_t created; boolean_t lockcreated; char lockname[LOCKNAME_SIZE]; - OS_LOCK_T lock OS_ATTRIBUTE_ALIGNED(8); + OS_PQILOCK_T lock OS_ATTRIBUTE_ALIGNED(8); }ib_queue_t; typedef struct ob_queue { @@ -931,6 +931,11 @@ boolean_t req_pending; }rcb_t; +typedef struct tid_pool { + int tid[PQI_MAX_PHYSICALS]; + int index; +}tid_pool_t; + typedef struct pqisrc_softstate { OS_SPECIFIC_T os_specific; struct ioa_registers *ioa_reg; @@ -992,6 +997,7 @@ pqi_scsi_dev_t *device_list[PQI_MAX_DEVICES][PQI_MAX_MULTILUN]; OS_SEMA_LOCK_T scan_lock; uint8_t lun_count[PQI_MAX_DEVICES]; + uint64_t target_sas_addr[PQI_MAX_EXT_TARGETS]; OS_ATOMIC64_T num_intrs; uint64_t prev_num_intrs; uint64_t prev_heartbeat_count; @@ -1005,6 +1011,7 @@ boolean_t ctrl_online; uint8_t pqi_reset_quiesce_allowed : 1; boolean_t ctrl_in_pqi_mode; + tid_pool_t tid_pool; }pqisrc_softstate_t; #endif