in myrb.c [911:1193]
static int myrb_get_hba_config(struct myrb_hba *cb)
{
struct myrb_enquiry2 *enquiry2;
dma_addr_t enquiry2_addr;
struct myrb_config2 *config2;
dma_addr_t config2_addr;
struct Scsi_Host *shost = cb->host;
struct pci_dev *pdev = cb->pdev;
int pchan_max = 0, pchan_cur = 0;
unsigned short status;
int ret = -ENODEV, memsize = 0;
enquiry2 = dma_alloc_coherent(&pdev->dev, sizeof(struct myrb_enquiry2),
&enquiry2_addr, GFP_KERNEL);
if (!enquiry2) {
shost_printk(KERN_ERR, cb->host,
"Failed to allocate V1 enquiry2 memory\n");
return -ENOMEM;
}
config2 = dma_alloc_coherent(&pdev->dev, sizeof(struct myrb_config2),
&config2_addr, GFP_KERNEL);
if (!config2) {
shost_printk(KERN_ERR, cb->host,
"Failed to allocate V1 config2 memory\n");
dma_free_coherent(&pdev->dev, sizeof(struct myrb_enquiry2),
enquiry2, enquiry2_addr);
return -ENOMEM;
}
mutex_lock(&cb->dma_mutex);
status = myrb_hba_enquiry(cb);
mutex_unlock(&cb->dma_mutex);
if (status != MYRB_STATUS_SUCCESS) {
shost_printk(KERN_WARNING, cb->host,
"Failed it issue V1 Enquiry\n");
goto out_free;
}
status = myrb_exec_type3(cb, MYRB_CMD_ENQUIRY2, enquiry2_addr);
if (status != MYRB_STATUS_SUCCESS) {
shost_printk(KERN_WARNING, cb->host,
"Failed to issue V1 Enquiry2\n");
goto out_free;
}
status = myrb_exec_type3(cb, MYRB_CMD_READ_CONFIG2, config2_addr);
if (status != MYRB_STATUS_SUCCESS) {
shost_printk(KERN_WARNING, cb->host,
"Failed to issue ReadConfig2\n");
goto out_free;
}
status = myrb_get_ldev_info(cb);
if (status != MYRB_STATUS_SUCCESS) {
shost_printk(KERN_WARNING, cb->host,
"Failed to get logical drive information\n");
goto out_free;
}
/*
* Initialize the Controller Model Name and Full Model Name fields.
*/
switch (enquiry2->hw.sub_model) {
case DAC960_V1_P_PD_PU:
if (enquiry2->scsi_cap.bus_speed == MYRB_SCSI_SPEED_ULTRA)
strcpy(cb->model_name, "DAC960PU");
else
strcpy(cb->model_name, "DAC960PD");
break;
case DAC960_V1_PL:
strcpy(cb->model_name, "DAC960PL");
break;
case DAC960_V1_PG:
strcpy(cb->model_name, "DAC960PG");
break;
case DAC960_V1_PJ:
strcpy(cb->model_name, "DAC960PJ");
break;
case DAC960_V1_PR:
strcpy(cb->model_name, "DAC960PR");
break;
case DAC960_V1_PT:
strcpy(cb->model_name, "DAC960PT");
break;
case DAC960_V1_PTL0:
strcpy(cb->model_name, "DAC960PTL0");
break;
case DAC960_V1_PRL:
strcpy(cb->model_name, "DAC960PRL");
break;
case DAC960_V1_PTL1:
strcpy(cb->model_name, "DAC960PTL1");
break;
case DAC960_V1_1164P:
strcpy(cb->model_name, "eXtremeRAID 1100");
break;
default:
shost_printk(KERN_WARNING, cb->host,
"Unknown Model %X\n",
enquiry2->hw.sub_model);
goto out;
}
/*
* Initialize the Controller Firmware Version field and verify that it
* is a supported firmware version.
* The supported firmware versions are:
*
* DAC1164P 5.06 and above
* DAC960PTL/PRL/PJ/PG 4.06 and above
* DAC960PU/PD/PL 3.51 and above
* DAC960PU/PD/PL/P 2.73 and above
*/
#if defined(CONFIG_ALPHA)
/*
* DEC Alpha machines were often equipped with DAC960 cards that were
* OEMed from Mylex, and had their own custom firmware. Version 2.70,
* the last custom FW revision to be released by DEC for these older
* controllers, appears to work quite well with this driver.
*
* Cards tested successfully were several versions each of the PD and
* PU, called by DEC the KZPSC and KZPAC, respectively, and having
* the Manufacturer Numbers (from Mylex), usually on a sticker on the
* back of the board, of:
*
* KZPSC: D040347 (1-channel) or D040348 (2-channel)
* or D040349 (3-channel)
* KZPAC: D040395 (1-channel) or D040396 (2-channel)
* or D040397 (3-channel)
*/
# define FIRMWARE_27X "2.70"
#else
# define FIRMWARE_27X "2.73"
#endif
if (enquiry2->fw.major_version == 0) {
enquiry2->fw.major_version = cb->enquiry->fw_major_version;
enquiry2->fw.minor_version = cb->enquiry->fw_minor_version;
enquiry2->fw.firmware_type = '0';
enquiry2->fw.turn_id = 0;
}
snprintf(cb->fw_version, sizeof(cb->fw_version),
"%u.%02u-%c-%02u",
enquiry2->fw.major_version,
enquiry2->fw.minor_version,
enquiry2->fw.firmware_type,
enquiry2->fw.turn_id);
if (!((enquiry2->fw.major_version == 5 &&
enquiry2->fw.minor_version >= 6) ||
(enquiry2->fw.major_version == 4 &&
enquiry2->fw.minor_version >= 6) ||
(enquiry2->fw.major_version == 3 &&
enquiry2->fw.minor_version >= 51) ||
(enquiry2->fw.major_version == 2 &&
strcmp(cb->fw_version, FIRMWARE_27X) >= 0))) {
shost_printk(KERN_WARNING, cb->host,
"Firmware Version '%s' unsupported\n",
cb->fw_version);
goto out;
}
/*
* Initialize the Channels, Targets, Memory Size, and SAF-TE
* Enclosure Management Enabled fields.
*/
switch (enquiry2->hw.model) {
case MYRB_5_CHANNEL_BOARD:
pchan_max = 5;
break;
case MYRB_3_CHANNEL_BOARD:
case MYRB_3_CHANNEL_ASIC_DAC:
pchan_max = 3;
break;
case MYRB_2_CHANNEL_BOARD:
pchan_max = 2;
break;
default:
pchan_max = enquiry2->cfg_chan;
break;
}
pchan_cur = enquiry2->cur_chan;
if (enquiry2->scsi_cap.bus_width == MYRB_WIDTH_WIDE_32BIT)
cb->bus_width = 32;
else if (enquiry2->scsi_cap.bus_width == MYRB_WIDTH_WIDE_16BIT)
cb->bus_width = 16;
else
cb->bus_width = 8;
cb->ldev_block_size = enquiry2->ldev_block_size;
shost->max_channel = pchan_cur;
shost->max_id = enquiry2->max_targets;
memsize = enquiry2->mem_size >> 20;
cb->safte_enabled = (enquiry2->fault_mgmt == MYRB_FAULT_SAFTE);
/*
* Initialize the Controller Queue Depth, Driver Queue Depth,
* Logical Drive Count, Maximum Blocks per Command, Controller
* Scatter/Gather Limit, and Driver Scatter/Gather Limit.
* The Driver Queue Depth must be at most one less than the
* Controller Queue Depth to allow for an automatic drive
* rebuild operation.
*/
shost->can_queue = cb->enquiry->max_tcq;
if (shost->can_queue < 3)
shost->can_queue = enquiry2->max_cmds;
if (shost->can_queue < 3)
/* Play safe and disable TCQ */
shost->can_queue = 1;
if (shost->can_queue > MYRB_CMD_MBOX_COUNT - 2)
shost->can_queue = MYRB_CMD_MBOX_COUNT - 2;
shost->max_sectors = enquiry2->max_sectors;
shost->sg_tablesize = enquiry2->max_sge;
if (shost->sg_tablesize > MYRB_SCATTER_GATHER_LIMIT)
shost->sg_tablesize = MYRB_SCATTER_GATHER_LIMIT;
/*
* Initialize the Stripe Size, Segment Size, and Geometry Translation.
*/
cb->stripe_size = config2->blocks_per_stripe * config2->block_factor
>> (10 - MYRB_BLKSIZE_BITS);
cb->segment_size = config2->blocks_per_cacheline * config2->block_factor
>> (10 - MYRB_BLKSIZE_BITS);
/* Assume 255/63 translation */
cb->ldev_geom_heads = 255;
cb->ldev_geom_sectors = 63;
if (config2->drive_geometry) {
cb->ldev_geom_heads = 128;
cb->ldev_geom_sectors = 32;
}
/*
* Initialize the Background Initialization Status.
*/
if ((cb->fw_version[0] == '4' &&
strcmp(cb->fw_version, "4.08") >= 0) ||
(cb->fw_version[0] == '5' &&
strcmp(cb->fw_version, "5.08") >= 0)) {
cb->bgi_status_supported = true;
myrb_bgi_control(cb);
}
cb->last_rbld_status = MYRB_NO_STDBY_RBLD_OR_CHECK_IN_PROGRESS;
ret = 0;
out:
shost_printk(KERN_INFO, cb->host,
"Configuring %s PCI RAID Controller\n", cb->model_name);
shost_printk(KERN_INFO, cb->host,
" Firmware Version: %s, Memory Size: %dMB\n",
cb->fw_version, memsize);
if (cb->io_addr == 0)
shost_printk(KERN_INFO, cb->host,
" I/O Address: n/a, PCI Address: 0x%lX, IRQ Channel: %d\n",
(unsigned long)cb->pci_addr, cb->irq);
else
shost_printk(KERN_INFO, cb->host,
" I/O Address: 0x%lX, PCI Address: 0x%lX, IRQ Channel: %d\n",
(unsigned long)cb->io_addr, (unsigned long)cb->pci_addr,
cb->irq);
shost_printk(KERN_INFO, cb->host,
" Controller Queue Depth: %d, Maximum Blocks per Command: %d\n",
cb->host->can_queue, cb->host->max_sectors);
shost_printk(KERN_INFO, cb->host,
" Driver Queue Depth: %d, Scatter/Gather Limit: %d of %d Segments\n",
cb->host->can_queue, cb->host->sg_tablesize,
MYRB_SCATTER_GATHER_LIMIT);
shost_printk(KERN_INFO, cb->host,
" Stripe Size: %dKB, Segment Size: %dKB, BIOS Geometry: %d/%d%s\n",
cb->stripe_size, cb->segment_size,
cb->ldev_geom_heads, cb->ldev_geom_sectors,
cb->safte_enabled ?
" SAF-TE Enclosure Management Enabled" : "");
shost_printk(KERN_INFO, cb->host,
" Physical: %d/%d channels %d/%d/%d devices\n",
pchan_cur, pchan_max, 0, cb->enquiry->pdev_dead,
cb->host->max_id);
shost_printk(KERN_INFO, cb->host,
" Logical: 1/1 channels, %d/%d disks\n",
cb->enquiry->ldev_count, MYRB_MAX_LDEVS);
out_free:
dma_free_coherent(&pdev->dev, sizeof(struct myrb_enquiry2),
enquiry2, enquiry2_addr);
dma_free_coherent(&pdev->dev, sizeof(struct myrb_config2),
config2, config2_addr);
return ret;
}