^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Adaptec AAC series RAID controller driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * (c) Copyright 2001 Red Hat Inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * based on the old aacraid driver that is..
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Adaptec aacraid device driver for Linux.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * Copyright (c) 2000-2010 Adaptec, Inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * 2010-2015 PMC-Sierra, Inc. (aacraid@pmc-sierra.com)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * 2016-2017 Microsemi Corp. (aacraid@microsemi.com)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) * Module Name:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) * aachba.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) * Abstract: Contains Interfaces to manage IOs.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/pci.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <linux/spinlock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <linux/completion.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include <linux/blkdev.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include <linux/uaccess.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #include <linux/highmem.h> /* For flush_kernel_dcache_page */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #include <asm/unaligned.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #include <scsi/scsi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #include <scsi/scsi_cmnd.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #include <scsi/scsi_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #include <scsi/scsi_host.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #include "aacraid.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) /* values for inqd_pdt: Peripheral device type in plain English */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #define INQD_PDT_DA 0x00 /* Direct-access (DISK) device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #define INQD_PDT_PROC 0x03 /* Processor device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #define INQD_PDT_CHNGR 0x08 /* Changer (jukebox, scsi2) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #define INQD_PDT_COMM 0x09 /* Communication device (scsi2) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #define INQD_PDT_NOLUN2 0x1f /* Unknown Device (scsi2) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #define INQD_PDT_NOLUN 0x7f /* Logical Unit Not Present */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #define INQD_PDT_DMASK 0x1F /* Peripheral Device Type Mask */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) #define INQD_PDT_QMASK 0xE0 /* Peripheral Device Qualifer Mask */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) * Sense codes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) #define SENCODE_NO_SENSE 0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) #define SENCODE_END_OF_DATA 0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) #define SENCODE_BECOMING_READY 0x04
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) #define SENCODE_INIT_CMD_REQUIRED 0x04
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) #define SENCODE_UNRECOVERED_READ_ERROR 0x11
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) #define SENCODE_PARAM_LIST_LENGTH_ERROR 0x1A
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) #define SENCODE_INVALID_COMMAND 0x20
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) #define SENCODE_LBA_OUT_OF_RANGE 0x21
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) #define SENCODE_INVALID_CDB_FIELD 0x24
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) #define SENCODE_LUN_NOT_SUPPORTED 0x25
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) #define SENCODE_INVALID_PARAM_FIELD 0x26
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) #define SENCODE_PARAM_NOT_SUPPORTED 0x26
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) #define SENCODE_PARAM_VALUE_INVALID 0x26
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) #define SENCODE_RESET_OCCURRED 0x29
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) #define SENCODE_LUN_NOT_SELF_CONFIGURED_YET 0x3E
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) #define SENCODE_INQUIRY_DATA_CHANGED 0x3F
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) #define SENCODE_SAVING_PARAMS_NOT_SUPPORTED 0x39
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) #define SENCODE_DIAGNOSTIC_FAILURE 0x40
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) #define SENCODE_INTERNAL_TARGET_FAILURE 0x44
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) #define SENCODE_INVALID_MESSAGE_ERROR 0x49
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) #define SENCODE_LUN_FAILED_SELF_CONFIG 0x4c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) #define SENCODE_OVERLAPPED_COMMAND 0x4E
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) * Additional sense codes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) #define ASENCODE_NO_SENSE 0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) #define ASENCODE_END_OF_DATA 0x05
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) #define ASENCODE_BECOMING_READY 0x01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) #define ASENCODE_INIT_CMD_REQUIRED 0x02
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) #define ASENCODE_PARAM_LIST_LENGTH_ERROR 0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) #define ASENCODE_INVALID_COMMAND 0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) #define ASENCODE_LBA_OUT_OF_RANGE 0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) #define ASENCODE_INVALID_CDB_FIELD 0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) #define ASENCODE_LUN_NOT_SUPPORTED 0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) #define ASENCODE_INVALID_PARAM_FIELD 0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) #define ASENCODE_PARAM_NOT_SUPPORTED 0x01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) #define ASENCODE_PARAM_VALUE_INVALID 0x02
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) #define ASENCODE_RESET_OCCURRED 0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) #define ASENCODE_LUN_NOT_SELF_CONFIGURED_YET 0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) #define ASENCODE_INQUIRY_DATA_CHANGED 0x03
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) #define ASENCODE_SAVING_PARAMS_NOT_SUPPORTED 0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) #define ASENCODE_DIAGNOSTIC_FAILURE 0x80
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) #define ASENCODE_INTERNAL_TARGET_FAILURE 0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) #define ASENCODE_INVALID_MESSAGE_ERROR 0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) #define ASENCODE_LUN_FAILED_SELF_CONFIG 0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) #define ASENCODE_OVERLAPPED_COMMAND 0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) #define BYTE0(x) (unsigned char)(x)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) #define BYTE1(x) (unsigned char)((x) >> 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) #define BYTE2(x) (unsigned char)((x) >> 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) #define BYTE3(x) (unsigned char)((x) >> 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) /* MODE_SENSE data format */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) typedef struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) u8 data_length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) u8 med_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) u8 dev_par;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) u8 bd_length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) } __attribute__((packed)) hd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) u8 dens_code;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) u8 block_count[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) u8 reserved;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) u8 block_length[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) } __attribute__((packed)) bd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) u8 mpc_buf[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) } __attribute__((packed)) aac_modep_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) /* MODE_SENSE_10 data format */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) typedef struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) u8 data_length[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) u8 med_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) u8 dev_par;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) u8 rsrvd[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) u8 bd_length[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) } __attribute__((packed)) hd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) u8 dens_code;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) u8 block_count[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) u8 reserved;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) u8 block_length[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) } __attribute__((packed)) bd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) u8 mpc_buf[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) } __attribute__((packed)) aac_modep10_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) /*------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) * S T R U C T S / T Y P E D E F S
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) *----------------------------------------------------------------------------*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) /* SCSI inquiry data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) struct inquiry_data {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) u8 inqd_pdt; /* Peripheral qualifier | Peripheral Device Type */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) u8 inqd_dtq; /* RMB | Device Type Qualifier */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) u8 inqd_ver; /* ISO version | ECMA version | ANSI-approved version */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) u8 inqd_rdf; /* AENC | TrmIOP | Response data format */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) u8 inqd_len; /* Additional length (n-4) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) u8 inqd_pad1[2];/* Reserved - must be zero */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) u8 inqd_pad2; /* RelAdr | WBus32 | WBus16 | Sync | Linked |Reserved| CmdQue | SftRe */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) u8 inqd_vid[8]; /* Vendor ID */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) u8 inqd_pid[16];/* Product ID */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) u8 inqd_prl[4]; /* Product Revision Level */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) /* Added for VPD 0x83 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) struct tvpd_id_descriptor_type_1 {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) u8 codeset:4; /* VPD_CODE_SET */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) u8 reserved:4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) u8 identifiertype:4; /* VPD_IDENTIFIER_TYPE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) u8 reserved2:4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) u8 reserved3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) u8 identifierlength;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) u8 venid[8];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) u8 productid[16];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) u8 serialnumber[8]; /* SN in ASCII */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) struct tvpd_id_descriptor_type_2 {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) u8 codeset:4; /* VPD_CODE_SET */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) u8 reserved:4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) u8 identifiertype:4; /* VPD_IDENTIFIER_TYPE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) u8 reserved2:4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) u8 reserved3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) u8 identifierlength;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) struct teu64id {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) u32 Serial;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) /* The serial number supposed to be 40 bits,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) * bit we only support 32, so make the last byte zero. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) u8 reserved;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) u8 venid[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) } eu64id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) struct tvpd_id_descriptor_type_3 {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) u8 codeset : 4; /* VPD_CODE_SET */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) u8 reserved : 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) u8 identifiertype : 4; /* VPD_IDENTIFIER_TYPE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) u8 reserved2 : 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) u8 reserved3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) u8 identifierlength;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) u8 Identifier[16];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) struct tvpd_page83 {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) u8 DeviceType:5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) u8 DeviceTypeQualifier:3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) u8 PageCode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) u8 reserved;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) u8 PageLength;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) struct tvpd_id_descriptor_type_1 type1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) struct tvpd_id_descriptor_type_2 type2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) struct tvpd_id_descriptor_type_3 type3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) * M O D U L E G L O B A L S
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) static long aac_build_sg(struct scsi_cmnd *scsicmd, struct sgmap *sgmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) static long aac_build_sg64(struct scsi_cmnd *scsicmd, struct sgmap64 *psg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) static long aac_build_sgraw(struct scsi_cmnd *scsicmd, struct sgmapraw *psg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) static long aac_build_sgraw2(struct scsi_cmnd *scsicmd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) struct aac_raw_io2 *rio2, int sg_max);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) static long aac_build_sghba(struct scsi_cmnd *scsicmd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) struct aac_hba_cmd_req *hbacmd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) int sg_max, u64 sg_address);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) static int aac_convert_sgraw2(struct aac_raw_io2 *rio2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) int pages, int nseg, int nseg_new);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) static int aac_send_srb_fib(struct scsi_cmnd* scsicmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) static int aac_send_hba_fib(struct scsi_cmnd *scsicmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) #ifdef AAC_DETAILED_STATUS_INFO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) static char *aac_get_status_string(u32 status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) * Non dasd selection is handled entirely in aachba now
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) static int nondasd = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) static int aac_cache = 2; /* WCE=0 to avoid performance problems */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) static int dacmode = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) int aac_msi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) int aac_commit = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) int startup_timeout = 180;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) int aif_timeout = 120;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) int aac_sync_mode; /* Only Sync. transfer - disabled */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) static int aac_convert_sgl = 1; /* convert non-conformable s/g list - enabled */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) module_param(aac_sync_mode, int, S_IRUGO|S_IWUSR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) MODULE_PARM_DESC(aac_sync_mode, "Force sync. transfer mode"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) " 0=off, 1=on");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) module_param(aac_convert_sgl, int, S_IRUGO|S_IWUSR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) MODULE_PARM_DESC(aac_convert_sgl, "Convert non-conformable s/g list"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) " 0=off, 1=on");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) module_param(nondasd, int, S_IRUGO|S_IWUSR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) MODULE_PARM_DESC(nondasd, "Control scanning of hba for nondasd devices."
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) " 0=off, 1=on");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) module_param_named(cache, aac_cache, int, S_IRUGO|S_IWUSR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) MODULE_PARM_DESC(cache, "Disable Queue Flush commands:\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) "\tbit 0 - Disable FUA in WRITE SCSI commands\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) "\tbit 1 - Disable SYNCHRONIZE_CACHE SCSI command\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) "\tbit 2 - Disable only if Battery is protecting Cache");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) module_param(dacmode, int, S_IRUGO|S_IWUSR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) MODULE_PARM_DESC(dacmode, "Control whether dma addressing is using 64 bit DAC."
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) " 0=off, 1=on");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) module_param_named(commit, aac_commit, int, S_IRUGO|S_IWUSR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) MODULE_PARM_DESC(commit, "Control whether a COMMIT_CONFIG is issued to the"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) " adapter for foreign arrays.\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) "This is typically needed in systems that do not have a BIOS."
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) " 0=off, 1=on");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) module_param_named(msi, aac_msi, int, S_IRUGO|S_IWUSR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) MODULE_PARM_DESC(msi, "IRQ handling."
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) " 0=PIC(default), 1=MSI, 2=MSI-X)");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) module_param(startup_timeout, int, S_IRUGO|S_IWUSR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) MODULE_PARM_DESC(startup_timeout, "The duration of time in seconds to wait for"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) " adapter to have it's kernel up and\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) "running. This is typically adjusted for large systems that do not"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) " have a BIOS.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) module_param(aif_timeout, int, S_IRUGO|S_IWUSR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) MODULE_PARM_DESC(aif_timeout, "The duration of time in seconds to wait for"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) " applications to pick up AIFs before\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) "deregistering them. This is typically adjusted for heavily burdened"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) " systems.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) int aac_fib_dump;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) module_param(aac_fib_dump, int, 0644);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) MODULE_PARM_DESC(aac_fib_dump, "Dump controller fibs prior to IOP_RESET 0=off, 1=on");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) int numacb = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) module_param(numacb, int, S_IRUGO|S_IWUSR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) MODULE_PARM_DESC(numacb, "Request a limit to the number of adapter control"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) " blocks (FIB) allocated. Valid values are 512 and down. Default is"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) " to use suggestion from Firmware.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) static int acbsize = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) module_param(acbsize, int, S_IRUGO|S_IWUSR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) MODULE_PARM_DESC(acbsize, "Request a specific adapter control block (FIB)"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) " size. Valid values are 512, 2048, 4096 and 8192. Default is to use"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) " suggestion from Firmware.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) int update_interval = 30 * 60;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) module_param(update_interval, int, S_IRUGO|S_IWUSR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) MODULE_PARM_DESC(update_interval, "Interval in seconds between time sync"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) " updates issued to adapter.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) int check_interval = 60;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) module_param(check_interval, int, S_IRUGO|S_IWUSR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) MODULE_PARM_DESC(check_interval, "Interval in seconds between adapter health"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) " checks.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) int aac_check_reset = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) module_param_named(check_reset, aac_check_reset, int, S_IRUGO|S_IWUSR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) MODULE_PARM_DESC(check_reset, "If adapter fails health check, reset the"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) " adapter. a value of -1 forces the reset to adapters programmed to"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) " ignore it.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) int expose_physicals = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) module_param(expose_physicals, int, S_IRUGO|S_IWUSR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) MODULE_PARM_DESC(expose_physicals, "Expose physical components of the arrays."
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) " -1=protect 0=off, 1=on");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) int aac_reset_devices;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) module_param_named(reset_devices, aac_reset_devices, int, S_IRUGO|S_IWUSR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) MODULE_PARM_DESC(reset_devices, "Force an adapter reset at initialization.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) static int aac_wwn = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) module_param_named(wwn, aac_wwn, int, S_IRUGO|S_IWUSR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) MODULE_PARM_DESC(wwn, "Select a WWN type for the arrays:\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) "\t0 - Disable\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) "\t1 - Array Meta Data Signature (default)\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) "\t2 - Adapter Serial Number");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) static inline int aac_valid_context(struct scsi_cmnd *scsicmd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) struct fib *fibptr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) struct scsi_device *device;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) if (unlikely(!scsicmd || !scsicmd->scsi_done)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) dprintk((KERN_WARNING "aac_valid_context: scsi command corrupt\n"));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) aac_fib_complete(fibptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) scsicmd->SCp.phase = AAC_OWNER_MIDLEVEL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) device = scsicmd->device;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) if (unlikely(!device)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) dprintk((KERN_WARNING "aac_valid_context: scsi device corrupt\n"));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) aac_fib_complete(fibptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) * aac_get_config_status - check the adapter configuration
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) * @dev: aac driver data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) * @commit_flag: force sending CT_COMMIT_CONFIG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) * Query config status, and commit the configuration if needed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) int aac_get_config_status(struct aac_dev *dev, int commit_flag)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) int status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) struct fib * fibptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) if (!(fibptr = aac_fib_alloc(dev)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) aac_fib_init(fibptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) struct aac_get_config_status *dinfo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) dinfo = (struct aac_get_config_status *) fib_data(fibptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) dinfo->command = cpu_to_le32(VM_ContainerConfig);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) dinfo->type = cpu_to_le32(CT_GET_CONFIG_STATUS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) dinfo->count = cpu_to_le32(sizeof(((struct aac_get_config_status_resp *)NULL)->data));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) status = aac_fib_send(ContainerCommand,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) fibptr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) sizeof (struct aac_get_config_status),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) FsaNormal,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) 1, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) NULL, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) if (status < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) printk(KERN_WARNING "aac_get_config_status: SendFIB failed.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) struct aac_get_config_status_resp *reply
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) = (struct aac_get_config_status_resp *) fib_data(fibptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) dprintk((KERN_WARNING
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) "aac_get_config_status: response=%d status=%d action=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) le32_to_cpu(reply->response),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) le32_to_cpu(reply->status),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) le32_to_cpu(reply->data.action)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) if ((le32_to_cpu(reply->response) != ST_OK) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) (le32_to_cpu(reply->status) != CT_OK) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) (le32_to_cpu(reply->data.action) > CFACT_PAUSE)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) printk(KERN_WARNING "aac_get_config_status: Will not issue the Commit Configuration\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) status = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) /* Do not set XferState to zero unless receives a response from F/W */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) if (status >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) aac_fib_complete(fibptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) /* Send a CT_COMMIT_CONFIG to enable discovery of devices */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) if (status >= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) if ((aac_commit == 1) || commit_flag) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) struct aac_commit_config * dinfo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) aac_fib_init(fibptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) dinfo = (struct aac_commit_config *) fib_data(fibptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) dinfo->command = cpu_to_le32(VM_ContainerConfig);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) dinfo->type = cpu_to_le32(CT_COMMIT_CONFIG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) status = aac_fib_send(ContainerCommand,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) fibptr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) sizeof (struct aac_commit_config),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) FsaNormal,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) 1, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) NULL, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) /* Do not set XferState to zero unless
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) * receives a response from F/W */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) if (status >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) aac_fib_complete(fibptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) } else if (aac_commit == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) printk(KERN_WARNING
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) "aac_get_config_status: Foreign device configurations are being ignored\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) /* FIB should be freed only after getting the response from the F/W */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) if (status != -ERESTARTSYS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) aac_fib_free(fibptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) static void aac_expose_phy_device(struct scsi_cmnd *scsicmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) char inq_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) scsi_sg_copy_to_buffer(scsicmd, &inq_data, sizeof(inq_data));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) if ((inq_data & 0x20) && (inq_data & 0x1f) == TYPE_DISK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) inq_data &= 0xdf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) scsi_sg_copy_from_buffer(scsicmd, &inq_data, sizeof(inq_data));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) * aac_get_containers - list containers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) * @dev: aac driver data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) * Make a list of all containers on this controller
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) int aac_get_containers(struct aac_dev *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) struct fsa_dev_info *fsa_dev_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) u32 index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) int status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) struct fib * fibptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) struct aac_get_container_count *dinfo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) struct aac_get_container_count_resp *dresp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) int maximum_num_containers = MAXIMUM_NUM_CONTAINERS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) if (!(fibptr = aac_fib_alloc(dev)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) aac_fib_init(fibptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) dinfo = (struct aac_get_container_count *) fib_data(fibptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) dinfo->command = cpu_to_le32(VM_ContainerConfig);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) dinfo->type = cpu_to_le32(CT_GET_CONTAINER_COUNT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) status = aac_fib_send(ContainerCommand,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) fibptr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) sizeof (struct aac_get_container_count),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) FsaNormal,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) 1, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) NULL, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) if (status >= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) dresp = (struct aac_get_container_count_resp *)fib_data(fibptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) maximum_num_containers = le32_to_cpu(dresp->ContainerSwitchEntries);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) if (fibptr->dev->supplement_adapter_info.supported_options2 &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) AAC_OPTION_SUPPORTED_240_VOLUMES) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) maximum_num_containers =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) le32_to_cpu(dresp->MaxSimpleVolumes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) aac_fib_complete(fibptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) /* FIB should be freed only after getting the response from the F/W */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) if (status != -ERESTARTSYS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) aac_fib_free(fibptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) if (maximum_num_containers < MAXIMUM_NUM_CONTAINERS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) maximum_num_containers = MAXIMUM_NUM_CONTAINERS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) if (dev->fsa_dev == NULL ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) dev->maximum_num_containers != maximum_num_containers) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) fsa_dev_ptr = dev->fsa_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) dev->fsa_dev = kcalloc(maximum_num_containers,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) sizeof(*fsa_dev_ptr), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) kfree(fsa_dev_ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) fsa_dev_ptr = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) if (!dev->fsa_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) dev->maximum_num_containers = maximum_num_containers;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) for (index = 0; index < dev->maximum_num_containers; index++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) dev->fsa_dev[index].devname[0] = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) dev->fsa_dev[index].valid = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) status = aac_probe_container(dev, index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) if (status < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) printk(KERN_WARNING "aac_get_containers: SendFIB failed.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) static void get_container_name_callback(void *context, struct fib * fibptr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) struct aac_get_name_resp * get_name_reply;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) struct scsi_cmnd * scsicmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) scsicmd = (struct scsi_cmnd *) context;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) if (!aac_valid_context(scsicmd, fibptr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) dprintk((KERN_DEBUG "get_container_name_callback[cpu %d]: t = %ld.\n", smp_processor_id(), jiffies));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) BUG_ON(fibptr == NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) get_name_reply = (struct aac_get_name_resp *) fib_data(fibptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) /* Failure is irrelevant, using default value instead */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) if ((le32_to_cpu(get_name_reply->status) == CT_OK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) && (get_name_reply->data[0] != '\0')) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) char *sp = get_name_reply->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) int data_size = sizeof_field(struct aac_get_name_resp, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) sp[data_size - 1] = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) while (*sp == ' ')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) ++sp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) if (*sp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) struct inquiry_data inq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) char d[sizeof(((struct inquiry_data *)NULL)->inqd_pid)];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) int count = sizeof(d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) char *dp = d;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) *dp++ = (*sp) ? *sp++ : ' ';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) } while (--count > 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) scsi_sg_copy_to_buffer(scsicmd, &inq, sizeof(inq));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) memcpy(inq.inqd_pid, d, sizeof(d));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) scsi_sg_copy_from_buffer(scsicmd, &inq, sizeof(inq));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) aac_fib_complete(fibptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) scsicmd->scsi_done(scsicmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) * aac_get_container_name - get container name, none blocking.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) static int aac_get_container_name(struct scsi_cmnd * scsicmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) int data_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) struct aac_get_name *dinfo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) struct fib * cmd_fibcontext;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) struct aac_dev * dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) dev = (struct aac_dev *)scsicmd->device->host->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) data_size = sizeof_field(struct aac_get_name_resp, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) cmd_fibcontext = aac_fib_alloc_tag(dev, scsicmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) aac_fib_init(cmd_fibcontext);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) dinfo = (struct aac_get_name *) fib_data(cmd_fibcontext);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) scsicmd->SCp.phase = AAC_OWNER_FIRMWARE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) dinfo->command = cpu_to_le32(VM_ContainerConfig);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) dinfo->type = cpu_to_le32(CT_READ_NAME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) dinfo->cid = cpu_to_le32(scmd_id(scsicmd));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) dinfo->count = cpu_to_le32(data_size - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) status = aac_fib_send(ContainerCommand,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) cmd_fibcontext,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) sizeof(struct aac_get_name_resp),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) FsaNormal,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) 0, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) (fib_callback)get_container_name_callback,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) (void *) scsicmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) * Check that the command queued to the controller
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) if (status == -EINPROGRESS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) printk(KERN_WARNING "aac_get_container_name: aac_fib_send failed with status: %d.\n", status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) aac_fib_complete(cmd_fibcontext);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) static int aac_probe_container_callback2(struct scsi_cmnd * scsicmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) struct fsa_dev_info *fsa_dev_ptr = ((struct aac_dev *)(scsicmd->device->host->hostdata))->fsa_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) if ((fsa_dev_ptr[scmd_id(scsicmd)].valid & 1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) return aac_scsi_cmd(scsicmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) scsicmd->result = DID_NO_CONNECT << 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) scsicmd->scsi_done(scsicmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) static void _aac_probe_container2(void * context, struct fib * fibptr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) struct fsa_dev_info *fsa_dev_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) int (*callback)(struct scsi_cmnd *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) struct scsi_cmnd * scsicmd = (struct scsi_cmnd *)context;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) if (!aac_valid_context(scsicmd, fibptr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) scsicmd->SCp.Status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) fsa_dev_ptr = fibptr->dev->fsa_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) if (fsa_dev_ptr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) struct aac_mount * dresp = (struct aac_mount *) fib_data(fibptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) __le32 sup_options2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) fsa_dev_ptr += scmd_id(scsicmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) sup_options2 =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) fibptr->dev->supplement_adapter_info.supported_options2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) if ((le32_to_cpu(dresp->status) == ST_OK) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) (le32_to_cpu(dresp->mnt[0].vol) != CT_NONE) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) (le32_to_cpu(dresp->mnt[0].state) != FSCS_HIDDEN)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) if (!(sup_options2 & AAC_OPTION_VARIABLE_BLOCK_SIZE)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) dresp->mnt[0].fileinfo.bdevinfo.block_size = 0x200;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) fsa_dev_ptr->block_size = 0x200;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) fsa_dev_ptr->block_size =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) le32_to_cpu(dresp->mnt[0].fileinfo.bdevinfo.block_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) for (i = 0; i < 16; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) fsa_dev_ptr->identifier[i] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) dresp->mnt[0].fileinfo.bdevinfo
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) .identifier[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) fsa_dev_ptr->valid = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) /* sense_key holds the current state of the spin-up */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) if (dresp->mnt[0].state & cpu_to_le32(FSCS_NOT_READY))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) fsa_dev_ptr->sense_data.sense_key = NOT_READY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) else if (fsa_dev_ptr->sense_data.sense_key == NOT_READY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) fsa_dev_ptr->sense_data.sense_key = NO_SENSE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) fsa_dev_ptr->type = le32_to_cpu(dresp->mnt[0].vol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) fsa_dev_ptr->size
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) = ((u64)le32_to_cpu(dresp->mnt[0].capacity)) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) (((u64)le32_to_cpu(dresp->mnt[0].capacityhigh)) << 32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) fsa_dev_ptr->ro = ((le32_to_cpu(dresp->mnt[0].state) & FSCS_READONLY) != 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) if ((fsa_dev_ptr->valid & 1) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) fsa_dev_ptr->valid = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) scsicmd->SCp.Status = le32_to_cpu(dresp->count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) aac_fib_complete(fibptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) aac_fib_free(fibptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) callback = (int (*)(struct scsi_cmnd *))(scsicmd->SCp.ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) scsicmd->SCp.ptr = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) (*callback)(scsicmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) static void _aac_probe_container1(void * context, struct fib * fibptr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) struct scsi_cmnd * scsicmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) struct aac_mount * dresp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) struct aac_query_mount *dinfo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) dresp = (struct aac_mount *) fib_data(fibptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) if (!aac_supports_2T(fibptr->dev)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) dresp->mnt[0].capacityhigh = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) if ((le32_to_cpu(dresp->status) == ST_OK) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) (le32_to_cpu(dresp->mnt[0].vol) != CT_NONE)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) _aac_probe_container2(context, fibptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) scsicmd = (struct scsi_cmnd *) context;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) if (!aac_valid_context(scsicmd, fibptr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) aac_fib_init(fibptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) dinfo = (struct aac_query_mount *)fib_data(fibptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) if (fibptr->dev->supplement_adapter_info.supported_options2 &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) AAC_OPTION_VARIABLE_BLOCK_SIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) dinfo->command = cpu_to_le32(VM_NameServeAllBlk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) dinfo->command = cpu_to_le32(VM_NameServe64);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) dinfo->count = cpu_to_le32(scmd_id(scsicmd));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) dinfo->type = cpu_to_le32(FT_FILESYS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) scsicmd->SCp.phase = AAC_OWNER_FIRMWARE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) status = aac_fib_send(ContainerCommand,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) fibptr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) sizeof(struct aac_query_mount),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) FsaNormal,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) 0, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) _aac_probe_container2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) (void *) scsicmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) * Check that the command queued to the controller
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) if (status < 0 && status != -EINPROGRESS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) /* Inherit results from VM_NameServe, if any */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) dresp->status = cpu_to_le32(ST_OK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) _aac_probe_container2(context, fibptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) static int _aac_probe_container(struct scsi_cmnd * scsicmd, int (*callback)(struct scsi_cmnd *))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) struct fib * fibptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) int status = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) if ((fibptr = aac_fib_alloc((struct aac_dev *)scsicmd->device->host->hostdata))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) struct aac_query_mount *dinfo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) aac_fib_init(fibptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) dinfo = (struct aac_query_mount *)fib_data(fibptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) if (fibptr->dev->supplement_adapter_info.supported_options2 &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) AAC_OPTION_VARIABLE_BLOCK_SIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) dinfo->command = cpu_to_le32(VM_NameServeAllBlk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) dinfo->command = cpu_to_le32(VM_NameServe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) dinfo->count = cpu_to_le32(scmd_id(scsicmd));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) dinfo->type = cpu_to_le32(FT_FILESYS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) scsicmd->SCp.ptr = (char *)callback;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) scsicmd->SCp.phase = AAC_OWNER_FIRMWARE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) status = aac_fib_send(ContainerCommand,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) fibptr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) sizeof(struct aac_query_mount),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) FsaNormal,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) 0, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) _aac_probe_container1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) (void *) scsicmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) * Check that the command queued to the controller
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) if (status == -EINPROGRESS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) if (status < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) scsicmd->SCp.ptr = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) aac_fib_complete(fibptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) aac_fib_free(fibptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) if (status < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) struct fsa_dev_info *fsa_dev_ptr = ((struct aac_dev *)(scsicmd->device->host->hostdata))->fsa_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) if (fsa_dev_ptr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) fsa_dev_ptr += scmd_id(scsicmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) if ((fsa_dev_ptr->valid & 1) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) fsa_dev_ptr->valid = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) return (*callback)(scsicmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) * aac_probe_container - query a logical volume
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) * @scsicmd: the scsi command block
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) * Queries the controller about the given volume. The volume information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) * is updated in the struct fsa_dev_info structure rather than returned.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) static int aac_probe_container_callback1(struct scsi_cmnd * scsicmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) scsicmd->device = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) static void aac_probe_container_scsi_done(struct scsi_cmnd *scsi_cmnd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) aac_probe_container_callback1(scsi_cmnd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) int aac_probe_container(struct aac_dev *dev, int cid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) struct scsi_cmnd *scsicmd = kmalloc(sizeof(*scsicmd), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) struct scsi_device *scsidev = kmalloc(sizeof(*scsidev), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) if (!scsicmd || !scsidev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) kfree(scsicmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) kfree(scsidev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) scsicmd->scsi_done = aac_probe_container_scsi_done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) scsicmd->device = scsidev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) scsidev->sdev_state = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) scsidev->id = cid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) scsidev->host = dev->scsi_host_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) if (_aac_probe_container(scsicmd, aac_probe_container_callback1) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) while (scsicmd->device == scsidev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) schedule();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) kfree(scsidev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) status = scsicmd->SCp.Status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) kfree(scsicmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) /* Local Structure to set SCSI inquiry data strings */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) struct scsi_inq {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) char vid[8]; /* Vendor ID */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) char pid[16]; /* Product ID */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) char prl[4]; /* Product Revision Level */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) * InqStrCopy - string merge
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) * @a: string to copy from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) * @b: string to copy to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) * Copy a String from one location to another
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) * without copying \0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) static void inqstrcpy(char *a, char *b)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) while (*a != (char)0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) *b++ = *a++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) static char *container_types[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) "None",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) "Volume",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) "Mirror",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) "Stripe",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) "RAID5",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) "SSRW",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) "SSRO",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) "Morph",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) "Legacy",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) "RAID4",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) "RAID10",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) "RAID00",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) "V-MIRRORS",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) "PSEUDO R4",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) "RAID50",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) "RAID5D",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) "RAID5D0",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) "RAID1E",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) "RAID6",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) "RAID60",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) "Unknown"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) char * get_container_type(unsigned tindex)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) if (tindex >= ARRAY_SIZE(container_types))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) tindex = ARRAY_SIZE(container_types) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) return container_types[tindex];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) /* Function: setinqstr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) * Arguments: [1] pointer to void [1] int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) * Purpose: Sets SCSI inquiry data strings for vendor, product
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) * and revision level. Allows strings to be set in platform dependent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) * files instead of in OS dependent driver source.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) static void setinqstr(struct aac_dev *dev, void *data, int tindex)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) struct scsi_inq *str;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) struct aac_supplement_adapter_info *sup_adap_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) sup_adap_info = &dev->supplement_adapter_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) str = (struct scsi_inq *)(data); /* cast data to scsi inq block */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) memset(str, ' ', sizeof(*str));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) if (sup_adap_info->adapter_type_text[0]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) int c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) char *cp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) char *cname = kmemdup(sup_adap_info->adapter_type_text,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) sizeof(sup_adap_info->adapter_type_text),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) if (!cname)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) cp = cname;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) if ((cp[0] == 'A') && (cp[1] == 'O') && (cp[2] == 'C'))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) inqstrcpy("SMC", str->vid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) c = sizeof(str->vid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) while (*cp && *cp != ' ' && --c)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) ++cp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) c = *cp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) *cp = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) inqstrcpy(cname, str->vid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) *cp = c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) while (*cp && *cp != ' ')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) ++cp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) while (*cp == ' ')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) ++cp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) /* last six chars reserved for vol type */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) if (strlen(cp) > sizeof(str->pid))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) cp[sizeof(str->pid)] = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) inqstrcpy (cp, str->pid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) kfree(cname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) struct aac_driver_ident *mp = aac_get_driver_ident(dev->cardtype);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) inqstrcpy (mp->vname, str->vid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) /* last six chars reserved for vol type */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) inqstrcpy (mp->model, str->pid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) if (tindex < ARRAY_SIZE(container_types)){
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) char *findit = str->pid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) for ( ; *findit != ' '; findit++); /* walk till we find a space */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) /* RAID is superfluous in the context of a RAID device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) if (memcmp(findit-4, "RAID", 4) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) *(findit -= 4) = ' ';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) if (((findit - str->pid) + strlen(container_types[tindex]))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) < (sizeof(str->pid) + sizeof(str->prl)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) inqstrcpy (container_types[tindex], findit + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) inqstrcpy ("V1.0", str->prl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) static void build_vpd83_type3(struct tvpd_page83 *vpdpage83data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) struct aac_dev *dev, struct scsi_cmnd *scsicmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) int container;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) vpdpage83data->type3.codeset = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) vpdpage83data->type3.identifiertype = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) vpdpage83data->type3.identifierlength = sizeof(vpdpage83data->type3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) - 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) for (container = 0; container < dev->maximum_num_containers;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) container++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) if (scmd_id(scsicmd) == container) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) memcpy(vpdpage83data->type3.Identifier,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) dev->fsa_dev[container].identifier,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) static void get_container_serial_callback(void *context, struct fib * fibptr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) struct aac_get_serial_resp * get_serial_reply;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) struct scsi_cmnd * scsicmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) BUG_ON(fibptr == NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) scsicmd = (struct scsi_cmnd *) context;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) if (!aac_valid_context(scsicmd, fibptr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) get_serial_reply = (struct aac_get_serial_resp *) fib_data(fibptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) /* Failure is irrelevant, using default value instead */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) if (le32_to_cpu(get_serial_reply->status) == CT_OK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) /*Check to see if it's for VPD 0x83 or 0x80 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) if (scsicmd->cmnd[2] == 0x83) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) /* vpd page 0x83 - Device Identification Page */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) struct aac_dev *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) struct tvpd_page83 vpdpage83data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) dev = (struct aac_dev *)scsicmd->device->host->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) memset(((u8 *)&vpdpage83data), 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) sizeof(vpdpage83data));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) /* DIRECT_ACCESS_DEVIC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) vpdpage83data.DeviceType = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) /* DEVICE_CONNECTED */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) vpdpage83data.DeviceTypeQualifier = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) /* VPD_DEVICE_IDENTIFIERS */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) vpdpage83data.PageCode = 0x83;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) vpdpage83data.reserved = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) vpdpage83data.PageLength =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) sizeof(vpdpage83data.type1) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) sizeof(vpdpage83data.type2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) /* VPD 83 Type 3 is not supported for ARC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) if (dev->sa_firmware)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) vpdpage83data.PageLength +=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) sizeof(vpdpage83data.type3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) /* T10 Vendor Identifier Field Format */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) /* VpdcodesetAscii */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) vpdpage83data.type1.codeset = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) /* VpdIdentifierTypeVendorId */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) vpdpage83data.type1.identifiertype = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) vpdpage83data.type1.identifierlength =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) sizeof(vpdpage83data.type1) - 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) /* "ADAPTEC " for adaptec */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) memcpy(vpdpage83data.type1.venid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) "ADAPTEC ",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) sizeof(vpdpage83data.type1.venid));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) memcpy(vpdpage83data.type1.productid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) "ARRAY ",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) sizeof(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) vpdpage83data.type1.productid));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) /* Convert to ascii based serial number.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) * The LSB is the the end.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) for (i = 0; i < 8; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) u8 temp =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) (u8)((get_serial_reply->uid >> ((7 - i) * 4)) & 0xF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) if (temp > 0x9) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) vpdpage83data.type1.serialnumber[i] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) 'A' + (temp - 0xA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) vpdpage83data.type1.serialnumber[i] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) '0' + temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) /* VpdCodeSetBinary */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) vpdpage83data.type2.codeset = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) /* VpdidentifiertypeEUI64 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) vpdpage83data.type2.identifiertype = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) vpdpage83data.type2.identifierlength =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) sizeof(vpdpage83data.type2) - 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) vpdpage83data.type2.eu64id.venid[0] = 0xD0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) vpdpage83data.type2.eu64id.venid[1] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) vpdpage83data.type2.eu64id.venid[2] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) vpdpage83data.type2.eu64id.Serial =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) get_serial_reply->uid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) vpdpage83data.type2.eu64id.reserved = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) * VpdIdentifierTypeFCPHName
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) * VPD 0x83 Type 3 not supported for ARC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) if (dev->sa_firmware) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) build_vpd83_type3(&vpdpage83data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) dev, scsicmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) /* Move the inquiry data to the response buffer. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) scsi_sg_copy_from_buffer(scsicmd, &vpdpage83data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) sizeof(vpdpage83data));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) /* It must be for VPD 0x80 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) char sp[13];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) /* EVPD bit set */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) sp[0] = INQD_PDT_DA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) sp[1] = scsicmd->cmnd[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) sp[2] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) sp[3] = snprintf(sp+4, sizeof(sp)-4, "%08X",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) le32_to_cpu(get_serial_reply->uid));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) scsi_sg_copy_from_buffer(scsicmd, sp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) sizeof(sp));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) aac_fib_complete(fibptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) scsicmd->scsi_done(scsicmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) * aac_get_container_serial - get container serial, none blocking.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) static int aac_get_container_serial(struct scsi_cmnd * scsicmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) struct aac_get_serial *dinfo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) struct fib * cmd_fibcontext;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) struct aac_dev * dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) dev = (struct aac_dev *)scsicmd->device->host->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) cmd_fibcontext = aac_fib_alloc_tag(dev, scsicmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) aac_fib_init(cmd_fibcontext);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) dinfo = (struct aac_get_serial *) fib_data(cmd_fibcontext);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) dinfo->command = cpu_to_le32(VM_ContainerConfig);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) dinfo->type = cpu_to_le32(CT_CID_TO_32BITS_UID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) dinfo->cid = cpu_to_le32(scmd_id(scsicmd));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) scsicmd->SCp.phase = AAC_OWNER_FIRMWARE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) status = aac_fib_send(ContainerCommand,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) cmd_fibcontext,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) sizeof(struct aac_get_serial_resp),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) FsaNormal,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) 0, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) (fib_callback) get_container_serial_callback,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) (void *) scsicmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) * Check that the command queued to the controller
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) if (status == -EINPROGRESS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) printk(KERN_WARNING "aac_get_container_serial: aac_fib_send failed with status: %d.\n", status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) aac_fib_complete(cmd_fibcontext);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) /* Function: setinqserial
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) * Arguments: [1] pointer to void [1] int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) * Purpose: Sets SCSI Unit Serial number.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) * This is a fake. We should read a proper
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) * serial number from the container. <SuSE>But
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) * without docs it's quite hard to do it :-)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) * So this will have to do in the meantime.</SuSE>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) static int setinqserial(struct aac_dev *dev, void *data, int cid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) * This breaks array migration.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) return snprintf((char *)(data), sizeof(struct scsi_inq) - 4, "%08X%02X",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) le32_to_cpu(dev->adapter_info.serial[0]), cid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) static inline void set_sense(struct sense_data *sense_data, u8 sense_key,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) u8 sense_code, u8 a_sense_code, u8 bit_pointer, u16 field_pointer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) u8 *sense_buf = (u8 *)sense_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) /* Sense data valid, err code 70h */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) sense_buf[0] = 0x70; /* No info field */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) sense_buf[1] = 0; /* Segment number, always zero */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) sense_buf[2] = sense_key; /* Sense key */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) sense_buf[12] = sense_code; /* Additional sense code */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) sense_buf[13] = a_sense_code; /* Additional sense code qualifier */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) if (sense_key == ILLEGAL_REQUEST) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) sense_buf[7] = 10; /* Additional sense length */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) sense_buf[15] = bit_pointer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) /* Illegal parameter is in the parameter block */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) if (sense_code == SENCODE_INVALID_CDB_FIELD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) sense_buf[15] |= 0xc0;/* Std sense key specific field */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) /* Illegal parameter is in the CDB block */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) sense_buf[16] = field_pointer >> 8; /* MSB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) sense_buf[17] = field_pointer; /* LSB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) sense_buf[7] = 6; /* Additional sense length */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) static int aac_bounds_32(struct aac_dev * dev, struct scsi_cmnd * cmd, u64 lba)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) if (lba & 0xffffffff00000000LL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) int cid = scmd_id(cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) dprintk((KERN_DEBUG "aacraid: Illegal lba\n"));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) cmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) SAM_STAT_CHECK_CONDITION;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) set_sense(&dev->fsa_dev[cid].sense_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) HARDWARE_ERROR, SENCODE_INTERNAL_TARGET_FAILURE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) ASENCODE_INTERNAL_TARGET_FAILURE, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) memcpy(cmd->sense_buffer, &dev->fsa_dev[cid].sense_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) min_t(size_t, sizeof(dev->fsa_dev[cid].sense_data),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) SCSI_SENSE_BUFFERSIZE));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) cmd->scsi_done(cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) static int aac_bounds_64(struct aac_dev * dev, struct scsi_cmnd * cmd, u64 lba)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) static void io_callback(void *context, struct fib * fibptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) static int aac_read_raw_io(struct fib * fib, struct scsi_cmnd * cmd, u64 lba, u32 count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) struct aac_dev *dev = fib->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) u16 fibsize, command;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) long ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) aac_fib_init(fib);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) if ((dev->comm_interface == AAC_COMM_MESSAGE_TYPE2 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) dev->comm_interface == AAC_COMM_MESSAGE_TYPE3) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) !dev->sync_mode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) struct aac_raw_io2 *readcmd2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) readcmd2 = (struct aac_raw_io2 *) fib_data(fib);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) memset(readcmd2, 0, sizeof(struct aac_raw_io2));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) readcmd2->blockLow = cpu_to_le32((u32)(lba&0xffffffff));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) readcmd2->blockHigh = cpu_to_le32((u32)((lba&0xffffffff00000000LL)>>32));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) readcmd2->byteCount = cpu_to_le32(count *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) dev->fsa_dev[scmd_id(cmd)].block_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) readcmd2->cid = cpu_to_le16(scmd_id(cmd));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) readcmd2->flags = cpu_to_le16(RIO2_IO_TYPE_READ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) ret = aac_build_sgraw2(cmd, readcmd2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) dev->scsi_host_ptr->sg_tablesize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) command = ContainerRawIo2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) fibsize = sizeof(struct aac_raw_io2) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) ((le32_to_cpu(readcmd2->sgeCnt)-1) * sizeof(struct sge_ieee1212));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) struct aac_raw_io *readcmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) readcmd = (struct aac_raw_io *) fib_data(fib);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) readcmd->block[0] = cpu_to_le32((u32)(lba&0xffffffff));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) readcmd->block[1] = cpu_to_le32((u32)((lba&0xffffffff00000000LL)>>32));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) readcmd->count = cpu_to_le32(count *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) dev->fsa_dev[scmd_id(cmd)].block_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) readcmd->cid = cpu_to_le16(scmd_id(cmd));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) readcmd->flags = cpu_to_le16(RIO_TYPE_READ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) readcmd->bpTotal = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) readcmd->bpComplete = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) ret = aac_build_sgraw(cmd, &readcmd->sg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) command = ContainerRawIo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) fibsize = sizeof(struct aac_raw_io) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) ((le32_to_cpu(readcmd->sg.count)-1) * sizeof(struct sgentryraw));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) BUG_ON(fibsize > (fib->dev->max_fib_size - sizeof(struct aac_fibhdr)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) * Now send the Fib to the adapter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) return aac_fib_send(command,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) fib,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) fibsize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) FsaNormal,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) 0, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) (fib_callback) io_callback,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) (void *) cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) static int aac_read_block64(struct fib * fib, struct scsi_cmnd * cmd, u64 lba, u32 count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) u16 fibsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) struct aac_read64 *readcmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) long ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) aac_fib_init(fib);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) readcmd = (struct aac_read64 *) fib_data(fib);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) readcmd->command = cpu_to_le32(VM_CtHostRead64);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) readcmd->cid = cpu_to_le16(scmd_id(cmd));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) readcmd->sector_count = cpu_to_le16(count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) readcmd->block = cpu_to_le32((u32)(lba&0xffffffff));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) readcmd->pad = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) readcmd->flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) ret = aac_build_sg64(cmd, &readcmd->sg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) fibsize = sizeof(struct aac_read64) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) ((le32_to_cpu(readcmd->sg.count) - 1) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) sizeof (struct sgentry64));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) BUG_ON (fibsize > (fib->dev->max_fib_size -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) sizeof(struct aac_fibhdr)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) * Now send the Fib to the adapter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) return aac_fib_send(ContainerCommand64,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) fib,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) fibsize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) FsaNormal,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) 0, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) (fib_callback) io_callback,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) (void *) cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) static int aac_read_block(struct fib * fib, struct scsi_cmnd * cmd, u64 lba, u32 count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) u16 fibsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) struct aac_read *readcmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) struct aac_dev *dev = fib->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) long ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) aac_fib_init(fib);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) readcmd = (struct aac_read *) fib_data(fib);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) readcmd->command = cpu_to_le32(VM_CtBlockRead);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) readcmd->cid = cpu_to_le32(scmd_id(cmd));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) readcmd->block = cpu_to_le32((u32)(lba&0xffffffff));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) readcmd->count = cpu_to_le32(count *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) dev->fsa_dev[scmd_id(cmd)].block_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) ret = aac_build_sg(cmd, &readcmd->sg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) fibsize = sizeof(struct aac_read) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) ((le32_to_cpu(readcmd->sg.count) - 1) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) sizeof (struct sgentry));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) BUG_ON (fibsize > (fib->dev->max_fib_size -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) sizeof(struct aac_fibhdr)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) * Now send the Fib to the adapter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) return aac_fib_send(ContainerCommand,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) fib,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) fibsize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) FsaNormal,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) 0, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) (fib_callback) io_callback,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) (void *) cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) static int aac_write_raw_io(struct fib * fib, struct scsi_cmnd * cmd, u64 lba, u32 count, int fua)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) struct aac_dev *dev = fib->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) u16 fibsize, command;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) long ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) aac_fib_init(fib);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) if ((dev->comm_interface == AAC_COMM_MESSAGE_TYPE2 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) dev->comm_interface == AAC_COMM_MESSAGE_TYPE3) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) !dev->sync_mode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) struct aac_raw_io2 *writecmd2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) writecmd2 = (struct aac_raw_io2 *) fib_data(fib);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) memset(writecmd2, 0, sizeof(struct aac_raw_io2));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) writecmd2->blockLow = cpu_to_le32((u32)(lba&0xffffffff));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) writecmd2->blockHigh = cpu_to_le32((u32)((lba&0xffffffff00000000LL)>>32));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) writecmd2->byteCount = cpu_to_le32(count *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) dev->fsa_dev[scmd_id(cmd)].block_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) writecmd2->cid = cpu_to_le16(scmd_id(cmd));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) writecmd2->flags = (fua && ((aac_cache & 5) != 1) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) (((aac_cache & 5) != 5) || !fib->dev->cache_protected)) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) cpu_to_le16(RIO2_IO_TYPE_WRITE|RIO2_IO_SUREWRITE) :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) cpu_to_le16(RIO2_IO_TYPE_WRITE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) ret = aac_build_sgraw2(cmd, writecmd2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) dev->scsi_host_ptr->sg_tablesize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) command = ContainerRawIo2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) fibsize = sizeof(struct aac_raw_io2) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) ((le32_to_cpu(writecmd2->sgeCnt)-1) * sizeof(struct sge_ieee1212));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) struct aac_raw_io *writecmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) writecmd = (struct aac_raw_io *) fib_data(fib);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) writecmd->block[0] = cpu_to_le32((u32)(lba&0xffffffff));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) writecmd->block[1] = cpu_to_le32((u32)((lba&0xffffffff00000000LL)>>32));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) writecmd->count = cpu_to_le32(count *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) dev->fsa_dev[scmd_id(cmd)].block_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) writecmd->cid = cpu_to_le16(scmd_id(cmd));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) writecmd->flags = (fua && ((aac_cache & 5) != 1) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) (((aac_cache & 5) != 5) || !fib->dev->cache_protected)) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) cpu_to_le16(RIO_TYPE_WRITE|RIO_SUREWRITE) :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) cpu_to_le16(RIO_TYPE_WRITE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) writecmd->bpTotal = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) writecmd->bpComplete = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) ret = aac_build_sgraw(cmd, &writecmd->sg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) command = ContainerRawIo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) fibsize = sizeof(struct aac_raw_io) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) ((le32_to_cpu(writecmd->sg.count)-1) * sizeof (struct sgentryraw));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) BUG_ON(fibsize > (fib->dev->max_fib_size - sizeof(struct aac_fibhdr)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) * Now send the Fib to the adapter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) return aac_fib_send(command,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) fib,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) fibsize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) FsaNormal,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) 0, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) (fib_callback) io_callback,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) (void *) cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) static int aac_write_block64(struct fib * fib, struct scsi_cmnd * cmd, u64 lba, u32 count, int fua)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) u16 fibsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) struct aac_write64 *writecmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) long ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) aac_fib_init(fib);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) writecmd = (struct aac_write64 *) fib_data(fib);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) writecmd->command = cpu_to_le32(VM_CtHostWrite64);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) writecmd->cid = cpu_to_le16(scmd_id(cmd));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) writecmd->sector_count = cpu_to_le16(count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) writecmd->block = cpu_to_le32((u32)(lba&0xffffffff));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) writecmd->pad = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) writecmd->flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) ret = aac_build_sg64(cmd, &writecmd->sg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) fibsize = sizeof(struct aac_write64) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) ((le32_to_cpu(writecmd->sg.count) - 1) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) sizeof (struct sgentry64));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) BUG_ON (fibsize > (fib->dev->max_fib_size -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) sizeof(struct aac_fibhdr)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) * Now send the Fib to the adapter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) return aac_fib_send(ContainerCommand64,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) fib,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) fibsize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) FsaNormal,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) 0, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) (fib_callback) io_callback,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) (void *) cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) static int aac_write_block(struct fib * fib, struct scsi_cmnd * cmd, u64 lba, u32 count, int fua)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) u16 fibsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) struct aac_write *writecmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) struct aac_dev *dev = fib->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) long ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) aac_fib_init(fib);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) writecmd = (struct aac_write *) fib_data(fib);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) writecmd->command = cpu_to_le32(VM_CtBlockWrite);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) writecmd->cid = cpu_to_le32(scmd_id(cmd));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) writecmd->block = cpu_to_le32((u32)(lba&0xffffffff));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) writecmd->count = cpu_to_le32(count *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) dev->fsa_dev[scmd_id(cmd)].block_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) writecmd->sg.count = cpu_to_le32(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) /* ->stable is not used - it did mean which type of write */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) ret = aac_build_sg(cmd, &writecmd->sg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) fibsize = sizeof(struct aac_write) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) ((le32_to_cpu(writecmd->sg.count) - 1) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) sizeof (struct sgentry));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) BUG_ON (fibsize > (fib->dev->max_fib_size -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) sizeof(struct aac_fibhdr)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) * Now send the Fib to the adapter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470) return aac_fib_send(ContainerCommand,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) fib,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) fibsize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) FsaNormal,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474) 0, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475) (fib_callback) io_callback,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) (void *) cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479) static struct aac_srb * aac_scsi_common(struct fib * fib, struct scsi_cmnd * cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481) struct aac_srb * srbcmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482) u32 flag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483) u32 timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484) struct aac_dev *dev = fib->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) aac_fib_init(fib);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487) switch(cmd->sc_data_direction){
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488) case DMA_TO_DEVICE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) flag = SRB_DataOut;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491) case DMA_BIDIRECTIONAL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) flag = SRB_DataIn | SRB_DataOut;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494) case DMA_FROM_DEVICE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) flag = SRB_DataIn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497) case DMA_NONE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498) default: /* shuts up some versions of gcc */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) flag = SRB_NoDataXfer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) srbcmd = (struct aac_srb*) fib_data(fib);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504) srbcmd->function = cpu_to_le32(SRBF_ExecuteScsi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) srbcmd->channel = cpu_to_le32(aac_logical_to_phys(scmd_channel(cmd)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506) srbcmd->id = cpu_to_le32(scmd_id(cmd));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) srbcmd->lun = cpu_to_le32(cmd->device->lun);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508) srbcmd->flags = cpu_to_le32(flag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509) timeout = cmd->request->timeout/HZ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510) if (timeout == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511) timeout = (dev->sa_firmware ? AAC_SA_TIMEOUT : AAC_ARC_TIMEOUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512) srbcmd->timeout = cpu_to_le32(timeout); // timeout in seconds
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) srbcmd->retry_limit = 0; /* Obsolete parameter */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514) srbcmd->cdb_size = cpu_to_le32(cmd->cmd_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) return srbcmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518) static struct aac_hba_cmd_req *aac_construct_hbacmd(struct fib *fib,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) struct scsi_cmnd *cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521) struct aac_hba_cmd_req *hbacmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522) struct aac_dev *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523) int bus, target;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524) u64 address;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526) dev = (struct aac_dev *)cmd->device->host->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528) hbacmd = (struct aac_hba_cmd_req *)fib->hw_fib_va;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529) memset(hbacmd, 0, 96); /* sizeof(*hbacmd) is not necessary */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530) /* iu_type is a parameter of aac_hba_send */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) switch (cmd->sc_data_direction) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532) case DMA_TO_DEVICE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533) hbacmd->byte1 = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535) case DMA_FROM_DEVICE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536) case DMA_BIDIRECTIONAL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537) hbacmd->byte1 = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539) case DMA_NONE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543) hbacmd->lun[1] = cpu_to_le32(cmd->device->lun);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545) bus = aac_logical_to_phys(scmd_channel(cmd));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546) target = scmd_id(cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547) hbacmd->it_nexus = dev->hba_map[bus][target].rmw_nexus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549) /* we fill in reply_qid later in aac_src_deliver_message */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550) /* we fill in iu_type, request_id later in aac_hba_send */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551) /* we fill in emb_data_desc_count later in aac_build_sghba */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553) memcpy(hbacmd->cdb, cmd->cmnd, cmd->cmd_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554) hbacmd->data_length = cpu_to_le32(scsi_bufflen(cmd));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556) address = (u64)fib->hw_error_pa;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557) hbacmd->error_ptr_hi = cpu_to_le32((u32)(address >> 32));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558) hbacmd->error_ptr_lo = cpu_to_le32((u32)(address & 0xffffffff));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559) hbacmd->error_length = cpu_to_le32(FW_ERROR_BUFFER_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561) return hbacmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564) static void aac_srb_callback(void *context, struct fib * fibptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566) static int aac_scsi_64(struct fib * fib, struct scsi_cmnd * cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568) u16 fibsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569) struct aac_srb * srbcmd = aac_scsi_common(fib, cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570) long ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572) ret = aac_build_sg64(cmd, (struct sgmap64 *) &srbcmd->sg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575) srbcmd->count = cpu_to_le32(scsi_bufflen(cmd));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577) memset(srbcmd->cdb, 0, sizeof(srbcmd->cdb));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578) memcpy(srbcmd->cdb, cmd->cmnd, cmd->cmd_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580) * Build Scatter/Gather list
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582) fibsize = sizeof (struct aac_srb) - sizeof (struct sgentry) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583) ((le32_to_cpu(srbcmd->sg.count) & 0xff) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584) sizeof (struct sgentry64));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585) BUG_ON (fibsize > (fib->dev->max_fib_size -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586) sizeof(struct aac_fibhdr)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589) * Now send the Fib to the adapter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591) return aac_fib_send(ScsiPortCommand64, fib,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592) fibsize, FsaNormal, 0, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593) (fib_callback) aac_srb_callback,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594) (void *) cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597) static int aac_scsi_32(struct fib * fib, struct scsi_cmnd * cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599) u16 fibsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600) struct aac_srb * srbcmd = aac_scsi_common(fib, cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601) long ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603) ret = aac_build_sg(cmd, (struct sgmap *)&srbcmd->sg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606) srbcmd->count = cpu_to_le32(scsi_bufflen(cmd));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608) memset(srbcmd->cdb, 0, sizeof(srbcmd->cdb));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609) memcpy(srbcmd->cdb, cmd->cmnd, cmd->cmd_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611) * Build Scatter/Gather list
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613) fibsize = sizeof (struct aac_srb) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614) (((le32_to_cpu(srbcmd->sg.count) & 0xff) - 1) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615) sizeof (struct sgentry));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1616) BUG_ON (fibsize > (fib->dev->max_fib_size -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1617) sizeof(struct aac_fibhdr)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1618)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1619) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1620) * Now send the Fib to the adapter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1621) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1622) return aac_fib_send(ScsiPortCommand, fib, fibsize, FsaNormal, 0, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1623) (fib_callback) aac_srb_callback, (void *) cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1624) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1625)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1626) static int aac_scsi_32_64(struct fib * fib, struct scsi_cmnd * cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1627) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1628) if ((sizeof(dma_addr_t) > 4) && fib->dev->needs_dac &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1629) (fib->dev->adapter_info.options & AAC_OPT_SGMAP_HOST64))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1630) return FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1631) return aac_scsi_32(fib, cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1632) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1633)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1634) static int aac_adapter_hba(struct fib *fib, struct scsi_cmnd *cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1635) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1636) struct aac_hba_cmd_req *hbacmd = aac_construct_hbacmd(fib, cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1637) struct aac_dev *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1638) long ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1639)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1640) dev = (struct aac_dev *)cmd->device->host->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1641)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1642) ret = aac_build_sghba(cmd, hbacmd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1643) dev->scsi_host_ptr->sg_tablesize, (u64)fib->hw_sgl_pa);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1644) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1645) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1646)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1647) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1648) * Now send the HBA command to the adapter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1649) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1650) fib->hbacmd_size = 64 + le32_to_cpu(hbacmd->emb_data_desc_count) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1651) sizeof(struct aac_hba_sgl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1652)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1653) return aac_hba_send(HBA_IU_TYPE_SCSI_CMD_REQ, fib,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1654) (fib_callback) aac_hba_callback,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1655) (void *) cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1656) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1657)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1658) static int aac_send_safw_bmic_cmd(struct aac_dev *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1659) struct aac_srb_unit *srbu, void *xfer_buf, int xfer_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1660) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1661) struct fib *fibptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1662) dma_addr_t addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1663) int rcode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1664) int fibsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1665) struct aac_srb *srb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1666) struct aac_srb_reply *srb_reply;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1667) struct sgmap64 *sg64;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1668) u32 vbus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1669) u32 vid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1670)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1671) if (!dev->sa_firmware)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1672) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1673)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1674) /* allocate FIB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1675) fibptr = aac_fib_alloc(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1676) if (!fibptr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1677) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1678)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1679) aac_fib_init(fibptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1680) fibptr->hw_fib_va->header.XferState &=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1681) ~cpu_to_le32(FastResponseCapable);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1682)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1683) fibsize = sizeof(struct aac_srb) - sizeof(struct sgentry) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1684) sizeof(struct sgentry64);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1685)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1686) /* allocate DMA buffer for response */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1687) addr = dma_map_single(&dev->pdev->dev, xfer_buf, xfer_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1688) DMA_BIDIRECTIONAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1689) if (dma_mapping_error(&dev->pdev->dev, addr)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1690) rcode = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1691) goto fib_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1692) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1693)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1694) srb = fib_data(fibptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1695) memcpy(srb, &srbu->srb, sizeof(struct aac_srb));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1696)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1697) vbus = (u32)le16_to_cpu(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1698) dev->supplement_adapter_info.virt_device_bus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1699) vid = (u32)le16_to_cpu(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1700) dev->supplement_adapter_info.virt_device_target);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1701)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1702) /* set the common request fields */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1703) srb->channel = cpu_to_le32(vbus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1704) srb->id = cpu_to_le32(vid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1705) srb->lun = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1706) srb->function = cpu_to_le32(SRBF_ExecuteScsi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1707) srb->timeout = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1708) srb->retry_limit = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1709) srb->cdb_size = cpu_to_le32(16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1710) srb->count = cpu_to_le32(xfer_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1711)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1712) sg64 = (struct sgmap64 *)&srb->sg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1713) sg64->count = cpu_to_le32(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1714) sg64->sg[0].addr[1] = cpu_to_le32(upper_32_bits(addr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1715) sg64->sg[0].addr[0] = cpu_to_le32(lower_32_bits(addr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1716) sg64->sg[0].count = cpu_to_le32(xfer_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1717)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1718) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1719) * Copy the updated data for other dumping or other usage if needed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1720) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1721) memcpy(&srbu->srb, srb, sizeof(struct aac_srb));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1722)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1723) /* issue request to the controller */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1724) rcode = aac_fib_send(ScsiPortCommand64, fibptr, fibsize, FsaNormal,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1725) 1, 1, NULL, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1726)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1727) if (rcode == -ERESTARTSYS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1728) rcode = -ERESTART;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1729)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1730) if (unlikely(rcode < 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1731) goto bmic_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1732)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1733) srb_reply = (struct aac_srb_reply *)fib_data(fibptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1734) memcpy(&srbu->srb_reply, srb_reply, sizeof(struct aac_srb_reply));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1735)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1736) bmic_error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1737) dma_unmap_single(&dev->pdev->dev, addr, xfer_len, DMA_BIDIRECTIONAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1738) fib_error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1739) aac_fib_complete(fibptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1740) aac_fib_free(fibptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1741) return rcode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1742) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1743)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1744) static void aac_set_safw_target_qd(struct aac_dev *dev, int bus, int target)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1745) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1746)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1747) struct aac_ciss_identify_pd *identify_resp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1748)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1749) if (dev->hba_map[bus][target].devtype != AAC_DEVTYPE_NATIVE_RAW)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1750) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1751)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1752) identify_resp = dev->hba_map[bus][target].safw_identify_resp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1753) if (identify_resp == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1754) dev->hba_map[bus][target].qd_limit = 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1755) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1756) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1757)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1758) if (identify_resp->current_queue_depth_limit <= 0 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1759) identify_resp->current_queue_depth_limit > 255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1760) dev->hba_map[bus][target].qd_limit = 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1761) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1762) dev->hba_map[bus][target].qd_limit =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1763) identify_resp->current_queue_depth_limit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1764) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1765)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1766) static int aac_issue_safw_bmic_identify(struct aac_dev *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1767) struct aac_ciss_identify_pd **identify_resp, u32 bus, u32 target)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1768) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1769) int rcode = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1770) int datasize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1771) struct aac_srb_unit srbu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1772) struct aac_srb *srbcmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1773) struct aac_ciss_identify_pd *identify_reply;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1774)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1775) datasize = sizeof(struct aac_ciss_identify_pd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1776) identify_reply = kmalloc(datasize, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1777) if (!identify_reply)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1778) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1779)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1780) memset(&srbu, 0, sizeof(struct aac_srb_unit));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1781)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1782) srbcmd = &srbu.srb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1783) srbcmd->flags = cpu_to_le32(SRB_DataIn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1784) srbcmd->cdb[0] = 0x26;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1785) srbcmd->cdb[2] = (u8)((AAC_MAX_LUN + target) & 0x00FF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1786) srbcmd->cdb[6] = CISS_IDENTIFY_PHYSICAL_DEVICE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1787)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1788) rcode = aac_send_safw_bmic_cmd(dev, &srbu, identify_reply, datasize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1789) if (unlikely(rcode < 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1790) goto mem_free_all;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1791)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1792) *identify_resp = identify_reply;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1793)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1794) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1795) return rcode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1796) mem_free_all:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1797) kfree(identify_reply);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1798) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1799) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1800)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1801) static inline void aac_free_safw_ciss_luns(struct aac_dev *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1802) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1803) kfree(dev->safw_phys_luns);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1804) dev->safw_phys_luns = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1805) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1806)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1807) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1808) * aac_get_safw_ciss_luns() Process topology change
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1809) * @dev: aac_dev structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1810) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1811) * Execute a CISS REPORT PHYS LUNS and process the results into
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1812) * the current hba_map.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1813) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1814) static int aac_get_safw_ciss_luns(struct aac_dev *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1815) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1816) int rcode = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1817) int datasize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1818) struct aac_srb *srbcmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1819) struct aac_srb_unit srbu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1820) struct aac_ciss_phys_luns_resp *phys_luns;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1821)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1822) datasize = sizeof(struct aac_ciss_phys_luns_resp) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1823) (AAC_MAX_TARGETS - 1) * sizeof(struct _ciss_lun);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1824) phys_luns = kmalloc(datasize, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1825) if (phys_luns == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1826) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1827)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1828) memset(&srbu, 0, sizeof(struct aac_srb_unit));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1829)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1830) srbcmd = &srbu.srb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1831) srbcmd->flags = cpu_to_le32(SRB_DataIn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1832) srbcmd->cdb[0] = CISS_REPORT_PHYSICAL_LUNS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1833) srbcmd->cdb[1] = 2; /* extended reporting */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1834) srbcmd->cdb[8] = (u8)(datasize >> 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1835) srbcmd->cdb[9] = (u8)(datasize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1836)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1837) rcode = aac_send_safw_bmic_cmd(dev, &srbu, phys_luns, datasize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1838) if (unlikely(rcode < 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1839) goto mem_free_all;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1840)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1841) if (phys_luns->resp_flag != 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1842) rcode = -ENOMSG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1843) goto mem_free_all;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1844) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1845)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1846) dev->safw_phys_luns = phys_luns;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1847)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1848) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1849) return rcode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1850) mem_free_all:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1851) kfree(phys_luns);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1852) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1853) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1854)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1855) static inline u32 aac_get_safw_phys_lun_count(struct aac_dev *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1856) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1857) return get_unaligned_be32(&dev->safw_phys_luns->list_length[0])/24;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1858) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1859)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1860) static inline u32 aac_get_safw_phys_bus(struct aac_dev *dev, int lun)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1861) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1862) return dev->safw_phys_luns->lun[lun].level2[1] & 0x3f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1863) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1864)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1865) static inline u32 aac_get_safw_phys_target(struct aac_dev *dev, int lun)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1866) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1867) return dev->safw_phys_luns->lun[lun].level2[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1868) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1869)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1870) static inline u32 aac_get_safw_phys_expose_flag(struct aac_dev *dev, int lun)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1871) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1872) return dev->safw_phys_luns->lun[lun].bus >> 6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1873) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1874)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1875) static inline u32 aac_get_safw_phys_attribs(struct aac_dev *dev, int lun)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1876) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1877) return dev->safw_phys_luns->lun[lun].node_ident[9];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1878) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1879)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1880) static inline u32 aac_get_safw_phys_nexus(struct aac_dev *dev, int lun)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1881) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1882) return *((u32 *)&dev->safw_phys_luns->lun[lun].node_ident[12]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1883) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1884)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1885) static inline u32 aac_get_safw_phys_device_type(struct aac_dev *dev, int lun)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1886) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1887) return dev->safw_phys_luns->lun[lun].node_ident[8];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1888) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1889)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1890) static inline void aac_free_safw_identify_resp(struct aac_dev *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1891) int bus, int target)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1892) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1893) kfree(dev->hba_map[bus][target].safw_identify_resp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1894) dev->hba_map[bus][target].safw_identify_resp = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1895) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1896)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1897) static inline void aac_free_safw_all_identify_resp(struct aac_dev *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1898) int lun_count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1899) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1900) int luns;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1901) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1902) u32 bus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1903) u32 target;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1904)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1905) luns = aac_get_safw_phys_lun_count(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1906)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1907) if (luns < lun_count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1908) lun_count = luns;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1909) else if (lun_count < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1910) lun_count = luns;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1911)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1912) for (i = 0; i < lun_count; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1913) bus = aac_get_safw_phys_bus(dev, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1914) target = aac_get_safw_phys_target(dev, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1915)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1916) aac_free_safw_identify_resp(dev, bus, target);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1917) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1918) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1919)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1920) static int aac_get_safw_attr_all_targets(struct aac_dev *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1921) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1922) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1923) int rcode = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1924) u32 lun_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1925) u32 bus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1926) u32 target;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1927) struct aac_ciss_identify_pd *identify_resp = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1928)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1929) lun_count = aac_get_safw_phys_lun_count(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1930)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1931) for (i = 0; i < lun_count; ++i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1932)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1933) bus = aac_get_safw_phys_bus(dev, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1934) target = aac_get_safw_phys_target(dev, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1935)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1936) rcode = aac_issue_safw_bmic_identify(dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1937) &identify_resp, bus, target);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1938)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1939) if (unlikely(rcode < 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1940) goto free_identify_resp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1941)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1942) dev->hba_map[bus][target].safw_identify_resp = identify_resp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1943) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1944)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1945) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1946) return rcode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1947) free_identify_resp:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1948) aac_free_safw_all_identify_resp(dev, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1949) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1950) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1951)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1952) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1953) * aac_set_safw_attr_all_targets- update current hba map with data from FW
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1954) * @dev: aac_dev structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1955) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1956) * Update our hba map with the information gathered from the FW
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1957) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1958) static void aac_set_safw_attr_all_targets(struct aac_dev *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1959) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1960) /* ok and extended reporting */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1961) u32 lun_count, nexus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1962) u32 i, bus, target;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1963) u8 expose_flag, attribs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1964)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1965) lun_count = aac_get_safw_phys_lun_count(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1966)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1967) dev->scan_counter++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1968)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1969) for (i = 0; i < lun_count; ++i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1970)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1971) bus = aac_get_safw_phys_bus(dev, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1972) target = aac_get_safw_phys_target(dev, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1973) expose_flag = aac_get_safw_phys_expose_flag(dev, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1974) attribs = aac_get_safw_phys_attribs(dev, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1975) nexus = aac_get_safw_phys_nexus(dev, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1976)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1977) if (bus >= AAC_MAX_BUSES || target >= AAC_MAX_TARGETS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1978) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1979)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1980) if (expose_flag != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1981) dev->hba_map[bus][target].devtype =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1982) AAC_DEVTYPE_RAID_MEMBER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1983) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1984) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1985)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1986) if (nexus != 0 && (attribs & 8)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1987) dev->hba_map[bus][target].devtype =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1988) AAC_DEVTYPE_NATIVE_RAW;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1989) dev->hba_map[bus][target].rmw_nexus =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1990) nexus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1991) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1992) dev->hba_map[bus][target].devtype =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1993) AAC_DEVTYPE_ARC_RAW;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1994)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1995) dev->hba_map[bus][target].scan_counter = dev->scan_counter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1996)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1997) aac_set_safw_target_qd(dev, bus, target);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1998) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1999) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2001) static int aac_setup_safw_targets(struct aac_dev *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2002) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2003) int rcode = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2004)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2005) rcode = aac_get_containers(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2006) if (unlikely(rcode < 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2007) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2008)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2009) rcode = aac_get_safw_ciss_luns(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2010) if (unlikely(rcode < 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2011) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2012)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2013) rcode = aac_get_safw_attr_all_targets(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2014) if (unlikely(rcode < 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2015) goto free_ciss_luns;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2016)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2017) aac_set_safw_attr_all_targets(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2018)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2019) aac_free_safw_all_identify_resp(dev, -1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2020) free_ciss_luns:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2021) aac_free_safw_ciss_luns(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2022) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2023) return rcode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2024) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2025)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2026) int aac_setup_safw_adapter(struct aac_dev *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2027) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2028) return aac_setup_safw_targets(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2029) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2030)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2031) int aac_get_adapter_info(struct aac_dev* dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2032) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2033) struct fib* fibptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2034) int rcode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2035) u32 tmp, bus, target;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2036) struct aac_adapter_info *info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2037) struct aac_bus_info *command;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2038) struct aac_bus_info_response *bus_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2039)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2040) if (!(fibptr = aac_fib_alloc(dev)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2041) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2042)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2043) aac_fib_init(fibptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2044) info = (struct aac_adapter_info *) fib_data(fibptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2045) memset(info,0,sizeof(*info));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2046)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2047) rcode = aac_fib_send(RequestAdapterInfo,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2048) fibptr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2049) sizeof(*info),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2050) FsaNormal,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2051) -1, 1, /* First `interrupt' command uses special wait */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2052) NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2053) NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2054)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2055) if (rcode < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2056) /* FIB should be freed only after
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2057) * getting the response from the F/W */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2058) if (rcode != -ERESTARTSYS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2059) aac_fib_complete(fibptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2060) aac_fib_free(fibptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2061) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2062) return rcode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2063) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2064) memcpy(&dev->adapter_info, info, sizeof(*info));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2065)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2066) dev->supplement_adapter_info.virt_device_bus = 0xffff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2067) if (dev->adapter_info.options & AAC_OPT_SUPPLEMENT_ADAPTER_INFO) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2068) struct aac_supplement_adapter_info * sinfo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2069)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2070) aac_fib_init(fibptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2071)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2072) sinfo = (struct aac_supplement_adapter_info *) fib_data(fibptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2073)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2074) memset(sinfo,0,sizeof(*sinfo));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2075)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2076) rcode = aac_fib_send(RequestSupplementAdapterInfo,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2077) fibptr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2078) sizeof(*sinfo),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2079) FsaNormal,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2080) 1, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2081) NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2082) NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2083)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2084) if (rcode >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2085) memcpy(&dev->supplement_adapter_info, sinfo, sizeof(*sinfo));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2086) if (rcode == -ERESTARTSYS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2087) fibptr = aac_fib_alloc(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2088) if (!fibptr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2089) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2090) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2091)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2092) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2093)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2094) /* reset all previous mapped devices (i.e. for init. after IOP_RESET) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2095) for (bus = 0; bus < AAC_MAX_BUSES; bus++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2096) for (target = 0; target < AAC_MAX_TARGETS; target++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2097) dev->hba_map[bus][target].devtype = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2098) dev->hba_map[bus][target].qd_limit = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2099) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2100) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2102) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2103) * GetBusInfo
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2104) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2106) aac_fib_init(fibptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2108) bus_info = (struct aac_bus_info_response *) fib_data(fibptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2109)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2110) memset(bus_info, 0, sizeof(*bus_info));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2112) command = (struct aac_bus_info *)bus_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2114) command->Command = cpu_to_le32(VM_Ioctl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2115) command->ObjType = cpu_to_le32(FT_DRIVE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2116) command->MethodId = cpu_to_le32(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2117) command->CtlCmd = cpu_to_le32(GetBusInfo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2119) rcode = aac_fib_send(ContainerCommand,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2120) fibptr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2121) sizeof (*bus_info),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2122) FsaNormal,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2123) 1, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2124) NULL, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2126) /* reasoned default */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2127) dev->maximum_num_physicals = 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2128) if (rcode >= 0 && le32_to_cpu(bus_info->Status) == ST_OK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2129) dev->maximum_num_physicals = le32_to_cpu(bus_info->TargetsPerBus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2130) dev->maximum_num_channels = le32_to_cpu(bus_info->BusCount);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2131) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2133) if (!dev->in_reset) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2134) char buffer[16];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2135) tmp = le32_to_cpu(dev->adapter_info.kernelrev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2136) printk(KERN_INFO "%s%d: kernel %d.%d-%d[%d] %.*s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2137) dev->name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2138) dev->id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2139) tmp>>24,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2140) (tmp>>16)&0xff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2141) tmp&0xff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2142) le32_to_cpu(dev->adapter_info.kernelbuild),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2143) (int)sizeof(dev->supplement_adapter_info.build_date),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2144) dev->supplement_adapter_info.build_date);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2145) tmp = le32_to_cpu(dev->adapter_info.monitorrev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2146) printk(KERN_INFO "%s%d: monitor %d.%d-%d[%d]\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2147) dev->name, dev->id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2148) tmp>>24,(tmp>>16)&0xff,tmp&0xff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2149) le32_to_cpu(dev->adapter_info.monitorbuild));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2150) tmp = le32_to_cpu(dev->adapter_info.biosrev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2151) printk(KERN_INFO "%s%d: bios %d.%d-%d[%d]\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2152) dev->name, dev->id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2153) tmp>>24,(tmp>>16)&0xff,tmp&0xff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2154) le32_to_cpu(dev->adapter_info.biosbuild));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2155) buffer[0] = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2156) if (aac_get_serial_number(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2157) shost_to_class(dev->scsi_host_ptr), buffer))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2158) printk(KERN_INFO "%s%d: serial %s",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2159) dev->name, dev->id, buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2160) if (dev->supplement_adapter_info.vpd_info.tsid[0]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2161) printk(KERN_INFO "%s%d: TSID %.*s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2162) dev->name, dev->id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2163) (int)sizeof(dev->supplement_adapter_info
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2164) .vpd_info.tsid),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2165) dev->supplement_adapter_info.vpd_info.tsid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2166) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2167) if (!aac_check_reset || ((aac_check_reset == 1) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2168) (dev->supplement_adapter_info.supported_options2 &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2169) AAC_OPTION_IGNORE_RESET))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2170) printk(KERN_INFO "%s%d: Reset Adapter Ignored\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2171) dev->name, dev->id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2172) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2173) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2174)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2175) dev->cache_protected = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2176) dev->jbod = ((dev->supplement_adapter_info.feature_bits &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2177) AAC_FEATURE_JBOD) != 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2178) dev->nondasd_support = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2179) dev->raid_scsi_mode = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2180) if(dev->adapter_info.options & AAC_OPT_NONDASD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2181) dev->nondasd_support = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2182)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2183) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2184) * If the firmware supports ROMB RAID/SCSI mode and we are currently
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2185) * in RAID/SCSI mode, set the flag. For now if in this mode we will
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2186) * force nondasd support on. If we decide to allow the non-dasd flag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2187) * additional changes changes will have to be made to support
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2188) * RAID/SCSI. the function aac_scsi_cmd in this module will have to be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2189) * changed to support the new dev->raid_scsi_mode flag instead of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2190) * leaching off of the dev->nondasd_support flag. Also in linit.c the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2191) * function aac_detect will have to be modified where it sets up the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2192) * max number of channels based on the aac->nondasd_support flag only.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2193) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2194) if ((dev->adapter_info.options & AAC_OPT_SCSI_MANAGED) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2195) (dev->adapter_info.options & AAC_OPT_RAID_SCSI_MODE)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2196) dev->nondasd_support = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2197) dev->raid_scsi_mode = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2198) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2199) if (dev->raid_scsi_mode != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2200) printk(KERN_INFO "%s%d: ROMB RAID/SCSI mode enabled\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2201) dev->name, dev->id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2202)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2203) if (nondasd != -1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2204) dev->nondasd_support = (nondasd!=0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2205) if (dev->nondasd_support && !dev->in_reset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2206) printk(KERN_INFO "%s%d: Non-DASD support enabled.\n",dev->name, dev->id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2207)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2208) if (dma_get_required_mask(&dev->pdev->dev) > DMA_BIT_MASK(32))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2209) dev->needs_dac = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2210) dev->dac_support = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2211) if ((sizeof(dma_addr_t) > 4) && dev->needs_dac &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2212) (dev->adapter_info.options & AAC_OPT_SGMAP_HOST64)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2213) if (!dev->in_reset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2214) printk(KERN_INFO "%s%d: 64bit support enabled.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2215) dev->name, dev->id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2216) dev->dac_support = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2217) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2218)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2219) if(dacmode != -1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2220) dev->dac_support = (dacmode!=0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2221) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2222)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2223) /* avoid problems with AAC_QUIRK_SCSI_32 controllers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2224) if (dev->dac_support && (aac_get_driver_ident(dev->cardtype)->quirks
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2225) & AAC_QUIRK_SCSI_32)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2226) dev->nondasd_support = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2227) dev->jbod = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2228) expose_physicals = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2229) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2230)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2231) if (dev->dac_support) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2232) if (!dma_set_mask(&dev->pdev->dev, DMA_BIT_MASK(64))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2233) if (!dev->in_reset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2234) dev_info(&dev->pdev->dev, "64 Bit DAC enabled\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2235) } else if (!dma_set_mask(&dev->pdev->dev, DMA_BIT_MASK(32))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2236) dev_info(&dev->pdev->dev, "DMA mask set failed, 64 Bit DAC disabled\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2237) dev->dac_support = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2238) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2239) dev_info(&dev->pdev->dev, "No suitable DMA available\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2240) rcode = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2241) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2242) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2243) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2244) * Deal with configuring for the individualized limits of each packet
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2245) * interface.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2246) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2247) dev->a_ops.adapter_scsi = (dev->dac_support)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2248) ? ((aac_get_driver_ident(dev->cardtype)->quirks & AAC_QUIRK_SCSI_32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2249) ? aac_scsi_32_64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2250) : aac_scsi_64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2251) : aac_scsi_32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2252) if (dev->raw_io_interface) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2253) dev->a_ops.adapter_bounds = (dev->raw_io_64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2254) ? aac_bounds_64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2255) : aac_bounds_32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2256) dev->a_ops.adapter_read = aac_read_raw_io;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2257) dev->a_ops.adapter_write = aac_write_raw_io;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2258) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2259) dev->a_ops.adapter_bounds = aac_bounds_32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2260) dev->scsi_host_ptr->sg_tablesize = (dev->max_fib_size -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2261) sizeof(struct aac_fibhdr) -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2262) sizeof(struct aac_write) + sizeof(struct sgentry)) /
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2263) sizeof(struct sgentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2264) if (dev->dac_support) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2265) dev->a_ops.adapter_read = aac_read_block64;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2266) dev->a_ops.adapter_write = aac_write_block64;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2267) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2268) * 38 scatter gather elements
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2269) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2270) dev->scsi_host_ptr->sg_tablesize =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2271) (dev->max_fib_size -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2272) sizeof(struct aac_fibhdr) -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2273) sizeof(struct aac_write64) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2274) sizeof(struct sgentry64)) /
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2275) sizeof(struct sgentry64);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2276) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2277) dev->a_ops.adapter_read = aac_read_block;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2278) dev->a_ops.adapter_write = aac_write_block;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2279) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2280) dev->scsi_host_ptr->max_sectors = AAC_MAX_32BIT_SGBCOUNT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2281) if (!(dev->adapter_info.options & AAC_OPT_NEW_COMM)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2282) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2283) * Worst case size that could cause sg overflow when
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2284) * we break up SG elements that are larger than 64KB.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2285) * Would be nice if we could tell the SCSI layer what
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2286) * the maximum SG element size can be. Worst case is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2287) * (sg_tablesize-1) 4KB elements with one 64KB
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2288) * element.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2289) * 32bit -> 468 or 238KB 64bit -> 424 or 212KB
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2290) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2291) dev->scsi_host_ptr->max_sectors =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2292) (dev->scsi_host_ptr->sg_tablesize * 8) + 112;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2293) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2294) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2295) if (!dev->sync_mode && dev->sa_firmware &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2296) dev->scsi_host_ptr->sg_tablesize > HBA_MAX_SG_SEPARATE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2297) dev->scsi_host_ptr->sg_tablesize = dev->sg_tablesize =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2298) HBA_MAX_SG_SEPARATE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2299)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2300) /* FIB should be freed only after getting the response from the F/W */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2301) if (rcode != -ERESTARTSYS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2302) aac_fib_complete(fibptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2303) aac_fib_free(fibptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2304) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2305)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2306) return rcode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2307) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2308)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2309)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2310) static void io_callback(void *context, struct fib * fibptr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2311) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2312) struct aac_dev *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2313) struct aac_read_reply *readreply;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2314) struct scsi_cmnd *scsicmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2315) u32 cid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2316)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2317) scsicmd = (struct scsi_cmnd *) context;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2318)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2319) if (!aac_valid_context(scsicmd, fibptr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2320) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2321)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2322) dev = fibptr->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2323) cid = scmd_id(scsicmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2324)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2325) if (nblank(dprintk(x))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2326) u64 lba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2327) switch (scsicmd->cmnd[0]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2328) case WRITE_6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2329) case READ_6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2330) lba = ((scsicmd->cmnd[1] & 0x1F) << 16) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2331) (scsicmd->cmnd[2] << 8) | scsicmd->cmnd[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2332) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2333) case WRITE_16:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2334) case READ_16:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2335) lba = ((u64)scsicmd->cmnd[2] << 56) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2336) ((u64)scsicmd->cmnd[3] << 48) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2337) ((u64)scsicmd->cmnd[4] << 40) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2338) ((u64)scsicmd->cmnd[5] << 32) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2339) ((u64)scsicmd->cmnd[6] << 24) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2340) (scsicmd->cmnd[7] << 16) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2341) (scsicmd->cmnd[8] << 8) | scsicmd->cmnd[9];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2342) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2343) case WRITE_12:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2344) case READ_12:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2345) lba = ((u64)scsicmd->cmnd[2] << 24) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2346) (scsicmd->cmnd[3] << 16) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2347) (scsicmd->cmnd[4] << 8) | scsicmd->cmnd[5];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2348) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2349) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2350) lba = ((u64)scsicmd->cmnd[2] << 24) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2351) (scsicmd->cmnd[3] << 16) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2352) (scsicmd->cmnd[4] << 8) | scsicmd->cmnd[5];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2353) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2354) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2355) printk(KERN_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2356) "io_callback[cpu %d]: lba = %llu, t = %ld.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2357) smp_processor_id(), (unsigned long long)lba, jiffies);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2358) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2359)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2360) BUG_ON(fibptr == NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2361)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2362) scsi_dma_unmap(scsicmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2363)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2364) readreply = (struct aac_read_reply *)fib_data(fibptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2365) switch (le32_to_cpu(readreply->status)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2366) case ST_OK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2367) scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2368) SAM_STAT_GOOD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2369) dev->fsa_dev[cid].sense_data.sense_key = NO_SENSE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2370) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2371) case ST_NOT_READY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2372) scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2373) SAM_STAT_CHECK_CONDITION;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2374) set_sense(&dev->fsa_dev[cid].sense_data, NOT_READY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2375) SENCODE_BECOMING_READY, ASENCODE_BECOMING_READY, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2376) memcpy(scsicmd->sense_buffer, &dev->fsa_dev[cid].sense_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2377) min_t(size_t, sizeof(dev->fsa_dev[cid].sense_data),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2378) SCSI_SENSE_BUFFERSIZE));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2379) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2380) case ST_MEDERR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2381) scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2382) SAM_STAT_CHECK_CONDITION;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2383) set_sense(&dev->fsa_dev[cid].sense_data, MEDIUM_ERROR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2384) SENCODE_UNRECOVERED_READ_ERROR, ASENCODE_NO_SENSE, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2385) memcpy(scsicmd->sense_buffer, &dev->fsa_dev[cid].sense_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2386) min_t(size_t, sizeof(dev->fsa_dev[cid].sense_data),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2387) SCSI_SENSE_BUFFERSIZE));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2388) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2389) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2390) #ifdef AAC_DETAILED_STATUS_INFO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2391) printk(KERN_WARNING "io_callback: io failed, status = %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2392) le32_to_cpu(readreply->status));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2393) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2394) scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2395) SAM_STAT_CHECK_CONDITION;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2396) set_sense(&dev->fsa_dev[cid].sense_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2397) HARDWARE_ERROR, SENCODE_INTERNAL_TARGET_FAILURE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2398) ASENCODE_INTERNAL_TARGET_FAILURE, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2399) memcpy(scsicmd->sense_buffer, &dev->fsa_dev[cid].sense_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2400) min_t(size_t, sizeof(dev->fsa_dev[cid].sense_data),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2401) SCSI_SENSE_BUFFERSIZE));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2402) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2403) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2404) aac_fib_complete(fibptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2405)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2406) scsicmd->scsi_done(scsicmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2407) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2408)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2409) static int aac_read(struct scsi_cmnd * scsicmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2410) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2411) u64 lba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2412) u32 count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2413) int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2414) struct aac_dev *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2415) struct fib * cmd_fibcontext;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2416) int cid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2417)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2418) dev = (struct aac_dev *)scsicmd->device->host->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2419) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2420) * Get block address and transfer length
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2421) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2422) switch (scsicmd->cmnd[0]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2423) case READ_6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2424) dprintk((KERN_DEBUG "aachba: received a read(6) command on id %d.\n", scmd_id(scsicmd)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2425)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2426) lba = ((scsicmd->cmnd[1] & 0x1F) << 16) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2427) (scsicmd->cmnd[2] << 8) | scsicmd->cmnd[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2428) count = scsicmd->cmnd[4];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2429)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2430) if (count == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2431) count = 256;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2432) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2433) case READ_16:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2434) dprintk((KERN_DEBUG "aachba: received a read(16) command on id %d.\n", scmd_id(scsicmd)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2435)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2436) lba = ((u64)scsicmd->cmnd[2] << 56) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2437) ((u64)scsicmd->cmnd[3] << 48) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2438) ((u64)scsicmd->cmnd[4] << 40) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2439) ((u64)scsicmd->cmnd[5] << 32) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2440) ((u64)scsicmd->cmnd[6] << 24) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2441) (scsicmd->cmnd[7] << 16) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2442) (scsicmd->cmnd[8] << 8) | scsicmd->cmnd[9];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2443) count = (scsicmd->cmnd[10] << 24) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2444) (scsicmd->cmnd[11] << 16) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2445) (scsicmd->cmnd[12] << 8) | scsicmd->cmnd[13];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2446) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2447) case READ_12:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2448) dprintk((KERN_DEBUG "aachba: received a read(12) command on id %d.\n", scmd_id(scsicmd)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2449)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2450) lba = ((u64)scsicmd->cmnd[2] << 24) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2451) (scsicmd->cmnd[3] << 16) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2452) (scsicmd->cmnd[4] << 8) | scsicmd->cmnd[5];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2453) count = (scsicmd->cmnd[6] << 24) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2454) (scsicmd->cmnd[7] << 16) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2455) (scsicmd->cmnd[8] << 8) | scsicmd->cmnd[9];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2456) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2457) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2458) dprintk((KERN_DEBUG "aachba: received a read(10) command on id %d.\n", scmd_id(scsicmd)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2459)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2460) lba = ((u64)scsicmd->cmnd[2] << 24) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2461) (scsicmd->cmnd[3] << 16) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2462) (scsicmd->cmnd[4] << 8) | scsicmd->cmnd[5];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2463) count = (scsicmd->cmnd[7] << 8) | scsicmd->cmnd[8];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2464) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2465) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2466)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2467) if ((lba + count) > (dev->fsa_dev[scmd_id(scsicmd)].size)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2468) cid = scmd_id(scsicmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2469) dprintk((KERN_DEBUG "aacraid: Illegal lba\n"));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2470) scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2471) SAM_STAT_CHECK_CONDITION;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2472) set_sense(&dev->fsa_dev[cid].sense_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2473) ILLEGAL_REQUEST, SENCODE_LBA_OUT_OF_RANGE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2474) ASENCODE_INTERNAL_TARGET_FAILURE, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2475) memcpy(scsicmd->sense_buffer, &dev->fsa_dev[cid].sense_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2476) min_t(size_t, sizeof(dev->fsa_dev[cid].sense_data),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2477) SCSI_SENSE_BUFFERSIZE));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2478) scsicmd->scsi_done(scsicmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2479) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2480) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2481)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2482) dprintk((KERN_DEBUG "aac_read[cpu %d]: lba = %llu, t = %ld.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2483) smp_processor_id(), (unsigned long long)lba, jiffies));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2484) if (aac_adapter_bounds(dev,scsicmd,lba))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2485) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2486) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2487) * Alocate and initialize a Fib
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2488) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2489) cmd_fibcontext = aac_fib_alloc_tag(dev, scsicmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2490) scsicmd->SCp.phase = AAC_OWNER_FIRMWARE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2491) status = aac_adapter_read(cmd_fibcontext, scsicmd, lba, count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2492)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2493) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2494) * Check that the command queued to the controller
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2495) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2496) if (status == -EINPROGRESS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2497) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2498)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2499) printk(KERN_WARNING "aac_read: aac_fib_send failed with status: %d.\n", status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2500) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2501) * For some reason, the Fib didn't queue, return QUEUE_FULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2502) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2503) scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_TASK_SET_FULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2504) scsicmd->scsi_done(scsicmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2505) aac_fib_complete(cmd_fibcontext);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2506) aac_fib_free(cmd_fibcontext);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2507) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2508) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2509)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2510) static int aac_write(struct scsi_cmnd * scsicmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2511) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2512) u64 lba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2513) u32 count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2514) int fua;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2515) int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2516) struct aac_dev *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2517) struct fib * cmd_fibcontext;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2518) int cid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2519)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2520) dev = (struct aac_dev *)scsicmd->device->host->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2521) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2522) * Get block address and transfer length
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2523) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2524) if (scsicmd->cmnd[0] == WRITE_6) /* 6 byte command */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2525) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2526) lba = ((scsicmd->cmnd[1] & 0x1F) << 16) | (scsicmd->cmnd[2] << 8) | scsicmd->cmnd[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2527) count = scsicmd->cmnd[4];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2528) if (count == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2529) count = 256;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2530) fua = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2531) } else if (scsicmd->cmnd[0] == WRITE_16) { /* 16 byte command */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2532) dprintk((KERN_DEBUG "aachba: received a write(16) command on id %d.\n", scmd_id(scsicmd)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2533)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2534) lba = ((u64)scsicmd->cmnd[2] << 56) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2535) ((u64)scsicmd->cmnd[3] << 48) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2536) ((u64)scsicmd->cmnd[4] << 40) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2537) ((u64)scsicmd->cmnd[5] << 32) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2538) ((u64)scsicmd->cmnd[6] << 24) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2539) (scsicmd->cmnd[7] << 16) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2540) (scsicmd->cmnd[8] << 8) | scsicmd->cmnd[9];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2541) count = (scsicmd->cmnd[10] << 24) | (scsicmd->cmnd[11] << 16) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2542) (scsicmd->cmnd[12] << 8) | scsicmd->cmnd[13];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2543) fua = scsicmd->cmnd[1] & 0x8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2544) } else if (scsicmd->cmnd[0] == WRITE_12) { /* 12 byte command */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2545) dprintk((KERN_DEBUG "aachba: received a write(12) command on id %d.\n", scmd_id(scsicmd)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2546)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2547) lba = ((u64)scsicmd->cmnd[2] << 24) | (scsicmd->cmnd[3] << 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2548) | (scsicmd->cmnd[4] << 8) | scsicmd->cmnd[5];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2549) count = (scsicmd->cmnd[6] << 24) | (scsicmd->cmnd[7] << 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2550) | (scsicmd->cmnd[8] << 8) | scsicmd->cmnd[9];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2551) fua = scsicmd->cmnd[1] & 0x8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2552) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2553) dprintk((KERN_DEBUG "aachba: received a write(10) command on id %d.\n", scmd_id(scsicmd)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2554) lba = ((u64)scsicmd->cmnd[2] << 24) | (scsicmd->cmnd[3] << 16) | (scsicmd->cmnd[4] << 8) | scsicmd->cmnd[5];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2555) count = (scsicmd->cmnd[7] << 8) | scsicmd->cmnd[8];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2556) fua = scsicmd->cmnd[1] & 0x8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2557) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2558)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2559) if ((lba + count) > (dev->fsa_dev[scmd_id(scsicmd)].size)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2560) cid = scmd_id(scsicmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2561) dprintk((KERN_DEBUG "aacraid: Illegal lba\n"));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2562) scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2563) SAM_STAT_CHECK_CONDITION;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2564) set_sense(&dev->fsa_dev[cid].sense_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2565) ILLEGAL_REQUEST, SENCODE_LBA_OUT_OF_RANGE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2566) ASENCODE_INTERNAL_TARGET_FAILURE, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2567) memcpy(scsicmd->sense_buffer, &dev->fsa_dev[cid].sense_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2568) min_t(size_t, sizeof(dev->fsa_dev[cid].sense_data),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2569) SCSI_SENSE_BUFFERSIZE));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2570) scsicmd->scsi_done(scsicmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2571) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2572) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2573)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2574) dprintk((KERN_DEBUG "aac_write[cpu %d]: lba = %llu, t = %ld.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2575) smp_processor_id(), (unsigned long long)lba, jiffies));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2576) if (aac_adapter_bounds(dev,scsicmd,lba))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2577) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2578) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2579) * Allocate and initialize a Fib then setup a BlockWrite command
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2580) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2581) cmd_fibcontext = aac_fib_alloc_tag(dev, scsicmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2582) scsicmd->SCp.phase = AAC_OWNER_FIRMWARE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2583) status = aac_adapter_write(cmd_fibcontext, scsicmd, lba, count, fua);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2584)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2585) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2586) * Check that the command queued to the controller
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2587) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2588) if (status == -EINPROGRESS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2589) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2590)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2591) printk(KERN_WARNING "aac_write: aac_fib_send failed with status: %d\n", status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2592) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2593) * For some reason, the Fib didn't queue, return QUEUE_FULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2594) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2595) scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_TASK_SET_FULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2596) scsicmd->scsi_done(scsicmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2597)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2598) aac_fib_complete(cmd_fibcontext);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2599) aac_fib_free(cmd_fibcontext);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2600) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2601) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2602)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2603) static void synchronize_callback(void *context, struct fib *fibptr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2604) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2605) struct aac_synchronize_reply *synchronizereply;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2606) struct scsi_cmnd *cmd = context;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2607)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2608) if (!aac_valid_context(cmd, fibptr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2609) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2610)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2611) dprintk((KERN_DEBUG "synchronize_callback[cpu %d]: t = %ld.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2612) smp_processor_id(), jiffies));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2613) BUG_ON(fibptr == NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2614)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2615)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2616) synchronizereply = fib_data(fibptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2617) if (le32_to_cpu(synchronizereply->status) == CT_OK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2618) cmd->result = DID_OK << 16 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2619) COMMAND_COMPLETE << 8 | SAM_STAT_GOOD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2620) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2621) struct scsi_device *sdev = cmd->device;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2622) struct aac_dev *dev = fibptr->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2623) u32 cid = sdev_id(sdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2624) printk(KERN_WARNING
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2625) "synchronize_callback: synchronize failed, status = %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2626) le32_to_cpu(synchronizereply->status));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2627) cmd->result = DID_OK << 16 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2628) COMMAND_COMPLETE << 8 | SAM_STAT_CHECK_CONDITION;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2629) set_sense(&dev->fsa_dev[cid].sense_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2630) HARDWARE_ERROR, SENCODE_INTERNAL_TARGET_FAILURE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2631) ASENCODE_INTERNAL_TARGET_FAILURE, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2632) memcpy(cmd->sense_buffer, &dev->fsa_dev[cid].sense_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2633) min_t(size_t, sizeof(dev->fsa_dev[cid].sense_data),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2634) SCSI_SENSE_BUFFERSIZE));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2635) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2636)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2637) aac_fib_complete(fibptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2638) aac_fib_free(fibptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2639) cmd->scsi_done(cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2640) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2641)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2642) static int aac_synchronize(struct scsi_cmnd *scsicmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2643) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2644) int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2645) struct fib *cmd_fibcontext;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2646) struct aac_synchronize *synchronizecmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2647) struct scsi_device *sdev = scsicmd->device;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2648) struct aac_dev *aac;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2649)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2650) aac = (struct aac_dev *)sdev->host->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2651) if (aac->in_reset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2652) return SCSI_MLQUEUE_HOST_BUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2653)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2654) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2655) * Allocate and initialize a Fib
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2656) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2657) cmd_fibcontext = aac_fib_alloc_tag(aac, scsicmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2658)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2659) aac_fib_init(cmd_fibcontext);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2660)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2661) synchronizecmd = fib_data(cmd_fibcontext);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2662) synchronizecmd->command = cpu_to_le32(VM_ContainerConfig);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2663) synchronizecmd->type = cpu_to_le32(CT_FLUSH_CACHE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2664) synchronizecmd->cid = cpu_to_le32(scmd_id(scsicmd));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2665) synchronizecmd->count =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2666) cpu_to_le32(sizeof(((struct aac_synchronize_reply *)NULL)->data));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2667) scsicmd->SCp.phase = AAC_OWNER_FIRMWARE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2668)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2669) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2670) * Now send the Fib to the adapter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2671) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2672) status = aac_fib_send(ContainerCommand,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2673) cmd_fibcontext,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2674) sizeof(struct aac_synchronize),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2675) FsaNormal,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2676) 0, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2677) (fib_callback)synchronize_callback,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2678) (void *)scsicmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2679)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2680) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2681) * Check that the command queued to the controller
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2682) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2683) if (status == -EINPROGRESS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2684) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2685)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2686) printk(KERN_WARNING
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2687) "aac_synchronize: aac_fib_send failed with status: %d.\n", status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2688) aac_fib_complete(cmd_fibcontext);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2689) aac_fib_free(cmd_fibcontext);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2690) return SCSI_MLQUEUE_HOST_BUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2691) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2692)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2693) static void aac_start_stop_callback(void *context, struct fib *fibptr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2694) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2695) struct scsi_cmnd *scsicmd = context;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2696)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2697) if (!aac_valid_context(scsicmd, fibptr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2698) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2699)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2700) BUG_ON(fibptr == NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2701)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2702) scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2703)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2704) aac_fib_complete(fibptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2705) aac_fib_free(fibptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2706) scsicmd->scsi_done(scsicmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2707) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2708)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2709) static int aac_start_stop(struct scsi_cmnd *scsicmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2710) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2711) int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2712) struct fib *cmd_fibcontext;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2713) struct aac_power_management *pmcmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2714) struct scsi_device *sdev = scsicmd->device;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2715) struct aac_dev *aac = (struct aac_dev *)sdev->host->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2716)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2717) if (!(aac->supplement_adapter_info.supported_options2 &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2718) AAC_OPTION_POWER_MANAGEMENT)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2719) scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2720) SAM_STAT_GOOD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2721) scsicmd->scsi_done(scsicmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2722) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2723) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2724)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2725) if (aac->in_reset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2726) return SCSI_MLQUEUE_HOST_BUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2727)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2728) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2729) * Allocate and initialize a Fib
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2730) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2731) cmd_fibcontext = aac_fib_alloc_tag(aac, scsicmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2732)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2733) aac_fib_init(cmd_fibcontext);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2734)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2735) pmcmd = fib_data(cmd_fibcontext);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2736) pmcmd->command = cpu_to_le32(VM_ContainerConfig);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2737) pmcmd->type = cpu_to_le32(CT_POWER_MANAGEMENT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2738) /* Eject bit ignored, not relevant */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2739) pmcmd->sub = (scsicmd->cmnd[4] & 1) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2740) cpu_to_le32(CT_PM_START_UNIT) : cpu_to_le32(CT_PM_STOP_UNIT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2741) pmcmd->cid = cpu_to_le32(sdev_id(sdev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2742) pmcmd->parm = (scsicmd->cmnd[1] & 1) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2743) cpu_to_le32(CT_PM_UNIT_IMMEDIATE) : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2744) scsicmd->SCp.phase = AAC_OWNER_FIRMWARE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2745)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2746) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2747) * Now send the Fib to the adapter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2748) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2749) status = aac_fib_send(ContainerCommand,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2750) cmd_fibcontext,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2751) sizeof(struct aac_power_management),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2752) FsaNormal,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2753) 0, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2754) (fib_callback)aac_start_stop_callback,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2755) (void *)scsicmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2756)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2757) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2758) * Check that the command queued to the controller
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2759) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2760) if (status == -EINPROGRESS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2761) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2762)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2763) aac_fib_complete(cmd_fibcontext);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2764) aac_fib_free(cmd_fibcontext);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2765) return SCSI_MLQUEUE_HOST_BUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2766) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2767)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2768) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2769) * aac_scsi_cmd() - Process SCSI command
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2770) * @scsicmd: SCSI command block
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2771) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2772) * Emulate a SCSI command and queue the required request for the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2773) * aacraid firmware.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2774) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2775)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2776) int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2777) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2778) u32 cid, bus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2779) struct Scsi_Host *host = scsicmd->device->host;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2780) struct aac_dev *dev = (struct aac_dev *)host->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2781) struct fsa_dev_info *fsa_dev_ptr = dev->fsa_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2782)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2783) if (fsa_dev_ptr == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2784) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2785) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2786) * If the bus, id or lun is out of range, return fail
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2787) * Test does not apply to ID 16, the pseudo id for the controller
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2788) * itself.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2789) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2790) cid = scmd_id(scsicmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2791) if (cid != host->this_id) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2792) if (scmd_channel(scsicmd) == CONTAINER_CHANNEL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2793) if((cid >= dev->maximum_num_containers) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2794) (scsicmd->device->lun != 0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2795) scsicmd->result = DID_NO_CONNECT << 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2796) goto scsi_done_ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2797) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2798)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2799) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2800) * If the target container doesn't exist, it may have
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2801) * been newly created
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2802) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2803) if (((fsa_dev_ptr[cid].valid & 1) == 0) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2804) (fsa_dev_ptr[cid].sense_data.sense_key ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2805) NOT_READY)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2806) switch (scsicmd->cmnd[0]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2807) case SERVICE_ACTION_IN_16:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2808) if (!(dev->raw_io_interface) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2809) !(dev->raw_io_64) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2810) ((scsicmd->cmnd[1] & 0x1f) != SAI_READ_CAPACITY_16))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2811) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2812) fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2813) case INQUIRY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2814) case READ_CAPACITY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2815) case TEST_UNIT_READY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2816) if (dev->in_reset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2817) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2818) return _aac_probe_container(scsicmd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2819) aac_probe_container_callback2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2820) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2821) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2822) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2823) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2824) } else { /* check for physical non-dasd devices */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2825) bus = aac_logical_to_phys(scmd_channel(scsicmd));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2826)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2827) if (bus < AAC_MAX_BUSES && cid < AAC_MAX_TARGETS &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2828) dev->hba_map[bus][cid].devtype
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2829) == AAC_DEVTYPE_NATIVE_RAW) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2830) if (dev->in_reset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2831) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2832) return aac_send_hba_fib(scsicmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2833) } else if (dev->nondasd_support || expose_physicals ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2834) dev->jbod) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2835) if (dev->in_reset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2836) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2837) return aac_send_srb_fib(scsicmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2838) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2839) scsicmd->result = DID_NO_CONNECT << 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2840) goto scsi_done_ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2841) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2842) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2843) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2844) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2845) * else Command for the controller itself
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2846) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2847) else if ((scsicmd->cmnd[0] != INQUIRY) && /* only INQUIRY & TUR cmnd supported for controller */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2848) (scsicmd->cmnd[0] != TEST_UNIT_READY))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2849) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2850) dprintk((KERN_WARNING "Only INQUIRY & TUR command supported for controller, rcvd = 0x%x.\n", scsicmd->cmnd[0]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2851) scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_CHECK_CONDITION;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2852) set_sense(&dev->fsa_dev[cid].sense_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2853) ILLEGAL_REQUEST, SENCODE_INVALID_COMMAND,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2854) ASENCODE_INVALID_COMMAND, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2855) memcpy(scsicmd->sense_buffer, &dev->fsa_dev[cid].sense_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2856) min_t(size_t, sizeof(dev->fsa_dev[cid].sense_data),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2857) SCSI_SENSE_BUFFERSIZE));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2858) goto scsi_done_ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2859) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2860)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2861) switch (scsicmd->cmnd[0]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2862) case READ_6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2863) case READ_10:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2864) case READ_12:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2865) case READ_16:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2866) if (dev->in_reset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2867) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2868) return aac_read(scsicmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2869)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2870) case WRITE_6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2871) case WRITE_10:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2872) case WRITE_12:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2873) case WRITE_16:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2874) if (dev->in_reset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2875) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2876) return aac_write(scsicmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2877)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2878) case SYNCHRONIZE_CACHE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2879) if (((aac_cache & 6) == 6) && dev->cache_protected) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2880) scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2881) SAM_STAT_GOOD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2882) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2883) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2884) /* Issue FIB to tell Firmware to flush it's cache */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2885) if ((aac_cache & 6) != 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2886) return aac_synchronize(scsicmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2887) fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2888) case INQUIRY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2889) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2890) struct inquiry_data inq_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2891)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2892) dprintk((KERN_DEBUG "INQUIRY command, ID: %d.\n", cid));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2893) memset(&inq_data, 0, sizeof (struct inquiry_data));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2894)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2895) if ((scsicmd->cmnd[1] & 0x1) && aac_wwn) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2896) char *arr = (char *)&inq_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2897)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2898) /* EVPD bit set */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2899) arr[0] = (scmd_id(scsicmd) == host->this_id) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2900) INQD_PDT_PROC : INQD_PDT_DA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2901) if (scsicmd->cmnd[2] == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2902) /* supported vital product data pages */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2903) arr[3] = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2904) arr[4] = 0x0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2905) arr[5] = 0x80;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2906) arr[6] = 0x83;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2907) arr[1] = scsicmd->cmnd[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2908) scsi_sg_copy_from_buffer(scsicmd, &inq_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2909) sizeof(inq_data));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2910) scsicmd->result = DID_OK << 16 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2911) COMMAND_COMPLETE << 8 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2912) SAM_STAT_GOOD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2913) } else if (scsicmd->cmnd[2] == 0x80) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2914) /* unit serial number page */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2915) arr[3] = setinqserial(dev, &arr[4],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2916) scmd_id(scsicmd));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2917) arr[1] = scsicmd->cmnd[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2918) scsi_sg_copy_from_buffer(scsicmd, &inq_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2919) sizeof(inq_data));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2920) if (aac_wwn != 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2921) return aac_get_container_serial(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2922) scsicmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2923) scsicmd->result = DID_OK << 16 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2924) COMMAND_COMPLETE << 8 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2925) SAM_STAT_GOOD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2926) } else if (scsicmd->cmnd[2] == 0x83) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2927) /* vpd page 0x83 - Device Identification Page */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2928) char *sno = (char *)&inq_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2929) sno[3] = setinqserial(dev, &sno[4],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2930) scmd_id(scsicmd));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2931) if (aac_wwn != 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2932) return aac_get_container_serial(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2933) scsicmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2934) scsicmd->result = DID_OK << 16 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2935) COMMAND_COMPLETE << 8 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2936) SAM_STAT_GOOD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2937) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2938) /* vpd page not implemented */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2939) scsicmd->result = DID_OK << 16 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2940) COMMAND_COMPLETE << 8 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2941) SAM_STAT_CHECK_CONDITION;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2942) set_sense(&dev->fsa_dev[cid].sense_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2943) ILLEGAL_REQUEST, SENCODE_INVALID_CDB_FIELD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2944) ASENCODE_NO_SENSE, 7, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2945) memcpy(scsicmd->sense_buffer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2946) &dev->fsa_dev[cid].sense_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2947) min_t(size_t,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2948) sizeof(dev->fsa_dev[cid].sense_data),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2949) SCSI_SENSE_BUFFERSIZE));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2950) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2951) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2952) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2953) inq_data.inqd_ver = 2; /* claim compliance to SCSI-2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2954) 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 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2955) inq_data.inqd_len = 31;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2956) /*Format for "pad2" is RelAdr | WBus32 | WBus16 | Sync | Linked |Reserved| CmdQue | SftRe */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2957) inq_data.inqd_pad2= 0x32 ; /*WBus16|Sync|CmdQue */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2958) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2959) * Set the Vendor, Product, and Revision Level
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2960) * see: <vendor>.c i.e. aac.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2961) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2962) if (cid == host->this_id) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2963) setinqstr(dev, (void *) (inq_data.inqd_vid), ARRAY_SIZE(container_types));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2964) inq_data.inqd_pdt = INQD_PDT_PROC; /* Processor device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2965) scsi_sg_copy_from_buffer(scsicmd, &inq_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2966) sizeof(inq_data));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2967) scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2968) SAM_STAT_GOOD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2969) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2970) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2971) if (dev->in_reset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2972) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2973) setinqstr(dev, (void *) (inq_data.inqd_vid), fsa_dev_ptr[cid].type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2974) inq_data.inqd_pdt = INQD_PDT_DA; /* Direct/random access device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2975) scsi_sg_copy_from_buffer(scsicmd, &inq_data, sizeof(inq_data));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2976) return aac_get_container_name(scsicmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2977) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2978) case SERVICE_ACTION_IN_16:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2979) if (!(dev->raw_io_interface) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2980) !(dev->raw_io_64) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2981) ((scsicmd->cmnd[1] & 0x1f) != SAI_READ_CAPACITY_16))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2982) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2983) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2984) u64 capacity;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2985) char cp[13];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2986) unsigned int alloc_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2987)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2988) dprintk((KERN_DEBUG "READ CAPACITY_16 command.\n"));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2989) capacity = fsa_dev_ptr[cid].size - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2990) cp[0] = (capacity >> 56) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2991) cp[1] = (capacity >> 48) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2992) cp[2] = (capacity >> 40) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2993) cp[3] = (capacity >> 32) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2994) cp[4] = (capacity >> 24) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2995) cp[5] = (capacity >> 16) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2996) cp[6] = (capacity >> 8) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2997) cp[7] = (capacity >> 0) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2998) cp[8] = (fsa_dev_ptr[cid].block_size >> 24) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2999) cp[9] = (fsa_dev_ptr[cid].block_size >> 16) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3000) cp[10] = (fsa_dev_ptr[cid].block_size >> 8) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3001) cp[11] = (fsa_dev_ptr[cid].block_size) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3002) cp[12] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3003)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3004) alloc_len = ((scsicmd->cmnd[10] << 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3005) + (scsicmd->cmnd[11] << 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3006) + (scsicmd->cmnd[12] << 8) + scsicmd->cmnd[13]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3007)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3008) alloc_len = min_t(size_t, alloc_len, sizeof(cp));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3009) scsi_sg_copy_from_buffer(scsicmd, cp, alloc_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3010) if (alloc_len < scsi_bufflen(scsicmd))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3011) scsi_set_resid(scsicmd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3012) scsi_bufflen(scsicmd) - alloc_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3013)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3014) /* Do not cache partition table for arrays */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3015) scsicmd->device->removable = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3016)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3017) scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3018) SAM_STAT_GOOD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3019) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3020) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3021)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3022) case READ_CAPACITY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3023) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3024) u32 capacity;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3025) char cp[8];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3026)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3027) dprintk((KERN_DEBUG "READ CAPACITY command.\n"));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3028) if (fsa_dev_ptr[cid].size <= 0x100000000ULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3029) capacity = fsa_dev_ptr[cid].size - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3030) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3031) capacity = (u32)-1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3032)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3033) cp[0] = (capacity >> 24) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3034) cp[1] = (capacity >> 16) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3035) cp[2] = (capacity >> 8) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3036) cp[3] = (capacity >> 0) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3037) cp[4] = (fsa_dev_ptr[cid].block_size >> 24) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3038) cp[5] = (fsa_dev_ptr[cid].block_size >> 16) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3039) cp[6] = (fsa_dev_ptr[cid].block_size >> 8) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3040) cp[7] = (fsa_dev_ptr[cid].block_size) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3041) scsi_sg_copy_from_buffer(scsicmd, cp, sizeof(cp));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3042) /* Do not cache partition table for arrays */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3043) scsicmd->device->removable = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3044) scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3045) SAM_STAT_GOOD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3046) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3047) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3048)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3049) case MODE_SENSE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3050) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3051) int mode_buf_length = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3052) u32 capacity;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3053) aac_modep_data mpd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3054)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3055) if (fsa_dev_ptr[cid].size <= 0x100000000ULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3056) capacity = fsa_dev_ptr[cid].size - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3057) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3058) capacity = (u32)-1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3059)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3060) dprintk((KERN_DEBUG "MODE SENSE command.\n"));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3061) memset((char *)&mpd, 0, sizeof(aac_modep_data));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3062)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3063) /* Mode data length */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3064) mpd.hd.data_length = sizeof(mpd.hd) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3065) /* Medium type - default */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3066) mpd.hd.med_type = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3067) /* Device-specific param,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3068) bit 8: 0/1 = write enabled/protected
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3069) bit 4: 0/1 = FUA enabled */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3070) mpd.hd.dev_par = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3071)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3072) if (dev->raw_io_interface && ((aac_cache & 5) != 1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3073) mpd.hd.dev_par = 0x10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3074) if (scsicmd->cmnd[1] & 0x8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3075) mpd.hd.bd_length = 0; /* Block descriptor length */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3076) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3077) mpd.hd.bd_length = sizeof(mpd.bd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3078) mpd.hd.data_length += mpd.hd.bd_length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3079) mpd.bd.block_length[0] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3080) (fsa_dev_ptr[cid].block_size >> 16) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3081) mpd.bd.block_length[1] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3082) (fsa_dev_ptr[cid].block_size >> 8) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3083) mpd.bd.block_length[2] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3084) fsa_dev_ptr[cid].block_size & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3085)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3086) mpd.mpc_buf[0] = scsicmd->cmnd[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3087) if (scsicmd->cmnd[2] == 0x1C) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3088) /* page length */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3089) mpd.mpc_buf[1] = 0xa;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3090) /* Mode data length */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3091) mpd.hd.data_length = 23;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3092) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3093) /* Mode data length */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3094) mpd.hd.data_length = 15;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3095) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3096)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3097) if (capacity > 0xffffff) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3098) mpd.bd.block_count[0] = 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3099) mpd.bd.block_count[1] = 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3100) mpd.bd.block_count[2] = 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3101) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3102) mpd.bd.block_count[0] = (capacity >> 16) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3103) mpd.bd.block_count[1] = (capacity >> 8) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3104) mpd.bd.block_count[2] = capacity & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3105) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3106) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3107) if (((scsicmd->cmnd[2] & 0x3f) == 8) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3108) ((scsicmd->cmnd[2] & 0x3f) == 0x3f)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3109) mpd.hd.data_length += 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3110) mpd.mpc_buf[0] = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3111) mpd.mpc_buf[1] = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3112) mpd.mpc_buf[2] = ((aac_cache & 6) == 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3113) ? 0 : 0x04; /* WCE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3114) mode_buf_length = sizeof(mpd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3115) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3117) if (mode_buf_length > scsicmd->cmnd[4])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3118) mode_buf_length = scsicmd->cmnd[4];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3119) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3120) mode_buf_length = sizeof(mpd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3121) scsi_sg_copy_from_buffer(scsicmd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3122) (char *)&mpd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3123) mode_buf_length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3124) scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3125) SAM_STAT_GOOD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3126) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3127) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3128) case MODE_SENSE_10:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3129) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3130) u32 capacity;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3131) int mode_buf_length = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3132) aac_modep10_data mpd10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3133)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3134) if (fsa_dev_ptr[cid].size <= 0x100000000ULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3135) capacity = fsa_dev_ptr[cid].size - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3136) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3137) capacity = (u32)-1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3139) dprintk((KERN_DEBUG "MODE SENSE 10 byte command.\n"));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3140) memset((char *)&mpd10, 0, sizeof(aac_modep10_data));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3141) /* Mode data length (MSB) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3142) mpd10.hd.data_length[0] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3143) /* Mode data length (LSB) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3144) mpd10.hd.data_length[1] = sizeof(mpd10.hd) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3145) /* Medium type - default */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3146) mpd10.hd.med_type = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3147) /* Device-specific param,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3148) bit 8: 0/1 = write enabled/protected
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3149) bit 4: 0/1 = FUA enabled */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3150) mpd10.hd.dev_par = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3151)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3152) if (dev->raw_io_interface && ((aac_cache & 5) != 1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3153) mpd10.hd.dev_par = 0x10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3154) mpd10.hd.rsrvd[0] = 0; /* reserved */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3155) mpd10.hd.rsrvd[1] = 0; /* reserved */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3156) if (scsicmd->cmnd[1] & 0x8) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3157) /* Block descriptor length (MSB) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3158) mpd10.hd.bd_length[0] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3159) /* Block descriptor length (LSB) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3160) mpd10.hd.bd_length[1] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3161) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3162) mpd10.hd.bd_length[0] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3163) mpd10.hd.bd_length[1] = sizeof(mpd10.bd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3164)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3165) mpd10.hd.data_length[1] += mpd10.hd.bd_length[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3166)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3167) mpd10.bd.block_length[0] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3168) (fsa_dev_ptr[cid].block_size >> 16) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3169) mpd10.bd.block_length[1] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3170) (fsa_dev_ptr[cid].block_size >> 8) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3171) mpd10.bd.block_length[2] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3172) fsa_dev_ptr[cid].block_size & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3174) if (capacity > 0xffffff) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3175) mpd10.bd.block_count[0] = 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3176) mpd10.bd.block_count[1] = 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3177) mpd10.bd.block_count[2] = 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3178) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3179) mpd10.bd.block_count[0] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3180) (capacity >> 16) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3181) mpd10.bd.block_count[1] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3182) (capacity >> 8) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3183) mpd10.bd.block_count[2] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3184) capacity & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3185) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3186) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3187) if (((scsicmd->cmnd[2] & 0x3f) == 8) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3188) ((scsicmd->cmnd[2] & 0x3f) == 0x3f)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3189) mpd10.hd.data_length[1] += 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3190) mpd10.mpc_buf[0] = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3191) mpd10.mpc_buf[1] = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3192) mpd10.mpc_buf[2] = ((aac_cache & 6) == 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3193) ? 0 : 0x04; /* WCE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3194) mode_buf_length = sizeof(mpd10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3195) if (mode_buf_length > scsicmd->cmnd[8])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3196) mode_buf_length = scsicmd->cmnd[8];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3197) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3198) scsi_sg_copy_from_buffer(scsicmd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3199) (char *)&mpd10,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3200) mode_buf_length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3201)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3202) scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3203) SAM_STAT_GOOD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3204) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3205) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3206) case REQUEST_SENSE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3207) dprintk((KERN_DEBUG "REQUEST SENSE command.\n"));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3208) memcpy(scsicmd->sense_buffer, &dev->fsa_dev[cid].sense_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3209) sizeof(struct sense_data));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3210) memset(&dev->fsa_dev[cid].sense_data, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3211) sizeof(struct sense_data));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3212) scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3213) SAM_STAT_GOOD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3214) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3215)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3216) case ALLOW_MEDIUM_REMOVAL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3217) dprintk((KERN_DEBUG "LOCK command.\n"));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3218) if (scsicmd->cmnd[4])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3219) fsa_dev_ptr[cid].locked = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3220) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3221) fsa_dev_ptr[cid].locked = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3222)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3223) scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3224) SAM_STAT_GOOD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3225) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3226) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3227) * These commands are all No-Ops
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3228) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3229) case TEST_UNIT_READY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3230) if (fsa_dev_ptr[cid].sense_data.sense_key == NOT_READY) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3231) scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3232) SAM_STAT_CHECK_CONDITION;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3233) set_sense(&dev->fsa_dev[cid].sense_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3234) NOT_READY, SENCODE_BECOMING_READY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3235) ASENCODE_BECOMING_READY, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3236) memcpy(scsicmd->sense_buffer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3237) &dev->fsa_dev[cid].sense_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3238) min_t(size_t,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3239) sizeof(dev->fsa_dev[cid].sense_data),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3240) SCSI_SENSE_BUFFERSIZE));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3241) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3242) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3243) fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3244) case RESERVE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3245) case RELEASE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3246) case REZERO_UNIT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3247) case REASSIGN_BLOCKS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3248) case SEEK_10:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3249) scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3250) SAM_STAT_GOOD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3251) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3253) case START_STOP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3254) return aac_start_stop(scsicmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3256) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3257) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3258) * Unhandled commands
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3259) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3260) dprintk((KERN_WARNING "Unhandled SCSI Command: 0x%x.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3261) scsicmd->cmnd[0]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3262) scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3263) SAM_STAT_CHECK_CONDITION;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3264) set_sense(&dev->fsa_dev[cid].sense_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3265) ILLEGAL_REQUEST, SENCODE_INVALID_COMMAND,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3266) ASENCODE_INVALID_COMMAND, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3267) memcpy(scsicmd->sense_buffer, &dev->fsa_dev[cid].sense_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3268) min_t(size_t,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3269) sizeof(dev->fsa_dev[cid].sense_data),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3270) SCSI_SENSE_BUFFERSIZE));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3271) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3272)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3273) scsi_done_ret:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3274)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3275) scsicmd->scsi_done(scsicmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3276) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3277) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3278)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3279) static int query_disk(struct aac_dev *dev, void __user *arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3280) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3281) struct aac_query_disk qd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3282) struct fsa_dev_info *fsa_dev_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3283)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3284) fsa_dev_ptr = dev->fsa_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3285) if (!fsa_dev_ptr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3286) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3287) if (copy_from_user(&qd, arg, sizeof (struct aac_query_disk)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3288) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3289) if (qd.cnum == -1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3290) if (qd.id < 0 || qd.id >= dev->maximum_num_containers)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3291) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3292) qd.cnum = qd.id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3293) } else if ((qd.bus == -1) && (qd.id == -1) && (qd.lun == -1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3294) if (qd.cnum < 0 || qd.cnum >= dev->maximum_num_containers)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3295) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3296) qd.instance = dev->scsi_host_ptr->host_no;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3297) qd.bus = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3298) qd.id = CONTAINER_TO_ID(qd.cnum);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3299) qd.lun = CONTAINER_TO_LUN(qd.cnum);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3300) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3301) else return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3302)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3303) qd.valid = fsa_dev_ptr[qd.cnum].valid != 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3304) qd.locked = fsa_dev_ptr[qd.cnum].locked;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3305) qd.deleted = fsa_dev_ptr[qd.cnum].deleted;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3306)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3307) if (fsa_dev_ptr[qd.cnum].devname[0] == '\0')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3308) qd.unmapped = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3309) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3310) qd.unmapped = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3311)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3312) strlcpy(qd.name, fsa_dev_ptr[qd.cnum].devname,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3313) min(sizeof(qd.name), sizeof(fsa_dev_ptr[qd.cnum].devname) + 1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3314)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3315) if (copy_to_user(arg, &qd, sizeof (struct aac_query_disk)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3316) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3317) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3318) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3319)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3320) static int force_delete_disk(struct aac_dev *dev, void __user *arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3321) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3322) struct aac_delete_disk dd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3323) struct fsa_dev_info *fsa_dev_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3324)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3325) fsa_dev_ptr = dev->fsa_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3326) if (!fsa_dev_ptr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3327) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3328)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3329) if (copy_from_user(&dd, arg, sizeof (struct aac_delete_disk)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3330) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3331)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3332) if (dd.cnum >= dev->maximum_num_containers)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3333) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3334) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3335) * Mark this container as being deleted.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3336) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3337) fsa_dev_ptr[dd.cnum].deleted = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3338) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3339) * Mark the container as no longer valid
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3340) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3341) fsa_dev_ptr[dd.cnum].valid = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3342) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3343) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3344)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3345) static int delete_disk(struct aac_dev *dev, void __user *arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3346) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3347) struct aac_delete_disk dd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3348) struct fsa_dev_info *fsa_dev_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3349)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3350) fsa_dev_ptr = dev->fsa_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3351) if (!fsa_dev_ptr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3352) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3353)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3354) if (copy_from_user(&dd, arg, sizeof (struct aac_delete_disk)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3355) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3356)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3357) if (dd.cnum >= dev->maximum_num_containers)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3358) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3359) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3360) * If the container is locked, it can not be deleted by the API.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3361) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3362) if (fsa_dev_ptr[dd.cnum].locked)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3363) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3364) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3365) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3366) * Mark the container as no longer being valid.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3367) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3368) fsa_dev_ptr[dd.cnum].valid = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3369) fsa_dev_ptr[dd.cnum].devname[0] = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3370) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3371) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3372) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3373)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3374) int aac_dev_ioctl(struct aac_dev *dev, unsigned int cmd, void __user *arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3375) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3376) switch (cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3377) case FSACTL_QUERY_DISK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3378) return query_disk(dev, arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3379) case FSACTL_DELETE_DISK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3380) return delete_disk(dev, arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3381) case FSACTL_FORCE_DELETE_DISK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3382) return force_delete_disk(dev, arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3383) case FSACTL_GET_CONTAINERS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3384) return aac_get_containers(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3385) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3386) return -ENOTTY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3387) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3388) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3389)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3390) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3391) * aac_srb_callback
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3392) * @context: the context set in the fib - here it is scsi cmd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3393) * @fibptr: pointer to the fib
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3394) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3395) * Handles the completion of a scsi command to a non dasd device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3396) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3397) static void aac_srb_callback(void *context, struct fib * fibptr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3398) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3399) struct aac_srb_reply *srbreply;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3400) struct scsi_cmnd *scsicmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3401)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3402) scsicmd = (struct scsi_cmnd *) context;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3403)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3404) if (!aac_valid_context(scsicmd, fibptr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3405) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3406)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3407) BUG_ON(fibptr == NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3408)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3409) srbreply = (struct aac_srb_reply *) fib_data(fibptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3410)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3411) scsicmd->sense_buffer[0] = '\0'; /* Initialize sense valid flag to false */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3412)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3413) if (fibptr->flags & FIB_CONTEXT_FLAG_FASTRESP) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3414) /* fast response */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3415) srbreply->srb_status = cpu_to_le32(SRB_STATUS_SUCCESS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3416) srbreply->scsi_status = cpu_to_le32(SAM_STAT_GOOD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3417) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3418) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3419) * Calculate resid for sg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3420) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3421) scsi_set_resid(scsicmd, scsi_bufflen(scsicmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3422) - le32_to_cpu(srbreply->data_xfer_length));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3423) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3424)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3425)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3426) scsi_dma_unmap(scsicmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3427)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3428) /* expose physical device if expose_physicald flag is on */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3429) if (scsicmd->cmnd[0] == INQUIRY && !(scsicmd->cmnd[1] & 0x01)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3430) && expose_physicals > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3431) aac_expose_phy_device(scsicmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3432)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3433) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3434) * First check the fib status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3435) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3436)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3437) if (le32_to_cpu(srbreply->status) != ST_OK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3438) int len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3439)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3440) pr_warn("aac_srb_callback: srb failed, status = %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3441) le32_to_cpu(srbreply->status));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3442) len = min_t(u32, le32_to_cpu(srbreply->sense_data_size),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3443) SCSI_SENSE_BUFFERSIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3444) scsicmd->result = DID_ERROR << 16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3445) | COMMAND_COMPLETE << 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3446) | SAM_STAT_CHECK_CONDITION;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3447) memcpy(scsicmd->sense_buffer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3448) srbreply->sense_data, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3449) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3450)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3451) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3452) * Next check the srb status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3453) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3454) switch ((le32_to_cpu(srbreply->srb_status))&0x3f) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3455) case SRB_STATUS_ERROR_RECOVERY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3456) case SRB_STATUS_PENDING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3457) case SRB_STATUS_SUCCESS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3458) scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3459) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3460) case SRB_STATUS_DATA_OVERRUN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3461) switch (scsicmd->cmnd[0]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3462) case READ_6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3463) case WRITE_6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3464) case READ_10:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3465) case WRITE_10:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3466) case READ_12:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3467) case WRITE_12:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3468) case READ_16:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3469) case WRITE_16:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3470) if (le32_to_cpu(srbreply->data_xfer_length)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3471) < scsicmd->underflow)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3472) pr_warn("aacraid: SCSI CMD underflow\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3473) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3474) pr_warn("aacraid: SCSI CMD Data Overrun\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3475) scsicmd->result = DID_ERROR << 16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3476) | COMMAND_COMPLETE << 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3477) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3478) case INQUIRY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3479) scsicmd->result = DID_OK << 16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3480) | COMMAND_COMPLETE << 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3481) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3482) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3483) scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3484) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3485) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3486) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3487) case SRB_STATUS_ABORTED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3488) scsicmd->result = DID_ABORT << 16 | ABORT << 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3489) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3490) case SRB_STATUS_ABORT_FAILED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3491) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3492) * Not sure about this one - but assuming the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3493) * hba was trying to abort for some reason
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3494) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3495) scsicmd->result = DID_ERROR << 16 | ABORT << 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3496) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3497) case SRB_STATUS_PARITY_ERROR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3498) scsicmd->result = DID_PARITY << 16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3499) | MSG_PARITY_ERROR << 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3500) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3501) case SRB_STATUS_NO_DEVICE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3502) case SRB_STATUS_INVALID_PATH_ID:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3503) case SRB_STATUS_INVALID_TARGET_ID:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3504) case SRB_STATUS_INVALID_LUN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3505) case SRB_STATUS_SELECTION_TIMEOUT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3506) scsicmd->result = DID_NO_CONNECT << 16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3507) | COMMAND_COMPLETE << 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3508) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3509)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3510) case SRB_STATUS_COMMAND_TIMEOUT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3511) case SRB_STATUS_TIMEOUT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3512) scsicmd->result = DID_TIME_OUT << 16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3513) | COMMAND_COMPLETE << 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3514) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3515)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3516) case SRB_STATUS_BUSY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3517) scsicmd->result = DID_BUS_BUSY << 16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3518) | COMMAND_COMPLETE << 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3519) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3520)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3521) case SRB_STATUS_BUS_RESET:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3522) scsicmd->result = DID_RESET << 16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3523) | COMMAND_COMPLETE << 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3524) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3525)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3526) case SRB_STATUS_MESSAGE_REJECTED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3527) scsicmd->result = DID_ERROR << 16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3528) | MESSAGE_REJECT << 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3529) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3530) case SRB_STATUS_REQUEST_FLUSHED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3531) case SRB_STATUS_ERROR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3532) case SRB_STATUS_INVALID_REQUEST:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3533) case SRB_STATUS_REQUEST_SENSE_FAILED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3534) case SRB_STATUS_NO_HBA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3535) case SRB_STATUS_UNEXPECTED_BUS_FREE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3536) case SRB_STATUS_PHASE_SEQUENCE_FAILURE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3537) case SRB_STATUS_BAD_SRB_BLOCK_LENGTH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3538) case SRB_STATUS_DELAYED_RETRY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3539) case SRB_STATUS_BAD_FUNCTION:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3540) case SRB_STATUS_NOT_STARTED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3541) case SRB_STATUS_NOT_IN_USE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3542) case SRB_STATUS_FORCE_ABORT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3543) case SRB_STATUS_DOMAIN_VALIDATION_FAIL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3544) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3545) #ifdef AAC_DETAILED_STATUS_INFO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3546) pr_info("aacraid: SRB ERROR(%u) %s scsi cmd 0x%x -scsi status 0x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3547) le32_to_cpu(srbreply->srb_status) & 0x3F,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3548) aac_get_status_string(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3549) le32_to_cpu(srbreply->srb_status) & 0x3F),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3550) scsicmd->cmnd[0],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3551) le32_to_cpu(srbreply->scsi_status));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3552) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3553) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3554) * When the CC bit is SET by the host in ATA pass thru CDB,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3555) * driver is supposed to return DID_OK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3556) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3557) * When the CC bit is RESET by the host, driver should
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3558) * return DID_ERROR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3559) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3560) if ((scsicmd->cmnd[0] == ATA_12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3561) || (scsicmd->cmnd[0] == ATA_16)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3562)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3563) if (scsicmd->cmnd[2] & (0x01 << 5)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3564) scsicmd->result = DID_OK << 16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3565) | COMMAND_COMPLETE << 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3566) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3567) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3568) scsicmd->result = DID_ERROR << 16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3569) | COMMAND_COMPLETE << 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3570) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3571) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3572) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3573) scsicmd->result = DID_ERROR << 16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3574) | COMMAND_COMPLETE << 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3575) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3576) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3577) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3578) if (le32_to_cpu(srbreply->scsi_status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3579) == SAM_STAT_CHECK_CONDITION) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3580) int len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3581)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3582) scsicmd->result |= SAM_STAT_CHECK_CONDITION;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3583) len = min_t(u32, le32_to_cpu(srbreply->sense_data_size),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3584) SCSI_SENSE_BUFFERSIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3585) #ifdef AAC_DETAILED_STATUS_INFO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3586) pr_warn("aac_srb_callback: check condition, status = %d len=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3587) le32_to_cpu(srbreply->status), len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3588) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3589) memcpy(scsicmd->sense_buffer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3590) srbreply->sense_data, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3591) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3592)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3593) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3594) * OR in the scsi status (already shifted up a bit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3595) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3596) scsicmd->result |= le32_to_cpu(srbreply->scsi_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3597)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3598) aac_fib_complete(fibptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3599) scsicmd->scsi_done(scsicmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3600) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3601)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3602) static void hba_resp_task_complete(struct aac_dev *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3603) struct scsi_cmnd *scsicmd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3604) struct aac_hba_resp *err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3605)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3606) scsicmd->result = err->status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3607) /* set residual count */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3608) scsi_set_resid(scsicmd, le32_to_cpu(err->residual_count));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3609)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3610) switch (err->status) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3611) case SAM_STAT_GOOD:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3612) scsicmd->result |= DID_OK << 16 | COMMAND_COMPLETE << 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3613) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3614) case SAM_STAT_CHECK_CONDITION:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3615) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3616) int len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3617)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3618) len = min_t(u8, err->sense_response_data_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3619) SCSI_SENSE_BUFFERSIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3620) if (len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3621) memcpy(scsicmd->sense_buffer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3622) err->sense_response_buf, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3623) scsicmd->result |= DID_OK << 16 | COMMAND_COMPLETE << 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3624) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3625) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3626) case SAM_STAT_BUSY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3627) scsicmd->result |= DID_BUS_BUSY << 16 | COMMAND_COMPLETE << 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3628) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3629) case SAM_STAT_TASK_ABORTED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3630) scsicmd->result |= DID_ABORT << 16 | ABORT << 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3631) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3632) case SAM_STAT_RESERVATION_CONFLICT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3633) case SAM_STAT_TASK_SET_FULL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3634) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3635) scsicmd->result |= DID_ERROR << 16 | COMMAND_COMPLETE << 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3636) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3637) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3638) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3639)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3640) static void hba_resp_task_failure(struct aac_dev *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3641) struct scsi_cmnd *scsicmd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3642) struct aac_hba_resp *err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3643) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3644) switch (err->status) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3645) case HBA_RESP_STAT_HBAMODE_DISABLED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3646) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3647) u32 bus, cid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3648)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3649) bus = aac_logical_to_phys(scmd_channel(scsicmd));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3650) cid = scmd_id(scsicmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3651) if (dev->hba_map[bus][cid].devtype == AAC_DEVTYPE_NATIVE_RAW) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3652) dev->hba_map[bus][cid].devtype = AAC_DEVTYPE_ARC_RAW;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3653) dev->hba_map[bus][cid].rmw_nexus = 0xffffffff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3654) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3655) scsicmd->result = DID_NO_CONNECT << 16 | COMMAND_COMPLETE << 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3656) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3657) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3658) case HBA_RESP_STAT_IO_ERROR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3659) case HBA_RESP_STAT_NO_PATH_TO_DEVICE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3660) scsicmd->result = DID_OK << 16 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3661) COMMAND_COMPLETE << 8 | SAM_STAT_BUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3662) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3663) case HBA_RESP_STAT_IO_ABORTED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3664) scsicmd->result = DID_ABORT << 16 | ABORT << 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3665) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3666) case HBA_RESP_STAT_INVALID_DEVICE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3667) scsicmd->result = DID_NO_CONNECT << 16 | COMMAND_COMPLETE << 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3668) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3669) case HBA_RESP_STAT_UNDERRUN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3670) /* UNDERRUN is OK */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3671) scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3672) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3673) case HBA_RESP_STAT_OVERRUN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3674) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3675) scsicmd->result = DID_ERROR << 16 | COMMAND_COMPLETE << 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3676) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3677) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3678) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3679)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3680) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3681) * aac_hba_callback
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3682) * @context: the context set in the fib - here it is scsi cmd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3683) * @fibptr: pointer to the fib
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3684) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3685) * Handles the completion of a native HBA scsi command
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3686) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3687) void aac_hba_callback(void *context, struct fib *fibptr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3688) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3689) struct aac_dev *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3690) struct scsi_cmnd *scsicmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3691)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3692) struct aac_hba_resp *err =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3693) &((struct aac_native_hba *)fibptr->hw_fib_va)->resp.err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3694)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3695) scsicmd = (struct scsi_cmnd *) context;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3696)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3697) if (!aac_valid_context(scsicmd, fibptr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3698) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3699)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3700) WARN_ON(fibptr == NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3701) dev = fibptr->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3702)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3703) if (!(fibptr->flags & FIB_CONTEXT_FLAG_NATIVE_HBA_TMF))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3704) scsi_dma_unmap(scsicmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3705)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3706) if (fibptr->flags & FIB_CONTEXT_FLAG_FASTRESP) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3707) /* fast response */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3708) scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3709) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3710) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3711)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3712) switch (err->service_response) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3713) case HBA_RESP_SVCRES_TASK_COMPLETE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3714) hba_resp_task_complete(dev, scsicmd, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3715) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3716) case HBA_RESP_SVCRES_FAILURE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3717) hba_resp_task_failure(dev, scsicmd, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3718) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3719) case HBA_RESP_SVCRES_TMF_REJECTED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3720) scsicmd->result = DID_ERROR << 16 | MESSAGE_REJECT << 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3721) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3722) case HBA_RESP_SVCRES_TMF_LUN_INVALID:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3723) scsicmd->result = DID_NO_CONNECT << 16 | COMMAND_COMPLETE << 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3724) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3725) case HBA_RESP_SVCRES_TMF_COMPLETE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3726) case HBA_RESP_SVCRES_TMF_SUCCEEDED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3727) scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3728) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3729) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3730) scsicmd->result = DID_ERROR << 16 | COMMAND_COMPLETE << 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3731) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3732) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3733)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3734) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3735) aac_fib_complete(fibptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3736)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3737) if (fibptr->flags & FIB_CONTEXT_FLAG_NATIVE_HBA_TMF)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3738) scsicmd->SCp.sent_command = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3739) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3740) scsicmd->scsi_done(scsicmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3741) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3742)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3743) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3744) * aac_send_srb_fib
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3745) * @scsicmd: the scsi command block
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3746) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3747) * This routine will form a FIB and fill in the aac_srb from the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3748) * scsicmd passed in.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3749) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3750) static int aac_send_srb_fib(struct scsi_cmnd* scsicmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3751) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3752) struct fib* cmd_fibcontext;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3753) struct aac_dev* dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3754) int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3755)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3756) dev = (struct aac_dev *)scsicmd->device->host->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3757) if (scmd_id(scsicmd) >= dev->maximum_num_physicals ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3758) scsicmd->device->lun > 7) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3759) scsicmd->result = DID_NO_CONNECT << 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3760) scsicmd->scsi_done(scsicmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3761) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3762) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3763)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3764) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3765) * Allocate and initialize a Fib then setup a BlockWrite command
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3766) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3767) cmd_fibcontext = aac_fib_alloc_tag(dev, scsicmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3768) scsicmd->SCp.phase = AAC_OWNER_FIRMWARE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3769) status = aac_adapter_scsi(cmd_fibcontext, scsicmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3770)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3771) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3772) * Check that the command queued to the controller
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3773) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3774) if (status == -EINPROGRESS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3775) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3776)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3777) printk(KERN_WARNING "aac_srb: aac_fib_send failed with status: %d\n", status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3778) aac_fib_complete(cmd_fibcontext);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3779) aac_fib_free(cmd_fibcontext);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3780)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3781) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3782) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3783)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3784) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3785) * aac_send_hba_fib
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3786) * @scsicmd: the scsi command block
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3787) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3788) * This routine will form a FIB and fill in the aac_hba_cmd_req from the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3789) * scsicmd passed in.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3790) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3791) static int aac_send_hba_fib(struct scsi_cmnd *scsicmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3792) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3793) struct fib *cmd_fibcontext;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3794) struct aac_dev *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3795) int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3796)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3797) dev = shost_priv(scsicmd->device->host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3798) if (scmd_id(scsicmd) >= dev->maximum_num_physicals ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3799) scsicmd->device->lun > AAC_MAX_LUN - 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3800) scsicmd->result = DID_NO_CONNECT << 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3801) scsicmd->scsi_done(scsicmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3802) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3803) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3804)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3805) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3806) * Allocate and initialize a Fib then setup a BlockWrite command
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3807) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3808) cmd_fibcontext = aac_fib_alloc_tag(dev, scsicmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3809) if (!cmd_fibcontext)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3810) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3811)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3812) scsicmd->SCp.phase = AAC_OWNER_FIRMWARE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3813) status = aac_adapter_hba(cmd_fibcontext, scsicmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3814)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3815) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3816) * Check that the command queued to the controller
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3817) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3818) if (status == -EINPROGRESS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3819) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3820)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3821) pr_warn("aac_hba_cmd_req: aac_fib_send failed with status: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3822) status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3823) aac_fib_complete(cmd_fibcontext);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3824) aac_fib_free(cmd_fibcontext);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3825)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3826) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3827) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3828)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3829)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3830) static long aac_build_sg(struct scsi_cmnd *scsicmd, struct sgmap *psg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3831) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3832) unsigned long byte_count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3833) int nseg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3834) struct scatterlist *sg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3835) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3836)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3837) // Get rid of old data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3838) psg->count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3839) psg->sg[0].addr = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3840) psg->sg[0].count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3841)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3842) nseg = scsi_dma_map(scsicmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3843) if (nseg <= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3844) return nseg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3845)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3846) psg->count = cpu_to_le32(nseg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3847)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3848) scsi_for_each_sg(scsicmd, sg, nseg, i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3849) psg->sg[i].addr = cpu_to_le32(sg_dma_address(sg));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3850) psg->sg[i].count = cpu_to_le32(sg_dma_len(sg));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3851) byte_count += sg_dma_len(sg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3852) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3853) /* hba wants the size to be exact */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3854) if (byte_count > scsi_bufflen(scsicmd)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3855) u32 temp = le32_to_cpu(psg->sg[i-1].count) -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3856) (byte_count - scsi_bufflen(scsicmd));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3857) psg->sg[i-1].count = cpu_to_le32(temp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3858) byte_count = scsi_bufflen(scsicmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3859) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3860) /* Check for command underflow */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3861) if (scsicmd->underflow && (byte_count < scsicmd->underflow)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3862) printk(KERN_WARNING"aacraid: cmd len %08lX cmd underflow %08X\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3863) byte_count, scsicmd->underflow);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3864) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3865)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3866) return byte_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3867) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3868)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3869)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3870) static long aac_build_sg64(struct scsi_cmnd *scsicmd, struct sgmap64 *psg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3871) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3872) unsigned long byte_count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3873) u64 addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3874) int nseg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3875) struct scatterlist *sg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3876) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3877)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3878) // Get rid of old data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3879) psg->count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3880) psg->sg[0].addr[0] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3881) psg->sg[0].addr[1] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3882) psg->sg[0].count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3883)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3884) nseg = scsi_dma_map(scsicmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3885) if (nseg <= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3886) return nseg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3887)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3888) scsi_for_each_sg(scsicmd, sg, nseg, i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3889) int count = sg_dma_len(sg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3890) addr = sg_dma_address(sg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3891) psg->sg[i].addr[0] = cpu_to_le32(addr & 0xffffffff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3892) psg->sg[i].addr[1] = cpu_to_le32(addr>>32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3893) psg->sg[i].count = cpu_to_le32(count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3894) byte_count += count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3895) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3896) psg->count = cpu_to_le32(nseg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3897) /* hba wants the size to be exact */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3898) if (byte_count > scsi_bufflen(scsicmd)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3899) u32 temp = le32_to_cpu(psg->sg[i-1].count) -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3900) (byte_count - scsi_bufflen(scsicmd));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3901) psg->sg[i-1].count = cpu_to_le32(temp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3902) byte_count = scsi_bufflen(scsicmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3903) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3904) /* Check for command underflow */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3905) if (scsicmd->underflow && (byte_count < scsicmd->underflow)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3906) printk(KERN_WARNING"aacraid: cmd len %08lX cmd underflow %08X\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3907) byte_count, scsicmd->underflow);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3908) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3909)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3910) return byte_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3911) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3912)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3913) static long aac_build_sgraw(struct scsi_cmnd *scsicmd, struct sgmapraw *psg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3914) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3915) unsigned long byte_count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3916) int nseg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3917) struct scatterlist *sg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3918) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3919)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3920) // Get rid of old data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3921) psg->count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3922) psg->sg[0].next = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3923) psg->sg[0].prev = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3924) psg->sg[0].addr[0] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3925) psg->sg[0].addr[1] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3926) psg->sg[0].count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3927) psg->sg[0].flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3928)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3929) nseg = scsi_dma_map(scsicmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3930) if (nseg <= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3931) return nseg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3932)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3933) scsi_for_each_sg(scsicmd, sg, nseg, i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3934) int count = sg_dma_len(sg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3935) u64 addr = sg_dma_address(sg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3936) psg->sg[i].next = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3937) psg->sg[i].prev = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3938) psg->sg[i].addr[1] = cpu_to_le32((u32)(addr>>32));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3939) psg->sg[i].addr[0] = cpu_to_le32((u32)(addr & 0xffffffff));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3940) psg->sg[i].count = cpu_to_le32(count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3941) psg->sg[i].flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3942) byte_count += count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3943) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3944) psg->count = cpu_to_le32(nseg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3945) /* hba wants the size to be exact */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3946) if (byte_count > scsi_bufflen(scsicmd)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3947) u32 temp = le32_to_cpu(psg->sg[i-1].count) -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3948) (byte_count - scsi_bufflen(scsicmd));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3949) psg->sg[i-1].count = cpu_to_le32(temp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3950) byte_count = scsi_bufflen(scsicmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3951) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3952) /* Check for command underflow */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3953) if (scsicmd->underflow && (byte_count < scsicmd->underflow)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3954) printk(KERN_WARNING"aacraid: cmd len %08lX cmd underflow %08X\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3955) byte_count, scsicmd->underflow);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3956) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3957)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3958) return byte_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3959) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3960)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3961) static long aac_build_sgraw2(struct scsi_cmnd *scsicmd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3962) struct aac_raw_io2 *rio2, int sg_max)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3963) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3964) unsigned long byte_count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3965) int nseg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3966) struct scatterlist *sg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3967) int i, conformable = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3968) u32 min_size = PAGE_SIZE, cur_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3969)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3970) nseg = scsi_dma_map(scsicmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3971) if (nseg <= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3972) return nseg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3973)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3974) scsi_for_each_sg(scsicmd, sg, nseg, i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3975) int count = sg_dma_len(sg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3976) u64 addr = sg_dma_address(sg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3977)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3978) BUG_ON(i >= sg_max);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3979) rio2->sge[i].addrHigh = cpu_to_le32((u32)(addr>>32));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3980) rio2->sge[i].addrLow = cpu_to_le32((u32)(addr & 0xffffffff));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3981) cur_size = cpu_to_le32(count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3982) rio2->sge[i].length = cur_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3983) rio2->sge[i].flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3984) if (i == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3985) conformable = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3986) rio2->sgeFirstSize = cur_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3987) } else if (i == 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3988) rio2->sgeNominalSize = cur_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3989) min_size = cur_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3990) } else if ((i+1) < nseg && cur_size != rio2->sgeNominalSize) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3991) conformable = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3992) if (cur_size < min_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3993) min_size = cur_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3994) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3995) byte_count += count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3996) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3997)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3998) /* hba wants the size to be exact */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3999) if (byte_count > scsi_bufflen(scsicmd)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4000) u32 temp = le32_to_cpu(rio2->sge[i-1].length) -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4001) (byte_count - scsi_bufflen(scsicmd));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4002) rio2->sge[i-1].length = cpu_to_le32(temp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4003) byte_count = scsi_bufflen(scsicmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4004) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4005)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4006) rio2->sgeCnt = cpu_to_le32(nseg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4007) rio2->flags |= cpu_to_le16(RIO2_SG_FORMAT_IEEE1212);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4008) /* not conformable: evaluate required sg elements */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4009) if (!conformable) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4010) int j, nseg_new = nseg, err_found;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4011) for (i = min_size / PAGE_SIZE; i >= 1; --i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4012) err_found = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4013) nseg_new = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4014) for (j = 1; j < nseg - 1; ++j) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4015) if (rio2->sge[j].length % (i*PAGE_SIZE)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4016) err_found = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4017) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4018) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4019) nseg_new += (rio2->sge[j].length / (i*PAGE_SIZE));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4020) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4021) if (!err_found)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4022) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4023) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4024) if (i > 0 && nseg_new <= sg_max) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4025) int ret = aac_convert_sgraw2(rio2, i, nseg, nseg_new);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4026)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4027) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4028) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4029) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4030) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4031) rio2->flags |= cpu_to_le16(RIO2_SGL_CONFORMANT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4032)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4033) /* Check for command underflow */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4034) if (scsicmd->underflow && (byte_count < scsicmd->underflow)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4035) printk(KERN_WARNING"aacraid: cmd len %08lX cmd underflow %08X\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4036) byte_count, scsicmd->underflow);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4037) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4038)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4039) return byte_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4040) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4041)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4042) static int aac_convert_sgraw2(struct aac_raw_io2 *rio2, int pages, int nseg, int nseg_new)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4043) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4044) struct sge_ieee1212 *sge;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4045) int i, j, pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4046) u32 addr_low;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4047)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4048) if (aac_convert_sgl == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4049) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4050)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4051) sge = kmalloc_array(nseg_new, sizeof(struct sge_ieee1212), GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4052) if (sge == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4053) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4054)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4055) for (i = 1, pos = 1; i < nseg-1; ++i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4056) for (j = 0; j < rio2->sge[i].length / (pages * PAGE_SIZE); ++j) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4057) addr_low = rio2->sge[i].addrLow + j * pages * PAGE_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4058) sge[pos].addrLow = addr_low;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4059) sge[pos].addrHigh = rio2->sge[i].addrHigh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4060) if (addr_low < rio2->sge[i].addrLow)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4061) sge[pos].addrHigh++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4062) sge[pos].length = pages * PAGE_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4063) sge[pos].flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4064) pos++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4065) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4066) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4067) sge[pos] = rio2->sge[nseg-1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4068) memcpy(&rio2->sge[1], &sge[1], (nseg_new-1)*sizeof(struct sge_ieee1212));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4069)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4070) kfree(sge);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4071) rio2->sgeCnt = cpu_to_le32(nseg_new);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4072) rio2->flags |= cpu_to_le16(RIO2_SGL_CONFORMANT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4073) rio2->sgeNominalSize = pages * PAGE_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4074) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4075) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4076)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4077) static long aac_build_sghba(struct scsi_cmnd *scsicmd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4078) struct aac_hba_cmd_req *hbacmd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4079) int sg_max,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4080) u64 sg_address)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4081) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4082) unsigned long byte_count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4083) int nseg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4084) struct scatterlist *sg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4085) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4086) u32 cur_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4087) struct aac_hba_sgl *sge;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4088)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4089) nseg = scsi_dma_map(scsicmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4090) if (nseg <= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4091) byte_count = nseg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4092) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4093) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4094)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4095) if (nseg > HBA_MAX_SG_EMBEDDED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4096) sge = &hbacmd->sge[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4097) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4098) sge = &hbacmd->sge[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4099)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4100) scsi_for_each_sg(scsicmd, sg, nseg, i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4101) int count = sg_dma_len(sg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4102) u64 addr = sg_dma_address(sg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4104) WARN_ON(i >= sg_max);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4105) sge->addr_hi = cpu_to_le32((u32)(addr>>32));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4106) sge->addr_lo = cpu_to_le32((u32)(addr & 0xffffffff));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4107) cur_size = cpu_to_le32(count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4108) sge->len = cur_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4109) sge->flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4110) byte_count += count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4111) sge++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4112) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4114) sge--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4115) /* hba wants the size to be exact */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4116) if (byte_count > scsi_bufflen(scsicmd)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4117) u32 temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4119) temp = le32_to_cpu(sge->len) - byte_count
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4120) - scsi_bufflen(scsicmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4121) sge->len = cpu_to_le32(temp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4122) byte_count = scsi_bufflen(scsicmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4123) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4125) if (nseg <= HBA_MAX_SG_EMBEDDED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4126) hbacmd->emb_data_desc_count = cpu_to_le32(nseg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4127) sge->flags = cpu_to_le32(0x40000000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4128) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4129) /* not embedded */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4130) hbacmd->sge[0].flags = cpu_to_le32(0x80000000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4131) hbacmd->emb_data_desc_count = (u8)cpu_to_le32(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4132) hbacmd->sge[0].addr_hi = (u32)cpu_to_le32(sg_address >> 32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4133) hbacmd->sge[0].addr_lo =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4134) cpu_to_le32((u32)(sg_address & 0xffffffff));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4135) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4137) /* Check for command underflow */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4138) if (scsicmd->underflow && (byte_count < scsicmd->underflow)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4139) pr_warn("aacraid: cmd len %08lX cmd underflow %08X\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4140) byte_count, scsicmd->underflow);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4141) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4142) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4143) return byte_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4144) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4146) #ifdef AAC_DETAILED_STATUS_INFO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4148) struct aac_srb_status_info {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4149) u32 status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4150) char *str;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4151) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4153)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4154) static struct aac_srb_status_info srb_status_info[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4155) { SRB_STATUS_PENDING, "Pending Status"},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4156) { SRB_STATUS_SUCCESS, "Success"},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4157) { SRB_STATUS_ABORTED, "Aborted Command"},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4158) { SRB_STATUS_ABORT_FAILED, "Abort Failed"},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4159) { SRB_STATUS_ERROR, "Error Event"},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4160) { SRB_STATUS_BUSY, "Device Busy"},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4161) { SRB_STATUS_INVALID_REQUEST, "Invalid Request"},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4162) { SRB_STATUS_INVALID_PATH_ID, "Invalid Path ID"},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4163) { SRB_STATUS_NO_DEVICE, "No Device"},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4164) { SRB_STATUS_TIMEOUT, "Timeout"},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4165) { SRB_STATUS_SELECTION_TIMEOUT, "Selection Timeout"},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4166) { SRB_STATUS_COMMAND_TIMEOUT, "Command Timeout"},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4167) { SRB_STATUS_MESSAGE_REJECTED, "Message Rejected"},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4168) { SRB_STATUS_BUS_RESET, "Bus Reset"},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4169) { SRB_STATUS_PARITY_ERROR, "Parity Error"},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4170) { SRB_STATUS_REQUEST_SENSE_FAILED,"Request Sense Failed"},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4171) { SRB_STATUS_NO_HBA, "No HBA"},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4172) { SRB_STATUS_DATA_OVERRUN, "Data Overrun/Data Underrun"},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4173) { SRB_STATUS_UNEXPECTED_BUS_FREE,"Unexpected Bus Free"},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4174) { SRB_STATUS_PHASE_SEQUENCE_FAILURE,"Phase Error"},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4175) { SRB_STATUS_BAD_SRB_BLOCK_LENGTH,"Bad Srb Block Length"},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4176) { SRB_STATUS_REQUEST_FLUSHED, "Request Flushed"},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4177) { SRB_STATUS_DELAYED_RETRY, "Delayed Retry"},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4178) { SRB_STATUS_INVALID_LUN, "Invalid LUN"},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4179) { SRB_STATUS_INVALID_TARGET_ID, "Invalid TARGET ID"},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4180) { SRB_STATUS_BAD_FUNCTION, "Bad Function"},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4181) { SRB_STATUS_ERROR_RECOVERY, "Error Recovery"},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4182) { SRB_STATUS_NOT_STARTED, "Not Started"},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4183) { SRB_STATUS_NOT_IN_USE, "Not In Use"},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4184) { SRB_STATUS_FORCE_ABORT, "Force Abort"},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4185) { SRB_STATUS_DOMAIN_VALIDATION_FAIL,"Domain Validation Failure"},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4186) { 0xff, "Unknown Error"}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4187) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4189) char *aac_get_status_string(u32 status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4190) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4191) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4193) for (i = 0; i < ARRAY_SIZE(srb_status_info); i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4194) if (srb_status_info[i].status == status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4195) return srb_status_info[i].str;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4196)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4197) return "Bad Status Code";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4198) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4200) #endif