-static void cciss_getgeometry(int cntl_num)
-{
- ReportLunData_struct *ld_buff;
- InquiryData_struct *inq_buff;
- int return_code;
- int i;
- int listlength = 0;
- __u32 lunid = 0;
- unsigned block_size;
- sector_t total_size;
-
- ld_buff = kzalloc(sizeof(ReportLunData_struct), GFP_KERNEL);
- if (ld_buff == NULL) {
- printk(KERN_ERR "cciss: out of memory\n");
- return;
- }
- inq_buff = kmalloc(sizeof(InquiryData_struct), GFP_KERNEL);
- if (inq_buff == NULL) {
- printk(KERN_ERR "cciss: out of memory\n");
- kfree(ld_buff);
- return;
- }
- /* Get the firmware version */
- return_code = sendcmd(CISS_INQUIRY, cntl_num, inq_buff,
- sizeof(InquiryData_struct), 0, 0, 0, NULL,
- TYPE_CMD);
- if (return_code == IO_OK) {
- hba[cntl_num]->firm_ver[0] = inq_buff->data_byte[32];
- hba[cntl_num]->firm_ver[1] = inq_buff->data_byte[33];
- hba[cntl_num]->firm_ver[2] = inq_buff->data_byte[34];
- hba[cntl_num]->firm_ver[3] = inq_buff->data_byte[35];
- } else { /* send command failed */
-
- printk(KERN_WARNING "cciss: unable to determine firmware"
- " version of controller\n");
- }
- /* Get the number of logical volumes */
- return_code = sendcmd(CISS_REPORT_LOG, cntl_num, ld_buff,
- sizeof(ReportLunData_struct), 0, 0, 0, NULL,
- TYPE_CMD);
-
- if (return_code == IO_OK) {
-#ifdef CCISS_DEBUG
- printk("LUN Data\n--------------------------\n");
-#endif /* CCISS_DEBUG */
-
- listlength |=
- (0xff & (unsigned int)(ld_buff->LUNListLength[0])) << 24;
- listlength |=
- (0xff & (unsigned int)(ld_buff->LUNListLength[1])) << 16;
- listlength |=
- (0xff & (unsigned int)(ld_buff->LUNListLength[2])) << 8;
- listlength |= 0xff & (unsigned int)(ld_buff->LUNListLength[3]);
- } else { /* reading number of logical volumes failed */
-
- printk(KERN_WARNING "cciss: report logical volume"
- " command failed\n");
- listlength = 0;
- }
- hba[cntl_num]->num_luns = listlength / 8; // 8 bytes pre entry
- if (hba[cntl_num]->num_luns > CISS_MAX_LUN) {
- printk(KERN_ERR
- "ciss: only %d number of logical volumes supported\n",
- CISS_MAX_LUN);
- hba[cntl_num]->num_luns = CISS_MAX_LUN;
- }
-#ifdef CCISS_DEBUG
- printk(KERN_DEBUG "Length = %x %x %x %x = %d\n",
- ld_buff->LUNListLength[0], ld_buff->LUNListLength[1],
- ld_buff->LUNListLength[2], ld_buff->LUNListLength[3],
- hba[cntl_num]->num_luns);
-#endif /* CCISS_DEBUG */
-
- hba[cntl_num]->highest_lun = hba[cntl_num]->num_luns - 1;
- for (i = 0; i < CISS_MAX_LUN; i++) {
- if (i < hba[cntl_num]->num_luns) {
- lunid = (0xff & (unsigned int)(ld_buff->LUN[i][3]))
- << 24;
- lunid |= (0xff & (unsigned int)(ld_buff->LUN[i][2]))
- << 16;
- lunid |= (0xff & (unsigned int)(ld_buff->LUN[i][1]))
- << 8;
- lunid |= 0xff & (unsigned int)(ld_buff->LUN[i][0]);
-
- hba[cntl_num]->drv[i].LunID = lunid;
-
-#ifdef CCISS_DEBUG
- printk(KERN_DEBUG "LUN[%d]: %x %x %x %x = %x\n", i,
- ld_buff->LUN[i][0], ld_buff->LUN[i][1],
- ld_buff->LUN[i][2], ld_buff->LUN[i][3],
- hba[cntl_num]->drv[i].LunID);
-#endif /* CCISS_DEBUG */
-
- /* testing to see if 16-byte CDBs are already being used */
- if(hba[cntl_num]->cciss_read == CCISS_READ_16) {
- cciss_read_capacity_16(cntl_num, i, 0,
- &total_size, &block_size);
- goto geo_inq;
- }
- cciss_read_capacity(cntl_num, i, 0, &total_size, &block_size);
-
- /* If read_capacity returns all F's the logical is >2TB */
- /* so we switch to 16-byte CDBs for all read/write ops */
- if(total_size == 0xFFFFFFFFULL) {
- cciss_read_capacity_16(cntl_num, i, 0,
- &total_size, &block_size);
- hba[cntl_num]->cciss_read = CCISS_READ_16;
- hba[cntl_num]->cciss_write = CCISS_WRITE_16;
- } else {
- hba[cntl_num]->cciss_read = CCISS_READ_10;
- hba[cntl_num]->cciss_write = CCISS_WRITE_10;
- }
-geo_inq:
- cciss_geometry_inquiry(cntl_num, i, 0, total_size,
- block_size, inq_buff,
- &hba[cntl_num]->drv[i]);
- cciss_get_serial_no(cntl_num, i, 0,
- hba[cntl_num]->drv[i].serial_no,
- sizeof(hba[cntl_num]->drv[i].serial_no));
- } else {
- /* initialize raid_level to indicate a free space */
- hba[cntl_num]->drv[i].raid_level = -1;
- }
- }
- kfree(ld_buff);
- kfree(inq_buff);
-}
-
-/* Function to find the first free pointer into our hba[] array */
-/* Returns -1 if no free entries are left. */