4163 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2/*3 * Adaptec AAC series RAID controller driver4 * (c) Copyright 2001 Red Hat Inc.5 *6 * based on the old aacraid driver that is..7 * Adaptec aacraid device driver for Linux.8 *9 * Copyright (c) 2000-2010 Adaptec, Inc.10 * 2010-2015 PMC-Sierra, Inc. (aacraid@pmc-sierra.com)11 * 2016-2017 Microsemi Corp. (aacraid@microsemi.com)12 *13 * Module Name:14 * aachba.c15 *16 * Abstract: Contains Interfaces to manage IOs.17 */18 19#include <linux/kernel.h>20#include <linux/init.h>21#include <linux/types.h>22#include <linux/pci.h>23#include <linux/spinlock.h>24#include <linux/slab.h>25#include <linux/completion.h>26#include <linux/blkdev.h>27#include <linux/uaccess.h>28#include <linux/module.h>29 30#include <linux/unaligned.h>31 32#include <scsi/scsi.h>33#include <scsi/scsi_cmnd.h>34#include <scsi/scsi_device.h>35#include <scsi/scsi_host.h>36 37#include "aacraid.h"38 39/* values for inqd_pdt: Peripheral device type in plain English */40#define INQD_PDT_DA 0x00 /* Direct-access (DISK) device */41#define INQD_PDT_PROC 0x03 /* Processor device */42#define INQD_PDT_CHNGR 0x08 /* Changer (jukebox, scsi2) */43#define INQD_PDT_COMM 0x09 /* Communication device (scsi2) */44#define INQD_PDT_NOLUN2 0x1f /* Unknown Device (scsi2) */45#define INQD_PDT_NOLUN 0x7f /* Logical Unit Not Present */46 47#define INQD_PDT_DMASK 0x1F /* Peripheral Device Type Mask */48#define INQD_PDT_QMASK 0xE0 /* Peripheral Device Qualifer Mask */49 50/*51 * Sense codes52 */53 54#define SENCODE_NO_SENSE 0x0055#define SENCODE_END_OF_DATA 0x0056#define SENCODE_BECOMING_READY 0x0457#define SENCODE_INIT_CMD_REQUIRED 0x0458#define SENCODE_UNRECOVERED_READ_ERROR 0x1159#define SENCODE_PARAM_LIST_LENGTH_ERROR 0x1A60#define SENCODE_INVALID_COMMAND 0x2061#define SENCODE_LBA_OUT_OF_RANGE 0x2162#define SENCODE_INVALID_CDB_FIELD 0x2463#define SENCODE_LUN_NOT_SUPPORTED 0x2564#define SENCODE_INVALID_PARAM_FIELD 0x2665#define SENCODE_PARAM_NOT_SUPPORTED 0x2666#define SENCODE_PARAM_VALUE_INVALID 0x2667#define SENCODE_RESET_OCCURRED 0x2968#define SENCODE_LUN_NOT_SELF_CONFIGURED_YET 0x3E69#define SENCODE_INQUIRY_DATA_CHANGED 0x3F70#define SENCODE_SAVING_PARAMS_NOT_SUPPORTED 0x3971#define SENCODE_DIAGNOSTIC_FAILURE 0x4072#define SENCODE_INTERNAL_TARGET_FAILURE 0x4473#define SENCODE_INVALID_MESSAGE_ERROR 0x4974#define SENCODE_LUN_FAILED_SELF_CONFIG 0x4c75#define SENCODE_OVERLAPPED_COMMAND 0x4E76 77/*78 * Additional sense codes79 */80 81#define ASENCODE_NO_SENSE 0x0082#define ASENCODE_END_OF_DATA 0x0583#define ASENCODE_BECOMING_READY 0x0184#define ASENCODE_INIT_CMD_REQUIRED 0x0285#define ASENCODE_PARAM_LIST_LENGTH_ERROR 0x0086#define ASENCODE_INVALID_COMMAND 0x0087#define ASENCODE_LBA_OUT_OF_RANGE 0x0088#define ASENCODE_INVALID_CDB_FIELD 0x0089#define ASENCODE_LUN_NOT_SUPPORTED 0x0090#define ASENCODE_INVALID_PARAM_FIELD 0x0091#define ASENCODE_PARAM_NOT_SUPPORTED 0x0192#define ASENCODE_PARAM_VALUE_INVALID 0x0293#define ASENCODE_RESET_OCCURRED 0x0094#define ASENCODE_LUN_NOT_SELF_CONFIGURED_YET 0x0095#define ASENCODE_INQUIRY_DATA_CHANGED 0x0396#define ASENCODE_SAVING_PARAMS_NOT_SUPPORTED 0x0097#define ASENCODE_DIAGNOSTIC_FAILURE 0x8098#define ASENCODE_INTERNAL_TARGET_FAILURE 0x0099#define ASENCODE_INVALID_MESSAGE_ERROR 0x00100#define ASENCODE_LUN_FAILED_SELF_CONFIG 0x00101#define ASENCODE_OVERLAPPED_COMMAND 0x00102 103#define BYTE0(x) (unsigned char)(x)104#define BYTE1(x) (unsigned char)((x) >> 8)105#define BYTE2(x) (unsigned char)((x) >> 16)106#define BYTE3(x) (unsigned char)((x) >> 24)107 108/* MODE_SENSE data format */109typedef struct {110 struct {111 u8 data_length;112 u8 med_type;113 u8 dev_par;114 u8 bd_length;115 } __attribute__((packed)) hd;116 struct {117 u8 dens_code;118 u8 block_count[3];119 u8 reserved;120 u8 block_length[3];121 } __attribute__((packed)) bd;122 u8 mpc_buf[3];123} __attribute__((packed)) aac_modep_data;124 125/* MODE_SENSE_10 data format */126typedef struct {127 struct {128 u8 data_length[2];129 u8 med_type;130 u8 dev_par;131 u8 rsrvd[2];132 u8 bd_length[2];133 } __attribute__((packed)) hd;134 struct {135 u8 dens_code;136 u8 block_count[3];137 u8 reserved;138 u8 block_length[3];139 } __attribute__((packed)) bd;140 u8 mpc_buf[3];141} __attribute__((packed)) aac_modep10_data;142 143/*------------------------------------------------------------------------------144 * S T R U C T S / T Y P E D E F S145 *----------------------------------------------------------------------------*/146/* SCSI inquiry data */147struct inquiry_data {148 u8 inqd_pdt; /* Peripheral qualifier | Peripheral Device Type */149 u8 inqd_dtq; /* RMB | Device Type Qualifier */150 u8 inqd_ver; /* ISO version | ECMA version | ANSI-approved version */151 u8 inqd_rdf; /* AENC | TrmIOP | Response data format */152 u8 inqd_len; /* Additional length (n-4) */153 u8 inqd_pad1[2];/* Reserved - must be zero */154 u8 inqd_pad2; /* RelAdr | WBus32 | WBus16 | Sync | Linked |Reserved| CmdQue | SftRe */155 u8 inqd_vid[8]; /* Vendor ID */156 u8 inqd_pid[16];/* Product ID */157 u8 inqd_prl[4]; /* Product Revision Level */158};159 160/* Added for VPD 0x83 */161struct tvpd_id_descriptor_type_1 {162 u8 codeset:4; /* VPD_CODE_SET */163 u8 reserved:4;164 u8 identifiertype:4; /* VPD_IDENTIFIER_TYPE */165 u8 reserved2:4;166 u8 reserved3;167 u8 identifierlength;168 u8 venid[8];169 u8 productid[16];170 u8 serialnumber[8]; /* SN in ASCII */171 172};173 174struct tvpd_id_descriptor_type_2 {175 u8 codeset:4; /* VPD_CODE_SET */176 u8 reserved:4;177 u8 identifiertype:4; /* VPD_IDENTIFIER_TYPE */178 u8 reserved2:4;179 u8 reserved3;180 u8 identifierlength;181 struct teu64id {182 u32 Serial;183 /* The serial number supposed to be 40 bits,184 * bit we only support 32, so make the last byte zero. */185 u8 reserved;186 u8 venid[3];187 } eu64id;188 189};190 191struct tvpd_id_descriptor_type_3 {192 u8 codeset : 4; /* VPD_CODE_SET */193 u8 reserved : 4;194 u8 identifiertype : 4; /* VPD_IDENTIFIER_TYPE */195 u8 reserved2 : 4;196 u8 reserved3;197 u8 identifierlength;198 u8 Identifier[16];199};200 201struct tvpd_page83 {202 u8 DeviceType:5;203 u8 DeviceTypeQualifier:3;204 u8 PageCode;205 u8 reserved;206 u8 PageLength;207 struct tvpd_id_descriptor_type_1 type1;208 struct tvpd_id_descriptor_type_2 type2;209 struct tvpd_id_descriptor_type_3 type3;210};211 212/*213 * M O D U L E G L O B A L S214 */215 216static long aac_build_sg(struct scsi_cmnd *scsicmd, struct sgmap *sgmap);217static long aac_build_sg64(struct scsi_cmnd *scsicmd, struct sgmap64 *psg);218static long aac_build_sgraw(struct scsi_cmnd *scsicmd, struct sgmapraw *psg);219static long aac_build_sgraw2(struct scsi_cmnd *scsicmd,220 struct aac_raw_io2 *rio2, int sg_max);221static long aac_build_sghba(struct scsi_cmnd *scsicmd,222 struct aac_hba_cmd_req *hbacmd,223 int sg_max, u64 sg_address);224static int aac_convert_sgraw2(struct aac_raw_io2 *rio2,225 int pages, int nseg, int nseg_new);226static void aac_probe_container_scsi_done(struct scsi_cmnd *scsi_cmnd);227static int aac_send_srb_fib(struct scsi_cmnd* scsicmd);228static int aac_send_hba_fib(struct scsi_cmnd *scsicmd);229#ifdef AAC_DETAILED_STATUS_INFO230static char *aac_get_status_string(u32 status);231#endif232 233/*234 * Non dasd selection is handled entirely in aachba now235 */236 237static int nondasd = -1;238static int aac_cache = 2; /* WCE=0 to avoid performance problems */239static int dacmode = -1;240int aac_msi;241int aac_commit = -1;242int startup_timeout = 180;243int aif_timeout = 120;244int aac_sync_mode; /* Only Sync. transfer - disabled */245static int aac_convert_sgl = 1; /* convert non-conformable s/g list - enabled */246 247module_param(aac_sync_mode, int, S_IRUGO|S_IWUSR);248MODULE_PARM_DESC(aac_sync_mode, "Force sync. transfer mode"249 " 0=off, 1=on");250module_param(aac_convert_sgl, int, S_IRUGO|S_IWUSR);251MODULE_PARM_DESC(aac_convert_sgl, "Convert non-conformable s/g list"252 " 0=off, 1=on");253module_param(nondasd, int, S_IRUGO|S_IWUSR);254MODULE_PARM_DESC(nondasd, "Control scanning of hba for nondasd devices."255 " 0=off, 1=on");256module_param_named(cache, aac_cache, int, S_IRUGO|S_IWUSR);257MODULE_PARM_DESC(cache, "Disable Queue Flush commands:\n"258 "\tbit 0 - Disable FUA in WRITE SCSI commands\n"259 "\tbit 1 - Disable SYNCHRONIZE_CACHE SCSI command\n"260 "\tbit 2 - Disable only if Battery is protecting Cache");261module_param(dacmode, int, S_IRUGO|S_IWUSR);262MODULE_PARM_DESC(dacmode, "Control whether dma addressing is using 64 bit DAC."263 " 0=off, 1=on");264module_param_named(commit, aac_commit, int, S_IRUGO|S_IWUSR);265MODULE_PARM_DESC(commit, "Control whether a COMMIT_CONFIG is issued to the"266 " adapter for foreign arrays.\n"267 "This is typically needed in systems that do not have a BIOS."268 " 0=off, 1=on");269module_param_named(msi, aac_msi, int, S_IRUGO|S_IWUSR);270MODULE_PARM_DESC(msi, "IRQ handling."271 " 0=PIC(default), 1=MSI, 2=MSI-X)");272module_param(startup_timeout, int, S_IRUGO|S_IWUSR);273MODULE_PARM_DESC(startup_timeout, "The duration of time in seconds to wait for"274 " adapter to have its kernel up and\n"275 "running. This is typically adjusted for large systems that do not"276 " have a BIOS.");277module_param(aif_timeout, int, S_IRUGO|S_IWUSR);278MODULE_PARM_DESC(aif_timeout, "The duration of time in seconds to wait for"279 " applications to pick up AIFs before\n"280 "deregistering them. This is typically adjusted for heavily burdened"281 " systems.");282 283int aac_fib_dump;284module_param(aac_fib_dump, int, 0644);285MODULE_PARM_DESC(aac_fib_dump, "Dump controller fibs prior to IOP_RESET 0=off, 1=on");286 287int numacb = -1;288module_param(numacb, int, S_IRUGO|S_IWUSR);289MODULE_PARM_DESC(numacb, "Request a limit to the number of adapter control"290 " blocks (FIB) allocated. Valid values are 512 and down. Default is"291 " to use suggestion from Firmware.");292 293static int acbsize = -1;294module_param(acbsize, int, S_IRUGO|S_IWUSR);295MODULE_PARM_DESC(acbsize, "Request a specific adapter control block (FIB)"296 " size. Valid values are 512, 2048, 4096 and 8192. Default is to use"297 " suggestion from Firmware.");298 299int update_interval = 30 * 60;300module_param(update_interval, int, S_IRUGO|S_IWUSR);301MODULE_PARM_DESC(update_interval, "Interval in seconds between time sync"302 " updates issued to adapter.");303 304int check_interval = 60;305module_param(check_interval, int, S_IRUGO|S_IWUSR);306MODULE_PARM_DESC(check_interval, "Interval in seconds between adapter health"307 " checks.");308 309int aac_check_reset = 1;310module_param_named(check_reset, aac_check_reset, int, S_IRUGO|S_IWUSR);311MODULE_PARM_DESC(check_reset, "If adapter fails health check, reset the"312 " adapter. a value of -1 forces the reset to adapters programmed to"313 " ignore it.");314 315int expose_physicals = -1;316module_param(expose_physicals, int, S_IRUGO|S_IWUSR);317MODULE_PARM_DESC(expose_physicals, "Expose physical components of the arrays."318 " -1=protect 0=off, 1=on");319 320int aac_reset_devices;321module_param_named(reset_devices, aac_reset_devices, int, S_IRUGO|S_IWUSR);322MODULE_PARM_DESC(reset_devices, "Force an adapter reset at initialization.");323 324static int aac_wwn = 1;325module_param_named(wwn, aac_wwn, int, S_IRUGO|S_IWUSR);326MODULE_PARM_DESC(wwn, "Select a WWN type for the arrays:\n"327 "\t0 - Disable\n"328 "\t1 - Array Meta Data Signature (default)\n"329 "\t2 - Adapter Serial Number");330 331 332static inline int aac_valid_context(struct scsi_cmnd *scsicmd,333 struct fib *fibptr) {334 struct scsi_device *device;335 336 if (unlikely(!scsicmd)) {337 dprintk((KERN_WARNING "aac_valid_context: scsi command corrupt\n"));338 aac_fib_complete(fibptr);339 return 0;340 }341 aac_priv(scsicmd)->owner = AAC_OWNER_MIDLEVEL;342 device = scsicmd->device;343 if (unlikely(!device)) {344 dprintk((KERN_WARNING "aac_valid_context: scsi device corrupt\n"));345 aac_fib_complete(fibptr);346 return 0;347 }348 return 1;349}350 351/**352 * aac_get_config_status - check the adapter configuration353 * @dev: aac driver data354 * @commit_flag: force sending CT_COMMIT_CONFIG355 *356 * Query config status, and commit the configuration if needed.357 */358int aac_get_config_status(struct aac_dev *dev, int commit_flag)359{360 int status = 0;361 struct fib * fibptr;362 363 if (!(fibptr = aac_fib_alloc(dev)))364 return -ENOMEM;365 366 aac_fib_init(fibptr);367 {368 struct aac_get_config_status *dinfo;369 dinfo = (struct aac_get_config_status *) fib_data(fibptr);370 371 dinfo->command = cpu_to_le32(VM_ContainerConfig);372 dinfo->type = cpu_to_le32(CT_GET_CONFIG_STATUS);373 dinfo->count = cpu_to_le32(sizeof(((struct aac_get_config_status_resp *)NULL)->data));374 }375 376 status = aac_fib_send(ContainerCommand,377 fibptr,378 sizeof (struct aac_get_config_status),379 FsaNormal,380 1, 1,381 NULL, NULL);382 if (status < 0) {383 printk(KERN_WARNING "aac_get_config_status: SendFIB failed.\n");384 } else {385 struct aac_get_config_status_resp *reply386 = (struct aac_get_config_status_resp *) fib_data(fibptr);387 dprintk((KERN_WARNING388 "aac_get_config_status: response=%d status=%d action=%d\n",389 le32_to_cpu(reply->response),390 le32_to_cpu(reply->status),391 le32_to_cpu(reply->data.action)));392 if ((le32_to_cpu(reply->response) != ST_OK) ||393 (le32_to_cpu(reply->status) != CT_OK) ||394 (le32_to_cpu(reply->data.action) > CFACT_PAUSE)) {395 printk(KERN_WARNING "aac_get_config_status: Will not issue the Commit Configuration\n");396 status = -EINVAL;397 }398 }399 /* Do not set XferState to zero unless receives a response from F/W */400 if (status >= 0)401 aac_fib_complete(fibptr);402 403 /* Send a CT_COMMIT_CONFIG to enable discovery of devices */404 if (status >= 0) {405 if ((aac_commit == 1) || commit_flag) {406 struct aac_commit_config * dinfo;407 aac_fib_init(fibptr);408 dinfo = (struct aac_commit_config *) fib_data(fibptr);409 410 dinfo->command = cpu_to_le32(VM_ContainerConfig);411 dinfo->type = cpu_to_le32(CT_COMMIT_CONFIG);412 413 status = aac_fib_send(ContainerCommand,414 fibptr,415 sizeof (struct aac_commit_config),416 FsaNormal,417 1, 1,418 NULL, NULL);419 /* Do not set XferState to zero unless420 * receives a response from F/W */421 if (status >= 0)422 aac_fib_complete(fibptr);423 } else if (aac_commit == 0) {424 printk(KERN_WARNING425 "aac_get_config_status: Foreign device configurations are being ignored\n");426 }427 }428 /* FIB should be freed only after getting the response from the F/W */429 if (status != -ERESTARTSYS)430 aac_fib_free(fibptr);431 return status;432}433 434static void aac_expose_phy_device(struct scsi_cmnd *scsicmd)435{436 char inq_data;437 scsi_sg_copy_to_buffer(scsicmd, &inq_data, sizeof(inq_data));438 if ((inq_data & 0x20) && (inq_data & 0x1f) == TYPE_DISK) {439 inq_data &= 0xdf;440 scsi_sg_copy_from_buffer(scsicmd, &inq_data, sizeof(inq_data));441 }442}443 444/**445 * aac_get_containers - list containers446 * @dev: aac driver data447 *448 * Make a list of all containers on this controller449 */450int aac_get_containers(struct aac_dev *dev)451{452 struct fsa_dev_info *fsa_dev_ptr;453 u32 index;454 int status = 0;455 struct fib * fibptr;456 struct aac_get_container_count *dinfo;457 struct aac_get_container_count_resp *dresp;458 int maximum_num_containers = MAXIMUM_NUM_CONTAINERS;459 460 if (!(fibptr = aac_fib_alloc(dev)))461 return -ENOMEM;462 463 aac_fib_init(fibptr);464 dinfo = (struct aac_get_container_count *) fib_data(fibptr);465 dinfo->command = cpu_to_le32(VM_ContainerConfig);466 dinfo->type = cpu_to_le32(CT_GET_CONTAINER_COUNT);467 468 status = aac_fib_send(ContainerCommand,469 fibptr,470 sizeof (struct aac_get_container_count),471 FsaNormal,472 1, 1,473 NULL, NULL);474 if (status >= 0) {475 dresp = (struct aac_get_container_count_resp *)fib_data(fibptr);476 maximum_num_containers = le32_to_cpu(dresp->ContainerSwitchEntries);477 if (fibptr->dev->supplement_adapter_info.supported_options2 &478 AAC_OPTION_SUPPORTED_240_VOLUMES) {479 maximum_num_containers =480 le32_to_cpu(dresp->MaxSimpleVolumes);481 }482 aac_fib_complete(fibptr);483 }484 /* FIB should be freed only after getting the response from the F/W */485 if (status != -ERESTARTSYS)486 aac_fib_free(fibptr);487 488 if (maximum_num_containers < MAXIMUM_NUM_CONTAINERS)489 maximum_num_containers = MAXIMUM_NUM_CONTAINERS;490 if (dev->fsa_dev == NULL ||491 dev->maximum_num_containers != maximum_num_containers) {492 493 fsa_dev_ptr = dev->fsa_dev;494 495 dev->fsa_dev = kcalloc(maximum_num_containers,496 sizeof(*fsa_dev_ptr), GFP_KERNEL);497 498 kfree(fsa_dev_ptr);499 fsa_dev_ptr = NULL;500 501 502 if (!dev->fsa_dev)503 return -ENOMEM;504 505 dev->maximum_num_containers = maximum_num_containers;506 }507 for (index = 0; index < dev->maximum_num_containers; index++) {508 dev->fsa_dev[index].devname[0] = '\0';509 dev->fsa_dev[index].valid = 0;510 511 status = aac_probe_container(dev, index);512 513 if (status < 0) {514 printk(KERN_WARNING "aac_get_containers: SendFIB failed.\n");515 break;516 }517 }518 return status;519}520 521static void aac_scsi_done(struct scsi_cmnd *scmd)522{523 if (scmd->device->request_queue) {524 /* SCSI command has been submitted by the SCSI mid-layer. */525 scsi_done(scmd);526 } else {527 /* SCSI command has been submitted by aac_probe_container(). */528 aac_probe_container_scsi_done(scmd);529 }530}531 532static void get_container_name_callback(void *context, struct fib * fibptr)533{534 struct aac_get_name_resp * get_name_reply;535 struct scsi_cmnd * scsicmd;536 537 scsicmd = (struct scsi_cmnd *) context;538 539 if (!aac_valid_context(scsicmd, fibptr))540 return;541 542 dprintk((KERN_DEBUG "get_container_name_callback[cpu %d]: t = %ld.\n", smp_processor_id(), jiffies));543 BUG_ON(fibptr == NULL);544 545 get_name_reply = (struct aac_get_name_resp *) fib_data(fibptr);546 /* Failure is irrelevant, using default value instead */547 if ((le32_to_cpu(get_name_reply->status) == CT_OK)548 && (get_name_reply->data[0] != '\0')) {549 char *sp = get_name_reply->data;550 int data_size = sizeof_field(struct aac_get_name_resp, data);551 552 sp[data_size - 1] = '\0';553 while (*sp == ' ')554 ++sp;555 if (*sp) {556 struct inquiry_data inq;557 char d[sizeof(((struct inquiry_data *)NULL)->inqd_pid)];558 int count = sizeof(d);559 char *dp = d;560 do {561 *dp++ = (*sp) ? *sp++ : ' ';562 } while (--count > 0);563 564 scsi_sg_copy_to_buffer(scsicmd, &inq, sizeof(inq));565 memcpy(inq.inqd_pid, d, sizeof(d));566 scsi_sg_copy_from_buffer(scsicmd, &inq, sizeof(inq));567 }568 }569 570 scsicmd->result = DID_OK << 16 | SAM_STAT_GOOD;571 572 aac_fib_complete(fibptr);573 aac_scsi_done(scsicmd);574}575 576/*577 * aac_get_container_name - get container name, none blocking.578 */579static int aac_get_container_name(struct scsi_cmnd * scsicmd)580{581 int status;582 int data_size;583 struct aac_get_name *dinfo;584 struct fib * cmd_fibcontext;585 struct aac_dev * dev;586 587 dev = (struct aac_dev *)scsicmd->device->host->hostdata;588 589 data_size = sizeof_field(struct aac_get_name_resp, data);590 591 cmd_fibcontext = aac_fib_alloc_tag(dev, scsicmd);592 593 aac_fib_init(cmd_fibcontext);594 dinfo = (struct aac_get_name *) fib_data(cmd_fibcontext);595 aac_priv(scsicmd)->owner = AAC_OWNER_FIRMWARE;596 597 dinfo->command = cpu_to_le32(VM_ContainerConfig);598 dinfo->type = cpu_to_le32(CT_READ_NAME);599 dinfo->cid = cpu_to_le32(scmd_id(scsicmd));600 dinfo->count = cpu_to_le32(data_size - 1);601 602 status = aac_fib_send(ContainerCommand,603 cmd_fibcontext,604 sizeof(struct aac_get_name_resp),605 FsaNormal,606 0, 1,607 (fib_callback)get_container_name_callback,608 (void *) scsicmd);609 610 /*611 * Check that the command queued to the controller612 */613 if (status == -EINPROGRESS)614 return 0;615 616 printk(KERN_WARNING "aac_get_container_name: aac_fib_send failed with status: %d.\n", status);617 aac_fib_complete(cmd_fibcontext);618 return -1;619}620 621static int aac_probe_container_callback2(struct scsi_cmnd * scsicmd)622{623 struct fsa_dev_info *fsa_dev_ptr = ((struct aac_dev *)(scsicmd->device->host->hostdata))->fsa_dev;624 625 if ((fsa_dev_ptr[scmd_id(scsicmd)].valid & 1))626 return aac_scsi_cmd(scsicmd);627 628 scsicmd->result = DID_NO_CONNECT << 16;629 aac_scsi_done(scsicmd);630 return 0;631}632 633static void _aac_probe_container2(void * context, struct fib * fibptr)634{635 struct fsa_dev_info *fsa_dev_ptr;636 int (*callback)(struct scsi_cmnd *);637 struct scsi_cmnd *scsicmd = context;638 struct aac_cmd_priv *cmd_priv = aac_priv(scsicmd);639 int i;640 641 642 if (!aac_valid_context(scsicmd, fibptr))643 return;644 645 cmd_priv->status = 0;646 fsa_dev_ptr = fibptr->dev->fsa_dev;647 if (fsa_dev_ptr) {648 struct aac_mount * dresp = (struct aac_mount *) fib_data(fibptr);649 __le32 sup_options2;650 651 fsa_dev_ptr += scmd_id(scsicmd);652 sup_options2 =653 fibptr->dev->supplement_adapter_info.supported_options2;654 655 if ((le32_to_cpu(dresp->status) == ST_OK) &&656 (le32_to_cpu(dresp->mnt[0].vol) != CT_NONE) &&657 (le32_to_cpu(dresp->mnt[0].state) != FSCS_HIDDEN)) {658 if (!(sup_options2 & AAC_OPTION_VARIABLE_BLOCK_SIZE)) {659 dresp->mnt[0].fileinfo.bdevinfo.block_size = 0x200;660 fsa_dev_ptr->block_size = 0x200;661 } else {662 fsa_dev_ptr->block_size =663 le32_to_cpu(dresp->mnt[0].fileinfo.bdevinfo.block_size);664 }665 for (i = 0; i < 16; i++)666 fsa_dev_ptr->identifier[i] =667 dresp->mnt[0].fileinfo.bdevinfo668 .identifier[i];669 fsa_dev_ptr->valid = 1;670 /* sense_key holds the current state of the spin-up */671 if (dresp->mnt[0].state & cpu_to_le32(FSCS_NOT_READY))672 fsa_dev_ptr->sense_data.sense_key = NOT_READY;673 else if (fsa_dev_ptr->sense_data.sense_key == NOT_READY)674 fsa_dev_ptr->sense_data.sense_key = NO_SENSE;675 fsa_dev_ptr->type = le32_to_cpu(dresp->mnt[0].vol);676 fsa_dev_ptr->size677 = ((u64)le32_to_cpu(dresp->mnt[0].capacity)) +678 (((u64)le32_to_cpu(dresp->mnt[0].capacityhigh)) << 32);679 fsa_dev_ptr->ro = ((le32_to_cpu(dresp->mnt[0].state) & FSCS_READONLY) != 0);680 }681 if ((fsa_dev_ptr->valid & 1) == 0)682 fsa_dev_ptr->valid = 0;683 cmd_priv->status = le32_to_cpu(dresp->count);684 }685 aac_fib_complete(fibptr);686 aac_fib_free(fibptr);687 callback = cmd_priv->callback;688 cmd_priv->callback = NULL;689 (*callback)(scsicmd);690 return;691}692 693static void _aac_probe_container1(void * context, struct fib * fibptr)694{695 struct scsi_cmnd * scsicmd;696 struct aac_mount * dresp;697 struct aac_query_mount *dinfo;698 int status;699 700 dresp = (struct aac_mount *) fib_data(fibptr);701 if (!aac_supports_2T(fibptr->dev)) {702 dresp->mnt[0].capacityhigh = 0;703 if ((le32_to_cpu(dresp->status) == ST_OK) &&704 (le32_to_cpu(dresp->mnt[0].vol) != CT_NONE)) {705 _aac_probe_container2(context, fibptr);706 return;707 }708 }709 scsicmd = (struct scsi_cmnd *) context;710 711 if (!aac_valid_context(scsicmd, fibptr))712 return;713 714 aac_fib_init(fibptr);715 716 dinfo = (struct aac_query_mount *)fib_data(fibptr);717 718 if (fibptr->dev->supplement_adapter_info.supported_options2 &719 AAC_OPTION_VARIABLE_BLOCK_SIZE)720 dinfo->command = cpu_to_le32(VM_NameServeAllBlk);721 else722 dinfo->command = cpu_to_le32(VM_NameServe64);723 724 dinfo->count = cpu_to_le32(scmd_id(scsicmd));725 dinfo->type = cpu_to_le32(FT_FILESYS);726 aac_priv(scsicmd)->owner = AAC_OWNER_FIRMWARE;727 728 status = aac_fib_send(ContainerCommand,729 fibptr,730 sizeof(struct aac_query_mount),731 FsaNormal,732 0, 1,733 _aac_probe_container2,734 (void *) scsicmd);735 /*736 * Check that the command queued to the controller737 */738 if (status < 0 && status != -EINPROGRESS) {739 /* Inherit results from VM_NameServe, if any */740 dresp->status = cpu_to_le32(ST_OK);741 _aac_probe_container2(context, fibptr);742 }743}744 745static int _aac_probe_container(struct scsi_cmnd * scsicmd, int (*callback)(struct scsi_cmnd *))746{747 struct aac_cmd_priv *cmd_priv = aac_priv(scsicmd);748 struct fib * fibptr;749 int status = -ENOMEM;750 751 if ((fibptr = aac_fib_alloc((struct aac_dev *)scsicmd->device->host->hostdata))) {752 struct aac_query_mount *dinfo;753 754 aac_fib_init(fibptr);755 756 dinfo = (struct aac_query_mount *)fib_data(fibptr);757 758 if (fibptr->dev->supplement_adapter_info.supported_options2 &759 AAC_OPTION_VARIABLE_BLOCK_SIZE)760 dinfo->command = cpu_to_le32(VM_NameServeAllBlk);761 else762 dinfo->command = cpu_to_le32(VM_NameServe);763 764 dinfo->count = cpu_to_le32(scmd_id(scsicmd));765 dinfo->type = cpu_to_le32(FT_FILESYS);766 cmd_priv->callback = callback;767 cmd_priv->owner = AAC_OWNER_FIRMWARE;768 769 status = aac_fib_send(ContainerCommand,770 fibptr,771 sizeof(struct aac_query_mount),772 FsaNormal,773 0, 1,774 _aac_probe_container1,775 (void *) scsicmd);776 /*777 * Check that the command queued to the controller778 */779 if (status == -EINPROGRESS)780 return 0;781 782 if (status < 0) {783 cmd_priv->callback = NULL;784 aac_fib_complete(fibptr);785 aac_fib_free(fibptr);786 }787 }788 if (status < 0) {789 struct fsa_dev_info *fsa_dev_ptr = ((struct aac_dev *)(scsicmd->device->host->hostdata))->fsa_dev;790 if (fsa_dev_ptr) {791 fsa_dev_ptr += scmd_id(scsicmd);792 if ((fsa_dev_ptr->valid & 1) == 0) {793 fsa_dev_ptr->valid = 0;794 return (*callback)(scsicmd);795 }796 }797 }798 return status;799}800 801/**802 * aac_probe_container_callback1 - query a logical volume803 * @scsicmd: the scsi command block804 *805 * Queries the controller about the given volume. The volume information806 * is updated in the struct fsa_dev_info structure rather than returned.807 */808static int aac_probe_container_callback1(struct scsi_cmnd * scsicmd)809{810 scsicmd->device = NULL;811 return 0;812}813 814static void aac_probe_container_scsi_done(struct scsi_cmnd *scsi_cmnd)815{816 aac_probe_container_callback1(scsi_cmnd);817}818 819int aac_probe_container(struct aac_dev *dev, int cid)820{821 struct aac_cmd_priv *cmd_priv;822 struct scsi_cmnd *scsicmd = kzalloc(sizeof(*scsicmd) + sizeof(*cmd_priv), GFP_KERNEL);823 struct scsi_device *scsidev = kzalloc(sizeof(*scsidev), GFP_KERNEL);824 int status;825 826 if (!scsicmd || !scsidev) {827 kfree(scsicmd);828 kfree(scsidev);829 return -ENOMEM;830 }831 832 scsicmd->device = scsidev;833 scsidev->sdev_state = 0;834 scsidev->id = cid;835 scsidev->host = dev->scsi_host_ptr;836 837 if (_aac_probe_container(scsicmd, aac_probe_container_callback1) == 0)838 while (scsicmd->device == scsidev)839 schedule();840 kfree(scsidev);841 cmd_priv = aac_priv(scsicmd);842 status = cmd_priv->status;843 kfree(scsicmd);844 return status;845}846 847/* Local Structure to set SCSI inquiry data strings */848struct scsi_inq {849 char vid[8]; /* Vendor ID */850 char pid[16]; /* Product ID */851 char prl[4]; /* Product Revision Level */852};853 854/**855 * inqstrcpy - string merge856 * @a: string to copy from857 * @b: string to copy to858 *859 * Copy a String from one location to another860 * without copying \0861 */862 863static void inqstrcpy(char *a, char *b)864{865 866 while (*a != (char)0)867 *b++ = *a++;868}869 870static char *container_types[] = {871 "None",872 "Volume",873 "Mirror",874 "Stripe",875 "RAID5",876 "SSRW",877 "SSRO",878 "Morph",879 "Legacy",880 "RAID4",881 "RAID10",882 "RAID00",883 "V-MIRRORS",884 "PSEUDO R4",885 "RAID50",886 "RAID5D",887 "RAID5D0",888 "RAID1E",889 "RAID6",890 "RAID60",891 "Unknown"892};893 894char * get_container_type(unsigned tindex)895{896 if (tindex >= ARRAY_SIZE(container_types))897 tindex = ARRAY_SIZE(container_types) - 1;898 return container_types[tindex];899}900 901/* Function: setinqstr902 *903 * Arguments: [1] pointer to void [1] int904 *905 * Purpose: Sets SCSI inquiry data strings for vendor, product906 * and revision level. Allows strings to be set in platform dependent907 * files instead of in OS dependent driver source.908 */909 910static void setinqstr(struct aac_dev *dev, void *data, int tindex)911{912 struct scsi_inq *str;913 struct aac_supplement_adapter_info *sup_adap_info;914 915 sup_adap_info = &dev->supplement_adapter_info;916 str = (struct scsi_inq *)(data); /* cast data to scsi inq block */917 memset(str, ' ', sizeof(*str));918 919 if (sup_adap_info->adapter_type_text[0]) {920 int c;921 char *cp;922 char *cname = kmemdup(sup_adap_info->adapter_type_text,923 sizeof(sup_adap_info->adapter_type_text),924 GFP_ATOMIC);925 if (!cname)926 return;927 928 cp = cname;929 if ((cp[0] == 'A') && (cp[1] == 'O') && (cp[2] == 'C'))930 inqstrcpy("SMC", str->vid);931 else {932 c = sizeof(str->vid);933 while (*cp && *cp != ' ' && --c)934 ++cp;935 c = *cp;936 *cp = '\0';937 inqstrcpy(cname, str->vid);938 *cp = c;939 while (*cp && *cp != ' ')940 ++cp;941 }942 while (*cp == ' ')943 ++cp;944 /* last six chars reserved for vol type */945 if (strlen(cp) > sizeof(str->pid))946 cp[sizeof(str->pid)] = '\0';947 inqstrcpy (cp, str->pid);948 949 kfree(cname);950 } else {951 struct aac_driver_ident *mp = aac_get_driver_ident(dev->cardtype);952 953 inqstrcpy (mp->vname, str->vid);954 /* last six chars reserved for vol type */955 inqstrcpy (mp->model, str->pid);956 }957 958 if (tindex < ARRAY_SIZE(container_types)){959 char *findit = str->pid;960 961 for ( ; *findit != ' '; findit++); /* walk till we find a space */962 /* RAID is superfluous in the context of a RAID device */963 if (memcmp(findit-4, "RAID", 4) == 0)964 *(findit -= 4) = ' ';965 if (((findit - str->pid) + strlen(container_types[tindex]))966 < (sizeof(str->pid) + sizeof(str->prl)))967 inqstrcpy (container_types[tindex], findit + 1);968 }969 inqstrcpy ("V1.0", str->prl);970}971 972static void build_vpd83_type3(struct tvpd_page83 *vpdpage83data,973 struct aac_dev *dev, struct scsi_cmnd *scsicmd)974{975 int container;976 977 vpdpage83data->type3.codeset = 1;978 vpdpage83data->type3.identifiertype = 3;979 vpdpage83data->type3.identifierlength = sizeof(vpdpage83data->type3)980 - 4;981 982 for (container = 0; container < dev->maximum_num_containers;983 container++) {984 985 if (scmd_id(scsicmd) == container) {986 memcpy(vpdpage83data->type3.Identifier,987 dev->fsa_dev[container].identifier,988 16);989 break;990 }991 }992}993 994static void get_container_serial_callback(void *context, struct fib * fibptr)995{996 struct aac_get_serial_resp * get_serial_reply;997 struct scsi_cmnd * scsicmd;998 999 BUG_ON(fibptr == NULL);1000 1001 scsicmd = (struct scsi_cmnd *) context;1002 if (!aac_valid_context(scsicmd, fibptr))1003 return;1004 1005 get_serial_reply = (struct aac_get_serial_resp *) fib_data(fibptr);1006 /* Failure is irrelevant, using default value instead */1007 if (le32_to_cpu(get_serial_reply->status) == CT_OK) {1008 /*Check to see if it's for VPD 0x83 or 0x80 */1009 if (scsicmd->cmnd[2] == 0x83) {1010 /* vpd page 0x83 - Device Identification Page */1011 struct aac_dev *dev;1012 int i;1013 struct tvpd_page83 vpdpage83data;1014 1015 dev = (struct aac_dev *)scsicmd->device->host->hostdata;1016 1017 memset(((u8 *)&vpdpage83data), 0,1018 sizeof(vpdpage83data));1019 1020 /* DIRECT_ACCESS_DEVIC */1021 vpdpage83data.DeviceType = 0;1022 /* DEVICE_CONNECTED */1023 vpdpage83data.DeviceTypeQualifier = 0;1024 /* VPD_DEVICE_IDENTIFIERS */1025 vpdpage83data.PageCode = 0x83;1026 vpdpage83data.reserved = 0;1027 vpdpage83data.PageLength =1028 sizeof(vpdpage83data.type1) +1029 sizeof(vpdpage83data.type2);1030 1031 /* VPD 83 Type 3 is not supported for ARC */1032 if (dev->sa_firmware)1033 vpdpage83data.PageLength +=1034 sizeof(vpdpage83data.type3);1035 1036 /* T10 Vendor Identifier Field Format */1037 /* VpdcodesetAscii */1038 vpdpage83data.type1.codeset = 2;1039 /* VpdIdentifierTypeVendorId */1040 vpdpage83data.type1.identifiertype = 1;1041 vpdpage83data.type1.identifierlength =1042 sizeof(vpdpage83data.type1) - 4;1043 1044 /* "ADAPTEC " for adaptec */1045 memcpy(vpdpage83data.type1.venid,1046 "ADAPTEC ",1047 sizeof(vpdpage83data.type1.venid));1048 memcpy(vpdpage83data.type1.productid,1049 "ARRAY ",1050 sizeof(1051 vpdpage83data.type1.productid));1052 1053 /* Convert to ascii based serial number.1054 * The LSB is the end.1055 */1056 for (i = 0; i < 8; i++) {1057 u8 temp =1058 (u8)((get_serial_reply->uid >> ((7 - i) * 4)) & 0xF);1059 if (temp > 0x9) {1060 vpdpage83data.type1.serialnumber[i] =1061 'A' + (temp - 0xA);1062 } else {1063 vpdpage83data.type1.serialnumber[i] =1064 '0' + temp;1065 }1066 }1067 1068 /* VpdCodeSetBinary */1069 vpdpage83data.type2.codeset = 1;1070 /* VpdidentifiertypeEUI64 */1071 vpdpage83data.type2.identifiertype = 2;1072 vpdpage83data.type2.identifierlength =1073 sizeof(vpdpage83data.type2) - 4;1074 1075 vpdpage83data.type2.eu64id.venid[0] = 0xD0;1076 vpdpage83data.type2.eu64id.venid[1] = 0;1077 vpdpage83data.type2.eu64id.venid[2] = 0;1078 1079 vpdpage83data.type2.eu64id.Serial =1080 get_serial_reply->uid;1081 vpdpage83data.type2.eu64id.reserved = 0;1082 1083 /*1084 * VpdIdentifierTypeFCPHName1085 * VPD 0x83 Type 3 not supported for ARC1086 */1087 if (dev->sa_firmware) {1088 build_vpd83_type3(&vpdpage83data,1089 dev, scsicmd);1090 }1091 1092 /* Move the inquiry data to the response buffer. */1093 scsi_sg_copy_from_buffer(scsicmd, &vpdpage83data,1094 sizeof(vpdpage83data));1095 } else {1096 /* It must be for VPD 0x80 */1097 char sp[13];1098 /* EVPD bit set */1099 sp[0] = INQD_PDT_DA;1100 sp[1] = scsicmd->cmnd[2];1101 sp[2] = 0;1102 sp[3] = scnprintf(sp+4, sizeof(sp)-4, "%08X",1103 le32_to_cpu(get_serial_reply->uid));1104 scsi_sg_copy_from_buffer(scsicmd, sp,1105 sizeof(sp));1106 }1107 }1108 1109 scsicmd->result = DID_OK << 16 | SAM_STAT_GOOD;1110 1111 aac_fib_complete(fibptr);1112 aac_scsi_done(scsicmd);1113}1114 1115/*1116 * aac_get_container_serial - get container serial, none blocking.1117 */1118static int aac_get_container_serial(struct scsi_cmnd * scsicmd)1119{1120 int status;1121 struct aac_get_serial *dinfo;1122 struct fib * cmd_fibcontext;1123 struct aac_dev * dev;1124 1125 dev = (struct aac_dev *)scsicmd->device->host->hostdata;1126 1127 cmd_fibcontext = aac_fib_alloc_tag(dev, scsicmd);1128 1129 aac_fib_init(cmd_fibcontext);1130 dinfo = (struct aac_get_serial *) fib_data(cmd_fibcontext);1131 1132 dinfo->command = cpu_to_le32(VM_ContainerConfig);1133 dinfo->type = cpu_to_le32(CT_CID_TO_32BITS_UID);1134 dinfo->cid = cpu_to_le32(scmd_id(scsicmd));1135 aac_priv(scsicmd)->owner = AAC_OWNER_FIRMWARE;1136 1137 status = aac_fib_send(ContainerCommand,1138 cmd_fibcontext,1139 sizeof(struct aac_get_serial_resp),1140 FsaNormal,1141 0, 1,1142 (fib_callback) get_container_serial_callback,1143 (void *) scsicmd);1144 1145 /*1146 * Check that the command queued to the controller1147 */1148 if (status == -EINPROGRESS)1149 return 0;1150 1151 printk(KERN_WARNING "aac_get_container_serial: aac_fib_send failed with status: %d.\n", status);1152 aac_fib_complete(cmd_fibcontext);1153 return -1;1154}1155 1156/* Function: setinqserial1157 *1158 * Arguments: [1] pointer to void [1] int1159 *1160 * Purpose: Sets SCSI Unit Serial number.1161 * This is a fake. We should read a proper1162 * serial number from the container. <SuSE>But1163 * without docs it's quite hard to do it :-)1164 * So this will have to do in the meantime.</SuSE>1165 */1166 1167static int setinqserial(struct aac_dev *dev, void *data, int cid)1168{1169 /*1170 * This breaks array migration.1171 */1172 return scnprintf((char *)(data), sizeof(struct scsi_inq) - 4, "%08X%02X",1173 le32_to_cpu(dev->adapter_info.serial[0]), cid);1174}1175 1176static inline void set_sense(struct sense_data *sense_data, u8 sense_key,1177 u8 sense_code, u8 a_sense_code, u8 bit_pointer, u16 field_pointer)1178{1179 u8 *sense_buf = (u8 *)sense_data;1180 /* Sense data valid, err code 70h */1181 sense_buf[0] = 0x70; /* No info field */1182 sense_buf[1] = 0; /* Segment number, always zero */1183 1184 sense_buf[2] = sense_key; /* Sense key */1185 1186 sense_buf[12] = sense_code; /* Additional sense code */1187 sense_buf[13] = a_sense_code; /* Additional sense code qualifier */1188 1189 if (sense_key == ILLEGAL_REQUEST) {1190 sense_buf[7] = 10; /* Additional sense length */1191 1192 sense_buf[15] = bit_pointer;1193 /* Illegal parameter is in the parameter block */1194 if (sense_code == SENCODE_INVALID_CDB_FIELD)1195 sense_buf[15] |= 0xc0;/* Std sense key specific field */1196 /* Illegal parameter is in the CDB block */1197 sense_buf[16] = field_pointer >> 8; /* MSB */1198 sense_buf[17] = field_pointer; /* LSB */1199 } else1200 sense_buf[7] = 6; /* Additional sense length */1201}1202 1203static int aac_bounds_32(struct aac_dev * dev, struct scsi_cmnd * cmd, u64 lba)1204{1205 if (lba & 0xffffffff00000000LL) {1206 int cid = scmd_id(cmd);1207 dprintk((KERN_DEBUG "aacraid: Illegal lba\n"));1208 cmd->result = DID_OK << 16 | SAM_STAT_CHECK_CONDITION;1209 set_sense(&dev->fsa_dev[cid].sense_data,1210 HARDWARE_ERROR, SENCODE_INTERNAL_TARGET_FAILURE,1211 ASENCODE_INTERNAL_TARGET_FAILURE, 0, 0);1212 memcpy(cmd->sense_buffer, &dev->fsa_dev[cid].sense_data,1213 min_t(size_t, sizeof(dev->fsa_dev[cid].sense_data),1214 SCSI_SENSE_BUFFERSIZE));1215 aac_scsi_done(cmd);1216 return 1;1217 }1218 return 0;1219}1220 1221static int aac_bounds_64(struct aac_dev * dev, struct scsi_cmnd * cmd, u64 lba)1222{1223 return 0;1224}1225 1226static void io_callback(void *context, struct fib * fibptr);1227 1228static int aac_read_raw_io(struct fib * fib, struct scsi_cmnd * cmd, u64 lba, u32 count)1229{1230 struct aac_dev *dev = fib->dev;1231 u16 fibsize, command;1232 long ret;1233 1234 aac_fib_init(fib);1235 if ((dev->comm_interface == AAC_COMM_MESSAGE_TYPE2 ||1236 dev->comm_interface == AAC_COMM_MESSAGE_TYPE3) &&1237 !dev->sync_mode) {1238 struct aac_raw_io2 *readcmd2;1239 readcmd2 = (struct aac_raw_io2 *) fib_data(fib);1240 memset(readcmd2, 0, sizeof(struct aac_raw_io2));1241 readcmd2->blockLow = cpu_to_le32((u32)(lba&0xffffffff));1242 readcmd2->blockHigh = cpu_to_le32((u32)((lba&0xffffffff00000000LL)>>32));1243 readcmd2->byteCount = cpu_to_le32(count *1244 dev->fsa_dev[scmd_id(cmd)].block_size);1245 readcmd2->cid = cpu_to_le16(scmd_id(cmd));1246 readcmd2->flags = cpu_to_le16(RIO2_IO_TYPE_READ);1247 ret = aac_build_sgraw2(cmd, readcmd2,1248 dev->scsi_host_ptr->sg_tablesize);1249 if (ret < 0)1250 return ret;1251 command = ContainerRawIo2;1252 fibsize = struct_size(readcmd2, sge,1253 le32_to_cpu(readcmd2->sgeCnt));1254 } else {1255 struct aac_raw_io *readcmd;1256 readcmd = (struct aac_raw_io *) fib_data(fib);1257 readcmd->block[0] = cpu_to_le32((u32)(lba&0xffffffff));1258 readcmd->block[1] = cpu_to_le32((u32)((lba&0xffffffff00000000LL)>>32));1259 readcmd->count = cpu_to_le32(count *1260 dev->fsa_dev[scmd_id(cmd)].block_size);1261 readcmd->cid = cpu_to_le16(scmd_id(cmd));1262 readcmd->flags = cpu_to_le16(RIO_TYPE_READ);1263 readcmd->bpTotal = 0;1264 readcmd->bpComplete = 0;1265 ret = aac_build_sgraw(cmd, &readcmd->sg);1266 if (ret < 0)1267 return ret;1268 command = ContainerRawIo;1269 fibsize = sizeof(struct aac_raw_io) +1270 (le32_to_cpu(readcmd->sg.count) * sizeof(struct sgentryraw));1271 }1272 1273 BUG_ON(fibsize > (fib->dev->max_fib_size - sizeof(struct aac_fibhdr)));1274 /*1275 * Now send the Fib to the adapter1276 */1277 return aac_fib_send(command,1278 fib,1279 fibsize,1280 FsaNormal,1281 0, 1,1282 (fib_callback) io_callback,1283 (void *) cmd);1284}1285 1286static int aac_read_block64(struct fib * fib, struct scsi_cmnd * cmd, u64 lba, u32 count)1287{1288 u16 fibsize;1289 struct aac_read64 *readcmd;1290 long ret;1291 1292 aac_fib_init(fib);1293 readcmd = (struct aac_read64 *) fib_data(fib);1294 readcmd->command = cpu_to_le32(VM_CtHostRead64);1295 readcmd->cid = cpu_to_le16(scmd_id(cmd));1296 readcmd->sector_count = cpu_to_le16(count);1297 readcmd->block = cpu_to_le32((u32)(lba&0xffffffff));1298 readcmd->pad = 0;1299 readcmd->flags = 0;1300 1301 ret = aac_build_sg64(cmd, &readcmd->sg);1302 if (ret < 0)1303 return ret;1304 fibsize = sizeof(struct aac_read64) +1305 (le32_to_cpu(readcmd->sg.count) *1306 sizeof (struct sgentry64));1307 BUG_ON (fibsize > (fib->dev->max_fib_size -1308 sizeof(struct aac_fibhdr)));1309 /*1310 * Now send the Fib to the adapter1311 */1312 return aac_fib_send(ContainerCommand64,1313 fib,1314 fibsize,1315 FsaNormal,1316 0, 1,1317 (fib_callback) io_callback,1318 (void *) cmd);1319}1320 1321static int aac_read_block(struct fib * fib, struct scsi_cmnd * cmd, u64 lba, u32 count)1322{1323 u16 fibsize;1324 struct aac_read *readcmd;1325 struct aac_dev *dev = fib->dev;1326 long ret;1327 1328 aac_fib_init(fib);1329 readcmd = (struct aac_read *) fib_data(fib);1330 readcmd->command = cpu_to_le32(VM_CtBlockRead);1331 readcmd->cid = cpu_to_le32(scmd_id(cmd));1332 readcmd->block = cpu_to_le32((u32)(lba&0xffffffff));1333 readcmd->count = cpu_to_le32(count *1334 dev->fsa_dev[scmd_id(cmd)].block_size);1335 1336 ret = aac_build_sg(cmd, &readcmd->sg);1337 if (ret < 0)1338 return ret;1339 fibsize = sizeof(struct aac_read) +1340 (le32_to_cpu(readcmd->sg.count) *1341 sizeof (struct sgentry));1342 BUG_ON (fibsize > (fib->dev->max_fib_size -1343 sizeof(struct aac_fibhdr)));1344 /*1345 * Now send the Fib to the adapter1346 */1347 return aac_fib_send(ContainerCommand,1348 fib,1349 fibsize,1350 FsaNormal,1351 0, 1,1352 (fib_callback) io_callback,1353 (void *) cmd);1354}1355 1356static int aac_write_raw_io(struct fib * fib, struct scsi_cmnd * cmd, u64 lba, u32 count, int fua)1357{1358 struct aac_dev *dev = fib->dev;1359 u16 fibsize, command;1360 long ret;1361 1362 aac_fib_init(fib);1363 if ((dev->comm_interface == AAC_COMM_MESSAGE_TYPE2 ||1364 dev->comm_interface == AAC_COMM_MESSAGE_TYPE3) &&1365 !dev->sync_mode) {1366 struct aac_raw_io2 *writecmd2;1367 writecmd2 = (struct aac_raw_io2 *) fib_data(fib);1368 memset(writecmd2, 0, sizeof(struct aac_raw_io2));1369 writecmd2->blockLow = cpu_to_le32((u32)(lba&0xffffffff));1370 writecmd2->blockHigh = cpu_to_le32((u32)((lba&0xffffffff00000000LL)>>32));1371 writecmd2->byteCount = cpu_to_le32(count *1372 dev->fsa_dev[scmd_id(cmd)].block_size);1373 writecmd2->cid = cpu_to_le16(scmd_id(cmd));1374 writecmd2->flags = (fua && ((aac_cache & 5) != 1) &&1375 (((aac_cache & 5) != 5) || !fib->dev->cache_protected)) ?1376 cpu_to_le16(RIO2_IO_TYPE_WRITE|RIO2_IO_SUREWRITE) :1377 cpu_to_le16(RIO2_IO_TYPE_WRITE);1378 ret = aac_build_sgraw2(cmd, writecmd2,1379 dev->scsi_host_ptr->sg_tablesize);1380 if (ret < 0)1381 return ret;1382 command = ContainerRawIo2;1383 fibsize = struct_size(writecmd2, sge,1384 le32_to_cpu(writecmd2->sgeCnt));1385 } else {1386 struct aac_raw_io *writecmd;1387 writecmd = (struct aac_raw_io *) fib_data(fib);1388 writecmd->block[0] = cpu_to_le32((u32)(lba&0xffffffff));1389 writecmd->block[1] = cpu_to_le32((u32)((lba&0xffffffff00000000LL)>>32));1390 writecmd->count = cpu_to_le32(count *1391 dev->fsa_dev[scmd_id(cmd)].block_size);1392 writecmd->cid = cpu_to_le16(scmd_id(cmd));1393 writecmd->flags = (fua && ((aac_cache & 5) != 1) &&1394 (((aac_cache & 5) != 5) || !fib->dev->cache_protected)) ?1395 cpu_to_le16(RIO_TYPE_WRITE|RIO_SUREWRITE) :1396 cpu_to_le16(RIO_TYPE_WRITE);1397 writecmd->bpTotal = 0;1398 writecmd->bpComplete = 0;1399 ret = aac_build_sgraw(cmd, &writecmd->sg);1400 if (ret < 0)1401 return ret;1402 command = ContainerRawIo;1403 fibsize = sizeof(struct aac_raw_io) +1404 (le32_to_cpu(writecmd->sg.count) * sizeof(struct sgentryraw));1405 }1406 1407 BUG_ON(fibsize > (fib->dev->max_fib_size - sizeof(struct aac_fibhdr)));1408 /*1409 * Now send the Fib to the adapter1410 */1411 return aac_fib_send(command,1412 fib,1413 fibsize,1414 FsaNormal,1415 0, 1,1416 (fib_callback) io_callback,1417 (void *) cmd);1418}1419 1420static int aac_write_block64(struct fib * fib, struct scsi_cmnd * cmd, u64 lba, u32 count, int fua)1421{1422 u16 fibsize;1423 struct aac_write64 *writecmd;1424 long ret;1425 1426 aac_fib_init(fib);1427 writecmd = (struct aac_write64 *) fib_data(fib);1428 writecmd->command = cpu_to_le32(VM_CtHostWrite64);1429 writecmd->cid = cpu_to_le16(scmd_id(cmd));1430 writecmd->sector_count = cpu_to_le16(count);1431 writecmd->block = cpu_to_le32((u32)(lba&0xffffffff));1432 writecmd->pad = 0;1433 writecmd->flags = 0;1434 1435 ret = aac_build_sg64(cmd, &writecmd->sg);1436 if (ret < 0)1437 return ret;1438 fibsize = sizeof(struct aac_write64) +1439 (le32_to_cpu(writecmd->sg.count) *1440 sizeof (struct sgentry64));1441 BUG_ON (fibsize > (fib->dev->max_fib_size -1442 sizeof(struct aac_fibhdr)));1443 /*1444 * Now send the Fib to the adapter1445 */1446 return aac_fib_send(ContainerCommand64,1447 fib,1448 fibsize,1449 FsaNormal,1450 0, 1,1451 (fib_callback) io_callback,1452 (void *) cmd);1453}1454 1455static int aac_write_block(struct fib * fib, struct scsi_cmnd * cmd, u64 lba, u32 count, int fua)1456{1457 u16 fibsize;1458 struct aac_write *writecmd;1459 struct aac_dev *dev = fib->dev;1460 long ret;1461 1462 aac_fib_init(fib);1463 writecmd = (struct aac_write *) fib_data(fib);1464 writecmd->command = cpu_to_le32(VM_CtBlockWrite);1465 writecmd->cid = cpu_to_le32(scmd_id(cmd));1466 writecmd->block = cpu_to_le32((u32)(lba&0xffffffff));1467 writecmd->count = cpu_to_le32(count *1468 dev->fsa_dev[scmd_id(cmd)].block_size);1469 writecmd->sg.count = cpu_to_le32(1);1470 /* ->stable is not used - it did mean which type of write */1471 1472 ret = aac_build_sg(cmd, &writecmd->sg);1473 if (ret < 0)1474 return ret;1475 fibsize = sizeof(struct aac_write) +1476 (le32_to_cpu(writecmd->sg.count) *1477 sizeof (struct sgentry));1478 BUG_ON (fibsize > (fib->dev->max_fib_size -1479 sizeof(struct aac_fibhdr)));1480 /*1481 * Now send the Fib to the adapter1482 */1483 return aac_fib_send(ContainerCommand,1484 fib,1485 fibsize,1486 FsaNormal,1487 0, 1,1488 (fib_callback) io_callback,1489 (void *) cmd);1490}1491 1492static struct aac_srb * aac_scsi_common(struct fib * fib, struct scsi_cmnd * cmd)1493{1494 struct aac_srb * srbcmd;1495 u32 flag;1496 u32 timeout;1497 struct aac_dev *dev = fib->dev;1498 1499 aac_fib_init(fib);1500 switch(cmd->sc_data_direction){1501 case DMA_TO_DEVICE:1502 flag = SRB_DataOut;1503 break;1504 case DMA_BIDIRECTIONAL:1505 flag = SRB_DataIn | SRB_DataOut;1506 break;1507 case DMA_FROM_DEVICE:1508 flag = SRB_DataIn;1509 break;1510 case DMA_NONE:1511 default: /* shuts up some versions of gcc */1512 flag = SRB_NoDataXfer;1513 break;1514 }1515 1516 srbcmd = (struct aac_srb*) fib_data(fib);1517 srbcmd->function = cpu_to_le32(SRBF_ExecuteScsi);1518 srbcmd->channel = cpu_to_le32(aac_logical_to_phys(scmd_channel(cmd)));1519 srbcmd->id = cpu_to_le32(scmd_id(cmd));1520 srbcmd->lun = cpu_to_le32(cmd->device->lun);1521 srbcmd->flags = cpu_to_le32(flag);1522 timeout = scsi_cmd_to_rq(cmd)->timeout / HZ;1523 if (timeout == 0)1524 timeout = (dev->sa_firmware ? AAC_SA_TIMEOUT : AAC_ARC_TIMEOUT);1525 srbcmd->timeout = cpu_to_le32(timeout); // timeout in seconds1526 srbcmd->retry_limit = 0; /* Obsolete parameter */1527 srbcmd->cdb_size = cpu_to_le32(cmd->cmd_len);1528 return srbcmd;1529}1530 1531static struct aac_hba_cmd_req *aac_construct_hbacmd(struct fib *fib,1532 struct scsi_cmnd *cmd)1533{1534 struct aac_hba_cmd_req *hbacmd;1535 struct aac_dev *dev;1536 int bus, target;1537 u64 address;1538 1539 dev = (struct aac_dev *)cmd->device->host->hostdata;1540 1541 hbacmd = (struct aac_hba_cmd_req *)fib->hw_fib_va;1542 memset(hbacmd, 0, 96); /* sizeof(*hbacmd) is not necessary */1543 /* iu_type is a parameter of aac_hba_send */1544 switch (cmd->sc_data_direction) {1545 case DMA_TO_DEVICE:1546 hbacmd->byte1 = 2;1547 break;1548 case DMA_FROM_DEVICE:1549 case DMA_BIDIRECTIONAL:1550 hbacmd->byte1 = 1;1551 break;1552 case DMA_NONE:1553 default:1554 break;1555 }1556 hbacmd->lun[1] = cpu_to_le32(cmd->device->lun);1557 1558 bus = aac_logical_to_phys(scmd_channel(cmd));1559 target = scmd_id(cmd);1560 hbacmd->it_nexus = dev->hba_map[bus][target].rmw_nexus;1561 1562 /* we fill in reply_qid later in aac_src_deliver_message */1563 /* we fill in iu_type, request_id later in aac_hba_send */1564 /* we fill in emb_data_desc_count later in aac_build_sghba */1565 1566 memcpy(hbacmd->cdb, cmd->cmnd, cmd->cmd_len);1567 hbacmd->data_length = cpu_to_le32(scsi_bufflen(cmd));1568 1569 address = (u64)fib->hw_error_pa;1570 hbacmd->error_ptr_hi = cpu_to_le32((u32)(address >> 32));1571 hbacmd->error_ptr_lo = cpu_to_le32((u32)(address & 0xffffffff));1572 hbacmd->error_length = cpu_to_le32(FW_ERROR_BUFFER_SIZE);1573 1574 return hbacmd;1575}1576 1577static void aac_srb_callback(void *context, struct fib * fibptr);1578 1579static int aac_scsi_64(struct fib * fib, struct scsi_cmnd * cmd)1580{1581 u16 fibsize;1582 struct aac_srb * srbcmd = aac_scsi_common(fib, cmd);1583 long ret;1584 1585 ret = aac_build_sg64(cmd, (struct sgmap64 *) &srbcmd->sg);1586 if (ret < 0)1587 return ret;1588 srbcmd->count = cpu_to_le32(scsi_bufflen(cmd));1589 1590 memset(srbcmd->cdb, 0, sizeof(srbcmd->cdb));1591 memcpy(srbcmd->cdb, cmd->cmnd, cmd->cmd_len);1592 /*1593 * Build Scatter/Gather list1594 */1595 fibsize = sizeof(struct aac_srb) +1596 ((le32_to_cpu(srbcmd->sg.count) & 0xff) *1597 sizeof(struct sgentry64));1598 BUG_ON (fibsize > (fib->dev->max_fib_size -1599 sizeof(struct aac_fibhdr)));1600 1601 /*1602 * Now send the Fib to the adapter1603 */1604 return aac_fib_send(ScsiPortCommand64, fib,1605 fibsize, FsaNormal, 0, 1,1606 (fib_callback) aac_srb_callback,1607 (void *) cmd);1608}1609 1610static int aac_scsi_32(struct fib * fib, struct scsi_cmnd * cmd)1611{1612 u16 fibsize;1613 struct aac_srb * srbcmd = aac_scsi_common(fib, cmd);1614 long ret;1615 1616 ret = aac_build_sg(cmd, (struct sgmap *)&srbcmd->sg);1617 if (ret < 0)1618 return ret;1619 srbcmd->count = cpu_to_le32(scsi_bufflen(cmd));1620 1621 memset(srbcmd->cdb, 0, sizeof(srbcmd->cdb));1622 memcpy(srbcmd->cdb, cmd->cmnd, cmd->cmd_len);1623 /*1624 * Build Scatter/Gather list1625 */1626 fibsize = sizeof (struct aac_srb) +1627 ((le32_to_cpu(srbcmd->sg.count) & 0xff) *1628 sizeof (struct sgentry));1629 BUG_ON (fibsize > (fib->dev->max_fib_size -1630 sizeof(struct aac_fibhdr)));1631 1632 /*1633 * Now send the Fib to the adapter1634 */1635 return aac_fib_send(ScsiPortCommand, fib, fibsize, FsaNormal, 0, 1,1636 (fib_callback) aac_srb_callback, (void *) cmd);1637}1638 1639static int aac_scsi_32_64(struct fib * fib, struct scsi_cmnd * cmd)1640{1641 if ((sizeof(dma_addr_t) > 4) && fib->dev->needs_dac &&1642 (fib->dev->adapter_info.options & AAC_OPT_SGMAP_HOST64))1643 return FAILED;1644 return aac_scsi_32(fib, cmd);1645}1646 1647static int aac_adapter_hba(struct fib *fib, struct scsi_cmnd *cmd)1648{1649 struct aac_hba_cmd_req *hbacmd = aac_construct_hbacmd(fib, cmd);1650 struct aac_dev *dev;1651 long ret;1652 1653 dev = (struct aac_dev *)cmd->device->host->hostdata;1654 1655 ret = aac_build_sghba(cmd, hbacmd,1656 dev->scsi_host_ptr->sg_tablesize, (u64)fib->hw_sgl_pa);1657 if (ret < 0)1658 return ret;1659 1660 /*1661 * Now send the HBA command to the adapter1662 */1663 fib->hbacmd_size = 64 + le32_to_cpu(hbacmd->emb_data_desc_count) *1664 sizeof(struct aac_hba_sgl);1665 1666 return aac_hba_send(HBA_IU_TYPE_SCSI_CMD_REQ, fib,1667 (fib_callback) aac_hba_callback,1668 (void *) cmd);1669}1670 1671static int aac_send_safw_bmic_cmd(struct aac_dev *dev,1672 struct aac_srb_unit *srbu, void *xfer_buf, int xfer_len)1673{1674 struct fib *fibptr;1675 dma_addr_t addr;1676 int rcode;1677 int fibsize;1678 struct aac_srb *srb;1679 struct aac_srb_reply *srb_reply;1680 struct sgmap64 *sg64;1681 u32 vbus;1682 u32 vid;1683 1684 if (!dev->sa_firmware)1685 return 0;1686 1687 /* allocate FIB */1688 fibptr = aac_fib_alloc(dev);1689 if (!fibptr)1690 return -ENOMEM;1691 1692 aac_fib_init(fibptr);1693 fibptr->hw_fib_va->header.XferState &=1694 ~cpu_to_le32(FastResponseCapable);1695 1696 fibsize = sizeof(struct aac_srb) + sizeof(struct sgentry64);1697 1698 /* allocate DMA buffer for response */1699 addr = dma_map_single(&dev->pdev->dev, xfer_buf, xfer_len,1700 DMA_BIDIRECTIONAL);1701 if (dma_mapping_error(&dev->pdev->dev, addr)) {1702 rcode = -ENOMEM;1703 goto fib_error;1704 }1705 1706 srb = fib_data(fibptr);1707 memcpy(srb, &srbu->srb, sizeof(struct aac_srb));1708 1709 vbus = (u32)le16_to_cpu(1710 dev->supplement_adapter_info.virt_device_bus);1711 vid = (u32)le16_to_cpu(1712 dev->supplement_adapter_info.virt_device_target);1713 1714 /* set the common request fields */1715 srb->channel = cpu_to_le32(vbus);1716 srb->id = cpu_to_le32(vid);1717 srb->lun = 0;1718 srb->function = cpu_to_le32(SRBF_ExecuteScsi);1719 srb->timeout = 0;1720 srb->retry_limit = 0;1721 srb->cdb_size = cpu_to_le32(16);1722 srb->count = cpu_to_le32(xfer_len);1723 1724 sg64 = (struct sgmap64 *)&srb->sg;1725 sg64->count = cpu_to_le32(1);1726 sg64->sg[0].addr[1] = cpu_to_le32(upper_32_bits(addr));1727 sg64->sg[0].addr[0] = cpu_to_le32(lower_32_bits(addr));1728 sg64->sg[0].count = cpu_to_le32(xfer_len);1729 1730 /*1731 * Copy the updated data for other dumping or other usage if needed1732 */1733 memcpy(&srbu->srb, srb, sizeof(struct aac_srb));1734 1735 /* issue request to the controller */1736 rcode = aac_fib_send(ScsiPortCommand64, fibptr, fibsize, FsaNormal,1737 1, 1, NULL, NULL);1738 1739 if (rcode == -ERESTARTSYS)1740 rcode = -ERESTART;1741 1742 if (unlikely(rcode < 0))1743 goto bmic_error;1744 1745 srb_reply = (struct aac_srb_reply *)fib_data(fibptr);1746 memcpy(&srbu->srb_reply, srb_reply, sizeof(struct aac_srb_reply));1747 1748bmic_error:1749 dma_unmap_single(&dev->pdev->dev, addr, xfer_len, DMA_BIDIRECTIONAL);1750fib_error:1751 aac_fib_complete(fibptr);1752 aac_fib_free(fibptr);1753 return rcode;1754}1755 1756static void aac_set_safw_target_qd(struct aac_dev *dev, int bus, int target)1757{1758 1759 struct aac_ciss_identify_pd *identify_resp;1760 1761 if (dev->hba_map[bus][target].devtype != AAC_DEVTYPE_NATIVE_RAW)1762 return;1763 1764 identify_resp = dev->hba_map[bus][target].safw_identify_resp;1765 if (identify_resp == NULL) {1766 dev->hba_map[bus][target].qd_limit = 32;1767 return;1768 }1769 1770 if (identify_resp->current_queue_depth_limit <= 0 ||1771 identify_resp->current_queue_depth_limit > 255)1772 dev->hba_map[bus][target].qd_limit = 32;1773 else1774 dev->hba_map[bus][target].qd_limit =1775 identify_resp->current_queue_depth_limit;1776}1777 1778static int aac_issue_safw_bmic_identify(struct aac_dev *dev,1779 struct aac_ciss_identify_pd **identify_resp, u32 bus, u32 target)1780{1781 int rcode = -ENOMEM;1782 int datasize;1783 struct aac_srb_unit srbu;1784 struct aac_srb *srbcmd;1785 struct aac_ciss_identify_pd *identify_reply;1786 1787 datasize = sizeof(struct aac_ciss_identify_pd);1788 identify_reply = kmalloc(datasize, GFP_KERNEL);1789 if (!identify_reply)1790 goto out;1791 1792 memset(&srbu, 0, sizeof(struct aac_srb_unit));1793 1794 srbcmd = &srbu.srb;1795 srbcmd->flags = cpu_to_le32(SRB_DataIn);1796 srbcmd->cdb[0] = 0x26;1797 srbcmd->cdb[2] = (u8)((AAC_MAX_LUN + target) & 0x00FF);1798 srbcmd->cdb[6] = CISS_IDENTIFY_PHYSICAL_DEVICE;1799 1800 rcode = aac_send_safw_bmic_cmd(dev, &srbu, identify_reply, datasize);1801 if (unlikely(rcode < 0))1802 goto mem_free_all;1803 1804 *identify_resp = identify_reply;1805 1806out:1807 return rcode;1808mem_free_all:1809 kfree(identify_reply);1810 goto out;1811}1812 1813static inline void aac_free_safw_ciss_luns(struct aac_dev *dev)1814{1815 kfree(dev->safw_phys_luns);1816 dev->safw_phys_luns = NULL;1817}1818 1819/**1820 * aac_get_safw_ciss_luns() - Process topology change1821 * @dev: aac_dev structure1822 *1823 * Execute a CISS REPORT PHYS LUNS and process the results into1824 * the current hba_map.1825 */1826static int aac_get_safw_ciss_luns(struct aac_dev *dev)1827{1828 int rcode = -ENOMEM;1829 int datasize;1830 struct aac_srb *srbcmd;1831 struct aac_srb_unit srbu;1832 struct aac_ciss_phys_luns_resp *phys_luns;1833 1834 datasize = sizeof(struct aac_ciss_phys_luns_resp) +1835 AAC_MAX_TARGETS * sizeof(struct _ciss_lun);1836 phys_luns = kmalloc(datasize, GFP_KERNEL);1837 if (phys_luns == NULL)1838 goto out;1839 1840 memset(&srbu, 0, sizeof(struct aac_srb_unit));1841 1842 srbcmd = &srbu.srb;1843 srbcmd->flags = cpu_to_le32(SRB_DataIn);1844 srbcmd->cdb[0] = CISS_REPORT_PHYSICAL_LUNS;1845 srbcmd->cdb[1] = 2; /* extended reporting */1846 srbcmd->cdb[8] = (u8)(datasize >> 8);1847 srbcmd->cdb[9] = (u8)(datasize);1848 1849 rcode = aac_send_safw_bmic_cmd(dev, &srbu, phys_luns, datasize);1850 if (unlikely(rcode < 0))1851 goto mem_free_all;1852 1853 if (phys_luns->resp_flag != 2) {1854 rcode = -ENOMSG;1855 goto mem_free_all;1856 }1857 1858 dev->safw_phys_luns = phys_luns;1859 1860out:1861 return rcode;1862mem_free_all:1863 kfree(phys_luns);1864 goto out;1865}1866 1867static inline u32 aac_get_safw_phys_lun_count(struct aac_dev *dev)1868{1869 return get_unaligned_be32(&dev->safw_phys_luns->list_length[0])/24;1870}1871 1872static inline u32 aac_get_safw_phys_bus(struct aac_dev *dev, int lun)1873{1874 return dev->safw_phys_luns->lun[lun].level2[1] & 0x3f;1875}1876 1877static inline u32 aac_get_safw_phys_target(struct aac_dev *dev, int lun)1878{1879 return dev->safw_phys_luns->lun[lun].level2[0];1880}1881 1882static inline u32 aac_get_safw_phys_expose_flag(struct aac_dev *dev, int lun)1883{1884 return dev->safw_phys_luns->lun[lun].bus >> 6;1885}1886 1887static inline u32 aac_get_safw_phys_attribs(struct aac_dev *dev, int lun)1888{1889 return dev->safw_phys_luns->lun[lun].node_ident[9];1890}1891 1892static inline u32 aac_get_safw_phys_nexus(struct aac_dev *dev, int lun)1893{1894 return *((u32 *)&dev->safw_phys_luns->lun[lun].node_ident[12]);1895}1896 1897static inline void aac_free_safw_identify_resp(struct aac_dev *dev,1898 int bus, int target)1899{1900 kfree(dev->hba_map[bus][target].safw_identify_resp);1901 dev->hba_map[bus][target].safw_identify_resp = NULL;1902}1903 1904static inline void aac_free_safw_all_identify_resp(struct aac_dev *dev,1905 int lun_count)1906{1907 int luns;1908 int i;1909 u32 bus;1910 u32 target;1911 1912 luns = aac_get_safw_phys_lun_count(dev);1913 1914 if (luns < lun_count)1915 lun_count = luns;1916 else if (lun_count < 0)1917 lun_count = luns;1918 1919 for (i = 0; i < lun_count; i++) {1920 bus = aac_get_safw_phys_bus(dev, i);1921 target = aac_get_safw_phys_target(dev, i);1922 1923 aac_free_safw_identify_resp(dev, bus, target);1924 }1925}1926 1927static int aac_get_safw_attr_all_targets(struct aac_dev *dev)1928{1929 int i;1930 int rcode = 0;1931 u32 lun_count;1932 u32 bus;1933 u32 target;1934 struct aac_ciss_identify_pd *identify_resp = NULL;1935 1936 lun_count = aac_get_safw_phys_lun_count(dev);1937 1938 for (i = 0; i < lun_count; ++i) {1939 1940 bus = aac_get_safw_phys_bus(dev, i);1941 target = aac_get_safw_phys_target(dev, i);1942 1943 rcode = aac_issue_safw_bmic_identify(dev,1944 &identify_resp, bus, target);1945 1946 if (unlikely(rcode < 0))1947 goto free_identify_resp;1948 1949 dev->hba_map[bus][target].safw_identify_resp = identify_resp;1950 }1951 1952out:1953 return rcode;1954free_identify_resp:1955 aac_free_safw_all_identify_resp(dev, i);1956 goto out;1957}1958 1959/**1960 * aac_set_safw_attr_all_targets- update current hba map with data from FW1961 * @dev: aac_dev structure1962 *1963 * Update our hba map with the information gathered from the FW1964 */1965static void aac_set_safw_attr_all_targets(struct aac_dev *dev)1966{1967 /* ok and extended reporting */1968 u32 lun_count, nexus;1969 u32 i, bus, target;1970 u8 expose_flag, attribs;1971 1972 lun_count = aac_get_safw_phys_lun_count(dev);1973 1974 dev->scan_counter++;1975 1976 for (i = 0; i < lun_count; ++i) {1977 1978 bus = aac_get_safw_phys_bus(dev, i);1979 target = aac_get_safw_phys_target(dev, i);1980 expose_flag = aac_get_safw_phys_expose_flag(dev, i);1981 attribs = aac_get_safw_phys_attribs(dev, i);1982 nexus = aac_get_safw_phys_nexus(dev, i);1983 1984 if (bus >= AAC_MAX_BUSES || target >= AAC_MAX_TARGETS)1985 continue;1986 1987 if (expose_flag != 0) {1988 dev->hba_map[bus][target].devtype =1989 AAC_DEVTYPE_RAID_MEMBER;1990 continue;1991 }1992 1993 if (nexus != 0 && (attribs & 8)) {1994 dev->hba_map[bus][target].devtype =1995 AAC_DEVTYPE_NATIVE_RAW;1996 dev->hba_map[bus][target].rmw_nexus =1997 nexus;1998 } else1999 dev->hba_map[bus][target].devtype =2000 AAC_DEVTYPE_ARC_RAW;2001 2002 dev->hba_map[bus][target].scan_counter = dev->scan_counter;2003 2004 aac_set_safw_target_qd(dev, bus, target);2005 }2006}2007 2008static int aac_setup_safw_targets(struct aac_dev *dev)2009{2010 int rcode = 0;2011 2012 rcode = aac_get_containers(dev);2013 if (unlikely(rcode < 0))2014 goto out;2015 2016 rcode = aac_get_safw_ciss_luns(dev);2017 if (unlikely(rcode < 0))2018 goto out;2019 2020 rcode = aac_get_safw_attr_all_targets(dev);2021 if (unlikely(rcode < 0))2022 goto free_ciss_luns;2023 2024 aac_set_safw_attr_all_targets(dev);2025 2026 aac_free_safw_all_identify_resp(dev, -1);2027free_ciss_luns:2028 aac_free_safw_ciss_luns(dev);2029out:2030 return rcode;2031}2032 2033int aac_setup_safw_adapter(struct aac_dev *dev)2034{2035 return aac_setup_safw_targets(dev);2036}2037 2038int aac_get_adapter_info(struct aac_dev* dev)2039{2040 struct fib* fibptr;2041 int rcode;2042 u32 tmp, bus, target;2043 struct aac_adapter_info *info;2044 struct aac_bus_info *command;2045 struct aac_bus_info_response *bus_info;2046 2047 if (!(fibptr = aac_fib_alloc(dev)))2048 return -ENOMEM;2049 2050 aac_fib_init(fibptr);2051 info = (struct aac_adapter_info *) fib_data(fibptr);2052 memset(info,0,sizeof(*info));2053 2054 rcode = aac_fib_send(RequestAdapterInfo,2055 fibptr,2056 sizeof(*info),2057 FsaNormal,2058 -1, 1, /* First `interrupt' command uses special wait */2059 NULL,2060 NULL);2061 2062 if (rcode < 0) {2063 /* FIB should be freed only after2064 * getting the response from the F/W */2065 if (rcode != -ERESTARTSYS) {2066 aac_fib_complete(fibptr);2067 aac_fib_free(fibptr);2068 }2069 return rcode;2070 }2071 memcpy(&dev->adapter_info, info, sizeof(*info));2072 2073 dev->supplement_adapter_info.virt_device_bus = 0xffff;2074 if (dev->adapter_info.options & AAC_OPT_SUPPLEMENT_ADAPTER_INFO) {2075 struct aac_supplement_adapter_info * sinfo;2076 2077 aac_fib_init(fibptr);2078 2079 sinfo = (struct aac_supplement_adapter_info *) fib_data(fibptr);2080 2081 memset(sinfo,0,sizeof(*sinfo));2082 2083 rcode = aac_fib_send(RequestSupplementAdapterInfo,2084 fibptr,2085 sizeof(*sinfo),2086 FsaNormal,2087 1, 1,2088 NULL,2089 NULL);2090 2091 if (rcode >= 0)2092 memcpy(&dev->supplement_adapter_info, sinfo, sizeof(*sinfo));2093 if (rcode == -ERESTARTSYS) {2094 fibptr = aac_fib_alloc(dev);2095 if (!fibptr)2096 return -ENOMEM;2097 }2098 2099 }2100 2101 /* reset all previous mapped devices (i.e. for init. after IOP_RESET) */2102 for (bus = 0; bus < AAC_MAX_BUSES; bus++) {2103 for (target = 0; target < AAC_MAX_TARGETS; target++) {2104 dev->hba_map[bus][target].devtype = 0;2105 dev->hba_map[bus][target].qd_limit = 0;2106 }2107 }2108 2109 /*2110 * GetBusInfo2111 */2112 2113 aac_fib_init(fibptr);2114 2115 bus_info = (struct aac_bus_info_response *) fib_data(fibptr);2116 2117 memset(bus_info, 0, sizeof(*bus_info));2118 2119 command = (struct aac_bus_info *)bus_info;2120 2121 command->Command = cpu_to_le32(VM_Ioctl);2122 command->ObjType = cpu_to_le32(FT_DRIVE);2123 command->MethodId = cpu_to_le32(1);2124 command->CtlCmd = cpu_to_le32(GetBusInfo);2125 2126 rcode = aac_fib_send(ContainerCommand,2127 fibptr,2128 sizeof (*bus_info),2129 FsaNormal,2130 1, 1,2131 NULL, NULL);2132 2133 /* reasoned default */2134 dev->maximum_num_physicals = 16;2135 if (rcode >= 0 && le32_to_cpu(bus_info->Status) == ST_OK) {2136 dev->maximum_num_physicals = le32_to_cpu(bus_info->TargetsPerBus);2137 dev->maximum_num_channels = le32_to_cpu(bus_info->BusCount);2138 }2139 2140 if (!dev->in_reset) {2141 char buffer[16];2142 tmp = le32_to_cpu(dev->adapter_info.kernelrev);2143 printk(KERN_INFO "%s%d: kernel %d.%d-%d[%d] %.*s\n",2144 dev->name,2145 dev->id,2146 tmp>>24,2147 (tmp>>16)&0xff,2148 tmp&0xff,2149 le32_to_cpu(dev->adapter_info.kernelbuild),2150 (int)sizeof(dev->supplement_adapter_info.build_date),2151 dev->supplement_adapter_info.build_date);2152 tmp = le32_to_cpu(dev->adapter_info.monitorrev);2153 printk(KERN_INFO "%s%d: monitor %d.%d-%d[%d]\n",2154 dev->name, dev->id,2155 tmp>>24,(tmp>>16)&0xff,tmp&0xff,2156 le32_to_cpu(dev->adapter_info.monitorbuild));2157 tmp = le32_to_cpu(dev->adapter_info.biosrev);2158 printk(KERN_INFO "%s%d: bios %d.%d-%d[%d]\n",2159 dev->name, dev->id,2160 tmp>>24,(tmp>>16)&0xff,tmp&0xff,2161 le32_to_cpu(dev->adapter_info.biosbuild));2162 buffer[0] = '\0';2163 if (aac_get_serial_number(2164 shost_to_class(dev->scsi_host_ptr), buffer))2165 printk(KERN_INFO "%s%d: serial %s",2166 dev->name, dev->id, buffer);2167 if (dev->supplement_adapter_info.vpd_info.tsid[0]) {2168 printk(KERN_INFO "%s%d: TSID %.*s\n",2169 dev->name, dev->id,2170 (int)sizeof(dev->supplement_adapter_info2171 .vpd_info.tsid),2172 dev->supplement_adapter_info.vpd_info.tsid);2173 }2174 if (!aac_check_reset || ((aac_check_reset == 1) &&2175 (dev->supplement_adapter_info.supported_options2 &2176 AAC_OPTION_IGNORE_RESET))) {2177 printk(KERN_INFO "%s%d: Reset Adapter Ignored\n",2178 dev->name, dev->id);2179 }2180 }2181 2182 dev->cache_protected = 0;2183 dev->jbod = ((dev->supplement_adapter_info.feature_bits &2184 AAC_FEATURE_JBOD) != 0);2185 dev->nondasd_support = 0;2186 dev->raid_scsi_mode = 0;2187 if(dev->adapter_info.options & AAC_OPT_NONDASD)2188 dev->nondasd_support = 1;2189 2190 /*2191 * If the firmware supports ROMB RAID/SCSI mode and we are currently2192 * in RAID/SCSI mode, set the flag. For now if in this mode we will2193 * force nondasd support on. If we decide to allow the non-dasd flag2194 * additional changes changes will have to be made to support2195 * RAID/SCSI. the function aac_scsi_cmd in this module will have to be2196 * changed to support the new dev->raid_scsi_mode flag instead of2197 * leaching off of the dev->nondasd_support flag. Also in linit.c the2198 * function aac_detect will have to be modified where it sets up the2199 * max number of channels based on the aac->nondasd_support flag only.2200 */2201 if ((dev->adapter_info.options & AAC_OPT_SCSI_MANAGED) &&2202 (dev->adapter_info.options & AAC_OPT_RAID_SCSI_MODE)) {2203 dev->nondasd_support = 1;2204 dev->raid_scsi_mode = 1;2205 }2206 if (dev->raid_scsi_mode != 0)2207 printk(KERN_INFO "%s%d: ROMB RAID/SCSI mode enabled\n",2208 dev->name, dev->id);2209 2210 if (nondasd != -1)2211 dev->nondasd_support = (nondasd!=0);2212 if (dev->nondasd_support && !dev->in_reset)2213 printk(KERN_INFO "%s%d: Non-DASD support enabled.\n",dev->name, dev->id);2214 2215 if (dma_get_required_mask(&dev->pdev->dev) > DMA_BIT_MASK(32))2216 dev->needs_dac = 1;2217 dev->dac_support = 0;2218 if ((sizeof(dma_addr_t) > 4) && dev->needs_dac &&2219 (dev->adapter_info.options & AAC_OPT_SGMAP_HOST64)) {2220 if (!dev->in_reset)2221 printk(KERN_INFO "%s%d: 64bit support enabled.\n",2222 dev->name, dev->id);2223 dev->dac_support = 1;2224 }2225 2226 if(dacmode != -1) {2227 dev->dac_support = (dacmode!=0);2228 }2229 2230 /* avoid problems with AAC_QUIRK_SCSI_32 controllers */2231 if (dev->dac_support && (aac_get_driver_ident(dev->cardtype)->quirks2232 & AAC_QUIRK_SCSI_32)) {2233 dev->nondasd_support = 0;2234 dev->jbod = 0;2235 expose_physicals = 0;2236 }2237 2238 if (dev->dac_support) {2239 if (!dma_set_mask(&dev->pdev->dev, DMA_BIT_MASK(64))) {2240 if (!dev->in_reset)2241 dev_info(&dev->pdev->dev, "64 Bit DAC enabled\n");2242 } else if (!dma_set_mask(&dev->pdev->dev, DMA_BIT_MASK(32))) {2243 dev_info(&dev->pdev->dev, "DMA mask set failed, 64 Bit DAC disabled\n");2244 dev->dac_support = 0;2245 } else {2246 dev_info(&dev->pdev->dev, "No suitable DMA available\n");2247 rcode = -ENOMEM;2248 }2249 }2250 /*2251 * Deal with configuring for the individualized limits of each packet2252 * interface.2253 */2254 dev->a_ops.adapter_scsi = (dev->dac_support)2255 ? ((aac_get_driver_ident(dev->cardtype)->quirks & AAC_QUIRK_SCSI_32)2256 ? aac_scsi_32_642257 : aac_scsi_64)2258 : aac_scsi_32;2259 if (dev->raw_io_interface) {2260 dev->a_ops.adapter_bounds = (dev->raw_io_64)2261 ? aac_bounds_642262 : aac_bounds_32;2263 dev->a_ops.adapter_read = aac_read_raw_io;2264 dev->a_ops.adapter_write = aac_write_raw_io;2265 } else {2266 dev->a_ops.adapter_bounds = aac_bounds_32;2267 dev->scsi_host_ptr->sg_tablesize = (dev->max_fib_size -2268 sizeof(struct aac_fibhdr) -2269 sizeof(struct aac_write)) /2270 sizeof(struct sgentry);2271 if (dev->dac_support) {2272 dev->a_ops.adapter_read = aac_read_block64;2273 dev->a_ops.adapter_write = aac_write_block64;2274 /*2275 * 38 scatter gather elements2276 */2277 dev->scsi_host_ptr->sg_tablesize =2278 (dev->max_fib_size -2279 sizeof(struct aac_fibhdr) -2280 sizeof(struct aac_write64)) /2281 sizeof(struct sgentry64);2282 } else {2283 dev->a_ops.adapter_read = aac_read_block;2284 dev->a_ops.adapter_write = aac_write_block;2285 }2286 dev->scsi_host_ptr->max_sectors = AAC_MAX_32BIT_SGBCOUNT;2287 if (!(dev->adapter_info.options & AAC_OPT_NEW_COMM)) {2288 /*2289 * Worst case size that could cause sg overflow when2290 * we break up SG elements that are larger than 64KB.2291 * Would be nice if we could tell the SCSI layer what2292 * the maximum SG element size can be. Worst case is2293 * (sg_tablesize-1) 4KB elements with one 64KB2294 * element.2295 * 32bit -> 468 or 238KB 64bit -> 424 or 212KB2296 */2297 dev->scsi_host_ptr->max_sectors =2298 (dev->scsi_host_ptr->sg_tablesize * 8) + 112;2299 }2300 }2301 if (!dev->sync_mode && dev->sa_firmware &&2302 dev->scsi_host_ptr->sg_tablesize > HBA_MAX_SG_SEPARATE)2303 dev->scsi_host_ptr->sg_tablesize = dev->sg_tablesize =2304 HBA_MAX_SG_SEPARATE;2305 2306 /* FIB should be freed only after getting the response from the F/W */2307 if (rcode != -ERESTARTSYS) {2308 aac_fib_complete(fibptr);2309 aac_fib_free(fibptr);2310 }2311 2312 return rcode;2313}2314 2315 2316static void io_callback(void *context, struct fib * fibptr)2317{2318 struct aac_dev *dev;2319 struct aac_read_reply *readreply;2320 struct scsi_cmnd *scsicmd;2321 u32 cid;2322 2323 scsicmd = (struct scsi_cmnd *) context;2324 2325 if (!aac_valid_context(scsicmd, fibptr))2326 return;2327 2328 dev = fibptr->dev;2329 cid = scmd_id(scsicmd);2330 2331 if (nblank(dprintk(x))) {2332 u64 lba;2333 switch (scsicmd->cmnd[0]) {2334 case WRITE_6:2335 case READ_6:2336 lba = ((scsicmd->cmnd[1] & 0x1F) << 16) |2337 (scsicmd->cmnd[2] << 8) | scsicmd->cmnd[3];2338 break;2339 case WRITE_16:2340 case READ_16:2341 lba = ((u64)scsicmd->cmnd[2] << 56) |2342 ((u64)scsicmd->cmnd[3] << 48) |2343 ((u64)scsicmd->cmnd[4] << 40) |2344 ((u64)scsicmd->cmnd[5] << 32) |2345 ((u64)scsicmd->cmnd[6] << 24) |2346 (scsicmd->cmnd[7] << 16) |2347 (scsicmd->cmnd[8] << 8) | scsicmd->cmnd[9];2348 break;2349 case WRITE_12:2350 case READ_12:2351 lba = ((u64)scsicmd->cmnd[2] << 24) |2352 (scsicmd->cmnd[3] << 16) |2353 (scsicmd->cmnd[4] << 8) | scsicmd->cmnd[5];2354 break;2355 default:2356 lba = ((u64)scsicmd->cmnd[2] << 24) |2357 (scsicmd->cmnd[3] << 16) |2358 (scsicmd->cmnd[4] << 8) | scsicmd->cmnd[5];2359 break;2360 }2361 printk(KERN_DEBUG2362 "io_callback[cpu %d]: lba = %llu, t = %ld.\n",2363 smp_processor_id(), (unsigned long long)lba, jiffies);2364 }2365 2366 BUG_ON(fibptr == NULL);2367 2368 scsi_dma_unmap(scsicmd);2369 2370 readreply = (struct aac_read_reply *)fib_data(fibptr);2371 switch (le32_to_cpu(readreply->status)) {2372 case ST_OK:2373 scsicmd->result = DID_OK << 16 | SAM_STAT_GOOD;2374 dev->fsa_dev[cid].sense_data.sense_key = NO_SENSE;2375 break;2376 case ST_NOT_READY:2377 scsicmd->result = DID_OK << 16 | SAM_STAT_CHECK_CONDITION;2378 set_sense(&dev->fsa_dev[cid].sense_data, NOT_READY,2379 SENCODE_BECOMING_READY, ASENCODE_BECOMING_READY, 0, 0);2380 memcpy(scsicmd->sense_buffer, &dev->fsa_dev[cid].sense_data,2381 min_t(size_t, sizeof(dev->fsa_dev[cid].sense_data),2382 SCSI_SENSE_BUFFERSIZE));2383 break;2384 case ST_MEDERR:2385 scsicmd->result = DID_OK << 16 | SAM_STAT_CHECK_CONDITION;2386 set_sense(&dev->fsa_dev[cid].sense_data, MEDIUM_ERROR,2387 SENCODE_UNRECOVERED_READ_ERROR, ASENCODE_NO_SENSE, 0, 0);2388 memcpy(scsicmd->sense_buffer, &dev->fsa_dev[cid].sense_data,2389 min_t(size_t, sizeof(dev->fsa_dev[cid].sense_data),2390 SCSI_SENSE_BUFFERSIZE));2391 break;2392 default:2393#ifdef AAC_DETAILED_STATUS_INFO2394 printk(KERN_WARNING "io_callback: io failed, status = %d\n",2395 le32_to_cpu(readreply->status));2396#endif2397 scsicmd->result = DID_OK << 16 | SAM_STAT_CHECK_CONDITION;2398 set_sense(&dev->fsa_dev[cid].sense_data,2399 HARDWARE_ERROR, SENCODE_INTERNAL_TARGET_FAILURE,2400 ASENCODE_INTERNAL_TARGET_FAILURE, 0, 0);2401 memcpy(scsicmd->sense_buffer, &dev->fsa_dev[cid].sense_data,2402 min_t(size_t, sizeof(dev->fsa_dev[cid].sense_data),2403 SCSI_SENSE_BUFFERSIZE));2404 break;2405 }2406 aac_fib_complete(fibptr);2407 2408 aac_scsi_done(scsicmd);2409}2410 2411static int aac_read(struct scsi_cmnd * scsicmd)2412{2413 u64 lba;2414 u32 count;2415 int status;2416 struct aac_dev *dev;2417 struct fib * cmd_fibcontext;2418 int cid;2419 2420 dev = (struct aac_dev *)scsicmd->device->host->hostdata;2421 /*2422 * Get block address and transfer length2423 */2424 switch (scsicmd->cmnd[0]) {2425 case READ_6:2426 dprintk((KERN_DEBUG "aachba: received a read(6) command on id %d.\n", scmd_id(scsicmd)));2427 2428 lba = ((scsicmd->cmnd[1] & 0x1F) << 16) |2429 (scsicmd->cmnd[2] << 8) | scsicmd->cmnd[3];2430 count = scsicmd->cmnd[4];2431 2432 if (count == 0)2433 count = 256;2434 break;2435 case READ_16:2436 dprintk((KERN_DEBUG "aachba: received a read(16) command on id %d.\n", scmd_id(scsicmd)));2437 2438 lba = ((u64)scsicmd->cmnd[2] << 56) |2439 ((u64)scsicmd->cmnd[3] << 48) |2440 ((u64)scsicmd->cmnd[4] << 40) |2441 ((u64)scsicmd->cmnd[5] << 32) |2442 ((u64)scsicmd->cmnd[6] << 24) |2443 (scsicmd->cmnd[7] << 16) |2444 (scsicmd->cmnd[8] << 8) | scsicmd->cmnd[9];2445 count = (scsicmd->cmnd[10] << 24) |2446 (scsicmd->cmnd[11] << 16) |2447 (scsicmd->cmnd[12] << 8) | scsicmd->cmnd[13];2448 break;2449 case READ_12:2450 dprintk((KERN_DEBUG "aachba: received a read(12) command on id %d.\n", scmd_id(scsicmd)));2451 2452 lba = ((u64)scsicmd->cmnd[2] << 24) |2453 (scsicmd->cmnd[3] << 16) |2454 (scsicmd->cmnd[4] << 8) | scsicmd->cmnd[5];2455 count = (scsicmd->cmnd[6] << 24) |2456 (scsicmd->cmnd[7] << 16) |2457 (scsicmd->cmnd[8] << 8) | scsicmd->cmnd[9];2458 break;2459 default:2460 dprintk((KERN_DEBUG "aachba: received a read(10) command on id %d.\n", scmd_id(scsicmd)));2461 2462 lba = ((u64)scsicmd->cmnd[2] << 24) |2463 (scsicmd->cmnd[3] << 16) |2464 (scsicmd->cmnd[4] << 8) | scsicmd->cmnd[5];2465 count = (scsicmd->cmnd[7] << 8) | scsicmd->cmnd[8];2466 break;2467 }2468 2469 if ((lba + count) > (dev->fsa_dev[scmd_id(scsicmd)].size)) {2470 cid = scmd_id(scsicmd);2471 dprintk((KERN_DEBUG "aacraid: Illegal lba\n"));2472 scsicmd->result = DID_OK << 16 | SAM_STAT_CHECK_CONDITION;2473 set_sense(&dev->fsa_dev[cid].sense_data,2474 ILLEGAL_REQUEST, SENCODE_LBA_OUT_OF_RANGE,2475 ASENCODE_INTERNAL_TARGET_FAILURE, 0, 0);2476 memcpy(scsicmd->sense_buffer, &dev->fsa_dev[cid].sense_data,2477 min_t(size_t, sizeof(dev->fsa_dev[cid].sense_data),2478 SCSI_SENSE_BUFFERSIZE));2479 aac_scsi_done(scsicmd);2480 return 0;2481 }2482 2483 dprintk((KERN_DEBUG "aac_read[cpu %d]: lba = %llu, t = %ld.\n",2484 smp_processor_id(), (unsigned long long)lba, jiffies));2485 if (aac_adapter_bounds(dev,scsicmd,lba))2486 return 0;2487 /*2488 * Alocate and initialize a Fib2489 */2490 cmd_fibcontext = aac_fib_alloc_tag(dev, scsicmd);2491 aac_priv(scsicmd)->owner = AAC_OWNER_FIRMWARE;2492 status = aac_adapter_read(cmd_fibcontext, scsicmd, lba, count);2493 2494 /*2495 * Check that the command queued to the controller2496 */2497 if (status == -EINPROGRESS)2498 return 0;2499 2500 printk(KERN_WARNING "aac_read: aac_fib_send failed with status: %d.\n", status);2501 /*2502 * For some reason, the Fib didn't queue, return QUEUE_FULL2503 */2504 scsicmd->result = DID_OK << 16 | SAM_STAT_TASK_SET_FULL;2505 aac_scsi_done(scsicmd);2506 aac_fib_complete(cmd_fibcontext);2507 aac_fib_free(cmd_fibcontext);2508 return 0;2509}2510 2511static int aac_write(struct scsi_cmnd * scsicmd)2512{2513 u64 lba;2514 u32 count;2515 int fua;2516 int status;2517 struct aac_dev *dev;2518 struct fib * cmd_fibcontext;2519 int cid;2520 2521 dev = (struct aac_dev *)scsicmd->device->host->hostdata;2522 /*2523 * Get block address and transfer length2524 */2525 if (scsicmd->cmnd[0] == WRITE_6) /* 6 byte command */2526 {2527 lba = ((scsicmd->cmnd[1] & 0x1F) << 16) | (scsicmd->cmnd[2] << 8) | scsicmd->cmnd[3];2528 count = scsicmd->cmnd[4];2529 if (count == 0)2530 count = 256;2531 fua = 0;2532 } else if (scsicmd->cmnd[0] == WRITE_16) { /* 16 byte command */2533 dprintk((KERN_DEBUG "aachba: received a write(16) command on id %d.\n", scmd_id(scsicmd)));2534 2535 lba = ((u64)scsicmd->cmnd[2] << 56) |2536 ((u64)scsicmd->cmnd[3] << 48) |2537 ((u64)scsicmd->cmnd[4] << 40) |2538 ((u64)scsicmd->cmnd[5] << 32) |2539 ((u64)scsicmd->cmnd[6] << 24) |2540 (scsicmd->cmnd[7] << 16) |2541 (scsicmd->cmnd[8] << 8) | scsicmd->cmnd[9];2542 count = (scsicmd->cmnd[10] << 24) | (scsicmd->cmnd[11] << 16) |2543 (scsicmd->cmnd[12] << 8) | scsicmd->cmnd[13];2544 fua = scsicmd->cmnd[1] & 0x8;2545 } else if (scsicmd->cmnd[0] == WRITE_12) { /* 12 byte command */2546 dprintk((KERN_DEBUG "aachba: received a write(12) command on id %d.\n", scmd_id(scsicmd)));2547 2548 lba = ((u64)scsicmd->cmnd[2] << 24) | (scsicmd->cmnd[3] << 16)2549 | (scsicmd->cmnd[4] << 8) | scsicmd->cmnd[5];2550 count = (scsicmd->cmnd[6] << 24) | (scsicmd->cmnd[7] << 16)2551 | (scsicmd->cmnd[8] << 8) | scsicmd->cmnd[9];2552 fua = scsicmd->cmnd[1] & 0x8;2553 } else {2554 dprintk((KERN_DEBUG "aachba: received a write(10) command on id %d.\n", scmd_id(scsicmd)));2555 lba = ((u64)scsicmd->cmnd[2] << 24) | (scsicmd->cmnd[3] << 16) | (scsicmd->cmnd[4] << 8) | scsicmd->cmnd[5];2556 count = (scsicmd->cmnd[7] << 8) | scsicmd->cmnd[8];2557 fua = scsicmd->cmnd[1] & 0x8;2558 }2559 2560 if ((lba + count) > (dev->fsa_dev[scmd_id(scsicmd)].size)) {2561 cid = scmd_id(scsicmd);2562 dprintk((KERN_DEBUG "aacraid: Illegal lba\n"));2563 scsicmd->result = DID_OK << 16 | SAM_STAT_CHECK_CONDITION;2564 set_sense(&dev->fsa_dev[cid].sense_data,2565 ILLEGAL_REQUEST, SENCODE_LBA_OUT_OF_RANGE,2566 ASENCODE_INTERNAL_TARGET_FAILURE, 0, 0);2567 memcpy(scsicmd->sense_buffer, &dev->fsa_dev[cid].sense_data,2568 min_t(size_t, sizeof(dev->fsa_dev[cid].sense_data),2569 SCSI_SENSE_BUFFERSIZE));2570 aac_scsi_done(scsicmd);2571 return 0;2572 }2573 2574 dprintk((KERN_DEBUG "aac_write[cpu %d]: lba = %llu, t = %ld.\n",2575 smp_processor_id(), (unsigned long long)lba, jiffies));2576 if (aac_adapter_bounds(dev,scsicmd,lba))2577 return 0;2578 /*2579 * Allocate and initialize a Fib then setup a BlockWrite command2580 */2581 cmd_fibcontext = aac_fib_alloc_tag(dev, scsicmd);2582 aac_priv(scsicmd)->owner = AAC_OWNER_FIRMWARE;2583 status = aac_adapter_write(cmd_fibcontext, scsicmd, lba, count, fua);2584 2585 /*2586 * Check that the command queued to the controller2587 */2588 if (status == -EINPROGRESS)2589 return 0;2590 2591 printk(KERN_WARNING "aac_write: aac_fib_send failed with status: %d\n", status);2592 /*2593 * For some reason, the Fib didn't queue, return QUEUE_FULL2594 */2595 scsicmd->result = DID_OK << 16 | SAM_STAT_TASK_SET_FULL;2596 aac_scsi_done(scsicmd);2597 2598 aac_fib_complete(cmd_fibcontext);2599 aac_fib_free(cmd_fibcontext);2600 return 0;2601}2602 2603static void synchronize_callback(void *context, struct fib *fibptr)2604{2605 struct aac_synchronize_reply *synchronizereply;2606 struct scsi_cmnd *cmd = context;2607 2608 if (!aac_valid_context(cmd, fibptr))2609 return;2610 2611 dprintk((KERN_DEBUG "synchronize_callback[cpu %d]: t = %ld.\n",2612 smp_processor_id(), jiffies));2613 BUG_ON(fibptr == NULL);2614 2615 2616 synchronizereply = fib_data(fibptr);2617 if (le32_to_cpu(synchronizereply->status) == CT_OK)2618 cmd->result = DID_OK << 16 | SAM_STAT_GOOD;2619 else {2620 struct scsi_device *sdev = cmd->device;2621 struct aac_dev *dev = fibptr->dev;2622 u32 cid = sdev_id(sdev);2623 printk(KERN_WARNING2624 "synchronize_callback: synchronize failed, status = %d\n",2625 le32_to_cpu(synchronizereply->status));2626 cmd->result = DID_OK << 16 | SAM_STAT_CHECK_CONDITION;2627 set_sense(&dev->fsa_dev[cid].sense_data,2628 HARDWARE_ERROR, SENCODE_INTERNAL_TARGET_FAILURE,2629 ASENCODE_INTERNAL_TARGET_FAILURE, 0, 0);2630 memcpy(cmd->sense_buffer, &dev->fsa_dev[cid].sense_data,2631 min_t(size_t, sizeof(dev->fsa_dev[cid].sense_data),2632 SCSI_SENSE_BUFFERSIZE));2633 }2634 2635 aac_fib_complete(fibptr);2636 aac_fib_free(fibptr);2637 aac_scsi_done(cmd);2638}2639 2640static int aac_synchronize(struct scsi_cmnd *scsicmd)2641{2642 int status;2643 struct fib *cmd_fibcontext;2644 struct aac_synchronize *synchronizecmd;2645 struct scsi_device *sdev = scsicmd->device;2646 struct aac_dev *aac;2647 2648 aac = (struct aac_dev *)sdev->host->hostdata;2649 if (aac->in_reset)2650 return SCSI_MLQUEUE_HOST_BUSY;2651 2652 /*2653 * Allocate and initialize a Fib2654 */2655 cmd_fibcontext = aac_fib_alloc_tag(aac, scsicmd);2656 2657 aac_fib_init(cmd_fibcontext);2658 2659 synchronizecmd = fib_data(cmd_fibcontext);2660 synchronizecmd->command = cpu_to_le32(VM_ContainerConfig);2661 synchronizecmd->type = cpu_to_le32(CT_FLUSH_CACHE);2662 synchronizecmd->cid = cpu_to_le32(scmd_id(scsicmd));2663 synchronizecmd->count =2664 cpu_to_le32(sizeof(((struct aac_synchronize_reply *)NULL)->data));2665 aac_priv(scsicmd)->owner = AAC_OWNER_FIRMWARE;2666 2667 /*2668 * Now send the Fib to the adapter2669 */2670 status = aac_fib_send(ContainerCommand,2671 cmd_fibcontext,2672 sizeof(struct aac_synchronize),2673 FsaNormal,2674 0, 1,2675 (fib_callback)synchronize_callback,2676 (void *)scsicmd);2677 2678 /*2679 * Check that the command queued to the controller2680 */2681 if (status == -EINPROGRESS)2682 return 0;2683 2684 printk(KERN_WARNING2685 "aac_synchronize: aac_fib_send failed with status: %d.\n", status);2686 aac_fib_complete(cmd_fibcontext);2687 aac_fib_free(cmd_fibcontext);2688 return SCSI_MLQUEUE_HOST_BUSY;2689}2690 2691static void aac_start_stop_callback(void *context, struct fib *fibptr)2692{2693 struct scsi_cmnd *scsicmd = context;2694 2695 if (!aac_valid_context(scsicmd, fibptr))2696 return;2697 2698 BUG_ON(fibptr == NULL);2699 2700 scsicmd->result = DID_OK << 16 | SAM_STAT_GOOD;2701 2702 aac_fib_complete(fibptr);2703 aac_fib_free(fibptr);2704 aac_scsi_done(scsicmd);2705}2706 2707static int aac_start_stop(struct scsi_cmnd *scsicmd)2708{2709 int status;2710 struct fib *cmd_fibcontext;2711 struct aac_power_management *pmcmd;2712 struct scsi_device *sdev = scsicmd->device;2713 struct aac_dev *aac = (struct aac_dev *)sdev->host->hostdata;2714 2715 if (!(aac->supplement_adapter_info.supported_options2 &2716 AAC_OPTION_POWER_MANAGEMENT)) {2717 scsicmd->result = DID_OK << 16 | SAM_STAT_GOOD;2718 aac_scsi_done(scsicmd);2719 return 0;2720 }2721 2722 if (aac->in_reset)2723 return SCSI_MLQUEUE_HOST_BUSY;2724 2725 /*2726 * Allocate and initialize a Fib2727 */2728 cmd_fibcontext = aac_fib_alloc_tag(aac, scsicmd);2729 2730 aac_fib_init(cmd_fibcontext);2731 2732 pmcmd = fib_data(cmd_fibcontext);2733 pmcmd->command = cpu_to_le32(VM_ContainerConfig);2734 pmcmd->type = cpu_to_le32(CT_POWER_MANAGEMENT);2735 /* Eject bit ignored, not relevant */2736 pmcmd->sub = (scsicmd->cmnd[4] & 1) ?2737 cpu_to_le32(CT_PM_START_UNIT) : cpu_to_le32(CT_PM_STOP_UNIT);2738 pmcmd->cid = cpu_to_le32(sdev_id(sdev));2739 pmcmd->parm = (scsicmd->cmnd[1] & 1) ?2740 cpu_to_le32(CT_PM_UNIT_IMMEDIATE) : 0;2741 aac_priv(scsicmd)->owner = AAC_OWNER_FIRMWARE;2742 2743 /*2744 * Now send the Fib to the adapter2745 */2746 status = aac_fib_send(ContainerCommand,2747 cmd_fibcontext,2748 sizeof(struct aac_power_management),2749 FsaNormal,2750 0, 1,2751 (fib_callback)aac_start_stop_callback,2752 (void *)scsicmd);2753 2754 /*2755 * Check that the command queued to the controller2756 */2757 if (status == -EINPROGRESS)2758 return 0;2759 2760 aac_fib_complete(cmd_fibcontext);2761 aac_fib_free(cmd_fibcontext);2762 return SCSI_MLQUEUE_HOST_BUSY;2763}2764 2765/**2766 * aac_scsi_cmd() - Process SCSI command2767 * @scsicmd: SCSI command block2768 *2769 * Emulate a SCSI command and queue the required request for the2770 * aacraid firmware.2771 */2772 2773int aac_scsi_cmd(struct scsi_cmnd * scsicmd)2774{2775 u32 cid, bus;2776 struct Scsi_Host *host = scsicmd->device->host;2777 struct aac_dev *dev = (struct aac_dev *)host->hostdata;2778 struct fsa_dev_info *fsa_dev_ptr = dev->fsa_dev;2779 2780 if (fsa_dev_ptr == NULL)2781 return -1;2782 /*2783 * If the bus, id or lun is out of range, return fail2784 * Test does not apply to ID 16, the pseudo id for the controller2785 * itself.2786 */2787 cid = scmd_id(scsicmd);2788 if (cid != host->this_id) {2789 if (scmd_channel(scsicmd) == CONTAINER_CHANNEL) {2790 if((cid >= dev->maximum_num_containers) ||2791 (scsicmd->device->lun != 0)) {2792 scsicmd->result = DID_NO_CONNECT << 16;2793 goto scsi_done_ret;2794 }2795 2796 /*2797 * If the target container doesn't exist, it may have2798 * been newly created2799 */2800 if (((fsa_dev_ptr[cid].valid & 1) == 0) ||2801 (fsa_dev_ptr[cid].sense_data.sense_key ==2802 NOT_READY)) {2803 switch (scsicmd->cmnd[0]) {2804 case SERVICE_ACTION_IN_16:2805 if (!(dev->raw_io_interface) ||2806 !(dev->raw_io_64) ||2807 ((scsicmd->cmnd[1] & 0x1f) != SAI_READ_CAPACITY_16))2808 break;2809 fallthrough;2810 case INQUIRY:2811 case READ_CAPACITY:2812 case TEST_UNIT_READY:2813 if (dev->in_reset)2814 return -1;2815 return _aac_probe_container(scsicmd,2816 aac_probe_container_callback2);2817 default:2818 break;2819 }2820 }2821 } else { /* check for physical non-dasd devices */2822 bus = aac_logical_to_phys(scmd_channel(scsicmd));2823 2824 if (bus < AAC_MAX_BUSES && cid < AAC_MAX_TARGETS &&2825 dev->hba_map[bus][cid].devtype2826 == AAC_DEVTYPE_NATIVE_RAW) {2827 if (dev->in_reset)2828 return -1;2829 return aac_send_hba_fib(scsicmd);2830 } else if (dev->nondasd_support || expose_physicals ||2831 dev->jbod) {2832 if (dev->in_reset)2833 return -1;2834 return aac_send_srb_fib(scsicmd);2835 } else {2836 scsicmd->result = DID_NO_CONNECT << 16;2837 goto scsi_done_ret;2838 }2839 }2840 }2841 /*2842 * else Command for the controller itself2843 */2844 else if ((scsicmd->cmnd[0] != INQUIRY) && /* only INQUIRY & TUR cmnd supported for controller */2845 (scsicmd->cmnd[0] != TEST_UNIT_READY))2846 {2847 dprintk((KERN_WARNING "Only INQUIRY & TUR command supported for controller, rcvd = 0x%x.\n", scsicmd->cmnd[0]));2848 scsicmd->result = DID_OK << 16 | SAM_STAT_CHECK_CONDITION;2849 set_sense(&dev->fsa_dev[cid].sense_data,2850 ILLEGAL_REQUEST, SENCODE_INVALID_COMMAND,2851 ASENCODE_INVALID_COMMAND, 0, 0);2852 memcpy(scsicmd->sense_buffer, &dev->fsa_dev[cid].sense_data,2853 min_t(size_t, sizeof(dev->fsa_dev[cid].sense_data),2854 SCSI_SENSE_BUFFERSIZE));2855 goto scsi_done_ret;2856 }2857 2858 switch (scsicmd->cmnd[0]) {2859 case READ_6:2860 case READ_10:2861 case READ_12:2862 case READ_16:2863 if (dev->in_reset)2864 return -1;2865 return aac_read(scsicmd);2866 2867 case WRITE_6:2868 case WRITE_10:2869 case WRITE_12:2870 case WRITE_16:2871 if (dev->in_reset)2872 return -1;2873 return aac_write(scsicmd);2874 2875 case SYNCHRONIZE_CACHE:2876 if (((aac_cache & 6) == 6) && dev->cache_protected) {2877 scsicmd->result = DID_OK << 16 | SAM_STAT_GOOD;2878 break;2879 }2880 /* Issue FIB to tell Firmware to flush it's cache */2881 if ((aac_cache & 6) != 2)2882 return aac_synchronize(scsicmd);2883 fallthrough;2884 case INQUIRY:2885 {2886 struct inquiry_data inq_data;2887 2888 dprintk((KERN_DEBUG "INQUIRY command, ID: %d.\n", cid));2889 memset(&inq_data, 0, sizeof (struct inquiry_data));2890 2891 if ((scsicmd->cmnd[1] & 0x1) && aac_wwn) {2892 char *arr = (char *)&inq_data;2893 2894 /* EVPD bit set */2895 arr[0] = (scmd_id(scsicmd) == host->this_id) ?2896 INQD_PDT_PROC : INQD_PDT_DA;2897 if (scsicmd->cmnd[2] == 0) {2898 /* supported vital product data pages */2899 arr[3] = 3;2900 arr[4] = 0x0;2901 arr[5] = 0x80;2902 arr[6] = 0x83;2903 arr[1] = scsicmd->cmnd[2];2904 scsi_sg_copy_from_buffer(scsicmd, &inq_data,2905 sizeof(inq_data));2906 scsicmd->result = DID_OK << 16 | SAM_STAT_GOOD;2907 } else if (scsicmd->cmnd[2] == 0x80) {2908 /* unit serial number page */2909 arr[3] = setinqserial(dev, &arr[4],2910 scmd_id(scsicmd));2911 arr[1] = scsicmd->cmnd[2];2912 scsi_sg_copy_from_buffer(scsicmd, &inq_data,2913 sizeof(inq_data));2914 if (aac_wwn != 2)2915 return aac_get_container_serial(2916 scsicmd);2917 scsicmd->result = DID_OK << 16 | SAM_STAT_GOOD;2918 } else if (scsicmd->cmnd[2] == 0x83) {2919 /* vpd page 0x83 - Device Identification Page */2920 char *sno = (char *)&inq_data;2921 sno[3] = setinqserial(dev, &sno[4],2922 scmd_id(scsicmd));2923 if (aac_wwn != 2)2924 return aac_get_container_serial(2925 scsicmd);2926 scsicmd->result = DID_OK << 16 | SAM_STAT_GOOD;2927 } else {2928 /* vpd page not implemented */2929 scsicmd->result = DID_OK << 16 | SAM_STAT_CHECK_CONDITION;2930 set_sense(&dev->fsa_dev[cid].sense_data,2931 ILLEGAL_REQUEST, SENCODE_INVALID_CDB_FIELD,2932 ASENCODE_NO_SENSE, 7, 2);2933 memcpy(scsicmd->sense_buffer,2934 &dev->fsa_dev[cid].sense_data,2935 min_t(size_t,2936 sizeof(dev->fsa_dev[cid].sense_data),2937 SCSI_SENSE_BUFFERSIZE));2938 }2939 break;2940 }2941 inq_data.inqd_ver = 2; /* claim compliance to SCSI-2 */2942 inq_data.inqd_rdf = 2; /* A response data format value of two indicates that the data shall be in the format specified in SCSI-2 */2943 inq_data.inqd_len = 31;2944 /*Format for "pad2" is RelAdr | WBus32 | WBus16 | Sync | Linked |Reserved| CmdQue | SftRe */2945 inq_data.inqd_pad2= 0x32 ; /*WBus16|Sync|CmdQue */2946 /*2947 * Set the Vendor, Product, and Revision Level2948 * see: <vendor>.c i.e. aac.c2949 */2950 if (cid == host->this_id) {2951 setinqstr(dev, (void *) (inq_data.inqd_vid), ARRAY_SIZE(container_types));2952 inq_data.inqd_pdt = INQD_PDT_PROC; /* Processor device */2953 scsi_sg_copy_from_buffer(scsicmd, &inq_data,2954 sizeof(inq_data));2955 scsicmd->result = DID_OK << 16 | SAM_STAT_GOOD;2956 break;2957 }2958 if (dev->in_reset)2959 return -1;2960 setinqstr(dev, (void *) (inq_data.inqd_vid), fsa_dev_ptr[cid].type);2961 inq_data.inqd_pdt = INQD_PDT_DA; /* Direct/random access device */2962 scsi_sg_copy_from_buffer(scsicmd, &inq_data, sizeof(inq_data));2963 return aac_get_container_name(scsicmd);2964 }2965 case SERVICE_ACTION_IN_16:2966 if (!(dev->raw_io_interface) ||2967 !(dev->raw_io_64) ||2968 ((scsicmd->cmnd[1] & 0x1f) != SAI_READ_CAPACITY_16))2969 break;2970 {2971 u64 capacity;2972 char cp[13];2973 unsigned int alloc_len;2974 2975 dprintk((KERN_DEBUG "READ CAPACITY_16 command.\n"));2976 capacity = fsa_dev_ptr[cid].size - 1;2977 cp[0] = (capacity >> 56) & 0xff;2978 cp[1] = (capacity >> 48) & 0xff;2979 cp[2] = (capacity >> 40) & 0xff;2980 cp[3] = (capacity >> 32) & 0xff;2981 cp[4] = (capacity >> 24) & 0xff;2982 cp[5] = (capacity >> 16) & 0xff;2983 cp[6] = (capacity >> 8) & 0xff;2984 cp[7] = (capacity >> 0) & 0xff;2985 cp[8] = (fsa_dev_ptr[cid].block_size >> 24) & 0xff;2986 cp[9] = (fsa_dev_ptr[cid].block_size >> 16) & 0xff;2987 cp[10] = (fsa_dev_ptr[cid].block_size >> 8) & 0xff;2988 cp[11] = (fsa_dev_ptr[cid].block_size) & 0xff;2989 cp[12] = 0;2990 2991 alloc_len = ((scsicmd->cmnd[10] << 24)2992 + (scsicmd->cmnd[11] << 16)2993 + (scsicmd->cmnd[12] << 8) + scsicmd->cmnd[13]);2994 2995 alloc_len = min_t(size_t, alloc_len, sizeof(cp));2996 scsi_sg_copy_from_buffer(scsicmd, cp, alloc_len);2997 if (alloc_len < scsi_bufflen(scsicmd))2998 scsi_set_resid(scsicmd,2999 scsi_bufflen(scsicmd) - alloc_len);3000 3001 /* Do not cache partition table for arrays */3002 scsicmd->device->removable = 1;3003 3004 scsicmd->result = DID_OK << 16 | SAM_STAT_GOOD;3005 break;3006 }3007 3008 case READ_CAPACITY:3009 {3010 u32 capacity;3011 char cp[8];3012 3013 dprintk((KERN_DEBUG "READ CAPACITY command.\n"));3014 if (fsa_dev_ptr[cid].size <= 0x100000000ULL)3015 capacity = fsa_dev_ptr[cid].size - 1;3016 else3017 capacity = (u32)-1;3018 3019 cp[0] = (capacity >> 24) & 0xff;3020 cp[1] = (capacity >> 16) & 0xff;3021 cp[2] = (capacity >> 8) & 0xff;3022 cp[3] = (capacity >> 0) & 0xff;3023 cp[4] = (fsa_dev_ptr[cid].block_size >> 24) & 0xff;3024 cp[5] = (fsa_dev_ptr[cid].block_size >> 16) & 0xff;3025 cp[6] = (fsa_dev_ptr[cid].block_size >> 8) & 0xff;3026 cp[7] = (fsa_dev_ptr[cid].block_size) & 0xff;3027 scsi_sg_copy_from_buffer(scsicmd, cp, sizeof(cp));3028 /* Do not cache partition table for arrays */3029 scsicmd->device->removable = 1;3030 scsicmd->result = DID_OK << 16 | SAM_STAT_GOOD;3031 break;3032 }3033 3034 case MODE_SENSE:3035 {3036 int mode_buf_length = 4;3037 u32 capacity;3038 aac_modep_data mpd;3039 3040 if (fsa_dev_ptr[cid].size <= 0x100000000ULL)3041 capacity = fsa_dev_ptr[cid].size - 1;3042 else3043 capacity = (u32)-1;3044 3045 dprintk((KERN_DEBUG "MODE SENSE command.\n"));3046 memset((char *)&mpd, 0, sizeof(aac_modep_data));3047 3048 /* Mode data length */3049 mpd.hd.data_length = sizeof(mpd.hd) - 1;3050 /* Medium type - default */3051 mpd.hd.med_type = 0;3052 /* Device-specific param,3053 bit 8: 0/1 = write enabled/protected3054 bit 4: 0/1 = FUA enabled */3055 mpd.hd.dev_par = 0;3056 3057 if (dev->raw_io_interface && ((aac_cache & 5) != 1))3058 mpd.hd.dev_par = 0x10;3059 if (scsicmd->cmnd[1] & 0x8)3060 mpd.hd.bd_length = 0; /* Block descriptor length */3061 else {3062 mpd.hd.bd_length = sizeof(mpd.bd);3063 mpd.hd.data_length += mpd.hd.bd_length;3064 mpd.bd.block_length[0] =3065 (fsa_dev_ptr[cid].block_size >> 16) & 0xff;3066 mpd.bd.block_length[1] =3067 (fsa_dev_ptr[cid].block_size >> 8) & 0xff;3068 mpd.bd.block_length[2] =3069 fsa_dev_ptr[cid].block_size & 0xff;3070 3071 mpd.mpc_buf[0] = scsicmd->cmnd[2];3072 if (scsicmd->cmnd[2] == 0x1C) {3073 /* page length */3074 mpd.mpc_buf[1] = 0xa;3075 /* Mode data length */3076 mpd.hd.data_length = 23;3077 } else {3078 /* Mode data length */3079 mpd.hd.data_length = 15;3080 }3081 3082 if (capacity > 0xffffff) {3083 mpd.bd.block_count[0] = 0xff;3084 mpd.bd.block_count[1] = 0xff;3085 mpd.bd.block_count[2] = 0xff;3086 } else {3087 mpd.bd.block_count[0] = (capacity >> 16) & 0xff;3088 mpd.bd.block_count[1] = (capacity >> 8) & 0xff;3089 mpd.bd.block_count[2] = capacity & 0xff;3090 }3091 }3092 if (((scsicmd->cmnd[2] & 0x3f) == 8) ||3093 ((scsicmd->cmnd[2] & 0x3f) == 0x3f)) {3094 mpd.hd.data_length += 3;3095 mpd.mpc_buf[0] = 8;3096 mpd.mpc_buf[1] = 1;3097 mpd.mpc_buf[2] = ((aac_cache & 6) == 2)3098 ? 0 : 0x04; /* WCE */3099 mode_buf_length = sizeof(mpd);3100 }3101 3102 if (mode_buf_length > scsicmd->cmnd[4])3103 mode_buf_length = scsicmd->cmnd[4];3104 else3105 mode_buf_length = sizeof(mpd);3106 scsi_sg_copy_from_buffer(scsicmd,3107 (char *)&mpd,3108 mode_buf_length);3109 scsicmd->result = DID_OK << 16 | SAM_STAT_GOOD;3110 break;3111 }3112 case MODE_SENSE_10:3113 {3114 u32 capacity;3115 int mode_buf_length = 8;3116 aac_modep10_data mpd10;3117 3118 if (fsa_dev_ptr[cid].size <= 0x100000000ULL)3119 capacity = fsa_dev_ptr[cid].size - 1;3120 else3121 capacity = (u32)-1;3122 3123 dprintk((KERN_DEBUG "MODE SENSE 10 byte command.\n"));3124 memset((char *)&mpd10, 0, sizeof(aac_modep10_data));3125 /* Mode data length (MSB) */3126 mpd10.hd.data_length[0] = 0;3127 /* Mode data length (LSB) */3128 mpd10.hd.data_length[1] = sizeof(mpd10.hd) - 1;3129 /* Medium type - default */3130 mpd10.hd.med_type = 0;3131 /* Device-specific param,3132 bit 8: 0/1 = write enabled/protected3133 bit 4: 0/1 = FUA enabled */3134 mpd10.hd.dev_par = 0;3135 3136 if (dev->raw_io_interface && ((aac_cache & 5) != 1))3137 mpd10.hd.dev_par = 0x10;3138 mpd10.hd.rsrvd[0] = 0; /* reserved */3139 mpd10.hd.rsrvd[1] = 0; /* reserved */3140 if (scsicmd->cmnd[1] & 0x8) {3141 /* Block descriptor length (MSB) */3142 mpd10.hd.bd_length[0] = 0;3143 /* Block descriptor length (LSB) */3144 mpd10.hd.bd_length[1] = 0;3145 } else {3146 mpd10.hd.bd_length[0] = 0;3147 mpd10.hd.bd_length[1] = sizeof(mpd10.bd);3148 3149 mpd10.hd.data_length[1] += mpd10.hd.bd_length[1];3150 3151 mpd10.bd.block_length[0] =3152 (fsa_dev_ptr[cid].block_size >> 16) & 0xff;3153 mpd10.bd.block_length[1] =3154 (fsa_dev_ptr[cid].block_size >> 8) & 0xff;3155 mpd10.bd.block_length[2] =3156 fsa_dev_ptr[cid].block_size & 0xff;3157 3158 if (capacity > 0xffffff) {3159 mpd10.bd.block_count[0] = 0xff;3160 mpd10.bd.block_count[1] = 0xff;3161 mpd10.bd.block_count[2] = 0xff;3162 } else {3163 mpd10.bd.block_count[0] =3164 (capacity >> 16) & 0xff;3165 mpd10.bd.block_count[1] =3166 (capacity >> 8) & 0xff;3167 mpd10.bd.block_count[2] =3168 capacity & 0xff;3169 }3170 }3171 if (((scsicmd->cmnd[2] & 0x3f) == 8) ||3172 ((scsicmd->cmnd[2] & 0x3f) == 0x3f)) {3173 mpd10.hd.data_length[1] += 3;3174 mpd10.mpc_buf[0] = 8;3175 mpd10.mpc_buf[1] = 1;3176 mpd10.mpc_buf[2] = ((aac_cache & 6) == 2)3177 ? 0 : 0x04; /* WCE */3178 mode_buf_length = sizeof(mpd10);3179 if (mode_buf_length > scsicmd->cmnd[8])3180 mode_buf_length = scsicmd->cmnd[8];3181 }3182 scsi_sg_copy_from_buffer(scsicmd,3183 (char *)&mpd10,3184 mode_buf_length);3185 3186 scsicmd->result = DID_OK << 16 | SAM_STAT_GOOD;3187 break;3188 }3189 case REQUEST_SENSE:3190 dprintk((KERN_DEBUG "REQUEST SENSE command.\n"));3191 memcpy(scsicmd->sense_buffer, &dev->fsa_dev[cid].sense_data,3192 sizeof(struct sense_data));3193 memset(&dev->fsa_dev[cid].sense_data, 0,3194 sizeof(struct sense_data));3195 scsicmd->result = DID_OK << 16 | SAM_STAT_GOOD;3196 break;3197 3198 case ALLOW_MEDIUM_REMOVAL:3199 dprintk((KERN_DEBUG "LOCK command.\n"));3200 if (scsicmd->cmnd[4])3201 fsa_dev_ptr[cid].locked = 1;3202 else3203 fsa_dev_ptr[cid].locked = 0;3204 3205 scsicmd->result = DID_OK << 16 | SAM_STAT_GOOD;3206 break;3207 /*3208 * These commands are all No-Ops3209 */3210 case TEST_UNIT_READY:3211 if (fsa_dev_ptr[cid].sense_data.sense_key == NOT_READY) {3212 scsicmd->result = DID_OK << 16 | SAM_STAT_CHECK_CONDITION;3213 set_sense(&dev->fsa_dev[cid].sense_data,3214 NOT_READY, SENCODE_BECOMING_READY,3215 ASENCODE_BECOMING_READY, 0, 0);3216 memcpy(scsicmd->sense_buffer,3217 &dev->fsa_dev[cid].sense_data,3218 min_t(size_t,3219 sizeof(dev->fsa_dev[cid].sense_data),3220 SCSI_SENSE_BUFFERSIZE));3221 break;3222 }3223 fallthrough;3224 case RESERVE:3225 case RELEASE:3226 case REZERO_UNIT:3227 case REASSIGN_BLOCKS:3228 case SEEK_10:3229 scsicmd->result = DID_OK << 16 | SAM_STAT_GOOD;3230 break;3231 3232 case START_STOP:3233 return aac_start_stop(scsicmd);3234 3235 default:3236 /*3237 * Unhandled commands3238 */3239 dprintk((KERN_WARNING "Unhandled SCSI Command: 0x%x.\n",3240 scsicmd->cmnd[0]));3241 scsicmd->result = DID_OK << 16 | SAM_STAT_CHECK_CONDITION;3242 set_sense(&dev->fsa_dev[cid].sense_data,3243 ILLEGAL_REQUEST, SENCODE_INVALID_COMMAND,3244 ASENCODE_INVALID_COMMAND, 0, 0);3245 memcpy(scsicmd->sense_buffer, &dev->fsa_dev[cid].sense_data,3246 min_t(size_t,3247 sizeof(dev->fsa_dev[cid].sense_data),3248 SCSI_SENSE_BUFFERSIZE));3249 }3250 3251scsi_done_ret:3252 3253 aac_scsi_done(scsicmd);3254 return 0;3255}3256 3257static int query_disk(struct aac_dev *dev, void __user *arg)3258{3259 struct aac_query_disk qd;3260 struct fsa_dev_info *fsa_dev_ptr;3261 3262 fsa_dev_ptr = dev->fsa_dev;3263 if (!fsa_dev_ptr)3264 return -EBUSY;3265 if (copy_from_user(&qd, arg, sizeof (struct aac_query_disk)))3266 return -EFAULT;3267 if (qd.cnum == -1) {3268 if (qd.id < 0 || qd.id >= dev->maximum_num_containers)3269 return -EINVAL;3270 qd.cnum = qd.id;3271 } else if ((qd.bus == -1) && (qd.id == -1) && (qd.lun == -1)) {3272 if (qd.cnum < 0 || qd.cnum >= dev->maximum_num_containers)3273 return -EINVAL;3274 qd.instance = dev->scsi_host_ptr->host_no;3275 qd.bus = 0;3276 qd.id = CONTAINER_TO_ID(qd.cnum);3277 qd.lun = CONTAINER_TO_LUN(qd.cnum);3278 }3279 else return -EINVAL;3280 3281 qd.valid = fsa_dev_ptr[qd.cnum].valid != 0;3282 qd.locked = fsa_dev_ptr[qd.cnum].locked;3283 qd.deleted = fsa_dev_ptr[qd.cnum].deleted;3284 3285 if (fsa_dev_ptr[qd.cnum].devname[0] == '\0')3286 qd.unmapped = 1;3287 else3288 qd.unmapped = 0;3289 3290 strscpy(qd.name, fsa_dev_ptr[qd.cnum].devname,3291 min(sizeof(qd.name), sizeof(fsa_dev_ptr[qd.cnum].devname) + 1));3292 3293 if (copy_to_user(arg, &qd, sizeof (struct aac_query_disk)))3294 return -EFAULT;3295 return 0;3296}3297 3298static int force_delete_disk(struct aac_dev *dev, void __user *arg)3299{3300 struct aac_delete_disk dd;3301 struct fsa_dev_info *fsa_dev_ptr;3302 3303 fsa_dev_ptr = dev->fsa_dev;3304 if (!fsa_dev_ptr)3305 return -EBUSY;3306 3307 if (copy_from_user(&dd, arg, sizeof (struct aac_delete_disk)))3308 return -EFAULT;3309 3310 if (dd.cnum >= dev->maximum_num_containers)3311 return -EINVAL;3312 /*3313 * Mark this container as being deleted.3314 */3315 fsa_dev_ptr[dd.cnum].deleted = 1;3316 /*3317 * Mark the container as no longer valid3318 */3319 fsa_dev_ptr[dd.cnum].valid = 0;3320 return 0;3321}3322 3323static int delete_disk(struct aac_dev *dev, void __user *arg)3324{3325 struct aac_delete_disk dd;3326 struct fsa_dev_info *fsa_dev_ptr;3327 3328 fsa_dev_ptr = dev->fsa_dev;3329 if (!fsa_dev_ptr)3330 return -EBUSY;3331 3332 if (copy_from_user(&dd, arg, sizeof (struct aac_delete_disk)))3333 return -EFAULT;3334 3335 if (dd.cnum >= dev->maximum_num_containers)3336 return -EINVAL;3337 /*3338 * If the container is locked, it can not be deleted by the API.3339 */3340 if (fsa_dev_ptr[dd.cnum].locked)3341 return -EBUSY;3342 else {3343 /*3344 * Mark the container as no longer being valid.3345 */3346 fsa_dev_ptr[dd.cnum].valid = 0;3347 fsa_dev_ptr[dd.cnum].devname[0] = '\0';3348 return 0;3349 }3350}3351 3352int aac_dev_ioctl(struct aac_dev *dev, unsigned int cmd, void __user *arg)3353{3354 switch (cmd) {3355 case FSACTL_QUERY_DISK:3356 return query_disk(dev, arg);3357 case FSACTL_DELETE_DISK:3358 return delete_disk(dev, arg);3359 case FSACTL_FORCE_DELETE_DISK:3360 return force_delete_disk(dev, arg);3361 case FSACTL_GET_CONTAINERS:3362 return aac_get_containers(dev);3363 default:3364 return -ENOTTY;3365 }3366}3367 3368/**3369 * aac_srb_callback3370 * @context: the context set in the fib - here it is scsi cmd3371 * @fibptr: pointer to the fib3372 *3373 * Handles the completion of a scsi command to a non dasd device3374 */3375static void aac_srb_callback(void *context, struct fib * fibptr)3376{3377 struct aac_srb_reply *srbreply;3378 struct scsi_cmnd *scsicmd;3379 3380 scsicmd = (struct scsi_cmnd *) context;3381 3382 if (!aac_valid_context(scsicmd, fibptr))3383 return;3384 3385 BUG_ON(fibptr == NULL);3386 3387 srbreply = (struct aac_srb_reply *) fib_data(fibptr);3388 3389 scsicmd->sense_buffer[0] = '\0'; /* Initialize sense valid flag to false */3390 3391 if (fibptr->flags & FIB_CONTEXT_FLAG_FASTRESP) {3392 /* fast response */3393 srbreply->srb_status = cpu_to_le32(SRB_STATUS_SUCCESS);3394 srbreply->scsi_status = cpu_to_le32(SAM_STAT_GOOD);3395 } else {3396 /*3397 * Calculate resid for sg3398 */3399 scsi_set_resid(scsicmd, scsi_bufflen(scsicmd)3400 - le32_to_cpu(srbreply->data_xfer_length));3401 }3402 3403 3404 scsi_dma_unmap(scsicmd);3405 3406 /* expose physical device if expose_physicald flag is on */3407 if (scsicmd->cmnd[0] == INQUIRY && !(scsicmd->cmnd[1] & 0x01)3408 && expose_physicals > 0)3409 aac_expose_phy_device(scsicmd);3410 3411 /*3412 * First check the fib status3413 */3414 3415 if (le32_to_cpu(srbreply->status) != ST_OK) {3416 int len;3417 3418 pr_warn("aac_srb_callback: srb failed, status = %d\n",3419 le32_to_cpu(srbreply->status));3420 len = min_t(u32, le32_to_cpu(srbreply->sense_data_size),3421 SCSI_SENSE_BUFFERSIZE);3422 scsicmd->result = DID_ERROR << 16 | SAM_STAT_CHECK_CONDITION;3423 memcpy(scsicmd->sense_buffer,3424 srbreply->sense_data, len);3425 }3426 3427 /*3428 * Next check the srb status3429 */3430 switch ((le32_to_cpu(srbreply->srb_status))&0x3f) {3431 case SRB_STATUS_ERROR_RECOVERY:3432 case SRB_STATUS_PENDING:3433 case SRB_STATUS_SUCCESS:3434 scsicmd->result = DID_OK << 16;3435 break;3436 case SRB_STATUS_DATA_OVERRUN:3437 switch (scsicmd->cmnd[0]) {3438 case READ_6:3439 case WRITE_6:3440 case READ_10:3441 case WRITE_10:3442 case READ_12:3443 case WRITE_12:3444 case READ_16:3445 case WRITE_16:3446 if (le32_to_cpu(srbreply->data_xfer_length)3447 < scsicmd->underflow)3448 pr_warn("aacraid: SCSI CMD underflow\n");3449 else3450 pr_warn("aacraid: SCSI CMD Data Overrun\n");3451 scsicmd->result = DID_ERROR << 16;3452 break;3453 case INQUIRY:3454 scsicmd->result = DID_OK << 16;3455 break;3456 default:3457 scsicmd->result = DID_OK << 16;3458 break;3459 }3460 break;3461 case SRB_STATUS_ABORTED:3462 scsicmd->result = DID_ABORT << 16;3463 break;3464 case SRB_STATUS_ABORT_FAILED:3465 /*3466 * Not sure about this one - but assuming the3467 * hba was trying to abort for some reason3468 */3469 scsicmd->result = DID_ERROR << 16;3470 break;3471 case SRB_STATUS_PARITY_ERROR:3472 scsicmd->result = DID_PARITY << 16;3473 break;3474 case SRB_STATUS_NO_DEVICE:3475 case SRB_STATUS_INVALID_PATH_ID:3476 case SRB_STATUS_INVALID_TARGET_ID:3477 case SRB_STATUS_INVALID_LUN:3478 case SRB_STATUS_SELECTION_TIMEOUT:3479 scsicmd->result = DID_NO_CONNECT << 16;3480 break;3481 3482 case SRB_STATUS_COMMAND_TIMEOUT:3483 case SRB_STATUS_TIMEOUT:3484 scsicmd->result = DID_TIME_OUT << 16;3485 break;3486 3487 case SRB_STATUS_BUSY:3488 scsicmd->result = DID_BUS_BUSY << 16;3489 break;3490 3491 case SRB_STATUS_BUS_RESET:3492 scsicmd->result = DID_RESET << 16;3493 break;3494 3495 case SRB_STATUS_MESSAGE_REJECTED:3496 scsicmd->result = DID_ERROR << 16;3497 break;3498 case SRB_STATUS_REQUEST_FLUSHED:3499 case SRB_STATUS_ERROR:3500 case SRB_STATUS_INVALID_REQUEST:3501 case SRB_STATUS_REQUEST_SENSE_FAILED:3502 case SRB_STATUS_NO_HBA:3503 case SRB_STATUS_UNEXPECTED_BUS_FREE:3504 case SRB_STATUS_PHASE_SEQUENCE_FAILURE:3505 case SRB_STATUS_BAD_SRB_BLOCK_LENGTH:3506 case SRB_STATUS_DELAYED_RETRY:3507 case SRB_STATUS_BAD_FUNCTION:3508 case SRB_STATUS_NOT_STARTED:3509 case SRB_STATUS_NOT_IN_USE:3510 case SRB_STATUS_FORCE_ABORT:3511 case SRB_STATUS_DOMAIN_VALIDATION_FAIL:3512 default:3513#ifdef AAC_DETAILED_STATUS_INFO3514 pr_info("aacraid: SRB ERROR(%u) %s scsi cmd 0x%x -scsi status 0x%x\n",3515 le32_to_cpu(srbreply->srb_status) & 0x3F,3516 aac_get_status_string(3517 le32_to_cpu(srbreply->srb_status) & 0x3F),3518 scsicmd->cmnd[0],3519 le32_to_cpu(srbreply->scsi_status));3520#endif3521 /*3522 * When the CC bit is SET by the host in ATA pass thru CDB,3523 * driver is supposed to return DID_OK3524 *3525 * When the CC bit is RESET by the host, driver should3526 * return DID_ERROR3527 */3528 if ((scsicmd->cmnd[0] == ATA_12)3529 || (scsicmd->cmnd[0] == ATA_16)) {3530 3531 if (scsicmd->cmnd[2] & (0x01 << 5)) {3532 scsicmd->result = DID_OK << 16;3533 } else {3534 scsicmd->result = DID_ERROR << 16;3535 }3536 } else {3537 scsicmd->result = DID_ERROR << 16;3538 }3539 break;3540 }3541 if (le32_to_cpu(srbreply->scsi_status)3542 == SAM_STAT_CHECK_CONDITION) {3543 int len;3544 3545 scsicmd->result |= SAM_STAT_CHECK_CONDITION;3546 len = min_t(u32, le32_to_cpu(srbreply->sense_data_size),3547 SCSI_SENSE_BUFFERSIZE);3548#ifdef AAC_DETAILED_STATUS_INFO3549 pr_warn("aac_srb_callback: check condition, status = %d len=%d\n",3550 le32_to_cpu(srbreply->status), len);3551#endif3552 memcpy(scsicmd->sense_buffer,3553 srbreply->sense_data, len);3554 }3555 3556 /*3557 * OR in the scsi status (already shifted up a bit)3558 */3559 scsicmd->result |= le32_to_cpu(srbreply->scsi_status);3560 3561 aac_fib_complete(fibptr);3562 aac_scsi_done(scsicmd);3563}3564 3565static void hba_resp_task_complete(struct aac_dev *dev,3566 struct scsi_cmnd *scsicmd,3567 struct aac_hba_resp *err) {3568 3569 scsicmd->result = err->status;3570 /* set residual count */3571 scsi_set_resid(scsicmd, le32_to_cpu(err->residual_count));3572 3573 switch (err->status) {3574 case SAM_STAT_GOOD:3575 scsicmd->result |= DID_OK << 16;3576 break;3577 case SAM_STAT_CHECK_CONDITION:3578 {3579 int len;3580 3581 len = min_t(u8, err->sense_response_data_len,3582 SCSI_SENSE_BUFFERSIZE);3583 if (len)3584 memcpy(scsicmd->sense_buffer,3585 err->sense_response_buf, len);3586 scsicmd->result |= DID_OK << 16;3587 break;3588 }3589 case SAM_STAT_BUSY:3590 scsicmd->result |= DID_BUS_BUSY << 16;3591 break;3592 case SAM_STAT_TASK_ABORTED:3593 scsicmd->result |= DID_ABORT << 16;3594 break;3595 case SAM_STAT_RESERVATION_CONFLICT:3596 case SAM_STAT_TASK_SET_FULL:3597 default:3598 scsicmd->result |= DID_ERROR << 16;3599 break;3600 }3601}3602 3603static void hba_resp_task_failure(struct aac_dev *dev,3604 struct scsi_cmnd *scsicmd,3605 struct aac_hba_resp *err)3606{3607 switch (err->status) {3608 case HBA_RESP_STAT_HBAMODE_DISABLED:3609 {3610 u32 bus, cid;3611 3612 bus = aac_logical_to_phys(scmd_channel(scsicmd));3613 cid = scmd_id(scsicmd);3614 if (dev->hba_map[bus][cid].devtype == AAC_DEVTYPE_NATIVE_RAW) {3615 dev->hba_map[bus][cid].devtype = AAC_DEVTYPE_ARC_RAW;3616 dev->hba_map[bus][cid].rmw_nexus = 0xffffffff;3617 }3618 scsicmd->result = DID_NO_CONNECT << 16;3619 break;3620 }3621 case HBA_RESP_STAT_IO_ERROR:3622 case HBA_RESP_STAT_NO_PATH_TO_DEVICE:3623 scsicmd->result = DID_OK << 16 | SAM_STAT_BUSY;3624 break;3625 case HBA_RESP_STAT_IO_ABORTED:3626 scsicmd->result = DID_ABORT << 16;3627 break;3628 case HBA_RESP_STAT_INVALID_DEVICE:3629 scsicmd->result = DID_NO_CONNECT << 16;3630 break;3631 case HBA_RESP_STAT_UNDERRUN:3632 /* UNDERRUN is OK */3633 scsicmd->result = DID_OK << 16;3634 break;3635 case HBA_RESP_STAT_OVERRUN:3636 default:3637 scsicmd->result = DID_ERROR << 16;3638 break;3639 }3640}3641 3642/**3643 * aac_hba_callback3644 * @context: the context set in the fib - here it is scsi cmd3645 * @fibptr: pointer to the fib3646 *3647 * Handles the completion of a native HBA scsi command3648 */3649void aac_hba_callback(void *context, struct fib *fibptr)3650{3651 struct aac_dev *dev;3652 struct scsi_cmnd *scsicmd;3653 3654 struct aac_hba_resp *err =3655 &((struct aac_native_hba *)fibptr->hw_fib_va)->resp.err;3656 3657 scsicmd = (struct scsi_cmnd *) context;3658 3659 if (!aac_valid_context(scsicmd, fibptr))3660 return;3661 3662 WARN_ON(fibptr == NULL);3663 dev = fibptr->dev;3664 3665 if (!(fibptr->flags & FIB_CONTEXT_FLAG_NATIVE_HBA_TMF))3666 scsi_dma_unmap(scsicmd);3667 3668 if (fibptr->flags & FIB_CONTEXT_FLAG_FASTRESP) {3669 /* fast response */3670 scsicmd->result = DID_OK << 16;3671 goto out;3672 }3673 3674 switch (err->service_response) {3675 case HBA_RESP_SVCRES_TASK_COMPLETE:3676 hba_resp_task_complete(dev, scsicmd, err);3677 break;3678 case HBA_RESP_SVCRES_FAILURE:3679 hba_resp_task_failure(dev, scsicmd, err);3680 break;3681 case HBA_RESP_SVCRES_TMF_REJECTED:3682 scsicmd->result = DID_ERROR << 16;3683 break;3684 case HBA_RESP_SVCRES_TMF_LUN_INVALID:3685 scsicmd->result = DID_NO_CONNECT << 16;3686 break;3687 case HBA_RESP_SVCRES_TMF_COMPLETE:3688 case HBA_RESP_SVCRES_TMF_SUCCEEDED:3689 scsicmd->result = DID_OK << 16;3690 break;3691 default:3692 scsicmd->result = DID_ERROR << 16;3693 break;3694 }3695 3696out:3697 aac_fib_complete(fibptr);3698 3699 if (fibptr->flags & FIB_CONTEXT_FLAG_NATIVE_HBA_TMF)3700 aac_priv(scsicmd)->sent_command = 1;3701 else3702 aac_scsi_done(scsicmd);3703}3704 3705/**3706 * aac_send_srb_fib3707 * @scsicmd: the scsi command block3708 *3709 * This routine will form a FIB and fill in the aac_srb from the3710 * scsicmd passed in.3711 */3712static int aac_send_srb_fib(struct scsi_cmnd* scsicmd)3713{3714 struct fib* cmd_fibcontext;3715 struct aac_dev* dev;3716 int status;3717 3718 dev = (struct aac_dev *)scsicmd->device->host->hostdata;3719 if (scmd_id(scsicmd) >= dev->maximum_num_physicals ||3720 scsicmd->device->lun > 7) {3721 scsicmd->result = DID_NO_CONNECT << 16;3722 aac_scsi_done(scsicmd);3723 return 0;3724 }3725 3726 /*3727 * Allocate and initialize a Fib then setup a BlockWrite command3728 */3729 cmd_fibcontext = aac_fib_alloc_tag(dev, scsicmd);3730 aac_priv(scsicmd)->owner = AAC_OWNER_FIRMWARE;3731 status = aac_adapter_scsi(cmd_fibcontext, scsicmd);3732 3733 /*3734 * Check that the command queued to the controller3735 */3736 if (status == -EINPROGRESS)3737 return 0;3738 3739 printk(KERN_WARNING "aac_srb: aac_fib_send failed with status: %d\n", status);3740 aac_fib_complete(cmd_fibcontext);3741 aac_fib_free(cmd_fibcontext);3742 3743 return -1;3744}3745 3746/**3747 * aac_send_hba_fib3748 * @scsicmd: the scsi command block3749 *3750 * This routine will form a FIB and fill in the aac_hba_cmd_req from the3751 * scsicmd passed in.3752 */3753static int aac_send_hba_fib(struct scsi_cmnd *scsicmd)3754{3755 struct fib *cmd_fibcontext;3756 struct aac_dev *dev;3757 int status;3758 3759 dev = shost_priv(scsicmd->device->host);3760 if (scmd_id(scsicmd) >= dev->maximum_num_physicals ||3761 scsicmd->device->lun > AAC_MAX_LUN - 1) {3762 scsicmd->result = DID_NO_CONNECT << 16;3763 aac_scsi_done(scsicmd);3764 return 0;3765 }3766 3767 /*3768 * Allocate and initialize a Fib then setup a BlockWrite command3769 */3770 cmd_fibcontext = aac_fib_alloc_tag(dev, scsicmd);3771 if (!cmd_fibcontext)3772 return -1;3773 3774 aac_priv(scsicmd)->owner = AAC_OWNER_FIRMWARE;3775 status = aac_adapter_hba(cmd_fibcontext, scsicmd);3776 3777 /*3778 * Check that the command queued to the controller3779 */3780 if (status == -EINPROGRESS)3781 return 0;3782 3783 pr_warn("aac_hba_cmd_req: aac_fib_send failed with status: %d\n",3784 status);3785 aac_fib_complete(cmd_fibcontext);3786 aac_fib_free(cmd_fibcontext);3787 3788 return -1;3789}3790 3791 3792static long aac_build_sg(struct scsi_cmnd *scsicmd, struct sgmap *psg)3793{3794 unsigned long byte_count = 0;3795 int nseg;3796 struct scatterlist *sg;3797 int i;3798 3799 // Get rid of old data3800 psg->count = 0;3801 psg->sg[0].addr = 0;3802 psg->sg[0].count = 0;3803 3804 nseg = scsi_dma_map(scsicmd);3805 if (nseg <= 0)3806 return nseg;3807 3808 psg->count = cpu_to_le32(nseg);3809 3810 scsi_for_each_sg(scsicmd, sg, nseg, i) {3811 psg->sg[i].addr = cpu_to_le32(sg_dma_address(sg));3812 psg->sg[i].count = cpu_to_le32(sg_dma_len(sg));3813 byte_count += sg_dma_len(sg);3814 }3815 /* hba wants the size to be exact */3816 if (byte_count > scsi_bufflen(scsicmd)) {3817 u32 temp = le32_to_cpu(psg->sg[i-1].count) -3818 (byte_count - scsi_bufflen(scsicmd));3819 psg->sg[i-1].count = cpu_to_le32(temp);3820 byte_count = scsi_bufflen(scsicmd);3821 }3822 /* Check for command underflow */3823 if (scsicmd->underflow && (byte_count < scsicmd->underflow)) {3824 printk(KERN_WARNING"aacraid: cmd len %08lX cmd underflow %08X\n",3825 byte_count, scsicmd->underflow);3826 }3827 3828 return byte_count;3829}3830 3831 3832static long aac_build_sg64(struct scsi_cmnd *scsicmd, struct sgmap64 *psg)3833{3834 unsigned long byte_count = 0;3835 u64 addr;3836 int nseg;3837 struct scatterlist *sg;3838 int i;3839 3840 // Get rid of old data3841 psg->count = 0;3842 psg->sg[0].addr[0] = 0;3843 psg->sg[0].addr[1] = 0;3844 psg->sg[0].count = 0;3845 3846 nseg = scsi_dma_map(scsicmd);3847 if (nseg <= 0)3848 return nseg;3849 3850 scsi_for_each_sg(scsicmd, sg, nseg, i) {3851 int count = sg_dma_len(sg);3852 addr = sg_dma_address(sg);3853 psg->sg[i].addr[0] = cpu_to_le32(addr & 0xffffffff);3854 psg->sg[i].addr[1] = cpu_to_le32(addr>>32);3855 psg->sg[i].count = cpu_to_le32(count);3856 byte_count += count;3857 }3858 psg->count = cpu_to_le32(nseg);3859 /* hba wants the size to be exact */3860 if (byte_count > scsi_bufflen(scsicmd)) {3861 u32 temp = le32_to_cpu(psg->sg[i-1].count) -3862 (byte_count - scsi_bufflen(scsicmd));3863 psg->sg[i-1].count = cpu_to_le32(temp);3864 byte_count = scsi_bufflen(scsicmd);3865 }3866 /* Check for command underflow */3867 if (scsicmd->underflow && (byte_count < scsicmd->underflow)) {3868 printk(KERN_WARNING"aacraid: cmd len %08lX cmd underflow %08X\n",3869 byte_count, scsicmd->underflow);3870 }3871 3872 return byte_count;3873}3874 3875static long aac_build_sgraw(struct scsi_cmnd *scsicmd, struct sgmapraw *psg)3876{3877 unsigned long byte_count = 0;3878 int nseg;3879 struct scatterlist *sg;3880 int i;3881 3882 // Get rid of old data3883 psg->count = 0;3884 psg->sg[0].next = 0;3885 psg->sg[0].prev = 0;3886 psg->sg[0].addr[0] = 0;3887 psg->sg[0].addr[1] = 0;3888 psg->sg[0].count = 0;3889 psg->sg[0].flags = 0;3890 3891 nseg = scsi_dma_map(scsicmd);3892 if (nseg <= 0)3893 return nseg;3894 3895 scsi_for_each_sg(scsicmd, sg, nseg, i) {3896 int count = sg_dma_len(sg);3897 u64 addr = sg_dma_address(sg);3898 psg->sg[i].next = 0;3899 psg->sg[i].prev = 0;3900 psg->sg[i].addr[1] = cpu_to_le32((u32)(addr>>32));3901 psg->sg[i].addr[0] = cpu_to_le32((u32)(addr & 0xffffffff));3902 psg->sg[i].count = cpu_to_le32(count);3903 psg->sg[i].flags = 0;3904 byte_count += count;3905 }3906 psg->count = cpu_to_le32(nseg);3907 /* hba wants the size to be exact */3908 if (byte_count > scsi_bufflen(scsicmd)) {3909 u32 temp = le32_to_cpu(psg->sg[i-1].count) -3910 (byte_count - scsi_bufflen(scsicmd));3911 psg->sg[i-1].count = cpu_to_le32(temp);3912 byte_count = scsi_bufflen(scsicmd);3913 }3914 /* Check for command underflow */3915 if (scsicmd->underflow && (byte_count < scsicmd->underflow)) {3916 printk(KERN_WARNING"aacraid: cmd len %08lX cmd underflow %08X\n",3917 byte_count, scsicmd->underflow);3918 }3919 3920 return byte_count;3921}3922 3923static long aac_build_sgraw2(struct scsi_cmnd *scsicmd,3924 struct aac_raw_io2 *rio2, int sg_max)3925{3926 unsigned long byte_count = 0;3927 int nseg;3928 struct scatterlist *sg;3929 int i, conformable = 0;3930 u32 min_size = PAGE_SIZE, cur_size;3931 3932 nseg = scsi_dma_map(scsicmd);3933 if (nseg <= 0)3934 return nseg;3935 3936 scsi_for_each_sg(scsicmd, sg, nseg, i) {3937 int count = sg_dma_len(sg);3938 u64 addr = sg_dma_address(sg);3939 3940 BUG_ON(i >= sg_max);3941 rio2->sge[i].addrHigh = cpu_to_le32((u32)(addr>>32));3942 rio2->sge[i].addrLow = cpu_to_le32((u32)(addr & 0xffffffff));3943 cur_size = cpu_to_le32(count);3944 rio2->sge[i].length = cur_size;3945 rio2->sge[i].flags = 0;3946 if (i == 0) {3947 conformable = 1;3948 rio2->sgeFirstSize = cur_size;3949 } else if (i == 1) {3950 rio2->sgeNominalSize = cur_size;3951 min_size = cur_size;3952 } else if ((i+1) < nseg && cur_size != rio2->sgeNominalSize) {3953 conformable = 0;3954 if (cur_size < min_size)3955 min_size = cur_size;3956 }3957 byte_count += count;3958 }3959 3960 /* hba wants the size to be exact */3961 if (byte_count > scsi_bufflen(scsicmd)) {3962 u32 temp = le32_to_cpu(rio2->sge[i-1].length) -3963 (byte_count - scsi_bufflen(scsicmd));3964 rio2->sge[i-1].length = cpu_to_le32(temp);3965 byte_count = scsi_bufflen(scsicmd);3966 }3967 3968 rio2->sgeCnt = cpu_to_le32(nseg);3969 rio2->flags |= cpu_to_le16(RIO2_SG_FORMAT_IEEE1212);3970 /* not conformable: evaluate required sg elements */3971 if (!conformable) {3972 int j, nseg_new = nseg, err_found;3973 for (i = min_size / PAGE_SIZE; i >= 1; --i) {3974 err_found = 0;3975 nseg_new = 2;3976 for (j = 1; j < nseg - 1; ++j) {3977 if (rio2->sge[j].length % (i*PAGE_SIZE)) {3978 err_found = 1;3979 break;3980 }3981 nseg_new += (rio2->sge[j].length / (i*PAGE_SIZE));3982 }3983 if (!err_found)3984 break;3985 }3986 if (i > 0 && nseg_new <= sg_max) {3987 int ret = aac_convert_sgraw2(rio2, i, nseg, nseg_new);3988 3989 if (ret < 0)3990 return ret;3991 }3992 } else3993 rio2->flags |= cpu_to_le16(RIO2_SGL_CONFORMANT);3994 3995 /* Check for command underflow */3996 if (scsicmd->underflow && (byte_count < scsicmd->underflow)) {3997 printk(KERN_WARNING"aacraid: cmd len %08lX cmd underflow %08X\n",3998 byte_count, scsicmd->underflow);3999 }4000 4001 return byte_count;4002}4003 4004static int aac_convert_sgraw2(struct aac_raw_io2 *rio2, int pages, int nseg, int nseg_new)4005{4006 struct sge_ieee1212 *sge;4007 int i, j, pos;4008 u32 addr_low;4009 4010 if (aac_convert_sgl == 0)4011 return 0;4012 4013 sge = kmalloc_array(nseg_new, sizeof(*sge), GFP_ATOMIC);4014 if (sge == NULL)4015 return -ENOMEM;4016 4017 for (i = 1, pos = 1; i < nseg-1; ++i) {4018 for (j = 0; j < rio2->sge[i].length / (pages * PAGE_SIZE); ++j) {4019 addr_low = rio2->sge[i].addrLow + j * pages * PAGE_SIZE;4020 sge[pos].addrLow = addr_low;4021 sge[pos].addrHigh = rio2->sge[i].addrHigh;4022 if (addr_low < rio2->sge[i].addrLow)4023 sge[pos].addrHigh++;4024 sge[pos].length = pages * PAGE_SIZE;4025 sge[pos].flags = 0;4026 pos++;4027 }4028 }4029 sge[pos] = rio2->sge[nseg-1];4030 memcpy(&rio2->sge[1], &sge[1], (nseg_new-1)*sizeof(struct sge_ieee1212));4031 4032 kfree(sge);4033 rio2->sgeCnt = cpu_to_le32(nseg_new);4034 rio2->flags |= cpu_to_le16(RIO2_SGL_CONFORMANT);4035 rio2->sgeNominalSize = pages * PAGE_SIZE;4036 return 0;4037}4038 4039static long aac_build_sghba(struct scsi_cmnd *scsicmd,4040 struct aac_hba_cmd_req *hbacmd,4041 int sg_max,4042 u64 sg_address)4043{4044 unsigned long byte_count = 0;4045 int nseg;4046 struct scatterlist *sg;4047 int i;4048 u32 cur_size;4049 struct aac_hba_sgl *sge;4050 4051 nseg = scsi_dma_map(scsicmd);4052 if (nseg <= 0) {4053 byte_count = nseg;4054 goto out;4055 }4056 4057 if (nseg > HBA_MAX_SG_EMBEDDED)4058 sge = &hbacmd->sge[2];4059 else4060 sge = &hbacmd->sge[0];4061 4062 scsi_for_each_sg(scsicmd, sg, nseg, i) {4063 int count = sg_dma_len(sg);4064 u64 addr = sg_dma_address(sg);4065 4066 WARN_ON(i >= sg_max);4067 sge->addr_hi = cpu_to_le32((u32)(addr>>32));4068 sge->addr_lo = cpu_to_le32((u32)(addr & 0xffffffff));4069 cur_size = cpu_to_le32(count);4070 sge->len = cur_size;4071 sge->flags = 0;4072 byte_count += count;4073 sge++;4074 }4075 4076 sge--;4077 /* hba wants the size to be exact */4078 if (byte_count > scsi_bufflen(scsicmd)) {4079 u32 temp;4080 4081 temp = le32_to_cpu(sge->len) - byte_count4082 - scsi_bufflen(scsicmd);4083 sge->len = cpu_to_le32(temp);4084 byte_count = scsi_bufflen(scsicmd);4085 }4086 4087 if (nseg <= HBA_MAX_SG_EMBEDDED) {4088 hbacmd->emb_data_desc_count = cpu_to_le32(nseg);4089 sge->flags = cpu_to_le32(0x40000000);4090 } else {4091 /* not embedded */4092 hbacmd->sge[0].flags = cpu_to_le32(0x80000000);4093 hbacmd->emb_data_desc_count = (u8)cpu_to_le32(1);4094 hbacmd->sge[0].addr_hi = (u32)cpu_to_le32(sg_address >> 32);4095 hbacmd->sge[0].addr_lo =4096 cpu_to_le32((u32)(sg_address & 0xffffffff));4097 }4098 4099 /* Check for command underflow */4100 if (scsicmd->underflow && (byte_count < scsicmd->underflow)) {4101 pr_warn("aacraid: cmd len %08lX cmd underflow %08X\n",4102 byte_count, scsicmd->underflow);4103 }4104out:4105 return byte_count;4106}4107 4108#ifdef AAC_DETAILED_STATUS_INFO4109 4110struct aac_srb_status_info {4111 u32 status;4112 char *str;4113};4114 4115 4116static struct aac_srb_status_info srb_status_info[] = {4117 { SRB_STATUS_PENDING, "Pending Status"},4118 { SRB_STATUS_SUCCESS, "Success"},4119 { SRB_STATUS_ABORTED, "Aborted Command"},4120 { SRB_STATUS_ABORT_FAILED, "Abort Failed"},4121 { SRB_STATUS_ERROR, "Error Event"},4122 { SRB_STATUS_BUSY, "Device Busy"},4123 { SRB_STATUS_INVALID_REQUEST, "Invalid Request"},4124 { SRB_STATUS_INVALID_PATH_ID, "Invalid Path ID"},4125 { SRB_STATUS_NO_DEVICE, "No Device"},4126 { SRB_STATUS_TIMEOUT, "Timeout"},4127 { SRB_STATUS_SELECTION_TIMEOUT, "Selection Timeout"},4128 { SRB_STATUS_COMMAND_TIMEOUT, "Command Timeout"},4129 { SRB_STATUS_MESSAGE_REJECTED, "Message Rejected"},4130 { SRB_STATUS_BUS_RESET, "Bus Reset"},4131 { SRB_STATUS_PARITY_ERROR, "Parity Error"},4132 { SRB_STATUS_REQUEST_SENSE_FAILED,"Request Sense Failed"},4133 { SRB_STATUS_NO_HBA, "No HBA"},4134 { SRB_STATUS_DATA_OVERRUN, "Data Overrun/Data Underrun"},4135 { SRB_STATUS_UNEXPECTED_BUS_FREE,"Unexpected Bus Free"},4136 { SRB_STATUS_PHASE_SEQUENCE_FAILURE,"Phase Error"},4137 { SRB_STATUS_BAD_SRB_BLOCK_LENGTH,"Bad Srb Block Length"},4138 { SRB_STATUS_REQUEST_FLUSHED, "Request Flushed"},4139 { SRB_STATUS_DELAYED_RETRY, "Delayed Retry"},4140 { SRB_STATUS_INVALID_LUN, "Invalid LUN"},4141 { SRB_STATUS_INVALID_TARGET_ID, "Invalid TARGET ID"},4142 { SRB_STATUS_BAD_FUNCTION, "Bad Function"},4143 { SRB_STATUS_ERROR_RECOVERY, "Error Recovery"},4144 { SRB_STATUS_NOT_STARTED, "Not Started"},4145 { SRB_STATUS_NOT_IN_USE, "Not In Use"},4146 { SRB_STATUS_FORCE_ABORT, "Force Abort"},4147 { SRB_STATUS_DOMAIN_VALIDATION_FAIL,"Domain Validation Failure"},4148 { 0xff, "Unknown Error"}4149};4150 4151char *aac_get_status_string(u32 status)4152{4153 int i;4154 4155 for (i = 0; i < ARRAY_SIZE(srb_status_info); i++)4156 if (srb_status_info[i].status == status)4157 return srb_status_info[i].str;4158 4159 return "Bad Status Code";4160}4161 4162#endif4163