📄 aachba.c
字号:
dinfo->count = cpu_to_le32(sizeof(((struct aac_get_name_resp *)NULL)->data)); status = fib_send(ContainerCommand, cmd_fibcontext, sizeof (struct aac_get_name), FsaNormal, 0, 1, (fib_callback) get_container_name_callback, (void *) scsicmd); /* * Check that the command queued to the controller */ if (status == -EINPROGRESS) return 0; printk(KERN_WARNING "aac_get_container_name: fib_send failed with status: %d.\n", status); fib_complete(cmd_fibcontext); fib_free(cmd_fibcontext); return -1;}/** * probe_container - query a logical volume * @dev: device to query * @cid: container identifier * * Queries the controller about the given volume. The volume information * is updated in the struct fsa_dev_info structure rather than returned. */ int probe_container(struct aac_dev *dev, int cid){ struct fsa_dev_info *fsa_dev_ptr; int status; struct aac_query_mount *dinfo; struct aac_mount *dresp; struct fib * fibptr; unsigned instance; fsa_dev_ptr = dev->fsa_dev; instance = dev->scsi_host_ptr->unique_id; if (!(fibptr = fib_alloc(dev))) return -ENOMEM; fib_init(fibptr); dinfo = (struct aac_query_mount *)fib_data(fibptr); dinfo->command = cpu_to_le32(VM_NameServe); dinfo->count = cpu_to_le32(cid); dinfo->type = cpu_to_le32(FT_FILESYS); status = fib_send(ContainerCommand, fibptr, sizeof(struct aac_query_mount), FsaNormal, 1, 1, NULL, NULL); if (status < 0) { printk(KERN_WARNING "aacraid: probe_container query failed.\n"); goto error; } dresp = (struct aac_mount *) fib_data(fibptr); if ((le32_to_cpu(dresp->status) == ST_OK) && (le32_to_cpu(dresp->mnt[0].vol) == CT_NONE)) { dinfo->command = cpu_to_le32(VM_NameServe64); dinfo->count = cpu_to_le32(cid); dinfo->type = cpu_to_le32(FT_FILESYS); if (fib_send(ContainerCommand, fibptr, sizeof(struct aac_query_mount), FsaNormal, 1, 1, NULL, NULL) < 0) goto error; } else dresp->mnt[0].capacityhigh = 0; if ((le32_to_cpu(dresp->status) == ST_OK) && (le32_to_cpu(dresp->mnt[0].vol) != CT_NONE) && (le32_to_cpu(dresp->mnt[0].state) != FSCS_HIDDEN)) { fsa_dev_ptr[cid].valid = 1; fsa_dev_ptr[cid].type = le32_to_cpu(dresp->mnt[0].vol); fsa_dev_ptr[cid].size = ((u64)le32_to_cpu(dresp->mnt[0].capacity)) + (((u64)le32_to_cpu(dresp->mnt[0].capacityhigh)) << 32); if (le32_to_cpu(dresp->mnt[0].state) & FSCS_READONLY) fsa_dev_ptr[cid].ro = 1; }error: fib_complete(fibptr); fib_free(fibptr); return status;}/* Local Structure to set SCSI inquiry data strings */struct scsi_inq { char vid[8]; /* Vendor ID */ char pid[16]; /* Product ID */ char prl[4]; /* Product Revision Level */};/** * InqStrCopy - string merge * @a: string to copy from * @b: string to copy to * * Copy a String from one location to another * without copying \0 */static void inqstrcpy(char *a, char *b){ while(*a != (char)0) *b++ = *a++;}static char *container_types[] = { "None", "Volume", "Mirror", "Stripe", "RAID5", "SSRW", "SSRO", "Morph", "Legacy", "RAID4", "RAID10", "RAID00", "V-MIRRORS", "PSEUDO R4", "RAID50", "RAID5D", "RAID5D0", "RAID1E", "RAID6", "RAID60", "Unknown"};/* Function: setinqstr * * Arguments: [1] pointer to void [1] int * * Purpose: Sets SCSI inquiry data strings for vendor, product * and revision level. Allows strings to be set in platform dependant * files instead of in OS dependant driver source. */static void setinqstr(struct aac_dev *dev, void *data, int tindex){ struct scsi_inq *str; str = (struct scsi_inq *)(data); /* cast data to scsi inq block */ memset(str, ' ', sizeof(*str)); if (dev->supplement_adapter_info.AdapterTypeText[0]) { char * cp = dev->supplement_adapter_info.AdapterTypeText; int c = sizeof(str->vid); while (*cp && *cp != ' ' && --c) ++cp; c = *cp; *cp = '\0'; inqstrcpy (dev->supplement_adapter_info.AdapterTypeText, str->vid); *cp = c; while (*cp && *cp != ' ') ++cp; while (*cp == ' ') ++cp; /* last six chars reserved for vol type */ c = 0; if (strlen(cp) > sizeof(str->pid)) { c = cp[sizeof(str->pid)]; cp[sizeof(str->pid)] = '\0'; } inqstrcpy (cp, str->pid); if (c) cp[sizeof(str->pid)] = c; } else { struct aac_driver_ident *mp = aac_get_driver_ident(dev->cardtype); inqstrcpy (mp->vname, str->vid); /* last six chars reserved for vol type */ inqstrcpy (mp->model, str->pid); } if (tindex < (sizeof(container_types)/sizeof(char *))){ char *findit = str->pid; for ( ; *findit != ' '; findit++); /* walk till we find a space */ /* RAID is superfluous in the context of a RAID device */ if (memcmp(findit-4, "RAID", 4) == 0) *(findit -= 4) = ' '; if (((findit - str->pid) + strlen(container_types[tindex])) < (sizeof(str->pid) + sizeof(str->prl))) inqstrcpy (container_types[tindex], findit + 1); } inqstrcpy ("V1.0", str->prl);}static void set_sense(u8 *sense_buf, u8 sense_key, u8 sense_code, u8 a_sense_code, u8 incorrect_length, u8 bit_pointer, u16 field_pointer, u32 residue){ sense_buf[0] = 0xF0; /* Sense data valid, err code 70h (current error) */ sense_buf[1] = 0; /* Segment number, always zero */ if (incorrect_length) { sense_buf[2] = sense_key | 0x20;/* Set ILI bit | sense key */ sense_buf[3] = BYTE3(residue); sense_buf[4] = BYTE2(residue); sense_buf[5] = BYTE1(residue); sense_buf[6] = BYTE0(residue); } else sense_buf[2] = sense_key; /* Sense key */ if (sense_key == ILLEGAL_REQUEST) sense_buf[7] = 10; /* Additional sense length */ else sense_buf[7] = 6; /* Additional sense length */ sense_buf[12] = sense_code; /* Additional sense code */ sense_buf[13] = a_sense_code; /* Additional sense code qualifier */ if (sense_key == ILLEGAL_REQUEST) { sense_buf[15] = 0; if (sense_code == SENCODE_INVALID_PARAM_FIELD) sense_buf[15] = 0x80;/* Std sense key specific field */ /* Illegal parameter is in the parameter block */ if (sense_code == SENCODE_INVALID_CDB_FIELD) sense_buf[15] = 0xc0;/* Std sense key specific field */ /* Illegal parameter is in the CDB block */ sense_buf[15] |= bit_pointer; sense_buf[16] = field_pointer >> 8; /* MSB */ sense_buf[17] = field_pointer; /* LSB */ }}int aac_get_adapter_info(struct aac_dev* dev){ struct fib* fibptr; int rcode; u32 tmp; struct aac_adapter_info *info; struct aac_bus_info *command; struct aac_bus_info_response *bus_info; if (!(fibptr = fib_alloc(dev))) return -ENOMEM; fib_init(fibptr); info = (struct aac_adapter_info *) fib_data(fibptr); memset(info,0,sizeof(*info)); rcode = fib_send(RequestAdapterInfo, fibptr, sizeof(*info), FsaNormal, -1, 1, /* First `interrupt' command uses special wait */ NULL, NULL); if (rcode < 0) { fib_complete(fibptr); fib_free(fibptr); return rcode; } memcpy(&dev->adapter_info, info, sizeof(*info)); if (dev->adapter_info.options & AAC_OPT_SUPPLEMENT_ADAPTER_INFO) { struct aac_supplement_adapter_info * info; fib_init(fibptr); info = (struct aac_supplement_adapter_info *) fib_data(fibptr); memset(info,0,sizeof(*info)); rcode = fib_send(RequestSupplementAdapterInfo, fibptr, sizeof(*info), FsaNormal, 1, 1, NULL, NULL); if (rcode >= 0) memcpy(&dev->supplement_adapter_info, info, sizeof(*info)); } /* * GetBusInfo */ fib_init(fibptr); bus_info = (struct aac_bus_info_response *) fib_data(fibptr); memset(bus_info, 0, sizeof(*bus_info)); command = (struct aac_bus_info *)bus_info; command->Command = cpu_to_le32(VM_Ioctl); command->ObjType = cpu_to_le32(FT_DRIVE); command->MethodId = cpu_to_le32(1); command->CtlCmd = cpu_to_le32(GetBusInfo); rcode = fib_send(ContainerCommand, fibptr, sizeof (*bus_info), FsaNormal, 1, 1, NULL, NULL); if (rcode >= 0 && le32_to_cpu(bus_info->Status) == ST_OK) { dev->maximum_num_physicals = le32_to_cpu(bus_info->TargetsPerBus); dev->maximum_num_channels = le32_to_cpu(bus_info->BusCount); } tmp = le32_to_cpu(dev->adapter_info.kernelrev); printk(KERN_INFO "%s%d: kernel %d.%d-%d[%d] %.*s\n", dev->name, dev->id, tmp>>24, (tmp>>16)&0xff, tmp&0xff, le32_to_cpu(dev->adapter_info.kernelbuild), (int)sizeof(dev->supplement_adapter_info.BuildDate), dev->supplement_adapter_info.BuildDate); tmp = le32_to_cpu(dev->adapter_info.monitorrev); printk(KERN_INFO "%s%d: monitor %d.%d-%d[%d]\n", dev->name, dev->id, tmp>>24,(tmp>>16)&0xff,tmp&0xff, le32_to_cpu(dev->adapter_info.monitorbuild)); tmp = le32_to_cpu(dev->adapter_info.biosrev); printk(KERN_INFO "%s%d: bios %d.%d-%d[%d]\n", dev->name, dev->id, tmp>>24,(tmp>>16)&0xff,tmp&0xff, le32_to_cpu(dev->adapter_info.biosbuild)); if (le32_to_cpu(dev->adapter_info.serial[0]) != 0xBAD0) printk(KERN_INFO "%s%d: serial %x\n", dev->name, dev->id, le32_to_cpu(dev->adapter_info.serial[0])); dev->nondasd_support = 0; dev->raid_scsi_mode = 0; if(dev->adapter_info.options & AAC_OPT_NONDASD){ dev->nondasd_support = 1; } /* * If the firmware supports ROMB RAID/SCSI mode and we are currently * in RAID/SCSI mode, set the flag. For now if in this mode we will * force nondasd support on. If we decide to allow the non-dasd flag * additional changes changes will have to be made to support * RAID/SCSI. the function aac_scsi_cmd in this module will have to be * changed to support the new dev->raid_scsi_mode flag instead of * leaching off of the dev->nondasd_support flag. Also in linit.c the * function aac_detect will have to be modified where it sets up the * max number of channels based on the aac->nondasd_support flag only. */ if ((dev->adapter_info.options & AAC_OPT_SCSI_MANAGED) && (dev->adapter_info.options & AAC_OPT_RAID_SCSI_MODE)) { dev->nondasd_support = 1; dev->raid_scsi_mode = 1; } if (dev->raid_scsi_mode != 0) printk(KERN_INFO "%s%d: ROMB RAID/SCSI mode enabled\n", dev->name, dev->id); if(nondasd != -1) { dev->nondasd_support = (nondasd!=0); } if(dev->nondasd_support != 0){ printk(KERN_INFO "%s%d: Non-DASD support enabled.\n",dev->name, dev->id); } dev->dac_support = 0; if( (sizeof(dma_addr_t) > 4) && (dev->adapter_info.options & AAC_OPT_SGMAP_HOST64)){ printk(KERN_INFO "%s%d: 64bit support enabled.\n", dev->name, dev->id); dev->dac_support = 1; } if(dacmode != -1) { dev->dac_support = (dacmode!=0); } if(dev->dac_support != 0) { if (!pci_set_dma_mask(dev->pdev, DMA_64BIT_MASK) && !pci_set_consistent_dma_mask(dev->pdev, DMA_64BIT_MASK)) { printk(KERN_INFO"%s%d: 64 Bit DAC enabled\n", dev->name, dev->id); } else if (!pci_set_dma_mask(dev->pdev, DMA_32BIT_MASK) && !pci_set_consistent_dma_mask(dev->pdev, DMA_32BIT_MASK)) { printk(KERN_INFO"%s%d: DMA mask set failed, 64 Bit DAC disabled\n", dev->name, dev->id); dev->dac_support = 0; } else { printk(KERN_WARNING"%s%d: No suitable DMA available.\n", dev->name, dev->id); rcode = -ENOMEM; } } /* * 57 scatter gather elements */ if (!(dev->raw_io_interface)) { dev->scsi_host_ptr->sg_tablesize = (dev->max_fib_size - sizeof(struct aac_fibhdr) - sizeof(struct aac_write) + sizeof(struct sgentry)) / sizeof(struct sgentry); if (dev->dac_support) { /* * 38 scatter gather elements */ dev->scsi_host_ptr->sg_tablesize = (dev->max_fib_size - sizeof(struct aac_fibhdr) - sizeof(struct aac_write64) + sizeof(struct sgentry64)) / sizeof(struct sgentry64); } dev->scsi_host_ptr->max_sectors = AAC_MAX_32BIT_SGBCOUNT; if(!(dev->adapter_info.options & AAC_OPT_NEW_COMM)) { /* * Worst case size that could cause sg overflow when * we break up SG elements that are larger than 64KB.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -