4250 lines · c
1/*2 * Management Module Support for MPT (Message Passing Technology) based3 * controllers4 *5 * This code is based on drivers/scsi/mpt3sas/mpt3sas_ctl.c6 * Copyright (C) 2012-2014 LSI Corporation7 * Copyright (C) 2013-2014 Avago Technologies8 * (mailto: MPT-FusionLinux.pdl@avagotech.com)9 *10 * This program is free software; you can redistribute it and/or11 * modify it under the terms of the GNU General Public License12 * as published by the Free Software Foundation; either version 213 * of the License, or (at your option) any later version.14 *15 * This program is distributed in the hope that it will be useful,16 * but WITHOUT ANY WARRANTY; without even the implied warranty of17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the18 * GNU General Public License for more details.19 *20 * NO WARRANTY21 * THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR22 * CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT23 * LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,24 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is25 * solely responsible for determining the appropriateness of using and26 * distributing the Program and assumes all risks associated with its27 * exercise of rights under this Agreement, including but not limited to28 * the risks and costs of program errors, damage to or loss of data,29 * programs or equipment, and unavailability or interruption of operations.30 31 * DISCLAIMER OF LIABILITY32 * NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY33 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL34 * DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND35 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR36 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE37 * USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED38 * HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES39 40 * You should have received a copy of the GNU General Public License41 * along with this program; if not, write to the Free Software42 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,43 * USA.44 */45 46#include <linux/kernel.h>47#include <linux/module.h>48#include <linux/errno.h>49#include <linux/init.h>50#include <linux/slab.h>51#include <linux/types.h>52#include <linux/pci.h>53#include <linux/delay.h>54#include <linux/compat.h>55#include <linux/poll.h>56 57#include <linux/io.h>58#include <linux/uaccess.h>59 60#include "mpt3sas_base.h"61#include "mpt3sas_ctl.h"62 63 64static struct fasync_struct *async_queue;65static DECLARE_WAIT_QUEUE_HEAD(ctl_poll_wait);66 67 68/**69 * enum block_state - blocking state70 * @NON_BLOCKING: non blocking71 * @BLOCKING: blocking72 *73 * These states are for ioctls that need to wait for a response74 * from firmware, so they probably require sleep.75 */76enum block_state {77 NON_BLOCKING,78 BLOCKING,79};80 81/**82 * _ctl_display_some_debug - debug routine83 * @ioc: per adapter object84 * @smid: system request message index85 * @calling_function_name: string pass from calling function86 * @mpi_reply: reply message frame87 * Context: none.88 *89 * Function for displaying debug info helpful when debugging issues90 * in this module.91 */92static void93_ctl_display_some_debug(struct MPT3SAS_ADAPTER *ioc, u16 smid,94 char *calling_function_name, MPI2DefaultReply_t *mpi_reply)95{96 Mpi2ConfigRequest_t *mpi_request;97 char *desc = NULL;98 99 if (!(ioc->logging_level & MPT_DEBUG_IOCTL))100 return;101 102 mpi_request = mpt3sas_base_get_msg_frame(ioc, smid);103 switch (mpi_request->Function) {104 case MPI2_FUNCTION_SCSI_IO_REQUEST:105 {106 Mpi2SCSIIORequest_t *scsi_request =107 (Mpi2SCSIIORequest_t *)mpi_request;108 109 snprintf(ioc->tmp_string, MPT_STRING_LENGTH,110 "scsi_io, cmd(0x%02x), cdb_len(%d)",111 scsi_request->CDB.CDB32[0],112 le16_to_cpu(scsi_request->IoFlags) & 0xF);113 desc = ioc->tmp_string;114 break;115 }116 case MPI2_FUNCTION_SCSI_TASK_MGMT:117 desc = "task_mgmt";118 break;119 case MPI2_FUNCTION_IOC_INIT:120 desc = "ioc_init";121 break;122 case MPI2_FUNCTION_IOC_FACTS:123 desc = "ioc_facts";124 break;125 case MPI2_FUNCTION_CONFIG:126 {127 Mpi2ConfigRequest_t *config_request =128 (Mpi2ConfigRequest_t *)mpi_request;129 130 snprintf(ioc->tmp_string, MPT_STRING_LENGTH,131 "config, type(0x%02x), ext_type(0x%02x), number(%d)",132 (config_request->Header.PageType &133 MPI2_CONFIG_PAGETYPE_MASK), config_request->ExtPageType,134 config_request->Header.PageNumber);135 desc = ioc->tmp_string;136 break;137 }138 case MPI2_FUNCTION_PORT_FACTS:139 desc = "port_facts";140 break;141 case MPI2_FUNCTION_PORT_ENABLE:142 desc = "port_enable";143 break;144 case MPI2_FUNCTION_EVENT_NOTIFICATION:145 desc = "event_notification";146 break;147 case MPI2_FUNCTION_FW_DOWNLOAD:148 desc = "fw_download";149 break;150 case MPI2_FUNCTION_FW_UPLOAD:151 desc = "fw_upload";152 break;153 case MPI2_FUNCTION_RAID_ACTION:154 desc = "raid_action";155 break;156 case MPI2_FUNCTION_RAID_SCSI_IO_PASSTHROUGH:157 {158 Mpi2SCSIIORequest_t *scsi_request =159 (Mpi2SCSIIORequest_t *)mpi_request;160 161 snprintf(ioc->tmp_string, MPT_STRING_LENGTH,162 "raid_pass, cmd(0x%02x), cdb_len(%d)",163 scsi_request->CDB.CDB32[0],164 le16_to_cpu(scsi_request->IoFlags) & 0xF);165 desc = ioc->tmp_string;166 break;167 }168 case MPI2_FUNCTION_SAS_IO_UNIT_CONTROL:169 desc = "sas_iounit_cntl";170 break;171 case MPI2_FUNCTION_SATA_PASSTHROUGH:172 desc = "sata_pass";173 break;174 case MPI2_FUNCTION_DIAG_BUFFER_POST:175 desc = "diag_buffer_post";176 break;177 case MPI2_FUNCTION_DIAG_RELEASE:178 desc = "diag_release";179 break;180 case MPI2_FUNCTION_SMP_PASSTHROUGH:181 desc = "smp_passthrough";182 break;183 case MPI2_FUNCTION_TOOLBOX:184 desc = "toolbox";185 break;186 case MPI2_FUNCTION_NVME_ENCAPSULATED:187 desc = "nvme_encapsulated";188 break;189 }190 191 if (!desc)192 return;193 194 ioc_info(ioc, "%s: %s, smid(%d)\n", calling_function_name, desc, smid);195 196 if (!mpi_reply)197 return;198 199 if (mpi_reply->IOCStatus || mpi_reply->IOCLogInfo)200 ioc_info(ioc, "\tiocstatus(0x%04x), loginfo(0x%08x)\n",201 le16_to_cpu(mpi_reply->IOCStatus),202 le32_to_cpu(mpi_reply->IOCLogInfo));203 204 if (mpi_request->Function == MPI2_FUNCTION_SCSI_IO_REQUEST ||205 mpi_request->Function ==206 MPI2_FUNCTION_RAID_SCSI_IO_PASSTHROUGH) {207 Mpi2SCSIIOReply_t *scsi_reply =208 (Mpi2SCSIIOReply_t *)mpi_reply;209 struct _sas_device *sas_device = NULL;210 struct _pcie_device *pcie_device = NULL;211 212 sas_device = mpt3sas_get_sdev_by_handle(ioc,213 le16_to_cpu(scsi_reply->DevHandle));214 if (sas_device) {215 ioc_warn(ioc, "\tsas_address(0x%016llx), phy(%d)\n",216 (u64)sas_device->sas_address,217 sas_device->phy);218 ioc_warn(ioc, "\tenclosure_logical_id(0x%016llx), slot(%d)\n",219 (u64)sas_device->enclosure_logical_id,220 sas_device->slot);221 sas_device_put(sas_device);222 }223 if (!sas_device) {224 pcie_device = mpt3sas_get_pdev_by_handle(ioc,225 le16_to_cpu(scsi_reply->DevHandle));226 if (pcie_device) {227 ioc_warn(ioc, "\tWWID(0x%016llx), port(%d)\n",228 (unsigned long long)pcie_device->wwid,229 pcie_device->port_num);230 if (pcie_device->enclosure_handle != 0)231 ioc_warn(ioc, "\tenclosure_logical_id(0x%016llx), slot(%d)\n",232 (u64)pcie_device->enclosure_logical_id,233 pcie_device->slot);234 pcie_device_put(pcie_device);235 }236 }237 if (scsi_reply->SCSIState || scsi_reply->SCSIStatus)238 ioc_info(ioc, "\tscsi_state(0x%02x), scsi_status(0x%02x)\n",239 scsi_reply->SCSIState,240 scsi_reply->SCSIStatus);241 }242}243 244/**245 * mpt3sas_ctl_done - ctl module completion routine246 * @ioc: per adapter object247 * @smid: system request message index248 * @msix_index: MSIX table index supplied by the OS249 * @reply: reply message frame(lower 32bit addr)250 * Context: none.251 *252 * The callback handler when using ioc->ctl_cb_idx.253 *254 * Return: 1 meaning mf should be freed from _base_interrupt255 * 0 means the mf is freed from this function.256 */257u8258mpt3sas_ctl_done(struct MPT3SAS_ADAPTER *ioc, u16 smid, u8 msix_index,259 u32 reply)260{261 MPI2DefaultReply_t *mpi_reply;262 Mpi2SCSIIOReply_t *scsiio_reply;263 Mpi26NVMeEncapsulatedErrorReply_t *nvme_error_reply;264 const void *sense_data;265 u32 sz;266 267 if (ioc->ctl_cmds.status == MPT3_CMD_NOT_USED)268 return 1;269 if (ioc->ctl_cmds.smid != smid)270 return 1;271 ioc->ctl_cmds.status |= MPT3_CMD_COMPLETE;272 mpi_reply = mpt3sas_base_get_reply_virt_addr(ioc, reply);273 if (mpi_reply) {274 memcpy(ioc->ctl_cmds.reply, mpi_reply, mpi_reply->MsgLength*4);275 ioc->ctl_cmds.status |= MPT3_CMD_REPLY_VALID;276 /* get sense data */277 if (mpi_reply->Function == MPI2_FUNCTION_SCSI_IO_REQUEST ||278 mpi_reply->Function ==279 MPI2_FUNCTION_RAID_SCSI_IO_PASSTHROUGH) {280 scsiio_reply = (Mpi2SCSIIOReply_t *)mpi_reply;281 if (scsiio_reply->SCSIState &282 MPI2_SCSI_STATE_AUTOSENSE_VALID) {283 sz = min_t(u32, SCSI_SENSE_BUFFERSIZE,284 le32_to_cpu(scsiio_reply->SenseCount));285 sense_data = mpt3sas_base_get_sense_buffer(ioc,286 smid);287 memcpy(ioc->ctl_cmds.sense, sense_data, sz);288 }289 }290 /*291 * Get Error Response data for NVMe device. The ctl_cmds.sense292 * buffer is used to store the Error Response data.293 */294 if (mpi_reply->Function == MPI2_FUNCTION_NVME_ENCAPSULATED) {295 nvme_error_reply =296 (Mpi26NVMeEncapsulatedErrorReply_t *)mpi_reply;297 sz = min_t(u32, NVME_ERROR_RESPONSE_SIZE,298 le16_to_cpu(nvme_error_reply->ErrorResponseCount));299 sense_data = mpt3sas_base_get_sense_buffer(ioc, smid);300 memcpy(ioc->ctl_cmds.sense, sense_data, sz);301 }302 }303 304 _ctl_display_some_debug(ioc, smid, "ctl_done", mpi_reply);305 ioc->ctl_cmds.status &= ~MPT3_CMD_PENDING;306 complete(&ioc->ctl_cmds.done);307 return 1;308}309 310/**311 * _ctl_check_event_type - determines when an event needs logging312 * @ioc: per adapter object313 * @event: firmware event314 *315 * The bitmask in ioc->event_type[] indicates which events should be316 * be saved in the driver event_log. This bitmask is set by application.317 *318 * Return: 1 when event should be captured, or zero means no match.319 */320static int321_ctl_check_event_type(struct MPT3SAS_ADAPTER *ioc, u16 event)322{323 u16 i;324 u32 desired_event;325 326 if (event >= 128 || !event || !ioc->event_log)327 return 0;328 329 desired_event = (1 << (event % 32));330 if (!desired_event)331 desired_event = 1;332 i = event / 32;333 return desired_event & ioc->event_type[i];334}335 336/**337 * mpt3sas_ctl_add_to_event_log - add event338 * @ioc: per adapter object339 * @mpi_reply: reply message frame340 */341void342mpt3sas_ctl_add_to_event_log(struct MPT3SAS_ADAPTER *ioc,343 Mpi2EventNotificationReply_t *mpi_reply)344{345 struct MPT3_IOCTL_EVENTS *event_log;346 u16 event;347 int i;348 u32 sz, event_data_sz;349 u8 send_aen = 0;350 351 if (!ioc->event_log)352 return;353 354 event = le16_to_cpu(mpi_reply->Event);355 356 if (_ctl_check_event_type(ioc, event)) {357 358 /* insert entry into circular event_log */359 i = ioc->event_context % MPT3SAS_CTL_EVENT_LOG_SIZE;360 event_log = ioc->event_log;361 event_log[i].event = event;362 event_log[i].context = ioc->event_context++;363 364 event_data_sz = le16_to_cpu(mpi_reply->EventDataLength)*4;365 sz = min_t(u32, event_data_sz, MPT3_EVENT_DATA_SIZE);366 memset(event_log[i].data, 0, MPT3_EVENT_DATA_SIZE);367 memcpy(event_log[i].data, mpi_reply->EventData, sz);368 send_aen = 1;369 }370 371 /* This aen_event_read_flag flag is set until the372 * application has read the event log.373 * For MPI2_EVENT_LOG_ENTRY_ADDED, we always notify.374 */375 if (event == MPI2_EVENT_LOG_ENTRY_ADDED ||376 (send_aen && !ioc->aen_event_read_flag)) {377 ioc->aen_event_read_flag = 1;378 wake_up_interruptible(&ctl_poll_wait);379 if (async_queue)380 kill_fasync(&async_queue, SIGIO, POLL_IN);381 }382}383 384/**385 * mpt3sas_ctl_event_callback - firmware event handler (called at ISR time)386 * @ioc: per adapter object387 * @msix_index: MSIX table index supplied by the OS388 * @reply: reply message frame(lower 32bit addr)389 * Context: interrupt.390 *391 * This function merely adds a new work task into ioc->firmware_event_thread.392 * The tasks are worked from _firmware_event_work in user context.393 *394 * Return: 1 meaning mf should be freed from _base_interrupt395 * 0 means the mf is freed from this function.396 */397u8398mpt3sas_ctl_event_callback(struct MPT3SAS_ADAPTER *ioc, u8 msix_index,399 u32 reply)400{401 Mpi2EventNotificationReply_t *mpi_reply;402 403 mpi_reply = mpt3sas_base_get_reply_virt_addr(ioc, reply);404 if (mpi_reply)405 mpt3sas_ctl_add_to_event_log(ioc, mpi_reply);406 return 1;407}408 409/**410 * _ctl_verify_adapter - validates ioc_number passed from application411 * @ioc_number: ?412 * @iocpp: The ioc pointer is returned in this.413 * @mpi_version: will be MPI2_VERSION for mpt2ctl ioctl device &414 * MPI25_VERSION | MPI26_VERSION for mpt3ctl ioctl device.415 *416 * Return: (-1) means error, else ioc_number.417 */418static int419_ctl_verify_adapter(int ioc_number, struct MPT3SAS_ADAPTER **iocpp,420 int mpi_version)421{422 struct MPT3SAS_ADAPTER *ioc;423 int version = 0;424 /* global ioc lock to protect controller on list operations */425 spin_lock(&gioc_lock);426 list_for_each_entry(ioc, &mpt3sas_ioc_list, list) {427 if (ioc->id != ioc_number)428 continue;429 /* Check whether this ioctl command is from right430 * ioctl device or not, if not continue the search.431 */432 version = ioc->hba_mpi_version_belonged;433 /* MPI25_VERSION and MPI26_VERSION uses same ioctl434 * device.435 */436 if (mpi_version == (MPI25_VERSION | MPI26_VERSION)) {437 if ((version == MPI25_VERSION) ||438 (version == MPI26_VERSION))439 goto out;440 else441 continue;442 } else {443 if (version != mpi_version)444 continue;445 }446out:447 spin_unlock(&gioc_lock);448 *iocpp = ioc;449 return ioc_number;450 }451 spin_unlock(&gioc_lock);452 *iocpp = NULL;453 return -1;454}455 456/**457 * mpt3sas_ctl_pre_reset_handler - reset callback handler (for ctl)458 * @ioc: per adapter object459 *460 * The handler for doing any required cleanup or initialization.461 */462void mpt3sas_ctl_pre_reset_handler(struct MPT3SAS_ADAPTER *ioc)463{464 int i;465 u8 issue_reset;466 467 dtmprintk(ioc, ioc_info(ioc, "%s: MPT3_IOC_PRE_RESET\n", __func__));468 for (i = 0; i < MPI2_DIAG_BUF_TYPE_COUNT; i++) {469 if (!(ioc->diag_buffer_status[i] &470 MPT3_DIAG_BUFFER_IS_REGISTERED))471 continue;472 if ((ioc->diag_buffer_status[i] &473 MPT3_DIAG_BUFFER_IS_RELEASED))474 continue;475 476 /*477 * add a log message to indicate the release478 */479 ioc_info(ioc,480 "%s: Releasing the trace buffer due to adapter reset.",481 __func__);482 ioc->htb_rel.buffer_rel_condition =483 MPT3_DIAG_BUFFER_REL_TRIGGER;484 mpt3sas_send_diag_release(ioc, i, &issue_reset);485 }486}487 488/**489 * mpt3sas_ctl_clear_outstanding_ioctls - clears outstanding ioctl cmd.490 * @ioc: per adapter object491 *492 * The handler for doing any required cleanup or initialization.493 */494void mpt3sas_ctl_clear_outstanding_ioctls(struct MPT3SAS_ADAPTER *ioc)495{496 dtmprintk(ioc,497 ioc_info(ioc, "%s: clear outstanding ioctl cmd\n", __func__));498 if (ioc->ctl_cmds.status & MPT3_CMD_PENDING) {499 ioc->ctl_cmds.status |= MPT3_CMD_RESET;500 mpt3sas_base_free_smid(ioc, ioc->ctl_cmds.smid);501 complete(&ioc->ctl_cmds.done);502 }503}504 505/**506 * mpt3sas_ctl_reset_done_handler - reset callback handler (for ctl)507 * @ioc: per adapter object508 *509 * The handler for doing any required cleanup or initialization.510 */511void mpt3sas_ctl_reset_done_handler(struct MPT3SAS_ADAPTER *ioc)512{513 int i;514 515 dtmprintk(ioc, ioc_info(ioc, "%s: MPT3_IOC_DONE_RESET\n", __func__));516 517 for (i = 0; i < MPI2_DIAG_BUF_TYPE_COUNT; i++) {518 if (!(ioc->diag_buffer_status[i] &519 MPT3_DIAG_BUFFER_IS_REGISTERED))520 continue;521 if ((ioc->diag_buffer_status[i] &522 MPT3_DIAG_BUFFER_IS_RELEASED))523 continue;524 ioc->diag_buffer_status[i] |=525 MPT3_DIAG_BUFFER_IS_DIAG_RESET;526 }527}528 529/**530 * _ctl_fasync -531 * @fd: ?532 * @filep: ?533 * @mode: ?534 *535 * Called when application request fasyn callback handler.536 */537static int538_ctl_fasync(int fd, struct file *filep, int mode)539{540 return fasync_helper(fd, filep, mode, &async_queue);541}542 543/**544 * _ctl_poll -545 * @filep: ?546 * @wait: ?547 *548 */549static __poll_t550_ctl_poll(struct file *filep, poll_table *wait)551{552 struct MPT3SAS_ADAPTER *ioc;553 554 poll_wait(filep, &ctl_poll_wait, wait);555 556 /* global ioc lock to protect controller on list operations */557 spin_lock(&gioc_lock);558 list_for_each_entry(ioc, &mpt3sas_ioc_list, list) {559 if (ioc->aen_event_read_flag) {560 spin_unlock(&gioc_lock);561 return EPOLLIN | EPOLLRDNORM;562 }563 }564 spin_unlock(&gioc_lock);565 return 0;566}567 568/**569 * _ctl_set_task_mid - assign an active smid to tm request570 * @ioc: per adapter object571 * @karg: (struct mpt3_ioctl_command)572 * @tm_request: pointer to mf from user space573 *574 * Return: 0 when an smid if found, else fail.575 * during failure, the reply frame is filled.576 */577static int578_ctl_set_task_mid(struct MPT3SAS_ADAPTER *ioc, struct mpt3_ioctl_command *karg,579 Mpi2SCSITaskManagementRequest_t *tm_request)580{581 bool found = false;582 u16 smid;583 u16 handle;584 struct scsi_cmnd *scmd;585 struct MPT3SAS_DEVICE *priv_data;586 Mpi2SCSITaskManagementReply_t *tm_reply;587 u32 sz;588 u32 lun;589 char *desc = NULL;590 591 if (tm_request->TaskType == MPI2_SCSITASKMGMT_TASKTYPE_ABORT_TASK)592 desc = "abort_task";593 else if (tm_request->TaskType == MPI2_SCSITASKMGMT_TASKTYPE_QUERY_TASK)594 desc = "query_task";595 else596 return 0;597 598 lun = scsilun_to_int((struct scsi_lun *)tm_request->LUN);599 600 handle = le16_to_cpu(tm_request->DevHandle);601 for (smid = ioc->scsiio_depth; smid && !found; smid--) {602 struct scsiio_tracker *st;603 __le16 task_mid;604 605 scmd = mpt3sas_scsih_scsi_lookup_get(ioc, smid);606 if (!scmd)607 continue;608 if (lun != scmd->device->lun)609 continue;610 priv_data = scmd->device->hostdata;611 if (priv_data->sas_target == NULL)612 continue;613 if (priv_data->sas_target->handle != handle)614 continue;615 st = scsi_cmd_priv(scmd);616 617 /*618 * If the given TaskMID from the user space is zero, then the619 * first outstanding smid will be picked up. Otherwise,620 * targeted smid will be the one.621 */622 task_mid = cpu_to_le16(st->smid);623 if (!tm_request->TaskMID)624 tm_request->TaskMID = task_mid;625 found = tm_request->TaskMID == task_mid;626 }627 628 if (!found) {629 dctlprintk(ioc,630 ioc_info(ioc, "%s: handle(0x%04x), lun(%d), no active mid!!\n",631 desc, le16_to_cpu(tm_request->DevHandle),632 lun));633 tm_reply = ioc->ctl_cmds.reply;634 tm_reply->DevHandle = tm_request->DevHandle;635 tm_reply->Function = MPI2_FUNCTION_SCSI_TASK_MGMT;636 tm_reply->TaskType = tm_request->TaskType;637 tm_reply->MsgLength = sizeof(Mpi2SCSITaskManagementReply_t)/4;638 tm_reply->VP_ID = tm_request->VP_ID;639 tm_reply->VF_ID = tm_request->VF_ID;640 sz = min_t(u32, karg->max_reply_bytes, ioc->reply_sz);641 if (copy_to_user(karg->reply_frame_buf_ptr, ioc->ctl_cmds.reply,642 sz))643 pr_err("failure at %s:%d/%s()!\n", __FILE__,644 __LINE__, __func__);645 return 1;646 }647 648 dctlprintk(ioc,649 ioc_info(ioc, "%s: handle(0x%04x), lun(%d), task_mid(%d)\n",650 desc, le16_to_cpu(tm_request->DevHandle), lun,651 le16_to_cpu(tm_request->TaskMID)));652 return 0;653}654 655/**656 * _ctl_do_mpt_command - main handler for MPT3COMMAND opcode657 * @ioc: per adapter object658 * @karg: (struct mpt3_ioctl_command)659 * @mf: pointer to mf in user space660 */661static long662_ctl_do_mpt_command(struct MPT3SAS_ADAPTER *ioc, struct mpt3_ioctl_command karg,663 void __user *mf)664{665 MPI2RequestHeader_t *mpi_request = NULL, *request;666 MPI2DefaultReply_t *mpi_reply;667 Mpi26NVMeEncapsulatedRequest_t *nvme_encap_request = NULL;668 struct _pcie_device *pcie_device = NULL;669 u16 smid;670 unsigned long timeout;671 u8 issue_reset;672 u32 sz, sz_arg;673 void *psge;674 void *data_out = NULL;675 dma_addr_t data_out_dma = 0;676 size_t data_out_sz = 0;677 void *data_in = NULL;678 dma_addr_t data_in_dma = 0;679 size_t data_in_sz = 0;680 long ret;681 u16 device_handle = MPT3SAS_INVALID_DEVICE_HANDLE;682 683 issue_reset = 0;684 685 if (ioc->ctl_cmds.status != MPT3_CMD_NOT_USED) {686 ioc_err(ioc, "%s: ctl_cmd in use\n", __func__);687 ret = -EAGAIN;688 goto out;689 }690 691 ret = mpt3sas_wait_for_ioc(ioc, IOC_OPERATIONAL_WAIT_COUNT);692 if (ret)693 goto out;694 695 mpi_request = kzalloc(ioc->request_sz, GFP_KERNEL);696 if (!mpi_request) {697 ioc_err(ioc, "%s: failed obtaining a memory for mpi_request\n",698 __func__);699 ret = -ENOMEM;700 goto out;701 }702 703 /* Check for overflow and wraparound */704 if (karg.data_sge_offset * 4 > ioc->request_sz ||705 karg.data_sge_offset > (UINT_MAX / 4)) {706 ret = -EINVAL;707 goto out;708 }709 710 /* copy in request message frame from user */711 if (copy_from_user(mpi_request, mf, karg.data_sge_offset*4)) {712 pr_err("failure at %s:%d/%s()!\n", __FILE__, __LINE__,713 __func__);714 ret = -EFAULT;715 goto out;716 }717 718 if (mpi_request->Function == MPI2_FUNCTION_SCSI_TASK_MGMT) {719 smid = mpt3sas_base_get_smid_hpr(ioc, ioc->ctl_cb_idx);720 if (!smid) {721 ioc_err(ioc, "%s: failed obtaining a smid\n", __func__);722 ret = -EAGAIN;723 goto out;724 }725 } else {726 /* Use first reserved smid for passthrough ioctls */727 smid = ioc->scsiio_depth - INTERNAL_SCSIIO_CMDS_COUNT + 1;728 }729 730 ret = 0;731 ioc->ctl_cmds.status = MPT3_CMD_PENDING;732 memset(ioc->ctl_cmds.reply, 0, ioc->reply_sz);733 request = mpt3sas_base_get_msg_frame(ioc, smid);734 memset(request, 0, ioc->request_sz);735 memcpy(request, mpi_request, karg.data_sge_offset*4);736 ioc->ctl_cmds.smid = smid;737 data_out_sz = karg.data_out_size;738 data_in_sz = karg.data_in_size;739 740 if (mpi_request->Function == MPI2_FUNCTION_SCSI_IO_REQUEST ||741 mpi_request->Function == MPI2_FUNCTION_RAID_SCSI_IO_PASSTHROUGH ||742 mpi_request->Function == MPI2_FUNCTION_SCSI_TASK_MGMT ||743 mpi_request->Function == MPI2_FUNCTION_SATA_PASSTHROUGH ||744 mpi_request->Function == MPI2_FUNCTION_NVME_ENCAPSULATED) {745 746 device_handle = le16_to_cpu(mpi_request->FunctionDependent1);747 if (!device_handle || (device_handle >748 ioc->facts.MaxDevHandle)) {749 ret = -EINVAL;750 mpt3sas_base_free_smid(ioc, smid);751 goto out;752 }753 }754 755 /* obtain dma-able memory for data transfer */756 if (data_out_sz) /* WRITE */ {757 data_out = dma_alloc_coherent(&ioc->pdev->dev, data_out_sz,758 &data_out_dma, GFP_KERNEL);759 if (!data_out) {760 pr_err("failure at %s:%d/%s()!\n", __FILE__,761 __LINE__, __func__);762 ret = -ENOMEM;763 mpt3sas_base_free_smid(ioc, smid);764 goto out;765 }766 if (copy_from_user(data_out, karg.data_out_buf_ptr,767 data_out_sz)) {768 pr_err("failure at %s:%d/%s()!\n", __FILE__,769 __LINE__, __func__);770 ret = -EFAULT;771 mpt3sas_base_free_smid(ioc, smid);772 goto out;773 }774 }775 776 if (data_in_sz) /* READ */ {777 data_in = dma_alloc_coherent(&ioc->pdev->dev, data_in_sz,778 &data_in_dma, GFP_KERNEL);779 if (!data_in) {780 pr_err("failure at %s:%d/%s()!\n", __FILE__,781 __LINE__, __func__);782 ret = -ENOMEM;783 mpt3sas_base_free_smid(ioc, smid);784 goto out;785 }786 }787 788 psge = (void *)request + (karg.data_sge_offset*4);789 790 /* send command to firmware */791 _ctl_display_some_debug(ioc, smid, "ctl_request", NULL);792 793 init_completion(&ioc->ctl_cmds.done);794 switch (mpi_request->Function) {795 case MPI2_FUNCTION_NVME_ENCAPSULATED:796 {797 nvme_encap_request = (Mpi26NVMeEncapsulatedRequest_t *)request;798 if (!ioc->pcie_sg_lookup) {799 dtmprintk(ioc, ioc_info(ioc,800 "HBA doesn't support NVMe. Rejecting NVMe Encapsulated request.\n"801 ));802 803 if (ioc->logging_level & MPT_DEBUG_TM)804 _debug_dump_mf(nvme_encap_request,805 ioc->request_sz/4);806 mpt3sas_base_free_smid(ioc, smid);807 ret = -EINVAL;808 goto out;809 }810 /*811 * Get the Physical Address of the sense buffer.812 * Use Error Response buffer address field to hold the sense813 * buffer address.814 * Clear the internal sense buffer, which will potentially hold815 * the Completion Queue Entry on return, or 0 if no Entry.816 * Build the PRPs and set direction bits.817 * Send the request.818 */819 nvme_encap_request->ErrorResponseBaseAddress =820 cpu_to_le64(ioc->sense_dma & 0xFFFFFFFF00000000UL);821 nvme_encap_request->ErrorResponseBaseAddress |=822 cpu_to_le64(le32_to_cpu(823 mpt3sas_base_get_sense_buffer_dma(ioc, smid)));824 nvme_encap_request->ErrorResponseAllocationLength =825 cpu_to_le16(NVME_ERROR_RESPONSE_SIZE);826 memset(ioc->ctl_cmds.sense, 0, NVME_ERROR_RESPONSE_SIZE);827 ioc->build_nvme_prp(ioc, smid, nvme_encap_request,828 data_out_dma, data_out_sz, data_in_dma, data_in_sz);829 if (test_bit(device_handle, ioc->device_remove_in_progress)) {830 dtmprintk(ioc,831 ioc_info(ioc, "handle(0x%04x): ioctl failed due to device removal in progress\n",832 device_handle));833 mpt3sas_base_free_smid(ioc, smid);834 ret = -EINVAL;835 goto out;836 }837 mpt3sas_base_put_smid_nvme_encap(ioc, smid);838 break;839 }840 case MPI2_FUNCTION_SCSI_IO_REQUEST:841 case MPI2_FUNCTION_RAID_SCSI_IO_PASSTHROUGH:842 {843 Mpi2SCSIIORequest_t *scsiio_request =844 (Mpi2SCSIIORequest_t *)request;845 scsiio_request->SenseBufferLength = SCSI_SENSE_BUFFERSIZE;846 scsiio_request->SenseBufferLowAddress =847 mpt3sas_base_get_sense_buffer_dma(ioc, smid);848 memset(ioc->ctl_cmds.sense, 0, SCSI_SENSE_BUFFERSIZE);849 if (test_bit(device_handle, ioc->device_remove_in_progress)) {850 dtmprintk(ioc,851 ioc_info(ioc, "handle(0x%04x) :ioctl failed due to device removal in progress\n",852 device_handle));853 mpt3sas_base_free_smid(ioc, smid);854 ret = -EINVAL;855 goto out;856 }857 ioc->build_sg(ioc, psge, data_out_dma, data_out_sz,858 data_in_dma, data_in_sz);859 if (mpi_request->Function == MPI2_FUNCTION_SCSI_IO_REQUEST)860 ioc->put_smid_scsi_io(ioc, smid, device_handle);861 else862 ioc->put_smid_default(ioc, smid);863 break;864 }865 case MPI2_FUNCTION_SCSI_TASK_MGMT:866 {867 Mpi2SCSITaskManagementRequest_t *tm_request =868 (Mpi2SCSITaskManagementRequest_t *)request;869 870 dtmprintk(ioc,871 ioc_info(ioc, "TASK_MGMT: handle(0x%04x), task_type(0x%02x)\n",872 le16_to_cpu(tm_request->DevHandle),873 tm_request->TaskType));874 ioc->got_task_abort_from_ioctl = 1;875 if (tm_request->TaskType ==876 MPI2_SCSITASKMGMT_TASKTYPE_ABORT_TASK ||877 tm_request->TaskType ==878 MPI2_SCSITASKMGMT_TASKTYPE_QUERY_TASK) {879 if (_ctl_set_task_mid(ioc, &karg, tm_request)) {880 mpt3sas_base_free_smid(ioc, smid);881 ioc->got_task_abort_from_ioctl = 0;882 goto out;883 }884 }885 ioc->got_task_abort_from_ioctl = 0;886 887 if (test_bit(device_handle, ioc->device_remove_in_progress)) {888 dtmprintk(ioc,889 ioc_info(ioc, "handle(0x%04x) :ioctl failed due to device removal in progress\n",890 device_handle));891 mpt3sas_base_free_smid(ioc, smid);892 ret = -EINVAL;893 goto out;894 }895 mpt3sas_scsih_set_tm_flag(ioc, le16_to_cpu(896 tm_request->DevHandle));897 ioc->build_sg_mpi(ioc, psge, data_out_dma, data_out_sz,898 data_in_dma, data_in_sz);899 ioc->put_smid_hi_priority(ioc, smid, 0);900 break;901 }902 case MPI2_FUNCTION_SMP_PASSTHROUGH:903 {904 Mpi2SmpPassthroughRequest_t *smp_request =905 (Mpi2SmpPassthroughRequest_t *)mpi_request;906 u8 *data;907 908 if (!ioc->multipath_on_hba) {909 /* ioc determines which port to use */910 smp_request->PhysicalPort = 0xFF;911 }912 if (smp_request->PassthroughFlags &913 MPI2_SMP_PT_REQ_PT_FLAGS_IMMEDIATE)914 data = (u8 *)&smp_request->SGL;915 else {916 if (unlikely(data_out == NULL)) {917 pr_err("failure at %s:%d/%s()!\n",918 __FILE__, __LINE__, __func__);919 mpt3sas_base_free_smid(ioc, smid);920 ret = -EINVAL;921 goto out;922 }923 data = data_out;924 }925 926 if (data[1] == 0x91 && (data[10] == 1 || data[10] == 2)) {927 ioc->ioc_link_reset_in_progress = 1;928 ioc->ignore_loginfos = 1;929 }930 ioc->build_sg(ioc, psge, data_out_dma, data_out_sz, data_in_dma,931 data_in_sz);932 ioc->put_smid_default(ioc, smid);933 break;934 }935 case MPI2_FUNCTION_SATA_PASSTHROUGH:936 {937 if (test_bit(device_handle, ioc->device_remove_in_progress)) {938 dtmprintk(ioc,939 ioc_info(ioc, "handle(0x%04x) :ioctl failed due to device removal in progress\n",940 device_handle));941 mpt3sas_base_free_smid(ioc, smid);942 ret = -EINVAL;943 goto out;944 }945 ioc->build_sg(ioc, psge, data_out_dma, data_out_sz, data_in_dma,946 data_in_sz);947 ioc->put_smid_default(ioc, smid);948 break;949 }950 case MPI2_FUNCTION_FW_DOWNLOAD:951 {952 if (ioc->pdev->vendor == MPI2_MFGPAGE_VENDORID_ATTO) {953 ioc_info(ioc, "Firmware download not supported for ATTO HBA.\n");954 ret = -EPERM;955 break;956 }957 fallthrough;958 }959 case MPI2_FUNCTION_FW_UPLOAD:960 {961 ioc->build_sg(ioc, psge, data_out_dma, data_out_sz, data_in_dma,962 data_in_sz);963 ioc->put_smid_default(ioc, smid);964 break;965 }966 case MPI2_FUNCTION_TOOLBOX:967 {968 Mpi2ToolboxCleanRequest_t *toolbox_request =969 (Mpi2ToolboxCleanRequest_t *)mpi_request;970 971 if ((toolbox_request->Tool == MPI2_TOOLBOX_DIAGNOSTIC_CLI_TOOL)972 || (toolbox_request->Tool ==973 MPI26_TOOLBOX_BACKEND_PCIE_LANE_MARGIN))974 ioc->build_sg(ioc, psge, data_out_dma, data_out_sz,975 data_in_dma, data_in_sz);976 else if (toolbox_request->Tool ==977 MPI2_TOOLBOX_MEMORY_MOVE_TOOL) {978 Mpi2ToolboxMemMoveRequest_t *mem_move_request =979 (Mpi2ToolboxMemMoveRequest_t *)request;980 Mpi2SGESimple64_t tmp, *src = NULL, *dst = NULL;981 982 ioc->build_sg_mpi(ioc, psge, data_out_dma,983 data_out_sz, data_in_dma, data_in_sz);984 if (data_out_sz && !data_in_sz) {985 dst =986 (Mpi2SGESimple64_t *)&mem_move_request->SGL;987 src = (void *)dst + ioc->sge_size;988 989 memcpy(&tmp, src, ioc->sge_size);990 memcpy(src, dst, ioc->sge_size);991 memcpy(dst, &tmp, ioc->sge_size);992 }993 if (ioc->logging_level & MPT_DEBUG_TM) {994 ioc_info(ioc,995 "Mpi2ToolboxMemMoveRequest_t request msg\n");996 _debug_dump_mf(mem_move_request,997 ioc->request_sz/4);998 }999 } else1000 ioc->build_sg_mpi(ioc, psge, data_out_dma, data_out_sz,1001 data_in_dma, data_in_sz);1002 ioc->put_smid_default(ioc, smid);1003 break;1004 }1005 case MPI2_FUNCTION_SAS_IO_UNIT_CONTROL:1006 {1007 Mpi2SasIoUnitControlRequest_t *sasiounit_request =1008 (Mpi2SasIoUnitControlRequest_t *)mpi_request;1009 1010 if (sasiounit_request->Operation == MPI2_SAS_OP_PHY_HARD_RESET1011 || sasiounit_request->Operation ==1012 MPI2_SAS_OP_PHY_LINK_RESET) {1013 ioc->ioc_link_reset_in_progress = 1;1014 ioc->ignore_loginfos = 1;1015 }1016 /* drop to default case for posting the request */1017 }1018 fallthrough;1019 default:1020 ioc->build_sg_mpi(ioc, psge, data_out_dma, data_out_sz,1021 data_in_dma, data_in_sz);1022 ioc->put_smid_default(ioc, smid);1023 break;1024 }1025 1026 if (karg.timeout < MPT3_IOCTL_DEFAULT_TIMEOUT)1027 timeout = MPT3_IOCTL_DEFAULT_TIMEOUT;1028 else1029 timeout = karg.timeout;1030 wait_for_completion_timeout(&ioc->ctl_cmds.done, timeout*HZ);1031 if (mpi_request->Function == MPI2_FUNCTION_SCSI_TASK_MGMT) {1032 Mpi2SCSITaskManagementRequest_t *tm_request =1033 (Mpi2SCSITaskManagementRequest_t *)mpi_request;1034 mpt3sas_scsih_clear_tm_flag(ioc, le16_to_cpu(1035 tm_request->DevHandle));1036 mpt3sas_trigger_master(ioc, MASTER_TRIGGER_TASK_MANAGMENT);1037 } else if ((mpi_request->Function == MPI2_FUNCTION_SMP_PASSTHROUGH ||1038 mpi_request->Function == MPI2_FUNCTION_SAS_IO_UNIT_CONTROL) &&1039 ioc->ioc_link_reset_in_progress) {1040 ioc->ioc_link_reset_in_progress = 0;1041 ioc->ignore_loginfos = 0;1042 }1043 if (!(ioc->ctl_cmds.status & MPT3_CMD_COMPLETE)) {1044 mpt3sas_check_cmd_timeout(ioc,1045 ioc->ctl_cmds.status, mpi_request,1046 karg.data_sge_offset, issue_reset);1047 goto issue_host_reset;1048 }1049 1050 mpi_reply = ioc->ctl_cmds.reply;1051 1052 if (mpi_reply->Function == MPI2_FUNCTION_SCSI_TASK_MGMT &&1053 (ioc->logging_level & MPT_DEBUG_TM)) {1054 Mpi2SCSITaskManagementReply_t *tm_reply =1055 (Mpi2SCSITaskManagementReply_t *)mpi_reply;1056 1057 ioc_info(ioc, "TASK_MGMT: IOCStatus(0x%04x), IOCLogInfo(0x%08x), TerminationCount(0x%08x)\n",1058 le16_to_cpu(tm_reply->IOCStatus),1059 le32_to_cpu(tm_reply->IOCLogInfo),1060 le32_to_cpu(tm_reply->TerminationCount));1061 }1062 1063 /* copy out xdata to user */1064 if (data_in_sz) {1065 if (copy_to_user(karg.data_in_buf_ptr, data_in,1066 data_in_sz)) {1067 pr_err("failure at %s:%d/%s()!\n", __FILE__,1068 __LINE__, __func__);1069 ret = -ENODATA;1070 goto out;1071 }1072 }1073 1074 /* copy out reply message frame to user */1075 if (karg.max_reply_bytes) {1076 sz = min_t(u32, karg.max_reply_bytes, ioc->reply_sz);1077 if (copy_to_user(karg.reply_frame_buf_ptr, ioc->ctl_cmds.reply,1078 sz)) {1079 pr_err("failure at %s:%d/%s()!\n", __FILE__,1080 __LINE__, __func__);1081 ret = -ENODATA;1082 goto out;1083 }1084 }1085 1086 /* copy out sense/NVMe Error Response to user */1087 if (karg.max_sense_bytes && (mpi_request->Function ==1088 MPI2_FUNCTION_SCSI_IO_REQUEST || mpi_request->Function ==1089 MPI2_FUNCTION_RAID_SCSI_IO_PASSTHROUGH || mpi_request->Function ==1090 MPI2_FUNCTION_NVME_ENCAPSULATED)) {1091 if (karg.sense_data_ptr == NULL) {1092 ioc_info(ioc, "Response buffer provided by application is NULL; Response data will not be returned\n");1093 goto out;1094 }1095 sz_arg = (mpi_request->Function ==1096 MPI2_FUNCTION_NVME_ENCAPSULATED) ? NVME_ERROR_RESPONSE_SIZE :1097 SCSI_SENSE_BUFFERSIZE;1098 sz = min_t(u32, karg.max_sense_bytes, sz_arg);1099 if (copy_to_user(karg.sense_data_ptr, ioc->ctl_cmds.sense,1100 sz)) {1101 pr_err("failure at %s:%d/%s()!\n", __FILE__,1102 __LINE__, __func__);1103 ret = -ENODATA;1104 goto out;1105 }1106 }1107 1108 issue_host_reset:1109 if (issue_reset) {1110 ret = -ENODATA;1111 if ((mpi_request->Function == MPI2_FUNCTION_SCSI_IO_REQUEST ||1112 mpi_request->Function ==1113 MPI2_FUNCTION_RAID_SCSI_IO_PASSTHROUGH ||1114 mpi_request->Function == MPI2_FUNCTION_SATA_PASSTHROUGH)) {1115 ioc_info(ioc, "issue target reset: handle = (0x%04x)\n",1116 le16_to_cpu(mpi_request->FunctionDependent1));1117 mpt3sas_halt_firmware(ioc);1118 pcie_device = mpt3sas_get_pdev_by_handle(ioc,1119 le16_to_cpu(mpi_request->FunctionDependent1));1120 if (pcie_device && (!ioc->tm_custom_handling) &&1121 (!(mpt3sas_scsih_is_pcie_scsi_device(1122 pcie_device->device_info))))1123 mpt3sas_scsih_issue_locked_tm(ioc,1124 le16_to_cpu(mpi_request->FunctionDependent1),1125 0, 0, 0,1126 MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET, 0,1127 0, pcie_device->reset_timeout,1128 MPI26_SCSITASKMGMT_MSGFLAGS_PROTOCOL_LVL_RST_PCIE);1129 else1130 mpt3sas_scsih_issue_locked_tm(ioc,1131 le16_to_cpu(mpi_request->FunctionDependent1),1132 0, 0, 0,1133 MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET, 0,1134 0, 30, MPI2_SCSITASKMGMT_MSGFLAGS_LINK_RESET);1135 } else1136 mpt3sas_base_hard_reset_handler(ioc, FORCE_BIG_HAMMER);1137 }1138 1139 out:1140 if (pcie_device)1141 pcie_device_put(pcie_device);1142 1143 /* free memory associated with sg buffers */1144 if (data_in)1145 dma_free_coherent(&ioc->pdev->dev, data_in_sz, data_in,1146 data_in_dma);1147 1148 if (data_out)1149 dma_free_coherent(&ioc->pdev->dev, data_out_sz, data_out,1150 data_out_dma);1151 1152 kfree(mpi_request);1153 ioc->ctl_cmds.status = MPT3_CMD_NOT_USED;1154 return ret;1155}1156 1157/**1158 * _ctl_getiocinfo - main handler for MPT3IOCINFO opcode1159 * @ioc: per adapter object1160 * @arg: user space buffer containing ioctl content1161 */1162static long1163_ctl_getiocinfo(struct MPT3SAS_ADAPTER *ioc, void __user *arg)1164{1165 struct mpt3_ioctl_iocinfo karg;1166 1167 dctlprintk(ioc, ioc_info(ioc, "%s: enter\n",1168 __func__));1169 1170 memset(&karg, 0 , sizeof(karg));1171 if (ioc->pfacts)1172 karg.port_number = ioc->pfacts[0].PortNumber;1173 karg.hw_rev = ioc->pdev->revision;1174 karg.pci_id = ioc->pdev->device;1175 karg.subsystem_device = ioc->pdev->subsystem_device;1176 karg.subsystem_vendor = ioc->pdev->subsystem_vendor;1177 karg.pci_information.u.bits.bus = ioc->pdev->bus->number;1178 karg.pci_information.u.bits.device = PCI_SLOT(ioc->pdev->devfn);1179 karg.pci_information.u.bits.function = PCI_FUNC(ioc->pdev->devfn);1180 karg.pci_information.segment_id = pci_domain_nr(ioc->pdev->bus);1181 karg.firmware_version = ioc->facts.FWVersion.Word;1182 strcpy(karg.driver_version, ioc->driver_name);1183 strcat(karg.driver_version, "-");1184 switch (ioc->hba_mpi_version_belonged) {1185 case MPI2_VERSION:1186 if (ioc->is_warpdrive)1187 karg.adapter_type = MPT2_IOCTL_INTERFACE_SAS2_SSS6200;1188 else1189 karg.adapter_type = MPT2_IOCTL_INTERFACE_SAS2;1190 strcat(karg.driver_version, MPT2SAS_DRIVER_VERSION);1191 break;1192 case MPI25_VERSION:1193 case MPI26_VERSION:1194 if (ioc->is_gen35_ioc)1195 karg.adapter_type = MPT3_IOCTL_INTERFACE_SAS35;1196 else1197 karg.adapter_type = MPT3_IOCTL_INTERFACE_SAS3;1198 strcat(karg.driver_version, MPT3SAS_DRIVER_VERSION);1199 break;1200 }1201 karg.bios_version = le32_to_cpu(ioc->bios_pg3.BiosVersion);1202 1203 if (copy_to_user(arg, &karg, sizeof(karg))) {1204 pr_err("failure at %s:%d/%s()!\n",1205 __FILE__, __LINE__, __func__);1206 return -EFAULT;1207 }1208 return 0;1209}1210 1211/**1212 * _ctl_eventquery - main handler for MPT3EVENTQUERY opcode1213 * @ioc: per adapter object1214 * @arg: user space buffer containing ioctl content1215 */1216static long1217_ctl_eventquery(struct MPT3SAS_ADAPTER *ioc, void __user *arg)1218{1219 struct mpt3_ioctl_eventquery karg;1220 1221 if (copy_from_user(&karg, arg, sizeof(karg))) {1222 pr_err("failure at %s:%d/%s()!\n",1223 __FILE__, __LINE__, __func__);1224 return -EFAULT;1225 }1226 1227 dctlprintk(ioc, ioc_info(ioc, "%s: enter\n",1228 __func__));1229 1230 karg.event_entries = MPT3SAS_CTL_EVENT_LOG_SIZE;1231 memcpy(karg.event_types, ioc->event_type,1232 MPI2_EVENT_NOTIFY_EVENTMASK_WORDS * sizeof(u32));1233 1234 if (copy_to_user(arg, &karg, sizeof(karg))) {1235 pr_err("failure at %s:%d/%s()!\n",1236 __FILE__, __LINE__, __func__);1237 return -EFAULT;1238 }1239 return 0;1240}1241 1242/**1243 * _ctl_eventenable - main handler for MPT3EVENTENABLE opcode1244 * @ioc: per adapter object1245 * @arg: user space buffer containing ioctl content1246 */1247static long1248_ctl_eventenable(struct MPT3SAS_ADAPTER *ioc, void __user *arg)1249{1250 struct mpt3_ioctl_eventenable karg;1251 1252 if (copy_from_user(&karg, arg, sizeof(karg))) {1253 pr_err("failure at %s:%d/%s()!\n",1254 __FILE__, __LINE__, __func__);1255 return -EFAULT;1256 }1257 1258 dctlprintk(ioc, ioc_info(ioc, "%s: enter\n",1259 __func__));1260 1261 memcpy(ioc->event_type, karg.event_types,1262 MPI2_EVENT_NOTIFY_EVENTMASK_WORDS * sizeof(u32));1263 mpt3sas_base_validate_event_type(ioc, ioc->event_type);1264 1265 if (ioc->event_log)1266 return 0;1267 /* initialize event_log */1268 ioc->event_context = 0;1269 ioc->aen_event_read_flag = 0;1270 ioc->event_log = kcalloc(MPT3SAS_CTL_EVENT_LOG_SIZE,1271 sizeof(struct MPT3_IOCTL_EVENTS), GFP_KERNEL);1272 if (!ioc->event_log) {1273 pr_err("failure at %s:%d/%s()!\n",1274 __FILE__, __LINE__, __func__);1275 return -ENOMEM;1276 }1277 return 0;1278}1279 1280/**1281 * _ctl_eventreport - main handler for MPT3EVENTREPORT opcode1282 * @ioc: per adapter object1283 * @arg: user space buffer containing ioctl content1284 */1285static long1286_ctl_eventreport(struct MPT3SAS_ADAPTER *ioc, void __user *arg)1287{1288 struct mpt3_ioctl_eventreport karg;1289 u32 number_bytes, max_events, max;1290 struct mpt3_ioctl_eventreport __user *uarg = arg;1291 1292 if (copy_from_user(&karg, arg, sizeof(karg))) {1293 pr_err("failure at %s:%d/%s()!\n",1294 __FILE__, __LINE__, __func__);1295 return -EFAULT;1296 }1297 1298 dctlprintk(ioc, ioc_info(ioc, "%s: enter\n",1299 __func__));1300 1301 number_bytes = karg.hdr.max_data_size -1302 sizeof(struct mpt3_ioctl_header);1303 max_events = number_bytes/sizeof(struct MPT3_IOCTL_EVENTS);1304 max = min_t(u32, MPT3SAS_CTL_EVENT_LOG_SIZE, max_events);1305 1306 /* If fewer than 1 event is requested, there must have1307 * been some type of error.1308 */1309 if (!max || !ioc->event_log)1310 return -ENODATA;1311 1312 number_bytes = max * sizeof(struct MPT3_IOCTL_EVENTS);1313 if (copy_to_user(uarg->event_data, ioc->event_log, number_bytes)) {1314 pr_err("failure at %s:%d/%s()!\n",1315 __FILE__, __LINE__, __func__);1316 return -EFAULT;1317 }1318 1319 /* reset flag so SIGIO can restart */1320 ioc->aen_event_read_flag = 0;1321 return 0;1322}1323 1324/**1325 * _ctl_do_reset - main handler for MPT3HARDRESET opcode1326 * @ioc: per adapter object1327 * @arg: user space buffer containing ioctl content1328 */1329static long1330_ctl_do_reset(struct MPT3SAS_ADAPTER *ioc, void __user *arg)1331{1332 struct mpt3_ioctl_diag_reset karg;1333 int retval;1334 1335 if (copy_from_user(&karg, arg, sizeof(karg))) {1336 pr_err("failure at %s:%d/%s()!\n",1337 __FILE__, __LINE__, __func__);1338 return -EFAULT;1339 }1340 1341 if (ioc->shost_recovery || ioc->pci_error_recovery ||1342 ioc->is_driver_loading)1343 return -EAGAIN;1344 1345 dctlprintk(ioc, ioc_info(ioc, "%s: enter\n",1346 __func__));1347 1348 ioc->reset_from_user = 1;1349 retval = mpt3sas_base_hard_reset_handler(ioc, FORCE_BIG_HAMMER);1350 ioc_info(ioc,1351 "Ioctl: host reset: %s\n", ((!retval) ? "SUCCESS" : "FAILED"));1352 return 0;1353}1354 1355/**1356 * _ctl_btdh_search_sas_device - searching for sas device1357 * @ioc: per adapter object1358 * @btdh: btdh ioctl payload1359 */1360static int1361_ctl_btdh_search_sas_device(struct MPT3SAS_ADAPTER *ioc,1362 struct mpt3_ioctl_btdh_mapping *btdh)1363{1364 struct _sas_device *sas_device;1365 unsigned long flags;1366 int rc = 0;1367 1368 if (list_empty(&ioc->sas_device_list))1369 return rc;1370 1371 spin_lock_irqsave(&ioc->sas_device_lock, flags);1372 list_for_each_entry(sas_device, &ioc->sas_device_list, list) {1373 if (btdh->bus == 0xFFFFFFFF && btdh->id == 0xFFFFFFFF &&1374 btdh->handle == sas_device->handle) {1375 btdh->bus = sas_device->channel;1376 btdh->id = sas_device->id;1377 rc = 1;1378 goto out;1379 } else if (btdh->bus == sas_device->channel && btdh->id ==1380 sas_device->id && btdh->handle == 0xFFFF) {1381 btdh->handle = sas_device->handle;1382 rc = 1;1383 goto out;1384 }1385 }1386 out:1387 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);1388 return rc;1389}1390 1391/**1392 * _ctl_btdh_search_pcie_device - searching for pcie device1393 * @ioc: per adapter object1394 * @btdh: btdh ioctl payload1395 */1396static int1397_ctl_btdh_search_pcie_device(struct MPT3SAS_ADAPTER *ioc,1398 struct mpt3_ioctl_btdh_mapping *btdh)1399{1400 struct _pcie_device *pcie_device;1401 unsigned long flags;1402 int rc = 0;1403 1404 if (list_empty(&ioc->pcie_device_list))1405 return rc;1406 1407 spin_lock_irqsave(&ioc->pcie_device_lock, flags);1408 list_for_each_entry(pcie_device, &ioc->pcie_device_list, list) {1409 if (btdh->bus == 0xFFFFFFFF && btdh->id == 0xFFFFFFFF &&1410 btdh->handle == pcie_device->handle) {1411 btdh->bus = pcie_device->channel;1412 btdh->id = pcie_device->id;1413 rc = 1;1414 goto out;1415 } else if (btdh->bus == pcie_device->channel && btdh->id ==1416 pcie_device->id && btdh->handle == 0xFFFF) {1417 btdh->handle = pcie_device->handle;1418 rc = 1;1419 goto out;1420 }1421 }1422 out:1423 spin_unlock_irqrestore(&ioc->pcie_device_lock, flags);1424 return rc;1425}1426 1427/**1428 * _ctl_btdh_search_raid_device - searching for raid device1429 * @ioc: per adapter object1430 * @btdh: btdh ioctl payload1431 */1432static int1433_ctl_btdh_search_raid_device(struct MPT3SAS_ADAPTER *ioc,1434 struct mpt3_ioctl_btdh_mapping *btdh)1435{1436 struct _raid_device *raid_device;1437 unsigned long flags;1438 int rc = 0;1439 1440 if (list_empty(&ioc->raid_device_list))1441 return rc;1442 1443 spin_lock_irqsave(&ioc->raid_device_lock, flags);1444 list_for_each_entry(raid_device, &ioc->raid_device_list, list) {1445 if (btdh->bus == 0xFFFFFFFF && btdh->id == 0xFFFFFFFF &&1446 btdh->handle == raid_device->handle) {1447 btdh->bus = raid_device->channel;1448 btdh->id = raid_device->id;1449 rc = 1;1450 goto out;1451 } else if (btdh->bus == raid_device->channel && btdh->id ==1452 raid_device->id && btdh->handle == 0xFFFF) {1453 btdh->handle = raid_device->handle;1454 rc = 1;1455 goto out;1456 }1457 }1458 out:1459 spin_unlock_irqrestore(&ioc->raid_device_lock, flags);1460 return rc;1461}1462 1463/**1464 * _ctl_btdh_mapping - main handler for MPT3BTDHMAPPING opcode1465 * @ioc: per adapter object1466 * @arg: user space buffer containing ioctl content1467 */1468static long1469_ctl_btdh_mapping(struct MPT3SAS_ADAPTER *ioc, void __user *arg)1470{1471 struct mpt3_ioctl_btdh_mapping karg;1472 int rc;1473 1474 if (copy_from_user(&karg, arg, sizeof(karg))) {1475 pr_err("failure at %s:%d/%s()!\n",1476 __FILE__, __LINE__, __func__);1477 return -EFAULT;1478 }1479 1480 dctlprintk(ioc, ioc_info(ioc, "%s\n",1481 __func__));1482 1483 rc = _ctl_btdh_search_sas_device(ioc, &karg);1484 if (!rc)1485 rc = _ctl_btdh_search_pcie_device(ioc, &karg);1486 if (!rc)1487 _ctl_btdh_search_raid_device(ioc, &karg);1488 1489 if (copy_to_user(arg, &karg, sizeof(karg))) {1490 pr_err("failure at %s:%d/%s()!\n",1491 __FILE__, __LINE__, __func__);1492 return -EFAULT;1493 }1494 return 0;1495}1496 1497/**1498 * _ctl_diag_capability - return diag buffer capability1499 * @ioc: per adapter object1500 * @buffer_type: specifies either TRACE, SNAPSHOT, or EXTENDED1501 *1502 * returns 1 when diag buffer support is enabled in firmware1503 */1504static u81505_ctl_diag_capability(struct MPT3SAS_ADAPTER *ioc, u8 buffer_type)1506{1507 u8 rc = 0;1508 1509 switch (buffer_type) {1510 case MPI2_DIAG_BUF_TYPE_TRACE:1511 if (ioc->facts.IOCCapabilities &1512 MPI2_IOCFACTS_CAPABILITY_DIAG_TRACE_BUFFER)1513 rc = 1;1514 break;1515 case MPI2_DIAG_BUF_TYPE_SNAPSHOT:1516 if (ioc->facts.IOCCapabilities &1517 MPI2_IOCFACTS_CAPABILITY_SNAPSHOT_BUFFER)1518 rc = 1;1519 break;1520 case MPI2_DIAG_BUF_TYPE_EXTENDED:1521 if (ioc->facts.IOCCapabilities &1522 MPI2_IOCFACTS_CAPABILITY_EXTENDED_BUFFER)1523 rc = 1;1524 }1525 1526 return rc;1527}1528 1529/**1530 * _ctl_diag_get_bufftype - return diag buffer type1531 * either TRACE, SNAPSHOT, or EXTENDED1532 * @ioc: per adapter object1533 * @unique_id: specifies the unique_id for the buffer1534 *1535 * returns MPT3_DIAG_UID_NOT_FOUND if the id not found1536 */1537static u81538_ctl_diag_get_bufftype(struct MPT3SAS_ADAPTER *ioc, u32 unique_id)1539{1540 u8 index;1541 1542 for (index = 0; index < MPI2_DIAG_BUF_TYPE_COUNT; index++) {1543 if (ioc->unique_id[index] == unique_id)1544 return index;1545 }1546 1547 return MPT3_DIAG_UID_NOT_FOUND;1548}1549 1550/**1551 * _ctl_diag_register_2 - wrapper for registering diag buffer support1552 * @ioc: per adapter object1553 * @diag_register: the diag_register struct passed in from user space1554 *1555 */1556static long1557_ctl_diag_register_2(struct MPT3SAS_ADAPTER *ioc,1558 struct mpt3_diag_register *diag_register)1559{1560 int rc, i;1561 void *request_data = NULL;1562 dma_addr_t request_data_dma;1563 u32 request_data_sz = 0;1564 Mpi2DiagBufferPostRequest_t *mpi_request;1565 Mpi2DiagBufferPostReply_t *mpi_reply;1566 u8 buffer_type;1567 u16 smid;1568 u16 ioc_status;1569 u32 ioc_state;1570 u8 issue_reset = 0;1571 1572 dctlprintk(ioc, ioc_info(ioc, "%s\n",1573 __func__));1574 1575 ioc_state = mpt3sas_base_get_iocstate(ioc, 1);1576 if (ioc_state != MPI2_IOC_STATE_OPERATIONAL) {1577 ioc_err(ioc, "%s: failed due to ioc not operational\n",1578 __func__);1579 rc = -EAGAIN;1580 goto out;1581 }1582 1583 if (ioc->ctl_cmds.status != MPT3_CMD_NOT_USED) {1584 ioc_err(ioc, "%s: ctl_cmd in use\n", __func__);1585 rc = -EAGAIN;1586 goto out;1587 }1588 1589 buffer_type = diag_register->buffer_type;1590 if (!_ctl_diag_capability(ioc, buffer_type)) {1591 ioc_err(ioc, "%s: doesn't have capability for buffer_type(0x%02x)\n",1592 __func__, buffer_type);1593 return -EPERM;1594 }1595 1596 if (diag_register->unique_id == 0) {1597 ioc_err(ioc,1598 "%s: Invalid UID(0x%08x), buffer_type(0x%02x)\n", __func__,1599 diag_register->unique_id, buffer_type);1600 return -EINVAL;1601 }1602 1603 if ((ioc->diag_buffer_status[buffer_type] &1604 MPT3_DIAG_BUFFER_IS_APP_OWNED) &&1605 !(ioc->diag_buffer_status[buffer_type] &1606 MPT3_DIAG_BUFFER_IS_RELEASED)) {1607 ioc_err(ioc,1608 "%s: buffer_type(0x%02x) is already registered by application with UID(0x%08x)\n",1609 __func__, buffer_type, ioc->unique_id[buffer_type]);1610 return -EINVAL;1611 }1612 1613 if (ioc->diag_buffer_status[buffer_type] &1614 MPT3_DIAG_BUFFER_IS_REGISTERED) {1615 /*1616 * If driver posts buffer initially, then an application wants1617 * to Register that buffer (own it) without Releasing first,1618 * the application Register command MUST have the same buffer1619 * type and size in the Register command (obtained from the1620 * Query command). Otherwise that Register command will be1621 * failed. If the application has released the buffer but wants1622 * to re-register it, it should be allowed as long as the1623 * Unique-Id/Size match.1624 */1625 1626 if (ioc->unique_id[buffer_type] == MPT3DIAGBUFFUNIQUEID &&1627 ioc->diag_buffer_sz[buffer_type] ==1628 diag_register->requested_buffer_size) {1629 1630 if (!(ioc->diag_buffer_status[buffer_type] &1631 MPT3_DIAG_BUFFER_IS_RELEASED)) {1632 dctlprintk(ioc, ioc_info(ioc,1633 "%s: diag_buffer (%d) ownership changed. old-ID(0x%08x), new-ID(0x%08x)\n",1634 __func__, buffer_type,1635 ioc->unique_id[buffer_type],1636 diag_register->unique_id));1637 1638 /*1639 * Application wants to own the buffer with1640 * the same size.1641 */1642 ioc->unique_id[buffer_type] =1643 diag_register->unique_id;1644 rc = 0; /* success */1645 goto out;1646 }1647 } else if (ioc->unique_id[buffer_type] !=1648 MPT3DIAGBUFFUNIQUEID) {1649 if (ioc->unique_id[buffer_type] !=1650 diag_register->unique_id ||1651 ioc->diag_buffer_sz[buffer_type] !=1652 diag_register->requested_buffer_size ||1653 !(ioc->diag_buffer_status[buffer_type] &1654 MPT3_DIAG_BUFFER_IS_RELEASED)) {1655 ioc_err(ioc,1656 "%s: already has a registered buffer for buffer_type(0x%02x)\n",1657 __func__, buffer_type);1658 return -EINVAL;1659 }1660 } else {1661 ioc_err(ioc, "%s: already has a registered buffer for buffer_type(0x%02x)\n",1662 __func__, buffer_type);1663 return -EINVAL;1664 }1665 } else if (ioc->diag_buffer_status[buffer_type] &1666 MPT3_DIAG_BUFFER_IS_DRIVER_ALLOCATED) {1667 1668 if (ioc->unique_id[buffer_type] != MPT3DIAGBUFFUNIQUEID ||1669 ioc->diag_buffer_sz[buffer_type] !=1670 diag_register->requested_buffer_size) {1671 1672 ioc_err(ioc,1673 "%s: already a buffer is allocated for buffer_type(0x%02x) of size %d bytes, so please try registering again with same size\n",1674 __func__, buffer_type,1675 ioc->diag_buffer_sz[buffer_type]);1676 return -EINVAL;1677 }1678 }1679 1680 if (diag_register->requested_buffer_size % 4) {1681 ioc_err(ioc, "%s: the requested_buffer_size is not 4 byte aligned\n",1682 __func__);1683 return -EINVAL;1684 }1685 1686 smid = mpt3sas_base_get_smid(ioc, ioc->ctl_cb_idx);1687 if (!smid) {1688 ioc_err(ioc, "%s: failed obtaining a smid\n", __func__);1689 rc = -EAGAIN;1690 goto out;1691 }1692 1693 rc = 0;1694 ioc->ctl_cmds.status = MPT3_CMD_PENDING;1695 memset(ioc->ctl_cmds.reply, 0, ioc->reply_sz);1696 mpi_request = mpt3sas_base_get_msg_frame(ioc, smid);1697 memset(mpi_request, 0, ioc->request_sz);1698 ioc->ctl_cmds.smid = smid;1699 1700 request_data = ioc->diag_buffer[buffer_type];1701 request_data_sz = diag_register->requested_buffer_size;1702 ioc->unique_id[buffer_type] = diag_register->unique_id;1703 /* Reset ioc variables used for additional query commands */1704 ioc->reset_from_user = 0;1705 memset(&ioc->htb_rel, 0, sizeof(struct htb_rel_query));1706 ioc->diag_buffer_status[buffer_type] &=1707 MPT3_DIAG_BUFFER_IS_DRIVER_ALLOCATED;1708 memcpy(ioc->product_specific[buffer_type],1709 diag_register->product_specific, MPT3_PRODUCT_SPECIFIC_DWORDS);1710 ioc->diagnostic_flags[buffer_type] = diag_register->diagnostic_flags;1711 1712 if (request_data) {1713 request_data_dma = ioc->diag_buffer_dma[buffer_type];1714 if (request_data_sz != ioc->diag_buffer_sz[buffer_type]) {1715 dma_free_coherent(&ioc->pdev->dev,1716 ioc->diag_buffer_sz[buffer_type],1717 request_data, request_data_dma);1718 request_data = NULL;1719 }1720 }1721 1722 if (request_data == NULL) {1723 ioc->diag_buffer_sz[buffer_type] = 0;1724 ioc->diag_buffer_dma[buffer_type] = 0;1725 request_data = dma_alloc_coherent(&ioc->pdev->dev,1726 request_data_sz, &request_data_dma, GFP_KERNEL);1727 if (request_data == NULL) {1728 ioc_err(ioc, "%s: failed allocating memory for diag buffers, requested size(%d)\n",1729 __func__, request_data_sz);1730 mpt3sas_base_free_smid(ioc, smid);1731 rc = -ENOMEM;1732 goto out;1733 }1734 ioc->diag_buffer[buffer_type] = request_data;1735 ioc->diag_buffer_sz[buffer_type] = request_data_sz;1736 ioc->diag_buffer_dma[buffer_type] = request_data_dma;1737 }1738 1739 mpi_request->Function = MPI2_FUNCTION_DIAG_BUFFER_POST;1740 mpi_request->BufferType = diag_register->buffer_type;1741 mpi_request->Flags = cpu_to_le32(diag_register->diagnostic_flags);1742 mpi_request->BufferAddress = cpu_to_le64(request_data_dma);1743 mpi_request->BufferLength = cpu_to_le32(request_data_sz);1744 mpi_request->VF_ID = 0; /* TODO */1745 mpi_request->VP_ID = 0;1746 1747 dctlprintk(ioc,1748 ioc_info(ioc, "%s: diag_buffer(0x%p), dma(0x%llx), sz(%d)\n",1749 __func__, request_data,1750 (unsigned long long)request_data_dma,1751 le32_to_cpu(mpi_request->BufferLength)));1752 1753 for (i = 0; i < MPT3_PRODUCT_SPECIFIC_DWORDS; i++)1754 mpi_request->ProductSpecific[i] =1755 cpu_to_le32(ioc->product_specific[buffer_type][i]);1756 1757 init_completion(&ioc->ctl_cmds.done);1758 ioc->put_smid_default(ioc, smid);1759 wait_for_completion_timeout(&ioc->ctl_cmds.done,1760 MPT3_IOCTL_DEFAULT_TIMEOUT*HZ);1761 1762 if (!(ioc->ctl_cmds.status & MPT3_CMD_COMPLETE)) {1763 mpt3sas_check_cmd_timeout(ioc,1764 ioc->ctl_cmds.status, mpi_request,1765 sizeof(Mpi2DiagBufferPostRequest_t)/4, issue_reset);1766 goto issue_host_reset;1767 }1768 1769 /* process the completed Reply Message Frame */1770 if ((ioc->ctl_cmds.status & MPT3_CMD_REPLY_VALID) == 0) {1771 ioc_err(ioc, "%s: no reply message\n", __func__);1772 rc = -EFAULT;1773 goto out;1774 }1775 1776 mpi_reply = ioc->ctl_cmds.reply;1777 ioc_status = le16_to_cpu(mpi_reply->IOCStatus) & MPI2_IOCSTATUS_MASK;1778 1779 if (ioc_status == MPI2_IOCSTATUS_SUCCESS) {1780 ioc->diag_buffer_status[buffer_type] |=1781 MPT3_DIAG_BUFFER_IS_REGISTERED;1782 dctlprintk(ioc, ioc_info(ioc, "%s: success\n", __func__));1783 } else {1784 ioc_info(ioc, "%s: ioc_status(0x%04x) log_info(0x%08x)\n",1785 __func__,1786 ioc_status, le32_to_cpu(mpi_reply->IOCLogInfo));1787 rc = -EFAULT;1788 }1789 1790 issue_host_reset:1791 if (issue_reset)1792 mpt3sas_base_hard_reset_handler(ioc, FORCE_BIG_HAMMER);1793 1794 out:1795 1796 if (rc && request_data) {1797 dma_free_coherent(&ioc->pdev->dev, request_data_sz,1798 request_data, request_data_dma);1799 ioc->diag_buffer[buffer_type] = NULL;1800 ioc->diag_buffer_status[buffer_type] &=1801 ~MPT3_DIAG_BUFFER_IS_DRIVER_ALLOCATED;1802 }1803 1804 ioc->ctl_cmds.status = MPT3_CMD_NOT_USED;1805 return rc;1806}1807 1808/**1809 * mpt3sas_enable_diag_buffer - enabling diag_buffers support driver load time1810 * @ioc: per adapter object1811 * @bits_to_register: bitwise field where trace is bit 0, and snapshot is bit 11812 *1813 * This is called when command line option diag_buffer_enable is enabled1814 * at driver load time.1815 */1816void1817mpt3sas_enable_diag_buffer(struct MPT3SAS_ADAPTER *ioc, u8 bits_to_register)1818{1819 struct mpt3_diag_register diag_register;1820 u32 ret_val;1821 u32 trace_buff_size = ioc->manu_pg11.HostTraceBufferMaxSizeKB<<10;1822 u32 min_trace_buff_size = 0;1823 u32 decr_trace_buff_size = 0;1824 1825 memset(&diag_register, 0, sizeof(struct mpt3_diag_register));1826 1827 if (bits_to_register & 1) {1828 ioc_info(ioc, "registering trace buffer support\n");1829 ioc->diag_trigger_master.MasterData =1830 (MASTER_TRIGGER_FW_FAULT + MASTER_TRIGGER_ADAPTER_RESET);1831 diag_register.buffer_type = MPI2_DIAG_BUF_TYPE_TRACE;1832 diag_register.unique_id =1833 (ioc->hba_mpi_version_belonged == MPI2_VERSION) ?1834 (MPT2DIAGBUFFUNIQUEID):(MPT3DIAGBUFFUNIQUEID);1835 1836 if (trace_buff_size != 0) {1837 diag_register.requested_buffer_size = trace_buff_size;1838 min_trace_buff_size =1839 ioc->manu_pg11.HostTraceBufferMinSizeKB<<10;1840 decr_trace_buff_size =1841 ioc->manu_pg11.HostTraceBufferDecrementSizeKB<<10;1842 1843 if (min_trace_buff_size > trace_buff_size) {1844 /* The buff size is not set correctly */1845 ioc_err(ioc,1846 "Min Trace Buff size (%d KB) greater than Max Trace Buff size (%d KB)\n",1847 min_trace_buff_size>>10,1848 trace_buff_size>>10);1849 ioc_err(ioc,1850 "Using zero Min Trace Buff Size\n");1851 min_trace_buff_size = 0;1852 }1853 1854 if (decr_trace_buff_size == 0) {1855 /*1856 * retry the min size if decrement1857 * is not available.1858 */1859 decr_trace_buff_size =1860 trace_buff_size - min_trace_buff_size;1861 }1862 } else {1863 /* register for 2MB buffers */1864 diag_register.requested_buffer_size = 2 * (1024 * 1024);1865 }1866 1867 do {1868 ret_val = _ctl_diag_register_2(ioc, &diag_register);1869 1870 if (ret_val == -ENOMEM && min_trace_buff_size &&1871 (trace_buff_size - decr_trace_buff_size) >=1872 min_trace_buff_size) {1873 /* adjust the buffer size */1874 trace_buff_size -= decr_trace_buff_size;1875 diag_register.requested_buffer_size =1876 trace_buff_size;1877 } else1878 break;1879 } while (true);1880 1881 if (ret_val == -ENOMEM)1882 ioc_err(ioc,1883 "Cannot allocate trace buffer memory. Last memory tried = %d KB\n",1884 diag_register.requested_buffer_size>>10);1885 else if (ioc->diag_buffer_status[MPI2_DIAG_BUF_TYPE_TRACE]1886 & MPT3_DIAG_BUFFER_IS_REGISTERED) {1887 ioc_info(ioc, "Trace buffer memory %d KB allocated\n",1888 diag_register.requested_buffer_size>>10);1889 if (ioc->hba_mpi_version_belonged != MPI2_VERSION)1890 ioc->diag_buffer_status[1891 MPI2_DIAG_BUF_TYPE_TRACE] |=1892 MPT3_DIAG_BUFFER_IS_DRIVER_ALLOCATED;1893 }1894 }1895 1896 if (bits_to_register & 2) {1897 ioc_info(ioc, "registering snapshot buffer support\n");1898 diag_register.buffer_type = MPI2_DIAG_BUF_TYPE_SNAPSHOT;1899 /* register for 2MB buffers */1900 diag_register.requested_buffer_size = 2 * (1024 * 1024);1901 diag_register.unique_id = 0x7075901;1902 _ctl_diag_register_2(ioc, &diag_register);1903 }1904 1905 if (bits_to_register & 4) {1906 ioc_info(ioc, "registering extended buffer support\n");1907 diag_register.buffer_type = MPI2_DIAG_BUF_TYPE_EXTENDED;1908 /* register for 2MB buffers */1909 diag_register.requested_buffer_size = 2 * (1024 * 1024);1910 diag_register.unique_id = 0x7075901;1911 _ctl_diag_register_2(ioc, &diag_register);1912 }1913}1914 1915/**1916 * _ctl_diag_register - application register with driver1917 * @ioc: per adapter object1918 * @arg: user space buffer containing ioctl content1919 *1920 * This will allow the driver to setup any required buffers that will be1921 * needed by firmware to communicate with the driver.1922 */1923static long1924_ctl_diag_register(struct MPT3SAS_ADAPTER *ioc, void __user *arg)1925{1926 struct mpt3_diag_register karg;1927 long rc;1928 1929 if (copy_from_user(&karg, arg, sizeof(karg))) {1930 pr_err("failure at %s:%d/%s()!\n",1931 __FILE__, __LINE__, __func__);1932 return -EFAULT;1933 }1934 1935 rc = _ctl_diag_register_2(ioc, &karg);1936 1937 if (!rc && (ioc->diag_buffer_status[karg.buffer_type] &1938 MPT3_DIAG_BUFFER_IS_REGISTERED))1939 ioc->diag_buffer_status[karg.buffer_type] |=1940 MPT3_DIAG_BUFFER_IS_APP_OWNED;1941 1942 return rc;1943}1944 1945/**1946 * _ctl_diag_unregister - application unregister with driver1947 * @ioc: per adapter object1948 * @arg: user space buffer containing ioctl content1949 *1950 * This will allow the driver to cleanup any memory allocated for diag1951 * messages and to free up any resources.1952 */1953static long1954_ctl_diag_unregister(struct MPT3SAS_ADAPTER *ioc, void __user *arg)1955{1956 struct mpt3_diag_unregister karg;1957 void *request_data;1958 dma_addr_t request_data_dma;1959 u32 request_data_sz;1960 u8 buffer_type;1961 1962 if (copy_from_user(&karg, arg, sizeof(karg))) {1963 pr_err("failure at %s:%d/%s()!\n",1964 __FILE__, __LINE__, __func__);1965 return -EFAULT;1966 }1967 1968 dctlprintk(ioc, ioc_info(ioc, "%s\n",1969 __func__));1970 1971 buffer_type = _ctl_diag_get_bufftype(ioc, karg.unique_id);1972 if (buffer_type == MPT3_DIAG_UID_NOT_FOUND) {1973 ioc_err(ioc, "%s: buffer with unique_id(0x%08x) not found\n",1974 __func__, karg.unique_id);1975 return -EINVAL;1976 }1977 1978 if (!_ctl_diag_capability(ioc, buffer_type)) {1979 ioc_err(ioc, "%s: doesn't have capability for buffer_type(0x%02x)\n",1980 __func__, buffer_type);1981 return -EPERM;1982 }1983 1984 if ((ioc->diag_buffer_status[buffer_type] &1985 MPT3_DIAG_BUFFER_IS_REGISTERED) == 0) {1986 ioc_err(ioc, "%s: buffer_type(0x%02x) is not registered\n",1987 __func__, buffer_type);1988 return -EINVAL;1989 }1990 if ((ioc->diag_buffer_status[buffer_type] &1991 MPT3_DIAG_BUFFER_IS_RELEASED) == 0) {1992 ioc_err(ioc, "%s: buffer_type(0x%02x) has not been released\n",1993 __func__, buffer_type);1994 return -EINVAL;1995 }1996 1997 if (karg.unique_id != ioc->unique_id[buffer_type]) {1998 ioc_err(ioc, "%s: unique_id(0x%08x) is not registered\n",1999 __func__, karg.unique_id);2000 return -EINVAL;2001 }2002 2003 request_data = ioc->diag_buffer[buffer_type];2004 if (!request_data) {2005 ioc_err(ioc, "%s: doesn't have memory allocated for buffer_type(0x%02x)\n",2006 __func__, buffer_type);2007 return -ENOMEM;2008 }2009 2010 if (ioc->diag_buffer_status[buffer_type] &2011 MPT3_DIAG_BUFFER_IS_DRIVER_ALLOCATED) {2012 ioc->unique_id[buffer_type] = MPT3DIAGBUFFUNIQUEID;2013 ioc->diag_buffer_status[buffer_type] &=2014 ~MPT3_DIAG_BUFFER_IS_APP_OWNED;2015 ioc->diag_buffer_status[buffer_type] &=2016 ~MPT3_DIAG_BUFFER_IS_REGISTERED;2017 } else {2018 request_data_sz = ioc->diag_buffer_sz[buffer_type];2019 request_data_dma = ioc->diag_buffer_dma[buffer_type];2020 dma_free_coherent(&ioc->pdev->dev, request_data_sz,2021 request_data, request_data_dma);2022 ioc->diag_buffer[buffer_type] = NULL;2023 ioc->diag_buffer_status[buffer_type] = 0;2024 }2025 return 0;2026}2027 2028/**2029 * _ctl_diag_query - query relevant info associated with diag buffers2030 * @ioc: per adapter object2031 * @arg: user space buffer containing ioctl content2032 *2033 * The application will send only buffer_type and unique_id. Driver will2034 * inspect unique_id first, if valid, fill in all the info. If unique_id is2035 * 0x00, the driver will return info specified by Buffer Type.2036 */2037static long2038_ctl_diag_query(struct MPT3SAS_ADAPTER *ioc, void __user *arg)2039{2040 struct mpt3_diag_query karg;2041 void *request_data;2042 int i;2043 u8 buffer_type;2044 2045 if (copy_from_user(&karg, arg, sizeof(karg))) {2046 pr_err("failure at %s:%d/%s()!\n",2047 __FILE__, __LINE__, __func__);2048 return -EFAULT;2049 }2050 2051 dctlprintk(ioc, ioc_info(ioc, "%s\n",2052 __func__));2053 2054 karg.application_flags = 0;2055 buffer_type = karg.buffer_type;2056 2057 if (!_ctl_diag_capability(ioc, buffer_type)) {2058 ioc_err(ioc, "%s: doesn't have capability for buffer_type(0x%02x)\n",2059 __func__, buffer_type);2060 return -EPERM;2061 }2062 2063 if (!(ioc->diag_buffer_status[buffer_type] &2064 MPT3_DIAG_BUFFER_IS_DRIVER_ALLOCATED)) {2065 if ((ioc->diag_buffer_status[buffer_type] &2066 MPT3_DIAG_BUFFER_IS_REGISTERED) == 0) {2067 ioc_err(ioc, "%s: buffer_type(0x%02x) is not registered\n",2068 __func__, buffer_type);2069 return -EINVAL;2070 }2071 }2072 2073 if (karg.unique_id) {2074 if (karg.unique_id != ioc->unique_id[buffer_type]) {2075 ioc_err(ioc, "%s: unique_id(0x%08x) is not registered\n",2076 __func__, karg.unique_id);2077 return -EINVAL;2078 }2079 }2080 2081 request_data = ioc->diag_buffer[buffer_type];2082 if (!request_data) {2083 ioc_err(ioc, "%s: doesn't have buffer for buffer_type(0x%02x)\n",2084 __func__, buffer_type);2085 return -ENOMEM;2086 }2087 2088 if ((ioc->diag_buffer_status[buffer_type] &2089 MPT3_DIAG_BUFFER_IS_REGISTERED))2090 karg.application_flags |= MPT3_APP_FLAGS_BUFFER_VALID;2091 2092 if (!(ioc->diag_buffer_status[buffer_type] &2093 MPT3_DIAG_BUFFER_IS_RELEASED))2094 karg.application_flags |= MPT3_APP_FLAGS_FW_BUFFER_ACCESS;2095 2096 if (!(ioc->diag_buffer_status[buffer_type] &2097 MPT3_DIAG_BUFFER_IS_DRIVER_ALLOCATED))2098 karg.application_flags |= MPT3_APP_FLAGS_DYNAMIC_BUFFER_ALLOC;2099 2100 if ((ioc->diag_buffer_status[buffer_type] &2101 MPT3_DIAG_BUFFER_IS_APP_OWNED))2102 karg.application_flags |= MPT3_APP_FLAGS_APP_OWNED;2103 2104 for (i = 0; i < MPT3_PRODUCT_SPECIFIC_DWORDS; i++)2105 karg.product_specific[i] =2106 ioc->product_specific[buffer_type][i];2107 2108 karg.total_buffer_size = ioc->diag_buffer_sz[buffer_type];2109 karg.driver_added_buffer_size = 0;2110 karg.unique_id = ioc->unique_id[buffer_type];2111 karg.diagnostic_flags = ioc->diagnostic_flags[buffer_type];2112 2113 if (copy_to_user(arg, &karg, sizeof(struct mpt3_diag_query))) {2114 ioc_err(ioc, "%s: unable to write mpt3_diag_query data @ %p\n",2115 __func__, arg);2116 return -EFAULT;2117 }2118 return 0;2119}2120 2121/**2122 * mpt3sas_send_diag_release - Diag Release Message2123 * @ioc: per adapter object2124 * @buffer_type: specifies either TRACE, SNAPSHOT, or EXTENDED2125 * @issue_reset: specifies whether host reset is required.2126 *2127 */2128int2129mpt3sas_send_diag_release(struct MPT3SAS_ADAPTER *ioc, u8 buffer_type,2130 u8 *issue_reset)2131{2132 Mpi2DiagReleaseRequest_t *mpi_request;2133 Mpi2DiagReleaseReply_t *mpi_reply;2134 u16 smid;2135 u16 ioc_status;2136 u32 ioc_state;2137 int rc;2138 u8 reset_needed = 0;2139 2140 dctlprintk(ioc, ioc_info(ioc, "%s\n",2141 __func__));2142 2143 rc = 0;2144 *issue_reset = 0;2145 2146 2147 ioc_state = mpt3sas_base_get_iocstate(ioc, 1);2148 if (ioc_state != MPI2_IOC_STATE_OPERATIONAL) {2149 if (ioc->diag_buffer_status[buffer_type] &2150 MPT3_DIAG_BUFFER_IS_REGISTERED)2151 ioc->diag_buffer_status[buffer_type] |=2152 MPT3_DIAG_BUFFER_IS_RELEASED;2153 dctlprintk(ioc,2154 ioc_info(ioc, "%s: skipping due to FAULT state\n",2155 __func__));2156 rc = -EAGAIN;2157 goto out;2158 }2159 2160 if (ioc->ctl_cmds.status != MPT3_CMD_NOT_USED) {2161 ioc_err(ioc, "%s: ctl_cmd in use\n", __func__);2162 rc = -EAGAIN;2163 goto out;2164 }2165 2166 smid = mpt3sas_base_get_smid(ioc, ioc->ctl_cb_idx);2167 if (!smid) {2168 ioc_err(ioc, "%s: failed obtaining a smid\n", __func__);2169 rc = -EAGAIN;2170 goto out;2171 }2172 2173 ioc->ctl_cmds.status = MPT3_CMD_PENDING;2174 memset(ioc->ctl_cmds.reply, 0, ioc->reply_sz);2175 mpi_request = mpt3sas_base_get_msg_frame(ioc, smid);2176 memset(mpi_request, 0, ioc->request_sz);2177 ioc->ctl_cmds.smid = smid;2178 2179 mpi_request->Function = MPI2_FUNCTION_DIAG_RELEASE;2180 mpi_request->BufferType = buffer_type;2181 mpi_request->VF_ID = 0; /* TODO */2182 mpi_request->VP_ID = 0;2183 2184 init_completion(&ioc->ctl_cmds.done);2185 ioc->put_smid_default(ioc, smid);2186 wait_for_completion_timeout(&ioc->ctl_cmds.done,2187 MPT3_IOCTL_DEFAULT_TIMEOUT*HZ);2188 2189 if (!(ioc->ctl_cmds.status & MPT3_CMD_COMPLETE)) {2190 mpt3sas_check_cmd_timeout(ioc,2191 ioc->ctl_cmds.status, mpi_request,2192 sizeof(Mpi2DiagReleaseRequest_t)/4, reset_needed);2193 *issue_reset = reset_needed;2194 rc = -EFAULT;2195 goto out;2196 }2197 2198 /* process the completed Reply Message Frame */2199 if ((ioc->ctl_cmds.status & MPT3_CMD_REPLY_VALID) == 0) {2200 ioc_err(ioc, "%s: no reply message\n", __func__);2201 rc = -EFAULT;2202 goto out;2203 }2204 2205 mpi_reply = ioc->ctl_cmds.reply;2206 ioc_status = le16_to_cpu(mpi_reply->IOCStatus) & MPI2_IOCSTATUS_MASK;2207 2208 if (ioc_status == MPI2_IOCSTATUS_SUCCESS) {2209 ioc->diag_buffer_status[buffer_type] |=2210 MPT3_DIAG_BUFFER_IS_RELEASED;2211 dctlprintk(ioc, ioc_info(ioc, "%s: success\n", __func__));2212 } else {2213 ioc_info(ioc, "%s: ioc_status(0x%04x) log_info(0x%08x)\n",2214 __func__,2215 ioc_status, le32_to_cpu(mpi_reply->IOCLogInfo));2216 rc = -EFAULT;2217 }2218 2219 out:2220 ioc->ctl_cmds.status = MPT3_CMD_NOT_USED;2221 return rc;2222}2223 2224/**2225 * _ctl_diag_release - request to send Diag Release Message to firmware2226 * @ioc: ?2227 * @arg: user space buffer containing ioctl content2228 *2229 * This allows ownership of the specified buffer to returned to the driver,2230 * allowing an application to read the buffer without fear that firmware is2231 * overwriting information in the buffer.2232 */2233static long2234_ctl_diag_release(struct MPT3SAS_ADAPTER *ioc, void __user *arg)2235{2236 struct mpt3_diag_release karg;2237 void *request_data;2238 int rc;2239 u8 buffer_type;2240 u8 issue_reset = 0;2241 2242 if (copy_from_user(&karg, arg, sizeof(karg))) {2243 pr_err("failure at %s:%d/%s()!\n",2244 __FILE__, __LINE__, __func__);2245 return -EFAULT;2246 }2247 2248 dctlprintk(ioc, ioc_info(ioc, "%s\n",2249 __func__));2250 2251 buffer_type = _ctl_diag_get_bufftype(ioc, karg.unique_id);2252 if (buffer_type == MPT3_DIAG_UID_NOT_FOUND) {2253 ioc_err(ioc, "%s: buffer with unique_id(0x%08x) not found\n",2254 __func__, karg.unique_id);2255 return -EINVAL;2256 }2257 2258 if (!_ctl_diag_capability(ioc, buffer_type)) {2259 ioc_err(ioc, "%s: doesn't have capability for buffer_type(0x%02x)\n",2260 __func__, buffer_type);2261 return -EPERM;2262 }2263 2264 if ((ioc->diag_buffer_status[buffer_type] &2265 MPT3_DIAG_BUFFER_IS_REGISTERED) == 0) {2266 ioc_err(ioc, "%s: buffer_type(0x%02x) is not registered\n",2267 __func__, buffer_type);2268 return -EINVAL;2269 }2270 2271 if (karg.unique_id != ioc->unique_id[buffer_type]) {2272 ioc_err(ioc, "%s: unique_id(0x%08x) is not registered\n",2273 __func__, karg.unique_id);2274 return -EINVAL;2275 }2276 2277 if (ioc->diag_buffer_status[buffer_type] &2278 MPT3_DIAG_BUFFER_IS_RELEASED) {2279 ioc_err(ioc, "%s: buffer_type(0x%02x) is already released\n",2280 __func__, buffer_type);2281 return -EINVAL;2282 }2283 2284 request_data = ioc->diag_buffer[buffer_type];2285 2286 if (!request_data) {2287 ioc_err(ioc, "%s: doesn't have memory allocated for buffer_type(0x%02x)\n",2288 __func__, buffer_type);2289 return -ENOMEM;2290 }2291 2292 /* buffers were released by due to host reset */2293 if ((ioc->diag_buffer_status[buffer_type] &2294 MPT3_DIAG_BUFFER_IS_DIAG_RESET)) {2295 ioc->diag_buffer_status[buffer_type] |=2296 MPT3_DIAG_BUFFER_IS_RELEASED;2297 ioc->diag_buffer_status[buffer_type] &=2298 ~MPT3_DIAG_BUFFER_IS_DIAG_RESET;2299 ioc_err(ioc, "%s: buffer_type(0x%02x) was released due to host reset\n",2300 __func__, buffer_type);2301 return 0;2302 }2303 2304 rc = mpt3sas_send_diag_release(ioc, buffer_type, &issue_reset);2305 2306 if (issue_reset)2307 mpt3sas_base_hard_reset_handler(ioc, FORCE_BIG_HAMMER);2308 2309 return rc;2310}2311 2312/**2313 * _ctl_diag_read_buffer - request for copy of the diag buffer2314 * @ioc: per adapter object2315 * @arg: user space buffer containing ioctl content2316 */2317static long2318_ctl_diag_read_buffer(struct MPT3SAS_ADAPTER *ioc, void __user *arg)2319{2320 struct mpt3_diag_read_buffer karg;2321 struct mpt3_diag_read_buffer __user *uarg = arg;2322 void *request_data, *diag_data;2323 Mpi2DiagBufferPostRequest_t *mpi_request;2324 Mpi2DiagBufferPostReply_t *mpi_reply;2325 int rc, i;2326 u8 buffer_type;2327 unsigned long request_size, copy_size;2328 u16 smid;2329 u16 ioc_status;2330 u8 issue_reset = 0;2331 2332 if (copy_from_user(&karg, arg, sizeof(karg))) {2333 pr_err("failure at %s:%d/%s()!\n",2334 __FILE__, __LINE__, __func__);2335 return -EFAULT;2336 }2337 2338 dctlprintk(ioc, ioc_info(ioc, "%s\n",2339 __func__));2340 2341 buffer_type = _ctl_diag_get_bufftype(ioc, karg.unique_id);2342 if (buffer_type == MPT3_DIAG_UID_NOT_FOUND) {2343 ioc_err(ioc, "%s: buffer with unique_id(0x%08x) not found\n",2344 __func__, karg.unique_id);2345 return -EINVAL;2346 }2347 2348 if (!_ctl_diag_capability(ioc, buffer_type)) {2349 ioc_err(ioc, "%s: doesn't have capability for buffer_type(0x%02x)\n",2350 __func__, buffer_type);2351 return -EPERM;2352 }2353 2354 if (karg.unique_id != ioc->unique_id[buffer_type]) {2355 ioc_err(ioc, "%s: unique_id(0x%08x) is not registered\n",2356 __func__, karg.unique_id);2357 return -EINVAL;2358 }2359 2360 request_data = ioc->diag_buffer[buffer_type];2361 if (!request_data) {2362 ioc_err(ioc, "%s: doesn't have buffer for buffer_type(0x%02x)\n",2363 __func__, buffer_type);2364 return -ENOMEM;2365 }2366 2367 request_size = ioc->diag_buffer_sz[buffer_type];2368 2369 if ((karg.starting_offset % 4) || (karg.bytes_to_read % 4)) {2370 ioc_err(ioc, "%s: either the starting_offset or bytes_to_read are not 4 byte aligned\n",2371 __func__);2372 return -EINVAL;2373 }2374 2375 if (karg.starting_offset > request_size)2376 return -EINVAL;2377 2378 diag_data = (void *)(request_data + karg.starting_offset);2379 dctlprintk(ioc,2380 ioc_info(ioc, "%s: diag_buffer(%p), offset(%d), sz(%d)\n",2381 __func__, diag_data, karg.starting_offset,2382 karg.bytes_to_read));2383 2384 /* Truncate data on requests that are too large */2385 if ((diag_data + karg.bytes_to_read < diag_data) ||2386 (diag_data + karg.bytes_to_read > request_data + request_size))2387 copy_size = request_size - karg.starting_offset;2388 else2389 copy_size = karg.bytes_to_read;2390 2391 if (copy_to_user((void __user *)uarg->diagnostic_data,2392 diag_data, copy_size)) {2393 ioc_err(ioc, "%s: Unable to write mpt_diag_read_buffer_t data @ %p\n",2394 __func__, diag_data);2395 return -EFAULT;2396 }2397 2398 if ((karg.flags & MPT3_FLAGS_REREGISTER) == 0)2399 return 0;2400 2401 dctlprintk(ioc,2402 ioc_info(ioc, "%s: Reregister buffer_type(0x%02x)\n",2403 __func__, buffer_type));2404 if ((ioc->diag_buffer_status[buffer_type] &2405 MPT3_DIAG_BUFFER_IS_RELEASED) == 0) {2406 dctlprintk(ioc,2407 ioc_info(ioc, "%s: buffer_type(0x%02x) is still registered\n",2408 __func__, buffer_type));2409 return 0;2410 }2411 /* Get a free request frame and save the message context.2412 */2413 2414 if (ioc->ctl_cmds.status != MPT3_CMD_NOT_USED) {2415 ioc_err(ioc, "%s: ctl_cmd in use\n", __func__);2416 rc = -EAGAIN;2417 goto out;2418 }2419 2420 smid = mpt3sas_base_get_smid(ioc, ioc->ctl_cb_idx);2421 if (!smid) {2422 ioc_err(ioc, "%s: failed obtaining a smid\n", __func__);2423 rc = -EAGAIN;2424 goto out;2425 }2426 2427 rc = 0;2428 ioc->ctl_cmds.status = MPT3_CMD_PENDING;2429 memset(ioc->ctl_cmds.reply, 0, ioc->reply_sz);2430 mpi_request = mpt3sas_base_get_msg_frame(ioc, smid);2431 memset(mpi_request, 0, ioc->request_sz);2432 ioc->ctl_cmds.smid = smid;2433 2434 mpi_request->Function = MPI2_FUNCTION_DIAG_BUFFER_POST;2435 mpi_request->BufferType = buffer_type;2436 mpi_request->BufferLength =2437 cpu_to_le32(ioc->diag_buffer_sz[buffer_type]);2438 mpi_request->BufferAddress =2439 cpu_to_le64(ioc->diag_buffer_dma[buffer_type]);2440 for (i = 0; i < MPT3_PRODUCT_SPECIFIC_DWORDS; i++)2441 mpi_request->ProductSpecific[i] =2442 cpu_to_le32(ioc->product_specific[buffer_type][i]);2443 mpi_request->VF_ID = 0; /* TODO */2444 mpi_request->VP_ID = 0;2445 2446 init_completion(&ioc->ctl_cmds.done);2447 ioc->put_smid_default(ioc, smid);2448 wait_for_completion_timeout(&ioc->ctl_cmds.done,2449 MPT3_IOCTL_DEFAULT_TIMEOUT*HZ);2450 2451 if (!(ioc->ctl_cmds.status & MPT3_CMD_COMPLETE)) {2452 mpt3sas_check_cmd_timeout(ioc,2453 ioc->ctl_cmds.status, mpi_request,2454 sizeof(Mpi2DiagBufferPostRequest_t)/4, issue_reset);2455 goto issue_host_reset;2456 }2457 2458 /* process the completed Reply Message Frame */2459 if ((ioc->ctl_cmds.status & MPT3_CMD_REPLY_VALID) == 0) {2460 ioc_err(ioc, "%s: no reply message\n", __func__);2461 rc = -EFAULT;2462 goto out;2463 }2464 2465 mpi_reply = ioc->ctl_cmds.reply;2466 ioc_status = le16_to_cpu(mpi_reply->IOCStatus) & MPI2_IOCSTATUS_MASK;2467 2468 if (ioc_status == MPI2_IOCSTATUS_SUCCESS) {2469 ioc->diag_buffer_status[buffer_type] |=2470 MPT3_DIAG_BUFFER_IS_REGISTERED;2471 ioc->diag_buffer_status[buffer_type] &=2472 ~MPT3_DIAG_BUFFER_IS_RELEASED;2473 dctlprintk(ioc, ioc_info(ioc, "%s: success\n", __func__));2474 } else {2475 ioc_info(ioc, "%s: ioc_status(0x%04x) log_info(0x%08x)\n",2476 __func__, ioc_status,2477 le32_to_cpu(mpi_reply->IOCLogInfo));2478 rc = -EFAULT;2479 }2480 2481 issue_host_reset:2482 if (issue_reset)2483 mpt3sas_base_hard_reset_handler(ioc, FORCE_BIG_HAMMER);2484 2485 out:2486 2487 ioc->ctl_cmds.status = MPT3_CMD_NOT_USED;2488 return rc;2489}2490 2491/**2492 * _ctl_addnl_diag_query - query relevant info associated with diag buffers2493 * @ioc: per adapter object2494 * @arg: user space buffer containing ioctl content2495 *2496 * The application will send only unique_id. Driver will2497 * inspect unique_id first, if valid, fill the details related to cause2498 * for diag buffer release.2499 */2500static long2501_ctl_addnl_diag_query(struct MPT3SAS_ADAPTER *ioc, void __user *arg)2502{2503 struct mpt3_addnl_diag_query karg;2504 u32 buffer_type = 0;2505 2506 if (copy_from_user(&karg, arg, sizeof(karg))) {2507 pr_err("%s: failure at %s:%d/%s()!\n",2508 ioc->name, __FILE__, __LINE__, __func__);2509 return -EFAULT;2510 }2511 dctlprintk(ioc, ioc_info(ioc, "%s\n", __func__));2512 if (karg.unique_id == 0) {2513 ioc_err(ioc, "%s: unique_id is(0x%08x)\n",2514 __func__, karg.unique_id);2515 return -EPERM;2516 }2517 buffer_type = _ctl_diag_get_bufftype(ioc, karg.unique_id);2518 if (buffer_type == MPT3_DIAG_UID_NOT_FOUND) {2519 ioc_err(ioc, "%s: buffer with unique_id(0x%08x) not found\n",2520 __func__, karg.unique_id);2521 return -EPERM;2522 }2523 memset(&karg.rel_query, 0, sizeof(karg.rel_query));2524 if ((ioc->diag_buffer_status[buffer_type] &2525 MPT3_DIAG_BUFFER_IS_REGISTERED) == 0) {2526 ioc_info(ioc, "%s: buffer_type(0x%02x) is not registered\n",2527 __func__, buffer_type);2528 goto out;2529 }2530 if ((ioc->diag_buffer_status[buffer_type] &2531 MPT3_DIAG_BUFFER_IS_RELEASED) == 0) {2532 ioc_err(ioc, "%s: buffer_type(0x%02x) is not released\n",2533 __func__, buffer_type);2534 return -EPERM;2535 }2536 memcpy(&karg.rel_query, &ioc->htb_rel, sizeof(karg.rel_query));2537out:2538 if (copy_to_user(arg, &karg, sizeof(struct mpt3_addnl_diag_query))) {2539 ioc_err(ioc, "%s: unable to write mpt3_addnl_diag_query data @ %p\n",2540 __func__, arg);2541 return -EFAULT;2542 }2543 return 0;2544}2545 2546/**2547 * _ctl_enable_diag_sbr_reload - enable sbr reload bit2548 * @ioc: per adapter object2549 * @arg: user space buffer containing ioctl content2550 *2551 * Enable the SBR reload bit2552 */2553static int2554_ctl_enable_diag_sbr_reload(struct MPT3SAS_ADAPTER *ioc, void __user *arg)2555{2556 u32 ioc_state, host_diagnostic;2557 2558 if (ioc->shost_recovery ||2559 ioc->pci_error_recovery || ioc->is_driver_loading ||2560 ioc->remove_host)2561 return -EAGAIN;2562 2563 ioc_state = mpt3sas_base_get_iocstate(ioc, 1);2564 2565 if (ioc_state != MPI2_IOC_STATE_OPERATIONAL)2566 return -EFAULT;2567 2568 host_diagnostic = ioc->base_readl(&ioc->chip->HostDiagnostic);2569 2570 if (host_diagnostic & MPI2_DIAG_SBR_RELOAD)2571 return 0;2572 2573 if (mutex_trylock(&ioc->hostdiag_unlock_mutex)) {2574 if (mpt3sas_base_unlock_and_get_host_diagnostic(ioc, &host_diagnostic)) {2575 mutex_unlock(&ioc->hostdiag_unlock_mutex);2576 return -EFAULT;2577 }2578 } else2579 return -EAGAIN;2580 2581 host_diagnostic |= MPI2_DIAG_SBR_RELOAD;2582 writel(host_diagnostic, &ioc->chip->HostDiagnostic);2583 host_diagnostic = ioc->base_readl(&ioc->chip->HostDiagnostic);2584 mpt3sas_base_lock_host_diagnostic(ioc);2585 mutex_unlock(&ioc->hostdiag_unlock_mutex);2586 2587 if (!(host_diagnostic & MPI2_DIAG_SBR_RELOAD)) {2588 ioc_err(ioc, "%s: Failed to set Diag SBR Reload Bit\n", __func__);2589 return -EFAULT;2590 }2591 2592 ioc_info(ioc, "%s: Successfully set the Diag SBR Reload Bit\n", __func__);2593 return 0;2594}2595 2596#ifdef CONFIG_COMPAT2597/**2598 * _ctl_compat_mpt_command - convert 32bit pointers to 64bit.2599 * @ioc: per adapter object2600 * @cmd: ioctl opcode2601 * @arg: (struct mpt3_ioctl_command32)2602 *2603 * MPT3COMMAND32 - Handle 32bit applications running on 64bit os.2604 */2605static long2606_ctl_compat_mpt_command(struct MPT3SAS_ADAPTER *ioc, unsigned cmd,2607 void __user *arg)2608{2609 struct mpt3_ioctl_command32 karg32;2610 struct mpt3_ioctl_command32 __user *uarg;2611 struct mpt3_ioctl_command karg;2612 2613 if (_IOC_SIZE(cmd) != sizeof(struct mpt3_ioctl_command32))2614 return -EINVAL;2615 2616 uarg = (struct mpt3_ioctl_command32 __user *) arg;2617 2618 if (copy_from_user(&karg32, (char __user *)arg, sizeof(karg32))) {2619 pr_err("failure at %s:%d/%s()!\n",2620 __FILE__, __LINE__, __func__);2621 return -EFAULT;2622 }2623 2624 memset(&karg, 0, sizeof(struct mpt3_ioctl_command));2625 karg.hdr.ioc_number = karg32.hdr.ioc_number;2626 karg.hdr.port_number = karg32.hdr.port_number;2627 karg.hdr.max_data_size = karg32.hdr.max_data_size;2628 karg.timeout = karg32.timeout;2629 karg.max_reply_bytes = karg32.max_reply_bytes;2630 karg.data_in_size = karg32.data_in_size;2631 karg.data_out_size = karg32.data_out_size;2632 karg.max_sense_bytes = karg32.max_sense_bytes;2633 karg.data_sge_offset = karg32.data_sge_offset;2634 karg.reply_frame_buf_ptr = compat_ptr(karg32.reply_frame_buf_ptr);2635 karg.data_in_buf_ptr = compat_ptr(karg32.data_in_buf_ptr);2636 karg.data_out_buf_ptr = compat_ptr(karg32.data_out_buf_ptr);2637 karg.sense_data_ptr = compat_ptr(karg32.sense_data_ptr);2638 return _ctl_do_mpt_command(ioc, karg, &uarg->mf);2639}2640#endif2641 2642/**2643 * _ctl_ioctl_main - main ioctl entry point2644 * @file: (struct file)2645 * @cmd: ioctl opcode2646 * @arg: user space data buffer2647 * @compat: handles 32 bit applications in 64bit os2648 * @mpi_version: will be MPI2_VERSION for mpt2ctl ioctl device &2649 * MPI25_VERSION | MPI26_VERSION for mpt3ctl ioctl device.2650 */2651static long2652_ctl_ioctl_main(struct file *file, unsigned int cmd, void __user *arg,2653 u8 compat, u16 mpi_version)2654{2655 struct MPT3SAS_ADAPTER *ioc;2656 struct mpt3_ioctl_header ioctl_header;2657 enum block_state state;2658 long ret = -ENOIOCTLCMD;2659 2660 /* get IOCTL header */2661 if (copy_from_user(&ioctl_header, (char __user *)arg,2662 sizeof(struct mpt3_ioctl_header))) {2663 pr_err("failure at %s:%d/%s()!\n",2664 __FILE__, __LINE__, __func__);2665 return -EFAULT;2666 }2667 2668 if (_ctl_verify_adapter(ioctl_header.ioc_number,2669 &ioc, mpi_version) == -1 || !ioc)2670 return -ENODEV;2671 2672 /* pci_access_mutex lock acquired by ioctl path */2673 mutex_lock(&ioc->pci_access_mutex);2674 2675 if (ioc->shost_recovery || ioc->pci_error_recovery ||2676 ioc->is_driver_loading || ioc->remove_host) {2677 ret = -EAGAIN;2678 goto out_unlock_pciaccess;2679 }2680 2681 state = (file->f_flags & O_NONBLOCK) ? NON_BLOCKING : BLOCKING;2682 if (state == NON_BLOCKING) {2683 if (!mutex_trylock(&ioc->ctl_cmds.mutex)) {2684 ret = -EAGAIN;2685 goto out_unlock_pciaccess;2686 }2687 } else if (mutex_lock_interruptible(&ioc->ctl_cmds.mutex)) {2688 ret = -ERESTARTSYS;2689 goto out_unlock_pciaccess;2690 }2691 2692 2693 switch (cmd) {2694 case MPT3IOCINFO:2695 if (_IOC_SIZE(cmd) == sizeof(struct mpt3_ioctl_iocinfo))2696 ret = _ctl_getiocinfo(ioc, arg);2697 break;2698#ifdef CONFIG_COMPAT2699 case MPT3COMMAND32:2700#endif2701 case MPT3COMMAND:2702 {2703 struct mpt3_ioctl_command __user *uarg;2704 struct mpt3_ioctl_command karg;2705 2706#ifdef CONFIG_COMPAT2707 if (compat) {2708 ret = _ctl_compat_mpt_command(ioc, cmd, arg);2709 break;2710 }2711#endif2712 if (copy_from_user(&karg, arg, sizeof(karg))) {2713 pr_err("failure at %s:%d/%s()!\n",2714 __FILE__, __LINE__, __func__);2715 ret = -EFAULT;2716 break;2717 }2718 2719 if (karg.hdr.ioc_number != ioctl_header.ioc_number) {2720 ret = -EINVAL;2721 break;2722 }2723 if (_IOC_SIZE(cmd) == sizeof(struct mpt3_ioctl_command)) {2724 uarg = arg;2725 ret = _ctl_do_mpt_command(ioc, karg, &uarg->mf);2726 }2727 break;2728 }2729 case MPT3EVENTQUERY:2730 if (_IOC_SIZE(cmd) == sizeof(struct mpt3_ioctl_eventquery))2731 ret = _ctl_eventquery(ioc, arg);2732 break;2733 case MPT3EVENTENABLE:2734 if (_IOC_SIZE(cmd) == sizeof(struct mpt3_ioctl_eventenable))2735 ret = _ctl_eventenable(ioc, arg);2736 break;2737 case MPT3EVENTREPORT:2738 ret = _ctl_eventreport(ioc, arg);2739 break;2740 case MPT3HARDRESET:2741 if (_IOC_SIZE(cmd) == sizeof(struct mpt3_ioctl_diag_reset))2742 ret = _ctl_do_reset(ioc, arg);2743 break;2744 case MPT3BTDHMAPPING:2745 if (_IOC_SIZE(cmd) == sizeof(struct mpt3_ioctl_btdh_mapping))2746 ret = _ctl_btdh_mapping(ioc, arg);2747 break;2748 case MPT3DIAGREGISTER:2749 if (_IOC_SIZE(cmd) == sizeof(struct mpt3_diag_register))2750 ret = _ctl_diag_register(ioc, arg);2751 break;2752 case MPT3DIAGUNREGISTER:2753 if (_IOC_SIZE(cmd) == sizeof(struct mpt3_diag_unregister))2754 ret = _ctl_diag_unregister(ioc, arg);2755 break;2756 case MPT3DIAGQUERY:2757 if (_IOC_SIZE(cmd) == sizeof(struct mpt3_diag_query))2758 ret = _ctl_diag_query(ioc, arg);2759 break;2760 case MPT3DIAGRELEASE:2761 if (_IOC_SIZE(cmd) == sizeof(struct mpt3_diag_release))2762 ret = _ctl_diag_release(ioc, arg);2763 break;2764 case MPT3DIAGREADBUFFER:2765 if (_IOC_SIZE(cmd) == sizeof(struct mpt3_diag_read_buffer))2766 ret = _ctl_diag_read_buffer(ioc, arg);2767 break;2768 case MPT3ADDNLDIAGQUERY:2769 if (_IOC_SIZE(cmd) == sizeof(struct mpt3_addnl_diag_query))2770 ret = _ctl_addnl_diag_query(ioc, arg);2771 break;2772 case MPT3ENABLEDIAGSBRRELOAD:2773 if (_IOC_SIZE(cmd) == sizeof(struct mpt3_enable_diag_sbr_reload))2774 ret = _ctl_enable_diag_sbr_reload(ioc, arg);2775 break;2776 default:2777 dctlprintk(ioc,2778 ioc_info(ioc, "unsupported ioctl opcode(0x%08x)\n",2779 cmd));2780 break;2781 }2782 2783 mutex_unlock(&ioc->ctl_cmds.mutex);2784out_unlock_pciaccess:2785 mutex_unlock(&ioc->pci_access_mutex);2786 return ret;2787}2788 2789/**2790 * _ctl_ioctl - mpt3ctl main ioctl entry point (unlocked)2791 * @file: (struct file)2792 * @cmd: ioctl opcode2793 * @arg: ?2794 */2795static long2796_ctl_ioctl(struct file *file, unsigned int cmd, unsigned long arg)2797{2798 long ret;2799 2800 /* pass MPI25_VERSION | MPI26_VERSION value,2801 * to indicate that this ioctl cmd2802 * came from mpt3ctl ioctl device.2803 */2804 ret = _ctl_ioctl_main(file, cmd, (void __user *)arg, 0,2805 MPI25_VERSION | MPI26_VERSION);2806 return ret;2807}2808 2809/**2810 * _ctl_mpt2_ioctl - mpt2ctl main ioctl entry point (unlocked)2811 * @file: (struct file)2812 * @cmd: ioctl opcode2813 * @arg: ?2814 */2815static long2816_ctl_mpt2_ioctl(struct file *file, unsigned int cmd, unsigned long arg)2817{2818 long ret;2819 2820 /* pass MPI2_VERSION value, to indicate that this ioctl cmd2821 * came from mpt2ctl ioctl device.2822 */2823 ret = _ctl_ioctl_main(file, cmd, (void __user *)arg, 0, MPI2_VERSION);2824 return ret;2825}2826#ifdef CONFIG_COMPAT2827/**2828 * _ctl_ioctl_compat - main ioctl entry point (compat)2829 * @file: ?2830 * @cmd: ?2831 * @arg: ?2832 *2833 * This routine handles 32 bit applications in 64bit os.2834 */2835static long2836_ctl_ioctl_compat(struct file *file, unsigned cmd, unsigned long arg)2837{2838 long ret;2839 2840 ret = _ctl_ioctl_main(file, cmd, (void __user *)arg, 1,2841 MPI25_VERSION | MPI26_VERSION);2842 return ret;2843}2844 2845/**2846 * _ctl_mpt2_ioctl_compat - main ioctl entry point (compat)2847 * @file: ?2848 * @cmd: ?2849 * @arg: ?2850 *2851 * This routine handles 32 bit applications in 64bit os.2852 */2853static long2854_ctl_mpt2_ioctl_compat(struct file *file, unsigned cmd, unsigned long arg)2855{2856 long ret;2857 2858 ret = _ctl_ioctl_main(file, cmd, (void __user *)arg, 1, MPI2_VERSION);2859 return ret;2860}2861#endif2862 2863/* scsi host attributes */2864/**2865 * version_fw_show - firmware version2866 * @cdev: pointer to embedded class device2867 * @attr: ?2868 * @buf: the buffer returned2869 *2870 * A sysfs 'read-only' shost attribute.2871 */2872static ssize_t2873version_fw_show(struct device *cdev, struct device_attribute *attr,2874 char *buf)2875{2876 struct Scsi_Host *shost = class_to_shost(cdev);2877 struct MPT3SAS_ADAPTER *ioc = shost_priv(shost);2878 2879 return snprintf(buf, PAGE_SIZE, "%02d.%02d.%02d.%02d\n",2880 (ioc->facts.FWVersion.Word & 0xFF000000) >> 24,2881 (ioc->facts.FWVersion.Word & 0x00FF0000) >> 16,2882 (ioc->facts.FWVersion.Word & 0x0000FF00) >> 8,2883 ioc->facts.FWVersion.Word & 0x000000FF);2884}2885static DEVICE_ATTR_RO(version_fw);2886 2887/**2888 * version_bios_show - bios version2889 * @cdev: pointer to embedded class device2890 * @attr: ?2891 * @buf: the buffer returned2892 *2893 * A sysfs 'read-only' shost attribute.2894 */2895static ssize_t2896version_bios_show(struct device *cdev, struct device_attribute *attr,2897 char *buf)2898{2899 struct Scsi_Host *shost = class_to_shost(cdev);2900 struct MPT3SAS_ADAPTER *ioc = shost_priv(shost);2901 2902 u32 version = le32_to_cpu(ioc->bios_pg3.BiosVersion);2903 2904 return snprintf(buf, PAGE_SIZE, "%02d.%02d.%02d.%02d\n",2905 (version & 0xFF000000) >> 24,2906 (version & 0x00FF0000) >> 16,2907 (version & 0x0000FF00) >> 8,2908 version & 0x000000FF);2909}2910static DEVICE_ATTR_RO(version_bios);2911 2912/**2913 * version_mpi_show - MPI (message passing interface) version2914 * @cdev: pointer to embedded class device2915 * @attr: ?2916 * @buf: the buffer returned2917 *2918 * A sysfs 'read-only' shost attribute.2919 */2920static ssize_t2921version_mpi_show(struct device *cdev, struct device_attribute *attr,2922 char *buf)2923{2924 struct Scsi_Host *shost = class_to_shost(cdev);2925 struct MPT3SAS_ADAPTER *ioc = shost_priv(shost);2926 2927 return snprintf(buf, PAGE_SIZE, "%03x.%02x\n",2928 ioc->facts.MsgVersion, ioc->facts.HeaderVersion >> 8);2929}2930static DEVICE_ATTR_RO(version_mpi);2931 2932/**2933 * version_product_show - product name2934 * @cdev: pointer to embedded class device2935 * @attr: ?2936 * @buf: the buffer returned2937 *2938 * A sysfs 'read-only' shost attribute.2939 */2940static ssize_t2941version_product_show(struct device *cdev, struct device_attribute *attr,2942 char *buf)2943{2944 struct Scsi_Host *shost = class_to_shost(cdev);2945 struct MPT3SAS_ADAPTER *ioc = shost_priv(shost);2946 2947 return snprintf(buf, 16, "%s\n", ioc->manu_pg0.ChipName);2948}2949static DEVICE_ATTR_RO(version_product);2950 2951/**2952 * version_nvdata_persistent_show - ndvata persistent version2953 * @cdev: pointer to embedded class device2954 * @attr: ?2955 * @buf: the buffer returned2956 *2957 * A sysfs 'read-only' shost attribute.2958 */2959static ssize_t2960version_nvdata_persistent_show(struct device *cdev,2961 struct device_attribute *attr, char *buf)2962{2963 struct Scsi_Host *shost = class_to_shost(cdev);2964 struct MPT3SAS_ADAPTER *ioc = shost_priv(shost);2965 2966 return snprintf(buf, PAGE_SIZE, "%08xh\n",2967 le32_to_cpu(ioc->iounit_pg0.NvdataVersionPersistent.Word));2968}2969static DEVICE_ATTR_RO(version_nvdata_persistent);2970 2971/**2972 * version_nvdata_default_show - nvdata default version2973 * @cdev: pointer to embedded class device2974 * @attr: ?2975 * @buf: the buffer returned2976 *2977 * A sysfs 'read-only' shost attribute.2978 */2979static ssize_t2980version_nvdata_default_show(struct device *cdev, struct device_attribute2981 *attr, char *buf)2982{2983 struct Scsi_Host *shost = class_to_shost(cdev);2984 struct MPT3SAS_ADAPTER *ioc = shost_priv(shost);2985 2986 return snprintf(buf, PAGE_SIZE, "%08xh\n",2987 le32_to_cpu(ioc->iounit_pg0.NvdataVersionDefault.Word));2988}2989static DEVICE_ATTR_RO(version_nvdata_default);2990 2991/**2992 * board_name_show - board name2993 * @cdev: pointer to embedded class device2994 * @attr: ?2995 * @buf: the buffer returned2996 *2997 * A sysfs 'read-only' shost attribute.2998 */2999static ssize_t3000board_name_show(struct device *cdev, struct device_attribute *attr,3001 char *buf)3002{3003 struct Scsi_Host *shost = class_to_shost(cdev);3004 struct MPT3SAS_ADAPTER *ioc = shost_priv(shost);3005 3006 return snprintf(buf, 16, "%s\n", ioc->manu_pg0.BoardName);3007}3008static DEVICE_ATTR_RO(board_name);3009 3010/**3011 * board_assembly_show - board assembly name3012 * @cdev: pointer to embedded class device3013 * @attr: ?3014 * @buf: the buffer returned3015 *3016 * A sysfs 'read-only' shost attribute.3017 */3018static ssize_t3019board_assembly_show(struct device *cdev, struct device_attribute *attr,3020 char *buf)3021{3022 struct Scsi_Host *shost = class_to_shost(cdev);3023 struct MPT3SAS_ADAPTER *ioc = shost_priv(shost);3024 3025 return snprintf(buf, 16, "%s\n", ioc->manu_pg0.BoardAssembly);3026}3027static DEVICE_ATTR_RO(board_assembly);3028 3029/**3030 * board_tracer_show - board tracer number3031 * @cdev: pointer to embedded class device3032 * @attr: ?3033 * @buf: the buffer returned3034 *3035 * A sysfs 'read-only' shost attribute.3036 */3037static ssize_t3038board_tracer_show(struct device *cdev, struct device_attribute *attr,3039 char *buf)3040{3041 struct Scsi_Host *shost = class_to_shost(cdev);3042 struct MPT3SAS_ADAPTER *ioc = shost_priv(shost);3043 3044 return snprintf(buf, 16, "%s\n", ioc->manu_pg0.BoardTracerNumber);3045}3046static DEVICE_ATTR_RO(board_tracer);3047 3048/**3049 * io_delay_show - io missing delay3050 * @cdev: pointer to embedded class device3051 * @attr: ?3052 * @buf: the buffer returned3053 *3054 * This is for firmware implemention for deboucing device3055 * removal events.3056 *3057 * A sysfs 'read-only' shost attribute.3058 */3059static ssize_t3060io_delay_show(struct device *cdev, struct device_attribute *attr,3061 char *buf)3062{3063 struct Scsi_Host *shost = class_to_shost(cdev);3064 struct MPT3SAS_ADAPTER *ioc = shost_priv(shost);3065 3066 return snprintf(buf, PAGE_SIZE, "%02d\n", ioc->io_missing_delay);3067}3068static DEVICE_ATTR_RO(io_delay);3069 3070/**3071 * device_delay_show - device missing delay3072 * @cdev: pointer to embedded class device3073 * @attr: ?3074 * @buf: the buffer returned3075 *3076 * This is for firmware implemention for deboucing device3077 * removal events.3078 *3079 * A sysfs 'read-only' shost attribute.3080 */3081static ssize_t3082device_delay_show(struct device *cdev, struct device_attribute *attr,3083 char *buf)3084{3085 struct Scsi_Host *shost = class_to_shost(cdev);3086 struct MPT3SAS_ADAPTER *ioc = shost_priv(shost);3087 3088 return snprintf(buf, PAGE_SIZE, "%02d\n", ioc->device_missing_delay);3089}3090static DEVICE_ATTR_RO(device_delay);3091 3092/**3093 * fw_queue_depth_show - global credits3094 * @cdev: pointer to embedded class device3095 * @attr: ?3096 * @buf: the buffer returned3097 *3098 * This is firmware queue depth limit3099 *3100 * A sysfs 'read-only' shost attribute.3101 */3102static ssize_t3103fw_queue_depth_show(struct device *cdev, struct device_attribute *attr,3104 char *buf)3105{3106 struct Scsi_Host *shost = class_to_shost(cdev);3107 struct MPT3SAS_ADAPTER *ioc = shost_priv(shost);3108 3109 return snprintf(buf, PAGE_SIZE, "%02d\n", ioc->facts.RequestCredit);3110}3111static DEVICE_ATTR_RO(fw_queue_depth);3112 3113/**3114 * host_sas_address_show - sas address3115 * @cdev: pointer to embedded class device3116 * @attr: ?3117 * @buf: the buffer returned3118 *3119 * This is the controller sas address3120 *3121 * A sysfs 'read-only' shost attribute.3122 */3123static ssize_t3124host_sas_address_show(struct device *cdev, struct device_attribute *attr,3125 char *buf)3126 3127{3128 struct Scsi_Host *shost = class_to_shost(cdev);3129 struct MPT3SAS_ADAPTER *ioc = shost_priv(shost);3130 3131 return snprintf(buf, PAGE_SIZE, "0x%016llx\n",3132 (unsigned long long)ioc->sas_hba.sas_address);3133}3134static DEVICE_ATTR_RO(host_sas_address);3135 3136/**3137 * logging_level_show - logging level3138 * @cdev: pointer to embedded class device3139 * @attr: ?3140 * @buf: the buffer returned3141 *3142 * A sysfs 'read/write' shost attribute.3143 */3144static ssize_t3145logging_level_show(struct device *cdev, struct device_attribute *attr,3146 char *buf)3147{3148 struct Scsi_Host *shost = class_to_shost(cdev);3149 struct MPT3SAS_ADAPTER *ioc = shost_priv(shost);3150 3151 return snprintf(buf, PAGE_SIZE, "%08xh\n", ioc->logging_level);3152}3153static ssize_t3154logging_level_store(struct device *cdev, struct device_attribute *attr,3155 const char *buf, size_t count)3156{3157 struct Scsi_Host *shost = class_to_shost(cdev);3158 struct MPT3SAS_ADAPTER *ioc = shost_priv(shost);3159 int val = 0;3160 3161 if (sscanf(buf, "%x", &val) != 1)3162 return -EINVAL;3163 3164 ioc->logging_level = val;3165 ioc_info(ioc, "logging_level=%08xh\n",3166 ioc->logging_level);3167 return strlen(buf);3168}3169static DEVICE_ATTR_RW(logging_level);3170 3171/**3172 * fwfault_debug_show - show/store fwfault_debug3173 * @cdev: pointer to embedded class device3174 * @attr: ?3175 * @buf: the buffer returned3176 *3177 * mpt3sas_fwfault_debug is command line option3178 * A sysfs 'read/write' shost attribute.3179 */3180static ssize_t3181fwfault_debug_show(struct device *cdev, struct device_attribute *attr,3182 char *buf)3183{3184 struct Scsi_Host *shost = class_to_shost(cdev);3185 struct MPT3SAS_ADAPTER *ioc = shost_priv(shost);3186 3187 return snprintf(buf, PAGE_SIZE, "%d\n", ioc->fwfault_debug);3188}3189static ssize_t3190fwfault_debug_store(struct device *cdev, struct device_attribute *attr,3191 const char *buf, size_t count)3192{3193 struct Scsi_Host *shost = class_to_shost(cdev);3194 struct MPT3SAS_ADAPTER *ioc = shost_priv(shost);3195 int val = 0;3196 3197 if (sscanf(buf, "%d", &val) != 1)3198 return -EINVAL;3199 3200 ioc->fwfault_debug = val;3201 ioc_info(ioc, "fwfault_debug=%d\n",3202 ioc->fwfault_debug);3203 return strlen(buf);3204}3205static DEVICE_ATTR_RW(fwfault_debug);3206 3207/**3208 * ioc_reset_count_show - ioc reset count3209 * @cdev: pointer to embedded class device3210 * @attr: ?3211 * @buf: the buffer returned3212 *3213 * This is firmware queue depth limit3214 *3215 * A sysfs 'read-only' shost attribute.3216 */3217static ssize_t3218ioc_reset_count_show(struct device *cdev, struct device_attribute *attr,3219 char *buf)3220{3221 struct Scsi_Host *shost = class_to_shost(cdev);3222 struct MPT3SAS_ADAPTER *ioc = shost_priv(shost);3223 3224 return snprintf(buf, PAGE_SIZE, "%d\n", ioc->ioc_reset_count);3225}3226static DEVICE_ATTR_RO(ioc_reset_count);3227 3228/**3229 * reply_queue_count_show - number of reply queues3230 * @cdev: pointer to embedded class device3231 * @attr: ?3232 * @buf: the buffer returned3233 *3234 * This is number of reply queues3235 *3236 * A sysfs 'read-only' shost attribute.3237 */3238static ssize_t3239reply_queue_count_show(struct device *cdev,3240 struct device_attribute *attr, char *buf)3241{3242 u8 reply_queue_count;3243 struct Scsi_Host *shost = class_to_shost(cdev);3244 struct MPT3SAS_ADAPTER *ioc = shost_priv(shost);3245 3246 if ((ioc->facts.IOCCapabilities &3247 MPI2_IOCFACTS_CAPABILITY_MSI_X_INDEX) && ioc->msix_enable)3248 reply_queue_count = ioc->reply_queue_count;3249 else3250 reply_queue_count = 1;3251 3252 return snprintf(buf, PAGE_SIZE, "%d\n", reply_queue_count);3253}3254static DEVICE_ATTR_RO(reply_queue_count);3255 3256/**3257 * BRM_status_show - Backup Rail Monitor Status3258 * @cdev: pointer to embedded class device3259 * @attr: ?3260 * @buf: the buffer returned3261 *3262 * This is number of reply queues3263 *3264 * A sysfs 'read-only' shost attribute.3265 */3266static ssize_t3267BRM_status_show(struct device *cdev, struct device_attribute *attr,3268 char *buf)3269{3270 struct Scsi_Host *shost = class_to_shost(cdev);3271 struct MPT3SAS_ADAPTER *ioc = shost_priv(shost);3272 Mpi2IOUnitPage3_t io_unit_pg3;3273 Mpi2ConfigReply_t mpi_reply;3274 u16 backup_rail_monitor_status = 0;3275 u16 ioc_status;3276 int sz;3277 ssize_t rc = 0;3278 3279 if (!ioc->is_warpdrive) {3280 ioc_err(ioc, "%s: BRM attribute is only for warpdrive\n",3281 __func__);3282 return 0;3283 }3284 /* pci_access_mutex lock acquired by sysfs show path */3285 mutex_lock(&ioc->pci_access_mutex);3286 if (ioc->pci_error_recovery || ioc->remove_host)3287 goto out;3288 3289 sz = sizeof(io_unit_pg3);3290 memset(&io_unit_pg3, 0, sz);3291 3292 if (mpt3sas_config_get_iounit_pg3(ioc, &mpi_reply, &io_unit_pg3, sz) !=3293 0) {3294 ioc_err(ioc, "%s: failed reading iounit_pg3\n",3295 __func__);3296 rc = -EINVAL;3297 goto out;3298 }3299 3300 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & MPI2_IOCSTATUS_MASK;3301 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {3302 ioc_err(ioc, "%s: iounit_pg3 failed with ioc_status(0x%04x)\n",3303 __func__, ioc_status);3304 rc = -EINVAL;3305 goto out;3306 }3307 3308 if (io_unit_pg3.GPIOCount < 25) {3309 ioc_err(ioc, "%s: iounit_pg3.GPIOCount less than 25 entries, detected (%d) entries\n",3310 __func__, io_unit_pg3.GPIOCount);3311 rc = -EINVAL;3312 goto out;3313 }3314 3315 /* BRM status is in bit zero of GPIOVal[24] */3316 backup_rail_monitor_status = le16_to_cpu(io_unit_pg3.GPIOVal[24]);3317 rc = snprintf(buf, PAGE_SIZE, "%d\n", (backup_rail_monitor_status & 1));3318 3319 out:3320 mutex_unlock(&ioc->pci_access_mutex);3321 return rc;3322}3323static DEVICE_ATTR_RO(BRM_status);3324 3325struct DIAG_BUFFER_START {3326 __le32 Size;3327 __le32 DiagVersion;3328 u8 BufferType;3329 u8 Reserved[3];3330 __le32 Reserved1;3331 __le32 Reserved2;3332 __le32 Reserved3;3333};3334 3335/**3336 * host_trace_buffer_size_show - host buffer size (trace only)3337 * @cdev: pointer to embedded class device3338 * @attr: ?3339 * @buf: the buffer returned3340 *3341 * A sysfs 'read-only' shost attribute.3342 */3343static ssize_t3344host_trace_buffer_size_show(struct device *cdev,3345 struct device_attribute *attr, char *buf)3346{3347 struct Scsi_Host *shost = class_to_shost(cdev);3348 struct MPT3SAS_ADAPTER *ioc = shost_priv(shost);3349 u32 size = 0;3350 struct DIAG_BUFFER_START *request_data;3351 3352 if (!ioc->diag_buffer[MPI2_DIAG_BUF_TYPE_TRACE]) {3353 ioc_err(ioc, "%s: host_trace_buffer is not registered\n",3354 __func__);3355 return 0;3356 }3357 3358 if ((ioc->diag_buffer_status[MPI2_DIAG_BUF_TYPE_TRACE] &3359 MPT3_DIAG_BUFFER_IS_REGISTERED) == 0) {3360 ioc_err(ioc, "%s: host_trace_buffer is not registered\n",3361 __func__);3362 return 0;3363 }3364 3365 request_data = (struct DIAG_BUFFER_START *)3366 ioc->diag_buffer[MPI2_DIAG_BUF_TYPE_TRACE];3367 if ((le32_to_cpu(request_data->DiagVersion) == 0x00000000 ||3368 le32_to_cpu(request_data->DiagVersion) == 0x01000000 ||3369 le32_to_cpu(request_data->DiagVersion) == 0x01010000) &&3370 le32_to_cpu(request_data->Reserved3) == 0x4742444c)3371 size = le32_to_cpu(request_data->Size);3372 3373 ioc->ring_buffer_sz = size;3374 return snprintf(buf, PAGE_SIZE, "%d\n", size);3375}3376static DEVICE_ATTR_RO(host_trace_buffer_size);3377 3378/**3379 * host_trace_buffer_show - firmware ring buffer (trace only)3380 * @cdev: pointer to embedded class device3381 * @attr: ?3382 * @buf: the buffer returned3383 *3384 * A sysfs 'read/write' shost attribute.3385 *3386 * You will only be able to read 4k bytes of ring buffer at a time.3387 * In order to read beyond 4k bytes, you will have to write out the3388 * offset to the same attribute, it will move the pointer.3389 */3390static ssize_t3391host_trace_buffer_show(struct device *cdev, struct device_attribute *attr,3392 char *buf)3393{3394 struct Scsi_Host *shost = class_to_shost(cdev);3395 struct MPT3SAS_ADAPTER *ioc = shost_priv(shost);3396 void *request_data;3397 u32 size;3398 3399 if (!ioc->diag_buffer[MPI2_DIAG_BUF_TYPE_TRACE]) {3400 ioc_err(ioc, "%s: host_trace_buffer is not registered\n",3401 __func__);3402 return 0;3403 }3404 3405 if ((ioc->diag_buffer_status[MPI2_DIAG_BUF_TYPE_TRACE] &3406 MPT3_DIAG_BUFFER_IS_REGISTERED) == 0) {3407 ioc_err(ioc, "%s: host_trace_buffer is not registered\n",3408 __func__);3409 return 0;3410 }3411 3412 if (ioc->ring_buffer_offset > ioc->ring_buffer_sz)3413 return 0;3414 3415 size = ioc->ring_buffer_sz - ioc->ring_buffer_offset;3416 size = (size >= PAGE_SIZE) ? (PAGE_SIZE - 1) : size;3417 request_data = ioc->diag_buffer[0] + ioc->ring_buffer_offset;3418 memcpy(buf, request_data, size);3419 return size;3420}3421 3422static ssize_t3423host_trace_buffer_store(struct device *cdev, struct device_attribute *attr,3424 const char *buf, size_t count)3425{3426 struct Scsi_Host *shost = class_to_shost(cdev);3427 struct MPT3SAS_ADAPTER *ioc = shost_priv(shost);3428 int val = 0;3429 3430 if (sscanf(buf, "%d", &val) != 1)3431 return -EINVAL;3432 3433 ioc->ring_buffer_offset = val;3434 return strlen(buf);3435}3436static DEVICE_ATTR_RW(host_trace_buffer);3437 3438 3439/*****************************************/3440 3441/**3442 * host_trace_buffer_enable_show - firmware ring buffer (trace only)3443 * @cdev: pointer to embedded class device3444 * @attr: ?3445 * @buf: the buffer returned3446 *3447 * A sysfs 'read/write' shost attribute.3448 *3449 * This is a mechnism to post/release host_trace_buffers3450 */3451static ssize_t3452host_trace_buffer_enable_show(struct device *cdev,3453 struct device_attribute *attr, char *buf)3454{3455 struct Scsi_Host *shost = class_to_shost(cdev);3456 struct MPT3SAS_ADAPTER *ioc = shost_priv(shost);3457 3458 if ((!ioc->diag_buffer[MPI2_DIAG_BUF_TYPE_TRACE]) ||3459 ((ioc->diag_buffer_status[MPI2_DIAG_BUF_TYPE_TRACE] &3460 MPT3_DIAG_BUFFER_IS_REGISTERED) == 0))3461 return snprintf(buf, PAGE_SIZE, "off\n");3462 else if ((ioc->diag_buffer_status[MPI2_DIAG_BUF_TYPE_TRACE] &3463 MPT3_DIAG_BUFFER_IS_RELEASED))3464 return snprintf(buf, PAGE_SIZE, "release\n");3465 else3466 return snprintf(buf, PAGE_SIZE, "post\n");3467}3468 3469static ssize_t3470host_trace_buffer_enable_store(struct device *cdev,3471 struct device_attribute *attr, const char *buf, size_t count)3472{3473 struct Scsi_Host *shost = class_to_shost(cdev);3474 struct MPT3SAS_ADAPTER *ioc = shost_priv(shost);3475 char str[10] = "";3476 struct mpt3_diag_register diag_register;3477 u8 issue_reset = 0;3478 3479 /* don't allow post/release occurr while recovery is active */3480 if (ioc->shost_recovery || ioc->remove_host ||3481 ioc->pci_error_recovery || ioc->is_driver_loading)3482 return -EBUSY;3483 3484 if (sscanf(buf, "%9s", str) != 1)3485 return -EINVAL;3486 3487 if (!strcmp(str, "post")) {3488 /* exit out if host buffers are already posted */3489 if ((ioc->diag_buffer[MPI2_DIAG_BUF_TYPE_TRACE]) &&3490 (ioc->diag_buffer_status[MPI2_DIAG_BUF_TYPE_TRACE] &3491 MPT3_DIAG_BUFFER_IS_REGISTERED) &&3492 ((ioc->diag_buffer_status[MPI2_DIAG_BUF_TYPE_TRACE] &3493 MPT3_DIAG_BUFFER_IS_RELEASED) == 0))3494 goto out;3495 memset(&diag_register, 0, sizeof(struct mpt3_diag_register));3496 ioc_info(ioc, "posting host trace buffers\n");3497 diag_register.buffer_type = MPI2_DIAG_BUF_TYPE_TRACE;3498 3499 if (ioc->manu_pg11.HostTraceBufferMaxSizeKB != 0 &&3500 ioc->diag_buffer_sz[MPI2_DIAG_BUF_TYPE_TRACE] != 0) {3501 /* post the same buffer allocated previously */3502 diag_register.requested_buffer_size =3503 ioc->diag_buffer_sz[MPI2_DIAG_BUF_TYPE_TRACE];3504 } else {3505 /*3506 * Free the diag buffer memory which was previously3507 * allocated by an application.3508 */3509 if ((ioc->diag_buffer_sz[MPI2_DIAG_BUF_TYPE_TRACE] != 0)3510 &&3511 (ioc->diag_buffer_status[MPI2_DIAG_BUF_TYPE_TRACE] &3512 MPT3_DIAG_BUFFER_IS_APP_OWNED)) {3513 dma_free_coherent(&ioc->pdev->dev,3514 ioc->diag_buffer_sz[MPI2_DIAG_BUF_TYPE_TRACE],3515 ioc->diag_buffer[MPI2_DIAG_BUF_TYPE_TRACE],3516 ioc->diag_buffer_dma[MPI2_DIAG_BUF_TYPE_TRACE]);3517 ioc->diag_buffer[MPI2_DIAG_BUF_TYPE_TRACE] =3518 NULL;3519 }3520 3521 diag_register.requested_buffer_size = (1024 * 1024);3522 }3523 3524 diag_register.unique_id =3525 (ioc->hba_mpi_version_belonged == MPI2_VERSION) ?3526 (MPT2DIAGBUFFUNIQUEID):(MPT3DIAGBUFFUNIQUEID);3527 ioc->diag_buffer_status[MPI2_DIAG_BUF_TYPE_TRACE] = 0;3528 _ctl_diag_register_2(ioc, &diag_register);3529 if (ioc->diag_buffer_status[MPI2_DIAG_BUF_TYPE_TRACE] &3530 MPT3_DIAG_BUFFER_IS_REGISTERED) {3531 ioc_info(ioc,3532 "Trace buffer %d KB allocated through sysfs\n",3533 diag_register.requested_buffer_size>>10);3534 if (ioc->hba_mpi_version_belonged != MPI2_VERSION)3535 ioc->diag_buffer_status[3536 MPI2_DIAG_BUF_TYPE_TRACE] |=3537 MPT3_DIAG_BUFFER_IS_DRIVER_ALLOCATED;3538 }3539 } else if (!strcmp(str, "release")) {3540 /* exit out if host buffers are already released */3541 if (!ioc->diag_buffer[MPI2_DIAG_BUF_TYPE_TRACE])3542 goto out;3543 if ((ioc->diag_buffer_status[MPI2_DIAG_BUF_TYPE_TRACE] &3544 MPT3_DIAG_BUFFER_IS_REGISTERED) == 0)3545 goto out;3546 if ((ioc->diag_buffer_status[MPI2_DIAG_BUF_TYPE_TRACE] &3547 MPT3_DIAG_BUFFER_IS_RELEASED))3548 goto out;3549 ioc_info(ioc, "releasing host trace buffer\n");3550 ioc->htb_rel.buffer_rel_condition = MPT3_DIAG_BUFFER_REL_SYSFS;3551 mpt3sas_send_diag_release(ioc, MPI2_DIAG_BUF_TYPE_TRACE,3552 &issue_reset);3553 }3554 3555 out:3556 return strlen(buf);3557}3558static DEVICE_ATTR_RW(host_trace_buffer_enable);3559 3560/*********** diagnostic trigger suppport *********************************/3561 3562/**3563 * diag_trigger_master_show - show the diag_trigger_master attribute3564 * @cdev: pointer to embedded class device3565 * @attr: ?3566 * @buf: the buffer returned3567 *3568 * A sysfs 'read/write' shost attribute.3569 */3570static ssize_t3571diag_trigger_master_show(struct device *cdev,3572 struct device_attribute *attr, char *buf)3573 3574{3575 struct Scsi_Host *shost = class_to_shost(cdev);3576 struct MPT3SAS_ADAPTER *ioc = shost_priv(shost);3577 unsigned long flags;3578 ssize_t rc;3579 3580 spin_lock_irqsave(&ioc->diag_trigger_lock, flags);3581 rc = sizeof(struct SL_WH_MASTER_TRIGGER_T);3582 memcpy(buf, &ioc->diag_trigger_master, rc);3583 spin_unlock_irqrestore(&ioc->diag_trigger_lock, flags);3584 return rc;3585}3586 3587/**3588 * diag_trigger_master_store - store the diag_trigger_master attribute3589 * @cdev: pointer to embedded class device3590 * @attr: ?3591 * @buf: the buffer returned3592 * @count: ?3593 *3594 * A sysfs 'read/write' shost attribute.3595 */3596static ssize_t3597diag_trigger_master_store(struct device *cdev,3598 struct device_attribute *attr, const char *buf, size_t count)3599 3600{3601 struct Scsi_Host *shost = class_to_shost(cdev);3602 struct MPT3SAS_ADAPTER *ioc = shost_priv(shost);3603 struct SL_WH_MASTER_TRIGGER_T *master_tg;3604 unsigned long flags;3605 ssize_t rc;3606 bool set = 1;3607 3608 rc = min(sizeof(struct SL_WH_MASTER_TRIGGER_T), count);3609 3610 if (ioc->supports_trigger_pages) {3611 master_tg = kzalloc(sizeof(struct SL_WH_MASTER_TRIGGER_T),3612 GFP_KERNEL);3613 if (!master_tg)3614 return -ENOMEM;3615 3616 memcpy(master_tg, buf, rc);3617 if (!master_tg->MasterData)3618 set = 0;3619 if (mpt3sas_config_update_driver_trigger_pg1(ioc, master_tg,3620 set)) {3621 kfree(master_tg);3622 return -EFAULT;3623 }3624 kfree(master_tg);3625 }3626 3627 spin_lock_irqsave(&ioc->diag_trigger_lock, flags);3628 memset(&ioc->diag_trigger_master, 0,3629 sizeof(struct SL_WH_MASTER_TRIGGER_T));3630 memcpy(&ioc->diag_trigger_master, buf, rc);3631 ioc->diag_trigger_master.MasterData |=3632 (MASTER_TRIGGER_FW_FAULT + MASTER_TRIGGER_ADAPTER_RESET);3633 spin_unlock_irqrestore(&ioc->diag_trigger_lock, flags);3634 return rc;3635}3636static DEVICE_ATTR_RW(diag_trigger_master);3637 3638 3639/**3640 * diag_trigger_event_show - show the diag_trigger_event attribute3641 * @cdev: pointer to embedded class device3642 * @attr: ?3643 * @buf: the buffer returned3644 *3645 * A sysfs 'read/write' shost attribute.3646 */3647static ssize_t3648diag_trigger_event_show(struct device *cdev,3649 struct device_attribute *attr, char *buf)3650{3651 struct Scsi_Host *shost = class_to_shost(cdev);3652 struct MPT3SAS_ADAPTER *ioc = shost_priv(shost);3653 unsigned long flags;3654 ssize_t rc;3655 3656 spin_lock_irqsave(&ioc->diag_trigger_lock, flags);3657 rc = sizeof(struct SL_WH_EVENT_TRIGGERS_T);3658 memcpy(buf, &ioc->diag_trigger_event, rc);3659 spin_unlock_irqrestore(&ioc->diag_trigger_lock, flags);3660 return rc;3661}3662 3663/**3664 * diag_trigger_event_store - store the diag_trigger_event attribute3665 * @cdev: pointer to embedded class device3666 * @attr: ?3667 * @buf: the buffer returned3668 * @count: ?3669 *3670 * A sysfs 'read/write' shost attribute.3671 */3672static ssize_t3673diag_trigger_event_store(struct device *cdev,3674 struct device_attribute *attr, const char *buf, size_t count)3675 3676{3677 struct Scsi_Host *shost = class_to_shost(cdev);3678 struct MPT3SAS_ADAPTER *ioc = shost_priv(shost);3679 struct SL_WH_EVENT_TRIGGERS_T *event_tg;3680 unsigned long flags;3681 ssize_t sz;3682 bool set = 1;3683 3684 sz = min(sizeof(struct SL_WH_EVENT_TRIGGERS_T), count);3685 if (ioc->supports_trigger_pages) {3686 event_tg = kzalloc(sizeof(struct SL_WH_EVENT_TRIGGERS_T),3687 GFP_KERNEL);3688 if (!event_tg)3689 return -ENOMEM;3690 3691 memcpy(event_tg, buf, sz);3692 if (!event_tg->ValidEntries)3693 set = 0;3694 if (mpt3sas_config_update_driver_trigger_pg2(ioc, event_tg,3695 set)) {3696 kfree(event_tg);3697 return -EFAULT;3698 }3699 kfree(event_tg);3700 }3701 3702 spin_lock_irqsave(&ioc->diag_trigger_lock, flags);3703 3704 memset(&ioc->diag_trigger_event, 0,3705 sizeof(struct SL_WH_EVENT_TRIGGERS_T));3706 memcpy(&ioc->diag_trigger_event, buf, sz);3707 if (ioc->diag_trigger_event.ValidEntries > NUM_VALID_ENTRIES)3708 ioc->diag_trigger_event.ValidEntries = NUM_VALID_ENTRIES;3709 spin_unlock_irqrestore(&ioc->diag_trigger_lock, flags);3710 return sz;3711}3712static DEVICE_ATTR_RW(diag_trigger_event);3713 3714 3715/**3716 * diag_trigger_scsi_show - show the diag_trigger_scsi attribute3717 * @cdev: pointer to embedded class device3718 * @attr: ?3719 * @buf: the buffer returned3720 *3721 * A sysfs 'read/write' shost attribute.3722 */3723static ssize_t3724diag_trigger_scsi_show(struct device *cdev,3725 struct device_attribute *attr, char *buf)3726{3727 struct Scsi_Host *shost = class_to_shost(cdev);3728 struct MPT3SAS_ADAPTER *ioc = shost_priv(shost);3729 unsigned long flags;3730 ssize_t rc;3731 3732 spin_lock_irqsave(&ioc->diag_trigger_lock, flags);3733 rc = sizeof(struct SL_WH_SCSI_TRIGGERS_T);3734 memcpy(buf, &ioc->diag_trigger_scsi, rc);3735 spin_unlock_irqrestore(&ioc->diag_trigger_lock, flags);3736 return rc;3737}3738 3739/**3740 * diag_trigger_scsi_store - store the diag_trigger_scsi attribute3741 * @cdev: pointer to embedded class device3742 * @attr: ?3743 * @buf: the buffer returned3744 * @count: ?3745 *3746 * A sysfs 'read/write' shost attribute.3747 */3748static ssize_t3749diag_trigger_scsi_store(struct device *cdev,3750 struct device_attribute *attr, const char *buf, size_t count)3751{3752 struct Scsi_Host *shost = class_to_shost(cdev);3753 struct MPT3SAS_ADAPTER *ioc = shost_priv(shost);3754 struct SL_WH_SCSI_TRIGGERS_T *scsi_tg;3755 unsigned long flags;3756 ssize_t sz;3757 bool set = 1;3758 3759 sz = min(sizeof(struct SL_WH_SCSI_TRIGGERS_T), count);3760 if (ioc->supports_trigger_pages) {3761 scsi_tg = kzalloc(sizeof(struct SL_WH_SCSI_TRIGGERS_T),3762 GFP_KERNEL);3763 if (!scsi_tg)3764 return -ENOMEM;3765 3766 memcpy(scsi_tg, buf, sz);3767 if (!scsi_tg->ValidEntries)3768 set = 0;3769 if (mpt3sas_config_update_driver_trigger_pg3(ioc, scsi_tg,3770 set)) {3771 kfree(scsi_tg);3772 return -EFAULT;3773 }3774 kfree(scsi_tg);3775 }3776 3777 spin_lock_irqsave(&ioc->diag_trigger_lock, flags);3778 3779 memset(&ioc->diag_trigger_scsi, 0, sizeof(ioc->diag_trigger_scsi));3780 memcpy(&ioc->diag_trigger_scsi, buf, sz);3781 if (ioc->diag_trigger_scsi.ValidEntries > NUM_VALID_ENTRIES)3782 ioc->diag_trigger_scsi.ValidEntries = NUM_VALID_ENTRIES;3783 spin_unlock_irqrestore(&ioc->diag_trigger_lock, flags);3784 return sz;3785}3786static DEVICE_ATTR_RW(diag_trigger_scsi);3787 3788 3789/**3790 * diag_trigger_mpi_show - show the diag_trigger_mpi attribute3791 * @cdev: pointer to embedded class device3792 * @attr: ?3793 * @buf: the buffer returned3794 *3795 * A sysfs 'read/write' shost attribute.3796 */3797static ssize_t3798diag_trigger_mpi_show(struct device *cdev,3799 struct device_attribute *attr, char *buf)3800{3801 struct Scsi_Host *shost = class_to_shost(cdev);3802 struct MPT3SAS_ADAPTER *ioc = shost_priv(shost);3803 unsigned long flags;3804 ssize_t rc;3805 3806 spin_lock_irqsave(&ioc->diag_trigger_lock, flags);3807 rc = sizeof(struct SL_WH_MPI_TRIGGERS_T);3808 memcpy(buf, &ioc->diag_trigger_mpi, rc);3809 spin_unlock_irqrestore(&ioc->diag_trigger_lock, flags);3810 return rc;3811}3812 3813/**3814 * diag_trigger_mpi_store - store the diag_trigger_mpi attribute3815 * @cdev: pointer to embedded class device3816 * @attr: ?3817 * @buf: the buffer returned3818 * @count: ?3819 *3820 * A sysfs 'read/write' shost attribute.3821 */3822static ssize_t3823diag_trigger_mpi_store(struct device *cdev,3824 struct device_attribute *attr, const char *buf, size_t count)3825{3826 struct Scsi_Host *shost = class_to_shost(cdev);3827 struct MPT3SAS_ADAPTER *ioc = shost_priv(shost);3828 struct SL_WH_MPI_TRIGGERS_T *mpi_tg;3829 unsigned long flags;3830 ssize_t sz;3831 bool set = 1;3832 3833 sz = min(sizeof(struct SL_WH_MPI_TRIGGERS_T), count);3834 if (ioc->supports_trigger_pages) {3835 mpi_tg = kzalloc(sizeof(struct SL_WH_MPI_TRIGGERS_T),3836 GFP_KERNEL);3837 if (!mpi_tg)3838 return -ENOMEM;3839 3840 memcpy(mpi_tg, buf, sz);3841 if (!mpi_tg->ValidEntries)3842 set = 0;3843 if (mpt3sas_config_update_driver_trigger_pg4(ioc, mpi_tg,3844 set)) {3845 kfree(mpi_tg);3846 return -EFAULT;3847 }3848 kfree(mpi_tg);3849 }3850 3851 spin_lock_irqsave(&ioc->diag_trigger_lock, flags);3852 memset(&ioc->diag_trigger_mpi, 0,3853 sizeof(ioc->diag_trigger_mpi));3854 memcpy(&ioc->diag_trigger_mpi, buf, sz);3855 if (ioc->diag_trigger_mpi.ValidEntries > NUM_VALID_ENTRIES)3856 ioc->diag_trigger_mpi.ValidEntries = NUM_VALID_ENTRIES;3857 spin_unlock_irqrestore(&ioc->diag_trigger_lock, flags);3858 return sz;3859}3860 3861static DEVICE_ATTR_RW(diag_trigger_mpi);3862 3863/*********** diagnostic trigger suppport *** END ****************************/3864 3865/*****************************************/3866 3867/**3868 * drv_support_bitmap_show - driver supported feature bitmap3869 * @cdev: pointer to embedded class device3870 * @attr: unused3871 * @buf: the buffer returned3872 *3873 * A sysfs 'read-only' shost attribute.3874 */3875static ssize_t3876drv_support_bitmap_show(struct device *cdev,3877 struct device_attribute *attr, char *buf)3878{3879 struct Scsi_Host *shost = class_to_shost(cdev);3880 struct MPT3SAS_ADAPTER *ioc = shost_priv(shost);3881 3882 return snprintf(buf, PAGE_SIZE, "0x%08x\n", ioc->drv_support_bitmap);3883}3884static DEVICE_ATTR_RO(drv_support_bitmap);3885 3886/**3887 * enable_sdev_max_qd_show - display whether sdev max qd is enabled/disabled3888 * @cdev: pointer to embedded class device3889 * @attr: unused3890 * @buf: the buffer returned3891 *3892 * A sysfs read/write shost attribute. This attribute is used to set the3893 * targets queue depth to HBA IO queue depth if this attribute is enabled.3894 */3895static ssize_t3896enable_sdev_max_qd_show(struct device *cdev,3897 struct device_attribute *attr, char *buf)3898{3899 struct Scsi_Host *shost = class_to_shost(cdev);3900 struct MPT3SAS_ADAPTER *ioc = shost_priv(shost);3901 3902 return snprintf(buf, PAGE_SIZE, "%d\n", ioc->enable_sdev_max_qd);3903}3904 3905/**3906 * enable_sdev_max_qd_store - Enable/disable sdev max qd3907 * @cdev: pointer to embedded class device3908 * @attr: unused3909 * @buf: the buffer returned3910 * @count: unused3911 *3912 * A sysfs read/write shost attribute. This attribute is used to set the3913 * targets queue depth to HBA IO queue depth if this attribute is enabled.3914 * If this attribute is disabled then targets will have corresponding default3915 * queue depth.3916 */3917static ssize_t3918enable_sdev_max_qd_store(struct device *cdev,3919 struct device_attribute *attr, const char *buf, size_t count)3920{3921 struct Scsi_Host *shost = class_to_shost(cdev);3922 struct MPT3SAS_ADAPTER *ioc = shost_priv(shost);3923 struct MPT3SAS_DEVICE *sas_device_priv_data;3924 struct MPT3SAS_TARGET *sas_target_priv_data;3925 int val = 0;3926 struct scsi_device *sdev;3927 struct _raid_device *raid_device;3928 int qdepth;3929 3930 if (kstrtoint(buf, 0, &val) != 0)3931 return -EINVAL;3932 3933 switch (val) {3934 case 0:3935 ioc->enable_sdev_max_qd = 0;3936 shost_for_each_device(sdev, ioc->shost) {3937 sas_device_priv_data = sdev->hostdata;3938 if (!sas_device_priv_data)3939 continue;3940 sas_target_priv_data = sas_device_priv_data->sas_target;3941 if (!sas_target_priv_data)3942 continue;3943 3944 if (sas_target_priv_data->flags &3945 MPT_TARGET_FLAGS_VOLUME) {3946 raid_device =3947 mpt3sas_raid_device_find_by_handle(ioc,3948 sas_target_priv_data->handle);3949 3950 switch (raid_device->volume_type) {3951 case MPI2_RAID_VOL_TYPE_RAID0:3952 if (raid_device->device_info &3953 MPI2_SAS_DEVICE_INFO_SSP_TARGET)3954 qdepth =3955 MPT3SAS_SAS_QUEUE_DEPTH;3956 else3957 qdepth =3958 MPT3SAS_SATA_QUEUE_DEPTH;3959 break;3960 case MPI2_RAID_VOL_TYPE_RAID1E:3961 case MPI2_RAID_VOL_TYPE_RAID1:3962 case MPI2_RAID_VOL_TYPE_RAID10:3963 case MPI2_RAID_VOL_TYPE_UNKNOWN:3964 default:3965 qdepth = MPT3SAS_RAID_QUEUE_DEPTH;3966 }3967 } else if (sas_target_priv_data->flags &3968 MPT_TARGET_FLAGS_PCIE_DEVICE)3969 qdepth = ioc->max_nvme_qd;3970 else3971 qdepth = (sas_target_priv_data->sas_dev->port_type > 1) ?3972 ioc->max_wideport_qd : ioc->max_narrowport_qd;3973 3974 mpt3sas_scsih_change_queue_depth(sdev, qdepth);3975 }3976 break;3977 case 1:3978 ioc->enable_sdev_max_qd = 1;3979 shost_for_each_device(sdev, ioc->shost)3980 mpt3sas_scsih_change_queue_depth(sdev,3981 shost->can_queue);3982 break;3983 default:3984 return -EINVAL;3985 }3986 3987 return strlen(buf);3988}3989static DEVICE_ATTR_RW(enable_sdev_max_qd);3990 3991static struct attribute *mpt3sas_host_attrs[] = {3992 &dev_attr_version_fw.attr,3993 &dev_attr_version_bios.attr,3994 &dev_attr_version_mpi.attr,3995 &dev_attr_version_product.attr,3996 &dev_attr_version_nvdata_persistent.attr,3997 &dev_attr_version_nvdata_default.attr,3998 &dev_attr_board_name.attr,3999 &dev_attr_board_assembly.attr,4000 &dev_attr_board_tracer.attr,4001 &dev_attr_io_delay.attr,4002 &dev_attr_device_delay.attr,4003 &dev_attr_logging_level.attr,4004 &dev_attr_fwfault_debug.attr,4005 &dev_attr_fw_queue_depth.attr,4006 &dev_attr_host_sas_address.attr,4007 &dev_attr_ioc_reset_count.attr,4008 &dev_attr_host_trace_buffer_size.attr,4009 &dev_attr_host_trace_buffer.attr,4010 &dev_attr_host_trace_buffer_enable.attr,4011 &dev_attr_reply_queue_count.attr,4012 &dev_attr_diag_trigger_master.attr,4013 &dev_attr_diag_trigger_event.attr,4014 &dev_attr_diag_trigger_scsi.attr,4015 &dev_attr_diag_trigger_mpi.attr,4016 &dev_attr_drv_support_bitmap.attr,4017 &dev_attr_BRM_status.attr,4018 &dev_attr_enable_sdev_max_qd.attr,4019 NULL,4020};4021 4022static const struct attribute_group mpt3sas_host_attr_group = {4023 .attrs = mpt3sas_host_attrs4024};4025 4026const struct attribute_group *mpt3sas_host_groups[] = {4027 &mpt3sas_host_attr_group,4028 NULL4029};4030 4031/* device attributes */4032 4033/**4034 * sas_address_show - sas address4035 * @dev: pointer to embedded class device4036 * @attr: ?4037 * @buf: the buffer returned4038 *4039 * This is the sas address for the target4040 *4041 * A sysfs 'read-only' shost attribute.4042 */4043static ssize_t4044sas_address_show(struct device *dev, struct device_attribute *attr,4045 char *buf)4046{4047 struct scsi_device *sdev = to_scsi_device(dev);4048 struct MPT3SAS_DEVICE *sas_device_priv_data = sdev->hostdata;4049 4050 return snprintf(buf, PAGE_SIZE, "0x%016llx\n",4051 (unsigned long long)sas_device_priv_data->sas_target->sas_address);4052}4053static DEVICE_ATTR_RO(sas_address);4054 4055/**4056 * sas_device_handle_show - device handle4057 * @dev: pointer to embedded class device4058 * @attr: ?4059 * @buf: the buffer returned4060 *4061 * This is the firmware assigned device handle4062 *4063 * A sysfs 'read-only' shost attribute.4064 */4065static ssize_t4066sas_device_handle_show(struct device *dev, struct device_attribute *attr,4067 char *buf)4068{4069 struct scsi_device *sdev = to_scsi_device(dev);4070 struct MPT3SAS_DEVICE *sas_device_priv_data = sdev->hostdata;4071 4072 return snprintf(buf, PAGE_SIZE, "0x%04x\n",4073 sas_device_priv_data->sas_target->handle);4074}4075static DEVICE_ATTR_RO(sas_device_handle);4076 4077/**4078 * sas_ncq_prio_supported_show - Indicate if device supports NCQ priority4079 * @dev: pointer to embedded device4080 * @attr: sas_ncq_prio_supported attribute descriptor4081 * @buf: the buffer returned4082 *4083 * A sysfs 'read-only' sdev attribute, only works with SATA4084 */4085static ssize_t4086sas_ncq_prio_supported_show(struct device *dev,4087 struct device_attribute *attr, char *buf)4088{4089 struct scsi_device *sdev = to_scsi_device(dev);4090 4091 return sysfs_emit(buf, "%d\n", sas_ata_ncq_prio_supported(sdev));4092}4093static DEVICE_ATTR_RO(sas_ncq_prio_supported);4094 4095/**4096 * sas_ncq_prio_enable_show - send prioritized io commands to device4097 * @dev: pointer to embedded device4098 * @attr: ?4099 * @buf: the buffer returned4100 *4101 * A sysfs 'read/write' sdev attribute, only works with SATA4102 */4103static ssize_t4104sas_ncq_prio_enable_show(struct device *dev,4105 struct device_attribute *attr, char *buf)4106{4107 struct scsi_device *sdev = to_scsi_device(dev);4108 struct MPT3SAS_DEVICE *sas_device_priv_data = sdev->hostdata;4109 4110 return snprintf(buf, PAGE_SIZE, "%d\n",4111 sas_device_priv_data->ncq_prio_enable);4112}4113 4114static ssize_t4115sas_ncq_prio_enable_store(struct device *dev,4116 struct device_attribute *attr,4117 const char *buf, size_t count)4118{4119 struct scsi_device *sdev = to_scsi_device(dev);4120 struct MPT3SAS_DEVICE *sas_device_priv_data = sdev->hostdata;4121 bool ncq_prio_enable = 0;4122 4123 if (kstrtobool(buf, &ncq_prio_enable))4124 return -EINVAL;4125 4126 if (!sas_ata_ncq_prio_supported(sdev))4127 return -EINVAL;4128 4129 sas_device_priv_data->ncq_prio_enable = ncq_prio_enable;4130 return strlen(buf);4131}4132static DEVICE_ATTR_RW(sas_ncq_prio_enable);4133 4134static struct attribute *mpt3sas_dev_attrs[] = {4135 &dev_attr_sas_address.attr,4136 &dev_attr_sas_device_handle.attr,4137 &dev_attr_sas_ncq_prio_supported.attr,4138 &dev_attr_sas_ncq_prio_enable.attr,4139 NULL,4140};4141 4142static const struct attribute_group mpt3sas_dev_attr_group = {4143 .attrs = mpt3sas_dev_attrs4144};4145 4146const struct attribute_group *mpt3sas_dev_groups[] = {4147 &mpt3sas_dev_attr_group,4148 NULL4149};4150 4151/* file operations table for mpt3ctl device */4152static const struct file_operations ctl_fops = {4153 .owner = THIS_MODULE,4154 .unlocked_ioctl = _ctl_ioctl,4155 .poll = _ctl_poll,4156 .fasync = _ctl_fasync,4157#ifdef CONFIG_COMPAT4158 .compat_ioctl = _ctl_ioctl_compat,4159#endif4160};4161 4162/* file operations table for mpt2ctl device */4163static const struct file_operations ctl_gen2_fops = {4164 .owner = THIS_MODULE,4165 .unlocked_ioctl = _ctl_mpt2_ioctl,4166 .poll = _ctl_poll,4167 .fasync = _ctl_fasync,4168#ifdef CONFIG_COMPAT4169 .compat_ioctl = _ctl_mpt2_ioctl_compat,4170#endif4171};4172 4173static struct miscdevice ctl_dev = {4174 .minor = MPT3SAS_MINOR,4175 .name = MPT3SAS_DEV_NAME,4176 .fops = &ctl_fops,4177};4178 4179static struct miscdevice gen2_ctl_dev = {4180 .minor = MPT2SAS_MINOR,4181 .name = MPT2SAS_DEV_NAME,4182 .fops = &ctl_gen2_fops,4183};4184 4185/**4186 * mpt3sas_ctl_init - main entry point for ctl.4187 * @hbas_to_enumerate: ?4188 */4189void4190mpt3sas_ctl_init(ushort hbas_to_enumerate)4191{4192 async_queue = NULL;4193 4194 /* Don't register mpt3ctl ioctl device if4195 * hbas_to_enumarate is one.4196 */4197 if (hbas_to_enumerate != 1)4198 if (misc_register(&ctl_dev) < 0)4199 pr_err("%s can't register misc device [minor=%d]\n",4200 MPT3SAS_DRIVER_NAME, MPT3SAS_MINOR);4201 4202 /* Don't register mpt3ctl ioctl device if4203 * hbas_to_enumarate is two.4204 */4205 if (hbas_to_enumerate != 2)4206 if (misc_register(&gen2_ctl_dev) < 0)4207 pr_err("%s can't register misc device [minor=%d]\n",4208 MPT2SAS_DRIVER_NAME, MPT2SAS_MINOR);4209 4210 init_waitqueue_head(&ctl_poll_wait);4211}4212 4213/**4214 * mpt3sas_ctl_release - release dma for ctl4215 * @ioc: per adapter object4216 */4217void4218mpt3sas_ctl_release(struct MPT3SAS_ADAPTER *ioc)4219{4220 int i;4221 4222 /* free memory associated to diag buffers */4223 for (i = 0; i < MPI2_DIAG_BUF_TYPE_COUNT; i++) {4224 if (!ioc->diag_buffer[i])4225 continue;4226 dma_free_coherent(&ioc->pdev->dev,4227 ioc->diag_buffer_sz[i],4228 ioc->diag_buffer[i],4229 ioc->diag_buffer_dma[i]);4230 ioc->diag_buffer[i] = NULL;4231 ioc->diag_buffer_status[i] = 0;4232 }4233 4234 kfree(ioc->event_log);4235}4236 4237/**4238 * mpt3sas_ctl_exit - exit point for ctl4239 * @hbas_to_enumerate: ?4240 */4241void4242mpt3sas_ctl_exit(ushort hbas_to_enumerate)4243{4244 4245 if (hbas_to_enumerate != 1)4246 misc_deregister(&ctl_dev);4247 if (hbas_to_enumerate != 2)4248 misc_deregister(&gen2_ctl_dev);4249}4250