2084 lines · c
1/*2 * linux/drivers/scsi/esas2r/esas2r_ioctl.c3 * For use with ATTO ExpressSAS R6xx SAS/SATA RAID controllers4 *5 * Copyright (c) 2001-2013 ATTO Technology, Inc.6 * (mailto:linuxdrivers@attotech.com)7 *8 * This program is free software; you can redistribute it and/or9 * modify it under the terms of the GNU General Public License10 * as published by the Free Software Foundation; either version 211 * of the License, or (at your option) any later version.12 *13 * This program is distributed in the hope that it will be useful,14 * but WITHOUT ANY WARRANTY; without even the implied warranty of15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the16 * GNU General Public License for more details.17 *18 * NO WARRANTY19 * THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR20 * CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT21 * LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,22 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is23 * solely responsible for determining the appropriateness of using and24 * distributing the Program and assumes all risks associated with its25 * exercise of rights under this Agreement, including but not limited to26 * the risks and costs of program errors, damage to or loss of data,27 * programs or equipment, and unavailability or interruption of operations.28 *29 * DISCLAIMER OF LIABILITY30 * NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY31 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL32 * DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND33 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR34 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE35 * USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED36 * HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES37 *38 * You should have received a copy of the GNU General Public License39 * along with this program; if not, write to the Free Software40 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,41 * USA.42 */43 44#include <linux/bitfield.h>45 46#include "esas2r.h"47 48/*49 * Buffered ioctl handlers. A buffered ioctl is one which requires that we50 * allocate a DMA-able memory area to communicate with the firmware. In51 * order to prevent continually allocating and freeing consistent memory,52 * we will allocate a global buffer the first time we need it and re-use53 * it for subsequent ioctl calls that require it.54 */55 56u8 *esas2r_buffered_ioctl;57dma_addr_t esas2r_buffered_ioctl_addr;58u32 esas2r_buffered_ioctl_size;59struct pci_dev *esas2r_buffered_ioctl_pcid;60 61static DEFINE_SEMAPHORE(buffered_ioctl_semaphore, 1);62typedef int (*BUFFERED_IOCTL_CALLBACK)(struct esas2r_adapter *,63 struct esas2r_request *,64 struct esas2r_sg_context *,65 void *);66typedef void (*BUFFERED_IOCTL_DONE_CALLBACK)(struct esas2r_adapter *,67 struct esas2r_request *, void *);68 69struct esas2r_buffered_ioctl {70 struct esas2r_adapter *a;71 void *ioctl;72 u32 length;73 u32 control_code;74 u32 offset;75 BUFFERED_IOCTL_CALLBACK76 callback;77 void *context;78 BUFFERED_IOCTL_DONE_CALLBACK79 done_callback;80 void *done_context;81 82};83 84static void complete_fm_api_req(struct esas2r_adapter *a,85 struct esas2r_request *rq)86{87 a->fm_api_command_done = 1;88 wake_up_interruptible(&a->fm_api_waiter);89}90 91/* Callbacks for building scatter/gather lists for FM API requests */92static u32 get_physaddr_fm_api(struct esas2r_sg_context *sgc, u64 *addr)93{94 struct esas2r_adapter *a = (struct esas2r_adapter *)sgc->adapter;95 int offset = sgc->cur_offset - a->save_offset;96 97 (*addr) = a->firmware.phys + offset;98 return a->firmware.orig_len - offset;99}100 101static u32 get_physaddr_fm_api_header(struct esas2r_sg_context *sgc, u64 *addr)102{103 struct esas2r_adapter *a = (struct esas2r_adapter *)sgc->adapter;104 int offset = sgc->cur_offset - a->save_offset;105 106 (*addr) = a->firmware.header_buff_phys + offset;107 return sizeof(struct esas2r_flash_img) - offset;108}109 110/* Handle EXPRESS_IOCTL_RW_FIRMWARE ioctl with img_type = FW_IMG_FM_API. */111static void do_fm_api(struct esas2r_adapter *a, struct esas2r_flash_img *fi)112{113 struct esas2r_request *rq;114 115 if (mutex_lock_interruptible(&a->fm_api_mutex)) {116 fi->status = FI_STAT_BUSY;117 return;118 }119 120 rq = esas2r_alloc_request(a);121 if (rq == NULL) {122 fi->status = FI_STAT_BUSY;123 goto free_sem;124 }125 126 if (fi == &a->firmware.header) {127 a->firmware.header_buff = dma_alloc_coherent(&a->pcid->dev,128 (size_t)sizeof(129 struct130 esas2r_flash_img),131 (dma_addr_t *)&a->132 firmware.133 header_buff_phys,134 GFP_KERNEL);135 136 if (a->firmware.header_buff == NULL) {137 esas2r_debug("failed to allocate header buffer!");138 fi->status = FI_STAT_BUSY;139 goto free_req;140 }141 142 memcpy(a->firmware.header_buff, fi,143 sizeof(struct esas2r_flash_img));144 a->save_offset = a->firmware.header_buff;145 a->fm_api_sgc.get_phys_addr =146 (PGETPHYSADDR)get_physaddr_fm_api_header;147 } else {148 a->save_offset = (u8 *)fi;149 a->fm_api_sgc.get_phys_addr =150 (PGETPHYSADDR)get_physaddr_fm_api;151 }152 153 rq->comp_cb = complete_fm_api_req;154 a->fm_api_command_done = 0;155 a->fm_api_sgc.cur_offset = a->save_offset;156 157 if (!esas2r_fm_api(a, (struct esas2r_flash_img *)a->save_offset, rq,158 &a->fm_api_sgc))159 goto all_done;160 161 /* Now wait around for it to complete. */162 while (!a->fm_api_command_done)163 wait_event_interruptible(a->fm_api_waiter,164 a->fm_api_command_done);165all_done:166 if (fi == &a->firmware.header) {167 memcpy(fi, a->firmware.header_buff,168 sizeof(struct esas2r_flash_img));169 170 dma_free_coherent(&a->pcid->dev,171 (size_t)sizeof(struct esas2r_flash_img),172 a->firmware.header_buff,173 (dma_addr_t)a->firmware.header_buff_phys);174 }175free_req:176 esas2r_free_request(a, (struct esas2r_request *)rq);177free_sem:178 mutex_unlock(&a->fm_api_mutex);179 return;180 181}182 183static void complete_nvr_req(struct esas2r_adapter *a,184 struct esas2r_request *rq)185{186 a->nvram_command_done = 1;187 wake_up_interruptible(&a->nvram_waiter);188}189 190/* Callback for building scatter/gather lists for buffered ioctls */191static u32 get_physaddr_buffered_ioctl(struct esas2r_sg_context *sgc,192 u64 *addr)193{194 int offset = (u8 *)sgc->cur_offset - esas2r_buffered_ioctl;195 196 (*addr) = esas2r_buffered_ioctl_addr + offset;197 return esas2r_buffered_ioctl_size - offset;198}199 200static void complete_buffered_ioctl_req(struct esas2r_adapter *a,201 struct esas2r_request *rq)202{203 a->buffered_ioctl_done = 1;204 wake_up_interruptible(&a->buffered_ioctl_waiter);205}206 207static u8 handle_buffered_ioctl(struct esas2r_buffered_ioctl *bi)208{209 struct esas2r_adapter *a = bi->a;210 struct esas2r_request *rq;211 struct esas2r_sg_context sgc;212 u8 result = IOCTL_SUCCESS;213 214 if (down_interruptible(&buffered_ioctl_semaphore))215 return IOCTL_OUT_OF_RESOURCES;216 217 /* allocate a buffer or use the existing buffer. */218 if (esas2r_buffered_ioctl) {219 if (esas2r_buffered_ioctl_size < bi->length) {220 /* free the too-small buffer and get a new one */221 dma_free_coherent(&a->pcid->dev,222 (size_t)esas2r_buffered_ioctl_size,223 esas2r_buffered_ioctl,224 esas2r_buffered_ioctl_addr);225 226 goto allocate_buffer;227 }228 } else {229allocate_buffer:230 esas2r_buffered_ioctl_size = bi->length;231 esas2r_buffered_ioctl_pcid = a->pcid;232 esas2r_buffered_ioctl = dma_alloc_coherent(&a->pcid->dev,233 (size_t)234 esas2r_buffered_ioctl_size,235 &236 esas2r_buffered_ioctl_addr,237 GFP_KERNEL);238 }239 240 if (!esas2r_buffered_ioctl) {241 esas2r_log(ESAS2R_LOG_CRIT,242 "could not allocate %d bytes of consistent memory "243 "for a buffered ioctl!",244 bi->length);245 246 esas2r_debug("buffered ioctl alloc failure");247 result = IOCTL_OUT_OF_RESOURCES;248 goto exit_cleanly;249 }250 251 memcpy(esas2r_buffered_ioctl, bi->ioctl, bi->length);252 253 rq = esas2r_alloc_request(a);254 if (rq == NULL) {255 esas2r_log(ESAS2R_LOG_CRIT,256 "could not allocate an internal request");257 258 result = IOCTL_OUT_OF_RESOURCES;259 esas2r_debug("buffered ioctl - no requests");260 goto exit_cleanly;261 }262 263 a->buffered_ioctl_done = 0;264 rq->comp_cb = complete_buffered_ioctl_req;265 sgc.cur_offset = esas2r_buffered_ioctl + bi->offset;266 sgc.get_phys_addr = (PGETPHYSADDR)get_physaddr_buffered_ioctl;267 sgc.length = esas2r_buffered_ioctl_size;268 269 if (!(*bi->callback)(a, rq, &sgc, bi->context)) {270 /* completed immediately, no need to wait */271 a->buffered_ioctl_done = 0;272 goto free_andexit_cleanly;273 }274 275 /* now wait around for it to complete. */276 while (!a->buffered_ioctl_done)277 wait_event_interruptible(a->buffered_ioctl_waiter,278 a->buffered_ioctl_done);279 280free_andexit_cleanly:281 if (result == IOCTL_SUCCESS && bi->done_callback)282 (*bi->done_callback)(a, rq, bi->done_context);283 284 esas2r_free_request(a, rq);285 286exit_cleanly:287 if (result == IOCTL_SUCCESS)288 memcpy(bi->ioctl, esas2r_buffered_ioctl, bi->length);289 290 up(&buffered_ioctl_semaphore);291 return result;292}293 294/* SMP ioctl support */295static int smp_ioctl_callback(struct esas2r_adapter *a,296 struct esas2r_request *rq,297 struct esas2r_sg_context *sgc, void *context)298{299 struct atto_ioctl_smp *si =300 (struct atto_ioctl_smp *)esas2r_buffered_ioctl;301 302 esas2r_sgc_init(sgc, a, rq, rq->vrq->ioctl.sge);303 esas2r_build_ioctl_req(a, rq, sgc->length, VDA_IOCTL_SMP);304 305 if (!esas2r_build_sg_list(a, rq, sgc)) {306 si->status = ATTO_STS_OUT_OF_RSRC;307 return false;308 }309 310 esas2r_start_request(a, rq);311 return true;312}313 314static u8 handle_smp_ioctl(struct esas2r_adapter *a, struct atto_ioctl_smp *si)315{316 struct esas2r_buffered_ioctl bi;317 318 memset(&bi, 0, sizeof(bi));319 320 bi.a = a;321 bi.ioctl = si;322 bi.length = sizeof(struct atto_ioctl_smp)323 + le32_to_cpu(si->req_length)324 + le32_to_cpu(si->rsp_length);325 bi.offset = 0;326 bi.callback = smp_ioctl_callback;327 return handle_buffered_ioctl(&bi);328}329 330 331/* CSMI ioctl support */332static void esas2r_csmi_ioctl_tunnel_comp_cb(struct esas2r_adapter *a,333 struct esas2r_request *rq)334{335 rq->target_id = le16_to_cpu(rq->func_rsp.ioctl_rsp.csmi.target_id);336 rq->vrq->scsi.flags |= cpu_to_le32(rq->func_rsp.ioctl_rsp.csmi.lun);337 338 /* Now call the original completion callback. */339 (*rq->aux_req_cb)(a, rq);340}341 342/* Tunnel a CSMI IOCTL to the back end driver for processing. */343static bool csmi_ioctl_tunnel(struct esas2r_adapter *a,344 union atto_ioctl_csmi *ci,345 struct esas2r_request *rq,346 struct esas2r_sg_context *sgc,347 u32 ctrl_code,348 u16 target_id)349{350 struct atto_vda_ioctl_req *ioctl = &rq->vrq->ioctl;351 352 if (test_bit(AF_DEGRADED_MODE, &a->flags))353 return false;354 355 esas2r_sgc_init(sgc, a, rq, rq->vrq->ioctl.sge);356 esas2r_build_ioctl_req(a, rq, sgc->length, VDA_IOCTL_CSMI);357 ioctl->csmi.ctrl_code = cpu_to_le32(ctrl_code);358 ioctl->csmi.target_id = cpu_to_le16(target_id);359 ioctl->csmi.lun = (u8)le32_to_cpu(rq->vrq->scsi.flags);360 361 /*362 * Always usurp the completion callback since the interrupt callback363 * mechanism may be used.364 */365 rq->aux_req_cx = ci;366 rq->aux_req_cb = rq->comp_cb;367 rq->comp_cb = esas2r_csmi_ioctl_tunnel_comp_cb;368 369 if (!esas2r_build_sg_list(a, rq, sgc))370 return false;371 372 esas2r_start_request(a, rq);373 return true;374}375 376static bool check_lun(struct scsi_lun lun)377{378 bool result;379 380 result = ((lun.scsi_lun[7] == 0) &&381 (lun.scsi_lun[6] == 0) &&382 (lun.scsi_lun[5] == 0) &&383 (lun.scsi_lun[4] == 0) &&384 (lun.scsi_lun[3] == 0) &&385 (lun.scsi_lun[2] == 0) &&386/* Byte 1 is intentionally skipped */387 (lun.scsi_lun[0] == 0));388 389 return result;390}391 392static int csmi_ioctl_callback(struct esas2r_adapter *a,393 struct esas2r_request *rq,394 struct esas2r_sg_context *sgc, void *context)395{396 struct atto_csmi *ci = (struct atto_csmi *)context;397 union atto_ioctl_csmi *ioctl_csmi =398 (union atto_ioctl_csmi *)esas2r_buffered_ioctl;399 u8 path = 0;400 u8 tid = 0;401 u8 lun = 0;402 u32 sts = CSMI_STS_SUCCESS;403 struct esas2r_target *t;404 unsigned long flags;405 406 if (ci->control_code == CSMI_CC_GET_DEV_ADDR) {407 struct atto_csmi_get_dev_addr *gda = &ci->data.dev_addr;408 409 path = gda->path_id;410 tid = gda->target_id;411 lun = gda->lun;412 } else if (ci->control_code == CSMI_CC_TASK_MGT) {413 struct atto_csmi_task_mgmt *tm = &ci->data.tsk_mgt;414 415 path = tm->path_id;416 tid = tm->target_id;417 lun = tm->lun;418 }419 420 if (path > 0) {421 rq->func_rsp.ioctl_rsp.csmi.csmi_status = cpu_to_le32(422 CSMI_STS_INV_PARAM);423 return false;424 }425 426 rq->target_id = tid;427 rq->vrq->scsi.flags |= cpu_to_le32(lun);428 429 switch (ci->control_code) {430 case CSMI_CC_GET_DRVR_INFO:431 {432 struct atto_csmi_get_driver_info *gdi = &ioctl_csmi->drvr_info;433 434 strcpy(gdi->description, esas2r_get_model_name(a));435 gdi->csmi_major_rev = CSMI_MAJOR_REV;436 gdi->csmi_minor_rev = CSMI_MINOR_REV;437 break;438 }439 440 case CSMI_CC_GET_CNTLR_CFG:441 {442 struct atto_csmi_get_cntlr_cfg *gcc = &ioctl_csmi->cntlr_cfg;443 444 gcc->base_io_addr = 0;445 pci_read_config_dword(a->pcid, PCI_BASE_ADDRESS_2,446 &gcc->base_memaddr_lo);447 pci_read_config_dword(a->pcid, PCI_BASE_ADDRESS_3,448 &gcc->base_memaddr_hi);449 gcc->board_id = MAKEDWORD(a->pcid->subsystem_device,450 a->pcid->subsystem_vendor);451 gcc->slot_num = CSMI_SLOT_NUM_UNKNOWN;452 gcc->cntlr_class = CSMI_CNTLR_CLASS_HBA;453 gcc->io_bus_type = CSMI_BUS_TYPE_PCI;454 gcc->pci_addr.bus_num = a->pcid->bus->number;455 gcc->pci_addr.device_num = PCI_SLOT(a->pcid->devfn);456 gcc->pci_addr.function_num = PCI_FUNC(a->pcid->devfn);457 458 memset(gcc->serial_num, 0, sizeof(gcc->serial_num));459 460 gcc->major_rev = LOBYTE(LOWORD(a->fw_version));461 gcc->minor_rev = HIBYTE(LOWORD(a->fw_version));462 gcc->build_rev = LOBYTE(HIWORD(a->fw_version));463 gcc->release_rev = HIBYTE(HIWORD(a->fw_version));464 gcc->bios_major_rev = HIBYTE(HIWORD(a->flash_ver));465 gcc->bios_minor_rev = LOBYTE(HIWORD(a->flash_ver));466 gcc->bios_build_rev = LOWORD(a->flash_ver);467 468 if (test_bit(AF2_THUNDERLINK, &a->flags2))469 gcc->cntlr_flags = CSMI_CNTLRF_SAS_HBA470 | CSMI_CNTLRF_SATA_HBA;471 else472 gcc->cntlr_flags = CSMI_CNTLRF_SAS_RAID473 | CSMI_CNTLRF_SATA_RAID;474 475 gcc->rrom_major_rev = 0;476 gcc->rrom_minor_rev = 0;477 gcc->rrom_build_rev = 0;478 gcc->rrom_release_rev = 0;479 gcc->rrom_biosmajor_rev = 0;480 gcc->rrom_biosminor_rev = 0;481 gcc->rrom_biosbuild_rev = 0;482 gcc->rrom_biosrelease_rev = 0;483 break;484 }485 486 case CSMI_CC_GET_CNTLR_STS:487 {488 struct atto_csmi_get_cntlr_sts *gcs = &ioctl_csmi->cntlr_sts;489 490 if (test_bit(AF_DEGRADED_MODE, &a->flags))491 gcs->status = CSMI_CNTLR_STS_FAILED;492 else493 gcs->status = CSMI_CNTLR_STS_GOOD;494 495 gcs->offline_reason = CSMI_OFFLINE_NO_REASON;496 break;497 }498 499 case CSMI_CC_FW_DOWNLOAD:500 case CSMI_CC_GET_RAID_INFO:501 case CSMI_CC_GET_RAID_CFG:502 503 sts = CSMI_STS_BAD_CTRL_CODE;504 break;505 506 case CSMI_CC_SMP_PASSTHRU:507 case CSMI_CC_SSP_PASSTHRU:508 case CSMI_CC_STP_PASSTHRU:509 case CSMI_CC_GET_PHY_INFO:510 case CSMI_CC_SET_PHY_INFO:511 case CSMI_CC_GET_LINK_ERRORS:512 case CSMI_CC_GET_SATA_SIG:513 case CSMI_CC_GET_CONN_INFO:514 case CSMI_CC_PHY_CTRL:515 516 if (!csmi_ioctl_tunnel(a, ioctl_csmi, rq, sgc,517 ci->control_code,518 ESAS2R_TARG_ID_INV)) {519 sts = CSMI_STS_FAILED;520 break;521 }522 523 return true;524 525 case CSMI_CC_GET_SCSI_ADDR:526 {527 struct atto_csmi_get_scsi_addr *gsa = &ioctl_csmi->scsi_addr;528 529 struct scsi_lun lun;530 531 memcpy(&lun, gsa->sas_lun, sizeof(struct scsi_lun));532 533 if (!check_lun(lun)) {534 sts = CSMI_STS_NO_SCSI_ADDR;535 break;536 }537 538 /* make sure the device is present */539 spin_lock_irqsave(&a->mem_lock, flags);540 t = esas2r_targ_db_find_by_sas_addr(a, (u64 *)gsa->sas_addr);541 spin_unlock_irqrestore(&a->mem_lock, flags);542 543 if (t == NULL) {544 sts = CSMI_STS_NO_SCSI_ADDR;545 break;546 }547 548 gsa->host_index = 0xFF;549 gsa->lun = gsa->sas_lun[1];550 rq->target_id = esas2r_targ_get_id(t, a);551 break;552 }553 554 case CSMI_CC_GET_DEV_ADDR:555 {556 struct atto_csmi_get_dev_addr *gda = &ioctl_csmi->dev_addr;557 558 /* make sure the target is present */559 t = a->targetdb + rq->target_id;560 561 if (t >= a->targetdb_end562 || t->target_state != TS_PRESENT563 || t->sas_addr == 0) {564 sts = CSMI_STS_NO_DEV_ADDR;565 break;566 }567 568 /* fill in the result */569 *(u64 *)gda->sas_addr = t->sas_addr;570 memset(gda->sas_lun, 0, sizeof(gda->sas_lun));571 gda->sas_lun[1] = (u8)le32_to_cpu(rq->vrq->scsi.flags);572 break;573 }574 575 case CSMI_CC_TASK_MGT:576 577 /* make sure the target is present */578 t = a->targetdb + rq->target_id;579 580 if (t >= a->targetdb_end581 || t->target_state != TS_PRESENT582 || !(t->flags & TF_PASS_THRU)) {583 sts = CSMI_STS_NO_DEV_ADDR;584 break;585 }586 587 if (!csmi_ioctl_tunnel(a, ioctl_csmi, rq, sgc,588 ci->control_code,589 t->phys_targ_id)) {590 sts = CSMI_STS_FAILED;591 break;592 }593 594 return true;595 596 default:597 598 sts = CSMI_STS_BAD_CTRL_CODE;599 break;600 }601 602 rq->func_rsp.ioctl_rsp.csmi.csmi_status = cpu_to_le32(sts);603 604 return false;605}606 607 608static void csmi_ioctl_done_callback(struct esas2r_adapter *a,609 struct esas2r_request *rq, void *context)610{611 struct atto_csmi *ci = (struct atto_csmi *)context;612 union atto_ioctl_csmi *ioctl_csmi =613 (union atto_ioctl_csmi *)esas2r_buffered_ioctl;614 615 switch (ci->control_code) {616 case CSMI_CC_GET_DRVR_INFO:617 {618 struct atto_csmi_get_driver_info *gdi =619 &ioctl_csmi->drvr_info;620 621 strcpy(gdi->name, ESAS2R_VERSION_STR);622 623 gdi->major_rev = ESAS2R_MAJOR_REV;624 gdi->minor_rev = ESAS2R_MINOR_REV;625 gdi->build_rev = 0;626 gdi->release_rev = 0;627 break;628 }629 630 case CSMI_CC_GET_SCSI_ADDR:631 {632 struct atto_csmi_get_scsi_addr *gsa = &ioctl_csmi->scsi_addr;633 634 if (le32_to_cpu(rq->func_rsp.ioctl_rsp.csmi.csmi_status) ==635 CSMI_STS_SUCCESS) {636 gsa->target_id = rq->target_id;637 gsa->path_id = 0;638 }639 640 break;641 }642 }643 644 ci->status = le32_to_cpu(rq->func_rsp.ioctl_rsp.csmi.csmi_status);645}646 647 648static u8 handle_csmi_ioctl(struct esas2r_adapter *a, struct atto_csmi *ci)649{650 struct esas2r_buffered_ioctl bi;651 652 memset(&bi, 0, sizeof(bi));653 654 bi.a = a;655 bi.ioctl = &ci->data;656 bi.length = sizeof(union atto_ioctl_csmi);657 bi.offset = 0;658 bi.callback = csmi_ioctl_callback;659 bi.context = ci;660 bi.done_callback = csmi_ioctl_done_callback;661 bi.done_context = ci;662 663 return handle_buffered_ioctl(&bi);664}665 666/* ATTO HBA ioctl support */667 668/* Tunnel an ATTO HBA IOCTL to the back end driver for processing. */669static bool hba_ioctl_tunnel(struct esas2r_adapter *a,670 struct atto_ioctl *hi,671 struct esas2r_request *rq,672 struct esas2r_sg_context *sgc)673{674 esas2r_sgc_init(sgc, a, rq, rq->vrq->ioctl.sge);675 676 esas2r_build_ioctl_req(a, rq, sgc->length, VDA_IOCTL_HBA);677 678 if (!esas2r_build_sg_list(a, rq, sgc)) {679 hi->status = ATTO_STS_OUT_OF_RSRC;680 681 return false;682 }683 684 esas2r_start_request(a, rq);685 686 return true;687}688 689static void scsi_passthru_comp_cb(struct esas2r_adapter *a,690 struct esas2r_request *rq)691{692 struct atto_ioctl *hi = (struct atto_ioctl *)rq->aux_req_cx;693 struct atto_hba_scsi_pass_thru *spt = &hi->data.scsi_pass_thru;694 u8 sts = ATTO_SPT_RS_FAILED;695 696 spt->scsi_status = rq->func_rsp.scsi_rsp.scsi_stat;697 spt->sense_length = rq->sense_len;698 spt->residual_length =699 le32_to_cpu(rq->func_rsp.scsi_rsp.residual_length);700 701 switch (rq->req_stat) {702 case RS_SUCCESS:703 case RS_SCSI_ERROR:704 sts = ATTO_SPT_RS_SUCCESS;705 break;706 case RS_UNDERRUN:707 sts = ATTO_SPT_RS_UNDERRUN;708 break;709 case RS_OVERRUN:710 sts = ATTO_SPT_RS_OVERRUN;711 break;712 case RS_SEL:713 case RS_SEL2:714 sts = ATTO_SPT_RS_NO_DEVICE;715 break;716 case RS_NO_LUN:717 sts = ATTO_SPT_RS_NO_LUN;718 break;719 case RS_TIMEOUT:720 sts = ATTO_SPT_RS_TIMEOUT;721 break;722 case RS_DEGRADED:723 sts = ATTO_SPT_RS_DEGRADED;724 break;725 case RS_BUSY:726 sts = ATTO_SPT_RS_BUSY;727 break;728 case RS_ABORTED:729 sts = ATTO_SPT_RS_ABORTED;730 break;731 case RS_RESET:732 sts = ATTO_SPT_RS_BUS_RESET;733 break;734 }735 736 spt->req_status = sts;737 738 /* Update the target ID to the next one present. */739 spt->target_id =740 esas2r_targ_db_find_next_present(a, (u16)spt->target_id);741 742 /* Done, call the completion callback. */743 (*rq->aux_req_cb)(a, rq);744}745 746static int hba_ioctl_callback(struct esas2r_adapter *a,747 struct esas2r_request *rq,748 struct esas2r_sg_context *sgc,749 void *context)750{751 struct atto_ioctl *hi = (struct atto_ioctl *)esas2r_buffered_ioctl;752 753 hi->status = ATTO_STS_SUCCESS;754 755 switch (hi->function) {756 case ATTO_FUNC_GET_ADAP_INFO:757 {758 u8 *class_code = (u8 *)&a->pcid->class;759 760 struct atto_hba_get_adapter_info *gai =761 &hi->data.get_adap_info;762 763 if (hi->flags & HBAF_TUNNEL) {764 hi->status = ATTO_STS_UNSUPPORTED;765 break;766 }767 768 if (hi->version > ATTO_VER_GET_ADAP_INFO0) {769 hi->status = ATTO_STS_INV_VERSION;770 hi->version = ATTO_VER_GET_ADAP_INFO0;771 break;772 }773 774 memset(gai, 0, sizeof(*gai));775 776 gai->pci.vendor_id = a->pcid->vendor;777 gai->pci.device_id = a->pcid->device;778 gai->pci.ss_vendor_id = a->pcid->subsystem_vendor;779 gai->pci.ss_device_id = a->pcid->subsystem_device;780 gai->pci.class_code[0] = class_code[0];781 gai->pci.class_code[1] = class_code[1];782 gai->pci.class_code[2] = class_code[2];783 gai->pci.rev_id = a->pcid->revision;784 gai->pci.bus_num = a->pcid->bus->number;785 gai->pci.dev_num = PCI_SLOT(a->pcid->devfn);786 gai->pci.func_num = PCI_FUNC(a->pcid->devfn);787 788 if (pci_is_pcie(a->pcid)) {789 u16 stat;790 u32 caps;791 792 pcie_capability_read_word(a->pcid, PCI_EXP_LNKSTA,793 &stat);794 pcie_capability_read_dword(a->pcid, PCI_EXP_LNKCAP,795 &caps);796 797 gai->pci.link_speed_curr = FIELD_GET(PCI_EXP_LNKSTA_CLS, stat);798 gai->pci.link_speed_max = FIELD_GET(PCI_EXP_LNKCAP_SLS, caps);799 gai->pci.link_width_curr = FIELD_GET(PCI_EXP_LNKSTA_NLW, stat);800 gai->pci.link_width_max = FIELD_GET(PCI_EXP_LNKCAP_MLW, caps);801 }802 803 gai->pci.msi_vector_cnt = 1;804 805 if (a->pcid->msix_enabled)806 gai->pci.interrupt_mode = ATTO_GAI_PCIIM_MSIX;807 else if (a->pcid->msi_enabled)808 gai->pci.interrupt_mode = ATTO_GAI_PCIIM_MSI;809 else810 gai->pci.interrupt_mode = ATTO_GAI_PCIIM_LEGACY;811 812 gai->adap_type = ATTO_GAI_AT_ESASRAID2;813 814 if (test_bit(AF2_THUNDERLINK, &a->flags2))815 gai->adap_type = ATTO_GAI_AT_TLSASHBA;816 817 if (test_bit(AF_DEGRADED_MODE, &a->flags))818 gai->adap_flags |= ATTO_GAI_AF_DEGRADED;819 820 gai->adap_flags |= ATTO_GAI_AF_SPT_SUPP |821 ATTO_GAI_AF_DEVADDR_SUPP;822 823 if (a->pcid->subsystem_device == ATTO_ESAS_R60F824 || a->pcid->subsystem_device == ATTO_ESAS_R608825 || a->pcid->subsystem_device == ATTO_ESAS_R644826 || a->pcid->subsystem_device == ATTO_TSSC_3808E)827 gai->adap_flags |= ATTO_GAI_AF_VIRT_SES;828 829 gai->num_ports = ESAS2R_NUM_PHYS;830 gai->num_phys = ESAS2R_NUM_PHYS;831 832 strcpy(gai->firmware_rev, a->fw_rev);833 strcpy(gai->flash_rev, a->flash_rev);834 strcpy(gai->model_name_short, esas2r_get_model_name_short(a));835 strcpy(gai->model_name, esas2r_get_model_name(a));836 837 gai->num_targets = ESAS2R_MAX_TARGETS;838 839 gai->num_busses = 1;840 gai->num_targsper_bus = gai->num_targets;841 gai->num_lunsper_targ = 256;842 843 if (a->pcid->subsystem_device == ATTO_ESAS_R6F0844 || a->pcid->subsystem_device == ATTO_ESAS_R60F)845 gai->num_connectors = 4;846 else847 gai->num_connectors = 2;848 849 gai->adap_flags2 |= ATTO_GAI_AF2_ADAP_CTRL_SUPP;850 851 gai->num_targets_backend = a->num_targets_backend;852 853 gai->tunnel_flags = a->ioctl_tunnel854 & (ATTO_GAI_TF_MEM_RW855 | ATTO_GAI_TF_TRACE856 | ATTO_GAI_TF_SCSI_PASS_THRU857 | ATTO_GAI_TF_GET_DEV_ADDR858 | ATTO_GAI_TF_PHY_CTRL859 | ATTO_GAI_TF_CONN_CTRL860 | ATTO_GAI_TF_GET_DEV_INFO);861 break;862 }863 864 case ATTO_FUNC_GET_ADAP_ADDR:865 {866 struct atto_hba_get_adapter_address *gaa =867 &hi->data.get_adap_addr;868 869 if (hi->flags & HBAF_TUNNEL) {870 hi->status = ATTO_STS_UNSUPPORTED;871 break;872 }873 874 if (hi->version > ATTO_VER_GET_ADAP_ADDR0) {875 hi->status = ATTO_STS_INV_VERSION;876 hi->version = ATTO_VER_GET_ADAP_ADDR0;877 } else if (gaa->addr_type == ATTO_GAA_AT_PORT878 || gaa->addr_type == ATTO_GAA_AT_NODE) {879 if (gaa->addr_type == ATTO_GAA_AT_PORT880 && gaa->port_id >= ESAS2R_NUM_PHYS) {881 hi->status = ATTO_STS_NOT_APPL;882 } else {883 memcpy((u64 *)gaa->address,884 &a->nvram->sas_addr[0], sizeof(u64));885 gaa->addr_len = sizeof(u64);886 }887 } else {888 hi->status = ATTO_STS_INV_PARAM;889 }890 891 break;892 }893 894 case ATTO_FUNC_MEM_RW:895 {896 if (hi->flags & HBAF_TUNNEL) {897 if (hba_ioctl_tunnel(a, hi, rq, sgc))898 return true;899 900 break;901 }902 903 hi->status = ATTO_STS_UNSUPPORTED;904 905 break;906 }907 908 case ATTO_FUNC_TRACE:909 {910 struct atto_hba_trace *trc = &hi->data.trace;911 912 if (hi->flags & HBAF_TUNNEL) {913 if (hba_ioctl_tunnel(a, hi, rq, sgc))914 return true;915 916 break;917 }918 919 if (hi->version > ATTO_VER_TRACE1) {920 hi->status = ATTO_STS_INV_VERSION;921 hi->version = ATTO_VER_TRACE1;922 break;923 }924 925 if (trc->trace_type == ATTO_TRC_TT_FWCOREDUMP926 && hi->version >= ATTO_VER_TRACE1) {927 if (trc->trace_func == ATTO_TRC_TF_UPLOAD) {928 u32 len = hi->data_length;929 u32 offset = trc->current_offset;930 u32 total_len = ESAS2R_FWCOREDUMP_SZ;931 932 /* Size is zero if a core dump isn't present */933 if (!test_bit(AF2_COREDUMP_SAVED, &a->flags2))934 total_len = 0;935 936 if (len > total_len)937 len = total_len;938 939 if (offset >= total_len940 || offset + len > total_len941 || len == 0) {942 hi->status = ATTO_STS_INV_PARAM;943 break;944 }945 946 memcpy(trc->contents,947 a->fw_coredump_buff + offset,948 len);949 hi->data_length = len;950 } else if (trc->trace_func == ATTO_TRC_TF_RESET) {951 memset(a->fw_coredump_buff, 0,952 ESAS2R_FWCOREDUMP_SZ);953 954 clear_bit(AF2_COREDUMP_SAVED, &a->flags2);955 } else if (trc->trace_func != ATTO_TRC_TF_GET_INFO) {956 hi->status = ATTO_STS_UNSUPPORTED;957 break;958 }959 960 /* Always return all the info we can. */961 trc->trace_mask = 0;962 trc->current_offset = 0;963 trc->total_length = ESAS2R_FWCOREDUMP_SZ;964 965 /* Return zero length buffer if core dump not present */966 if (!test_bit(AF2_COREDUMP_SAVED, &a->flags2))967 trc->total_length = 0;968 } else {969 hi->status = ATTO_STS_UNSUPPORTED;970 }971 972 break;973 }974 975 case ATTO_FUNC_SCSI_PASS_THRU:976 {977 struct atto_hba_scsi_pass_thru *spt = &hi->data.scsi_pass_thru;978 struct scsi_lun lun;979 980 memcpy(&lun, spt->lun, sizeof(struct scsi_lun));981 982 if (hi->flags & HBAF_TUNNEL) {983 if (hba_ioctl_tunnel(a, hi, rq, sgc))984 return true;985 986 break;987 }988 989 if (hi->version > ATTO_VER_SCSI_PASS_THRU0) {990 hi->status = ATTO_STS_INV_VERSION;991 hi->version = ATTO_VER_SCSI_PASS_THRU0;992 break;993 }994 995 if (spt->target_id >= ESAS2R_MAX_TARGETS || !check_lun(lun)) {996 hi->status = ATTO_STS_INV_PARAM;997 break;998 }999 1000 esas2r_sgc_init(sgc, a, rq, NULL);1001 1002 sgc->length = hi->data_length;1003 sgc->cur_offset += offsetof(struct atto_ioctl, data.byte)1004 + sizeof(struct atto_hba_scsi_pass_thru);1005 1006 /* Finish request initialization */1007 rq->target_id = (u16)spt->target_id;1008 rq->vrq->scsi.flags |= cpu_to_le32(spt->lun[1]);1009 memcpy(rq->vrq->scsi.cdb, spt->cdb, 16);1010 rq->vrq->scsi.length = cpu_to_le32(hi->data_length);1011 rq->sense_len = spt->sense_length;1012 rq->sense_buf = (u8 *)spt->sense_data;1013 /* NOTE: we ignore spt->timeout */1014 1015 /*1016 * always usurp the completion callback since the interrupt1017 * callback mechanism may be used.1018 */1019 1020 rq->aux_req_cx = hi;1021 rq->aux_req_cb = rq->comp_cb;1022 rq->comp_cb = scsi_passthru_comp_cb;1023 1024 if (spt->flags & ATTO_SPTF_DATA_IN) {1025 rq->vrq->scsi.flags |= cpu_to_le32(FCP_CMND_RDD);1026 } else if (spt->flags & ATTO_SPTF_DATA_OUT) {1027 rq->vrq->scsi.flags |= cpu_to_le32(FCP_CMND_WRD);1028 } else {1029 if (sgc->length) {1030 hi->status = ATTO_STS_INV_PARAM;1031 break;1032 }1033 }1034 1035 if (spt->flags & ATTO_SPTF_ORDERED_Q)1036 rq->vrq->scsi.flags |=1037 cpu_to_le32(FCP_CMND_TA_ORDRD_Q);1038 else if (spt->flags & ATTO_SPTF_HEAD_OF_Q)1039 rq->vrq->scsi.flags |= cpu_to_le32(FCP_CMND_TA_HEAD_Q);1040 1041 1042 if (!esas2r_build_sg_list(a, rq, sgc)) {1043 hi->status = ATTO_STS_OUT_OF_RSRC;1044 break;1045 }1046 1047 esas2r_start_request(a, rq);1048 1049 return true;1050 }1051 1052 case ATTO_FUNC_GET_DEV_ADDR:1053 {1054 struct atto_hba_get_device_address *gda =1055 &hi->data.get_dev_addr;1056 struct esas2r_target *t;1057 1058 if (hi->flags & HBAF_TUNNEL) {1059 if (hba_ioctl_tunnel(a, hi, rq, sgc))1060 return true;1061 1062 break;1063 }1064 1065 if (hi->version > ATTO_VER_GET_DEV_ADDR0) {1066 hi->status = ATTO_STS_INV_VERSION;1067 hi->version = ATTO_VER_GET_DEV_ADDR0;1068 break;1069 }1070 1071 if (gda->target_id >= ESAS2R_MAX_TARGETS) {1072 hi->status = ATTO_STS_INV_PARAM;1073 break;1074 }1075 1076 t = a->targetdb + (u16)gda->target_id;1077 1078 if (t->target_state != TS_PRESENT) {1079 hi->status = ATTO_STS_FAILED;1080 } else if (gda->addr_type == ATTO_GDA_AT_PORT) {1081 if (t->sas_addr == 0) {1082 hi->status = ATTO_STS_UNSUPPORTED;1083 } else {1084 *(u64 *)gda->address = t->sas_addr;1085 1086 gda->addr_len = sizeof(u64);1087 }1088 } else if (gda->addr_type == ATTO_GDA_AT_NODE) {1089 hi->status = ATTO_STS_NOT_APPL;1090 } else {1091 hi->status = ATTO_STS_INV_PARAM;1092 }1093 1094 /* update the target ID to the next one present. */1095 1096 gda->target_id =1097 esas2r_targ_db_find_next_present(a,1098 (u16)gda->target_id);1099 break;1100 }1101 1102 case ATTO_FUNC_PHY_CTRL:1103 case ATTO_FUNC_CONN_CTRL:1104 {1105 if (hba_ioctl_tunnel(a, hi, rq, sgc))1106 return true;1107 1108 break;1109 }1110 1111 case ATTO_FUNC_ADAP_CTRL:1112 {1113 struct atto_hba_adap_ctrl *ac = &hi->data.adap_ctrl;1114 1115 if (hi->flags & HBAF_TUNNEL) {1116 hi->status = ATTO_STS_UNSUPPORTED;1117 break;1118 }1119 1120 if (hi->version > ATTO_VER_ADAP_CTRL0) {1121 hi->status = ATTO_STS_INV_VERSION;1122 hi->version = ATTO_VER_ADAP_CTRL0;1123 break;1124 }1125 1126 if (ac->adap_func == ATTO_AC_AF_HARD_RST) {1127 esas2r_reset_adapter(a);1128 } else if (ac->adap_func != ATTO_AC_AF_GET_STATE) {1129 hi->status = ATTO_STS_UNSUPPORTED;1130 break;1131 }1132 1133 if (test_bit(AF_CHPRST_NEEDED, &a->flags))1134 ac->adap_state = ATTO_AC_AS_RST_SCHED;1135 else if (test_bit(AF_CHPRST_PENDING, &a->flags))1136 ac->adap_state = ATTO_AC_AS_RST_IN_PROG;1137 else if (test_bit(AF_DISC_PENDING, &a->flags))1138 ac->adap_state = ATTO_AC_AS_RST_DISC;1139 else if (test_bit(AF_DISABLED, &a->flags))1140 ac->adap_state = ATTO_AC_AS_DISABLED;1141 else if (test_bit(AF_DEGRADED_MODE, &a->flags))1142 ac->adap_state = ATTO_AC_AS_DEGRADED;1143 else1144 ac->adap_state = ATTO_AC_AS_OK;1145 1146 break;1147 }1148 1149 case ATTO_FUNC_GET_DEV_INFO:1150 {1151 struct atto_hba_get_device_info *gdi = &hi->data.get_dev_info;1152 struct esas2r_target *t;1153 1154 if (hi->flags & HBAF_TUNNEL) {1155 if (hba_ioctl_tunnel(a, hi, rq, sgc))1156 return true;1157 1158 break;1159 }1160 1161 if (hi->version > ATTO_VER_GET_DEV_INFO0) {1162 hi->status = ATTO_STS_INV_VERSION;1163 hi->version = ATTO_VER_GET_DEV_INFO0;1164 break;1165 }1166 1167 if (gdi->target_id >= ESAS2R_MAX_TARGETS) {1168 hi->status = ATTO_STS_INV_PARAM;1169 break;1170 }1171 1172 t = a->targetdb + (u16)gdi->target_id;1173 1174 /* update the target ID to the next one present. */1175 1176 gdi->target_id =1177 esas2r_targ_db_find_next_present(a,1178 (u16)gdi->target_id);1179 1180 if (t->target_state != TS_PRESENT) {1181 hi->status = ATTO_STS_FAILED;1182 break;1183 }1184 1185 hi->status = ATTO_STS_UNSUPPORTED;1186 break;1187 }1188 1189 default:1190 1191 hi->status = ATTO_STS_INV_FUNC;1192 break;1193 }1194 1195 return false;1196}1197 1198static void hba_ioctl_done_callback(struct esas2r_adapter *a,1199 struct esas2r_request *rq, void *context)1200{1201 struct atto_ioctl *ioctl_hba =1202 (struct atto_ioctl *)esas2r_buffered_ioctl;1203 1204 esas2r_debug("hba_ioctl_done_callback %d", a->index);1205 1206 if (ioctl_hba->function == ATTO_FUNC_GET_ADAP_INFO) {1207 struct atto_hba_get_adapter_info *gai =1208 &ioctl_hba->data.get_adap_info;1209 1210 esas2r_debug("ATTO_FUNC_GET_ADAP_INFO");1211 1212 gai->drvr_rev_major = ESAS2R_MAJOR_REV;1213 gai->drvr_rev_minor = ESAS2R_MINOR_REV;1214 1215 strcpy(gai->drvr_rev_ascii, ESAS2R_VERSION_STR);1216 strcpy(gai->drvr_name, ESAS2R_DRVR_NAME);1217 1218 gai->num_busses = 1;1219 gai->num_targsper_bus = ESAS2R_MAX_ID + 1;1220 gai->num_lunsper_targ = 1;1221 }1222}1223 1224u8 handle_hba_ioctl(struct esas2r_adapter *a,1225 struct atto_ioctl *ioctl_hba)1226{1227 struct esas2r_buffered_ioctl bi;1228 1229 memset(&bi, 0, sizeof(bi));1230 1231 bi.a = a;1232 bi.ioctl = ioctl_hba;1233 bi.length = sizeof(struct atto_ioctl) + ioctl_hba->data_length;1234 bi.callback = hba_ioctl_callback;1235 bi.context = NULL;1236 bi.done_callback = hba_ioctl_done_callback;1237 bi.done_context = NULL;1238 bi.offset = 0;1239 1240 return handle_buffered_ioctl(&bi);1241}1242 1243 1244int esas2r_write_params(struct esas2r_adapter *a, struct esas2r_request *rq,1245 struct esas2r_sas_nvram *data)1246{1247 int result = 0;1248 1249 a->nvram_command_done = 0;1250 rq->comp_cb = complete_nvr_req;1251 1252 if (esas2r_nvram_write(a, rq, data)) {1253 /* now wait around for it to complete. */1254 while (!a->nvram_command_done)1255 wait_event_interruptible(a->nvram_waiter,1256 a->nvram_command_done);1257 ;1258 1259 /* done, check the status. */1260 if (rq->req_stat == RS_SUCCESS)1261 result = 1;1262 }1263 return result;1264}1265 1266 1267/* This function only cares about ATTO-specific ioctls (atto_express_ioctl) */1268int esas2r_ioctl_handler(void *hostdata, unsigned int cmd, void __user *arg)1269{1270 struct atto_express_ioctl *ioctl = NULL;1271 struct esas2r_adapter *a;1272 struct esas2r_request *rq;1273 u16 code;1274 int err;1275 1276 esas2r_log(ESAS2R_LOG_DEBG, "ioctl (%p, %x, %p)", hostdata, cmd, arg);1277 1278 if ((arg == NULL)1279 || (cmd < EXPRESS_IOCTL_MIN)1280 || (cmd > EXPRESS_IOCTL_MAX))1281 return -ENOTSUPP;1282 1283 ioctl = memdup_user(arg, sizeof(struct atto_express_ioctl));1284 if (IS_ERR(ioctl)) {1285 esas2r_log(ESAS2R_LOG_WARN,1286 "ioctl_handler access_ok failed for cmd %u, address %p",1287 cmd, arg);1288 return PTR_ERR(ioctl);1289 }1290 1291 /* verify the signature */1292 1293 if (memcmp(ioctl->header.signature,1294 EXPRESS_IOCTL_SIGNATURE,1295 EXPRESS_IOCTL_SIGNATURE_SIZE) != 0) {1296 esas2r_log(ESAS2R_LOG_WARN, "invalid signature");1297 kfree(ioctl);1298 1299 return -ENOTSUPP;1300 }1301 1302 /* assume success */1303 1304 ioctl->header.return_code = IOCTL_SUCCESS;1305 err = 0;1306 1307 /*1308 * handle EXPRESS_IOCTL_GET_CHANNELS1309 * without paying attention to channel1310 */1311 1312 if (cmd == EXPRESS_IOCTL_GET_CHANNELS) {1313 int i = 0, k = 0;1314 1315 ioctl->data.chanlist.num_channels = 0;1316 1317 while (i < MAX_ADAPTERS) {1318 if (esas2r_adapters[i]) {1319 ioctl->data.chanlist.num_channels++;1320 ioctl->data.chanlist.channel[k] = i;1321 k++;1322 }1323 i++;1324 }1325 1326 goto ioctl_done;1327 }1328 1329 /* get the channel */1330 1331 if (ioctl->header.channel == 0xFF) {1332 a = (struct esas2r_adapter *)hostdata;1333 } else {1334 if (ioctl->header.channel >= MAX_ADAPTERS ||1335 esas2r_adapters[ioctl->header.channel] == NULL) {1336 ioctl->header.return_code = IOCTL_BAD_CHANNEL;1337 esas2r_log(ESAS2R_LOG_WARN, "bad channel value");1338 kfree(ioctl);1339 1340 return -ENOTSUPP;1341 }1342 a = esas2r_adapters[ioctl->header.channel];1343 }1344 1345 switch (cmd) {1346 case EXPRESS_IOCTL_RW_FIRMWARE:1347 1348 if (ioctl->data.fwrw.img_type == FW_IMG_FM_API) {1349 err = esas2r_write_fw(a,1350 (char *)ioctl->data.fwrw.image,1351 0,1352 sizeof(struct1353 atto_express_ioctl));1354 1355 if (err >= 0) {1356 err = esas2r_read_fw(a,1357 (char *)ioctl->data.fwrw.1358 image,1359 0,1360 sizeof(struct1361 atto_express_ioctl));1362 }1363 } else if (ioctl->data.fwrw.img_type == FW_IMG_FS_API) {1364 err = esas2r_write_fs(a,1365 (char *)ioctl->data.fwrw.image,1366 0,1367 sizeof(struct1368 atto_express_ioctl));1369 1370 if (err >= 0) {1371 err = esas2r_read_fs(a,1372 (char *)ioctl->data.fwrw.1373 image,1374 0,1375 sizeof(struct1376 atto_express_ioctl));1377 }1378 } else {1379 ioctl->header.return_code = IOCTL_BAD_FLASH_IMGTYPE;1380 }1381 1382 break;1383 1384 case EXPRESS_IOCTL_READ_PARAMS:1385 1386 memcpy(ioctl->data.prw.data_buffer, a->nvram,1387 sizeof(struct esas2r_sas_nvram));1388 ioctl->data.prw.code = 1;1389 break;1390 1391 case EXPRESS_IOCTL_WRITE_PARAMS:1392 1393 rq = esas2r_alloc_request(a);1394 if (rq == NULL) {1395 kfree(ioctl);1396 esas2r_log(ESAS2R_LOG_WARN,1397 "could not allocate an internal request");1398 return -ENOMEM;1399 }1400 1401 code = esas2r_write_params(a, rq,1402 (struct esas2r_sas_nvram *)ioctl->data.prw.data_buffer);1403 ioctl->data.prw.code = code;1404 1405 esas2r_free_request(a, rq);1406 1407 break;1408 1409 case EXPRESS_IOCTL_DEFAULT_PARAMS:1410 1411 esas2r_nvram_get_defaults(a,1412 (struct esas2r_sas_nvram *)ioctl->data.prw.data_buffer);1413 ioctl->data.prw.code = 1;1414 break;1415 1416 case EXPRESS_IOCTL_CHAN_INFO:1417 1418 ioctl->data.chaninfo.major_rev = ESAS2R_MAJOR_REV;1419 ioctl->data.chaninfo.minor_rev = ESAS2R_MINOR_REV;1420 ioctl->data.chaninfo.IRQ = a->pcid->irq;1421 ioctl->data.chaninfo.device_id = a->pcid->device;1422 ioctl->data.chaninfo.vendor_id = a->pcid->vendor;1423 ioctl->data.chaninfo.ven_dev_id = a->pcid->subsystem_device;1424 ioctl->data.chaninfo.revision_id = a->pcid->revision;1425 ioctl->data.chaninfo.pci_bus = a->pcid->bus->number;1426 ioctl->data.chaninfo.pci_dev_func = a->pcid->devfn;1427 ioctl->data.chaninfo.core_rev = 0;1428 ioctl->data.chaninfo.host_no = a->host->host_no;1429 ioctl->data.chaninfo.hbaapi_rev = 0;1430 break;1431 1432 case EXPRESS_IOCTL_SMP:1433 ioctl->header.return_code = handle_smp_ioctl(a,1434 &ioctl->data.1435 ioctl_smp);1436 break;1437 1438 case EXPRESS_CSMI:1439 ioctl->header.return_code =1440 handle_csmi_ioctl(a, &ioctl->data.csmi);1441 break;1442 1443 case EXPRESS_IOCTL_HBA:1444 ioctl->header.return_code = handle_hba_ioctl(a,1445 &ioctl->data.1446 ioctl_hba);1447 break;1448 1449 case EXPRESS_IOCTL_VDA:1450 err = esas2r_write_vda(a,1451 (char *)&ioctl->data.ioctl_vda,1452 0,1453 sizeof(struct atto_ioctl_vda) +1454 ioctl->data.ioctl_vda.data_length);1455 1456 if (err >= 0) {1457 err = esas2r_read_vda(a,1458 (char *)&ioctl->data.ioctl_vda,1459 0,1460 sizeof(struct atto_ioctl_vda) +1461 ioctl->data.ioctl_vda.data_length);1462 }1463 1464 1465 1466 1467 break;1468 1469 case EXPRESS_IOCTL_GET_MOD_INFO:1470 1471 ioctl->data.modinfo.adapter = a;1472 ioctl->data.modinfo.pci_dev = a->pcid;1473 ioctl->data.modinfo.scsi_host = a->host;1474 ioctl->data.modinfo.host_no = a->host->host_no;1475 1476 break;1477 1478 default:1479 esas2r_debug("esas2r_ioctl invalid cmd %p!", cmd);1480 ioctl->header.return_code = IOCTL_ERR_INVCMD;1481 }1482 1483ioctl_done:1484 1485 if (err < 0) {1486 esas2r_log(ESAS2R_LOG_WARN, "err %d on ioctl cmd %u", err,1487 cmd);1488 1489 switch (err) {1490 case -ENOMEM:1491 case -EBUSY:1492 ioctl->header.return_code = IOCTL_OUT_OF_RESOURCES;1493 break;1494 1495 case -ENOSYS:1496 case -EINVAL:1497 ioctl->header.return_code = IOCTL_INVALID_PARAM;1498 break;1499 1500 default:1501 ioctl->header.return_code = IOCTL_GENERAL_ERROR;1502 break;1503 }1504 1505 }1506 1507 /* Always copy the buffer back, if only to pick up the status */1508 err = copy_to_user(arg, ioctl, sizeof(struct atto_express_ioctl));1509 if (err != 0) {1510 esas2r_log(ESAS2R_LOG_WARN,1511 "ioctl_handler copy_to_user didn't copy everything (err %d, cmd %u)",1512 err, cmd);1513 kfree(ioctl);1514 1515 return -EFAULT;1516 }1517 1518 kfree(ioctl);1519 1520 return 0;1521}1522 1523int esas2r_ioctl(struct scsi_device *sd, unsigned int cmd, void __user *arg)1524{1525 return esas2r_ioctl_handler(sd->host->hostdata, cmd, arg);1526}1527 1528static void free_fw_buffers(struct esas2r_adapter *a)1529{1530 if (a->firmware.data) {1531 dma_free_coherent(&a->pcid->dev,1532 (size_t)a->firmware.orig_len,1533 a->firmware.data,1534 (dma_addr_t)a->firmware.phys);1535 1536 a->firmware.data = NULL;1537 }1538}1539 1540static int allocate_fw_buffers(struct esas2r_adapter *a, u32 length)1541{1542 free_fw_buffers(a);1543 1544 a->firmware.orig_len = length;1545 1546 a->firmware.data = dma_alloc_coherent(&a->pcid->dev,1547 (size_t)length,1548 (dma_addr_t *)&a->firmware.phys,1549 GFP_KERNEL);1550 1551 if (!a->firmware.data) {1552 esas2r_debug("buffer alloc failed!");1553 return 0;1554 }1555 1556 return 1;1557}1558 1559/* Handle a call to read firmware. */1560int esas2r_read_fw(struct esas2r_adapter *a, char *buf, long off, int count)1561{1562 esas2r_trace_enter();1563 /* if the cached header is a status, simply copy it over and return. */1564 if (a->firmware.state == FW_STATUS_ST) {1565 int size = min_t(int, count, sizeof(a->firmware.header));1566 esas2r_trace_exit();1567 memcpy(buf, &a->firmware.header, size);1568 esas2r_debug("esas2r_read_fw: STATUS size %d", size);1569 return size;1570 }1571 1572 /*1573 * if the cached header is a command, do it if at1574 * offset 0, otherwise copy the pieces.1575 */1576 1577 if (a->firmware.state == FW_COMMAND_ST) {1578 u32 length = a->firmware.header.length;1579 esas2r_trace_exit();1580 1581 esas2r_debug("esas2r_read_fw: COMMAND length %d off %d",1582 length,1583 off);1584 1585 if (off == 0) {1586 if (a->firmware.header.action == FI_ACT_UP) {1587 if (!allocate_fw_buffers(a, length))1588 return -ENOMEM;1589 1590 1591 /* copy header over */1592 1593 memcpy(a->firmware.data,1594 &a->firmware.header,1595 sizeof(a->firmware.header));1596 1597 do_fm_api(a,1598 (struct esas2r_flash_img *)a->firmware.data);1599 } else if (a->firmware.header.action == FI_ACT_UPSZ) {1600 int size =1601 min((int)count,1602 (int)sizeof(a->firmware.header));1603 do_fm_api(a, &a->firmware.header);1604 memcpy(buf, &a->firmware.header, size);1605 esas2r_debug("FI_ACT_UPSZ size %d", size);1606 return size;1607 } else {1608 esas2r_debug("invalid action %d",1609 a->firmware.header.action);1610 return -ENOSYS;1611 }1612 }1613 1614 if (count + off > length)1615 count = length - off;1616 1617 if (count < 0)1618 return 0;1619 1620 if (!a->firmware.data) {1621 esas2r_debug(1622 "read: nonzero offset but no buffer available!");1623 return -ENOMEM;1624 }1625 1626 esas2r_debug("esas2r_read_fw: off %d count %d length %d ", off,1627 count,1628 length);1629 1630 memcpy(buf, &a->firmware.data[off], count);1631 1632 /* when done, release the buffer */1633 1634 if (length <= off + count) {1635 esas2r_debug("esas2r_read_fw: freeing buffer!");1636 1637 free_fw_buffers(a);1638 }1639 1640 return count;1641 }1642 1643 esas2r_trace_exit();1644 esas2r_debug("esas2r_read_fw: invalid firmware state %d",1645 a->firmware.state);1646 1647 return -EINVAL;1648}1649 1650/* Handle a call to write firmware. */1651int esas2r_write_fw(struct esas2r_adapter *a, const char *buf, long off,1652 int count)1653{1654 u32 length;1655 1656 if (off == 0) {1657 struct esas2r_flash_img *header =1658 (struct esas2r_flash_img *)buf;1659 1660 /* assume version 0 flash image */1661 1662 int min_size = sizeof(struct esas2r_flash_img_v0);1663 1664 a->firmware.state = FW_INVALID_ST;1665 1666 /* validate the version field first */1667 1668 if (count < 41669 || header->fi_version > FI_VERSION_1) {1670 esas2r_debug(1671 "esas2r_write_fw: short header or invalid version");1672 return -EINVAL;1673 }1674 1675 /* See if its a version 1 flash image */1676 1677 if (header->fi_version == FI_VERSION_1)1678 min_size = sizeof(struct esas2r_flash_img);1679 1680 /* If this is the start, the header must be full and valid. */1681 if (count < min_size) {1682 esas2r_debug("esas2r_write_fw: short header, aborting");1683 return -EINVAL;1684 }1685 1686 /* Make sure the size is reasonable. */1687 length = header->length;1688 1689 if (length > 1024 * 1024) {1690 esas2r_debug(1691 "esas2r_write_fw: hosed, length %d fi_version %d",1692 length, header->fi_version);1693 return -EINVAL;1694 }1695 1696 /*1697 * If this is a write command, allocate memory because1698 * we have to cache everything. otherwise, just cache1699 * the header, because the read op will do the command.1700 */1701 1702 if (header->action == FI_ACT_DOWN) {1703 if (!allocate_fw_buffers(a, length))1704 return -ENOMEM;1705 1706 /*1707 * Store the command, so there is context on subsequent1708 * calls.1709 */1710 memcpy(&a->firmware.header,1711 buf,1712 sizeof(*header));1713 } else if (header->action == FI_ACT_UP1714 || header->action == FI_ACT_UPSZ) {1715 /* Save the command, result will be picked up on read */1716 memcpy(&a->firmware.header,1717 buf,1718 sizeof(*header));1719 1720 a->firmware.state = FW_COMMAND_ST;1721 1722 esas2r_debug(1723 "esas2r_write_fw: COMMAND, count %d, action %d ",1724 count, header->action);1725 1726 /*1727 * Pretend we took the whole buffer,1728 * so we don't get bothered again.1729 */1730 1731 return count;1732 } else {1733 esas2r_debug("esas2r_write_fw: invalid action %d ",1734 a->firmware.header.action);1735 return -ENOSYS;1736 }1737 } else {1738 length = a->firmware.header.length;1739 }1740 1741 /*1742 * We only get here on a download command, regardless of offset.1743 * the chunks written by the system need to be cached, and when1744 * the final one arrives, issue the fmapi command.1745 */1746 1747 if (off + count > length)1748 count = length - off;1749 1750 if (count > 0) {1751 esas2r_debug("esas2r_write_fw: off %d count %d length %d", off,1752 count,1753 length);1754 1755 /*1756 * On a full upload, the system tries sending the whole buffer.1757 * there's nothing to do with it, so just drop it here, before1758 * trying to copy over into unallocated memory!1759 */1760 if (a->firmware.header.action == FI_ACT_UP)1761 return count;1762 1763 if (!a->firmware.data) {1764 esas2r_debug(1765 "write: nonzero offset but no buffer available!");1766 return -ENOMEM;1767 }1768 1769 memcpy(&a->firmware.data[off], buf, count);1770 1771 if (length == off + count) {1772 do_fm_api(a,1773 (struct esas2r_flash_img *)a->firmware.data);1774 1775 /*1776 * Now copy the header result to be picked up by the1777 * next read1778 */1779 memcpy(&a->firmware.header,1780 a->firmware.data,1781 sizeof(a->firmware.header));1782 1783 a->firmware.state = FW_STATUS_ST;1784 1785 esas2r_debug("write completed");1786 1787 /*1788 * Since the system has the data buffered, the only way1789 * this can leak is if a root user writes a program1790 * that writes a shorter buffer than it claims, and the1791 * copyin fails.1792 */1793 free_fw_buffers(a);1794 }1795 }1796 1797 return count;1798}1799 1800/* Callback for the completion of a VDA request. */1801static void vda_complete_req(struct esas2r_adapter *a,1802 struct esas2r_request *rq)1803{1804 a->vda_command_done = 1;1805 wake_up_interruptible(&a->vda_waiter);1806}1807 1808/* Scatter/gather callback for VDA requests */1809static u32 get_physaddr_vda(struct esas2r_sg_context *sgc, u64 *addr)1810{1811 struct esas2r_adapter *a = (struct esas2r_adapter *)sgc->adapter;1812 int offset = (u8 *)sgc->cur_offset - (u8 *)a->vda_buffer;1813 1814 (*addr) = a->ppvda_buffer + offset;1815 return VDA_MAX_BUFFER_SIZE - offset;1816}1817 1818/* Handle a call to read a VDA command. */1819int esas2r_read_vda(struct esas2r_adapter *a, char *buf, long off, int count)1820{1821 if (!a->vda_buffer)1822 return -ENOMEM;1823 1824 if (off == 0) {1825 struct esas2r_request *rq;1826 struct atto_ioctl_vda *vi =1827 (struct atto_ioctl_vda *)a->vda_buffer;1828 struct esas2r_sg_context sgc;1829 bool wait_for_completion;1830 1831 /*1832 * Presumeably, someone has already written to the vda_buffer,1833 * and now they are reading the node the response, so now we1834 * will actually issue the request to the chip and reply.1835 */1836 1837 /* allocate a request */1838 rq = esas2r_alloc_request(a);1839 if (rq == NULL) {1840 esas2r_debug("esas2r_read_vda: out of requests");1841 return -EBUSY;1842 }1843 1844 rq->comp_cb = vda_complete_req;1845 1846 sgc.first_req = rq;1847 sgc.adapter = a;1848 sgc.cur_offset = a->vda_buffer + VDA_BUFFER_HEADER_SZ;1849 sgc.get_phys_addr = (PGETPHYSADDR)get_physaddr_vda;1850 1851 a->vda_command_done = 0;1852 1853 wait_for_completion =1854 esas2r_process_vda_ioctl(a, vi, rq, &sgc);1855 1856 if (wait_for_completion) {1857 /* now wait around for it to complete. */1858 1859 while (!a->vda_command_done)1860 wait_event_interruptible(a->vda_waiter,1861 a->vda_command_done);1862 }1863 1864 esas2r_free_request(a, (struct esas2r_request *)rq);1865 }1866 1867 if (off > VDA_MAX_BUFFER_SIZE)1868 return 0;1869 1870 if (count + off > VDA_MAX_BUFFER_SIZE)1871 count = VDA_MAX_BUFFER_SIZE - off;1872 1873 if (count < 0)1874 return 0;1875 1876 memcpy(buf, a->vda_buffer + off, count);1877 1878 return count;1879}1880 1881/* Handle a call to write a VDA command. */1882int esas2r_write_vda(struct esas2r_adapter *a, const char *buf, long off,1883 int count)1884{1885 /*1886 * allocate memory for it, if not already done. once allocated,1887 * we will keep it around until the driver is unloaded.1888 */1889 1890 if (!a->vda_buffer) {1891 dma_addr_t dma_addr;1892 a->vda_buffer = dma_alloc_coherent(&a->pcid->dev,1893 (size_t)1894 VDA_MAX_BUFFER_SIZE,1895 &dma_addr,1896 GFP_KERNEL);1897 1898 a->ppvda_buffer = dma_addr;1899 }1900 1901 if (!a->vda_buffer)1902 return -ENOMEM;1903 1904 if (off > VDA_MAX_BUFFER_SIZE)1905 return 0;1906 1907 if (count + off > VDA_MAX_BUFFER_SIZE)1908 count = VDA_MAX_BUFFER_SIZE - off;1909 1910 if (count < 1)1911 return 0;1912 1913 memcpy(a->vda_buffer + off, buf, count);1914 1915 return count;1916}1917 1918/* Callback for the completion of an FS_API request.*/1919static void fs_api_complete_req(struct esas2r_adapter *a,1920 struct esas2r_request *rq)1921{1922 a->fs_api_command_done = 1;1923 1924 wake_up_interruptible(&a->fs_api_waiter);1925}1926 1927/* Scatter/gather callback for VDA requests */1928static u32 get_physaddr_fs_api(struct esas2r_sg_context *sgc, u64 *addr)1929{1930 struct esas2r_adapter *a = (struct esas2r_adapter *)sgc->adapter;1931 struct esas2r_ioctl_fs *fs =1932 (struct esas2r_ioctl_fs *)a->fs_api_buffer;1933 u32 offset = (u8 *)sgc->cur_offset - (u8 *)fs;1934 1935 (*addr) = a->ppfs_api_buffer + offset;1936 1937 return a->fs_api_buffer_size - offset;1938}1939 1940/* Handle a call to read firmware via FS_API. */1941int esas2r_read_fs(struct esas2r_adapter *a, char *buf, long off, int count)1942{1943 if (!a->fs_api_buffer)1944 return -ENOMEM;1945 1946 if (off == 0) {1947 struct esas2r_request *rq;1948 struct esas2r_sg_context sgc;1949 struct esas2r_ioctl_fs *fs =1950 (struct esas2r_ioctl_fs *)a->fs_api_buffer;1951 1952 /* If another flash request is already in progress, return. */1953 if (mutex_lock_interruptible(&a->fs_api_mutex)) {1954busy:1955 fs->status = ATTO_STS_OUT_OF_RSRC;1956 return -EBUSY;1957 }1958 1959 /*1960 * Presumeably, someone has already written to the1961 * fs_api_buffer, and now they are reading the node the1962 * response, so now we will actually issue the request to the1963 * chip and reply. Allocate a request1964 */1965 1966 rq = esas2r_alloc_request(a);1967 if (rq == NULL) {1968 esas2r_debug("esas2r_read_fs: out of requests");1969 mutex_unlock(&a->fs_api_mutex);1970 goto busy;1971 }1972 1973 rq->comp_cb = fs_api_complete_req;1974 1975 /* Set up the SGCONTEXT for to build the s/g table */1976 1977 sgc.cur_offset = fs->data;1978 sgc.get_phys_addr = (PGETPHYSADDR)get_physaddr_fs_api;1979 1980 a->fs_api_command_done = 0;1981 1982 if (!esas2r_process_fs_ioctl(a, fs, rq, &sgc)) {1983 if (fs->status == ATTO_STS_OUT_OF_RSRC)1984 count = -EBUSY;1985 1986 goto dont_wait;1987 }1988 1989 /* Now wait around for it to complete. */1990 1991 while (!a->fs_api_command_done)1992 wait_event_interruptible(a->fs_api_waiter,1993 a->fs_api_command_done);1994 ;1995dont_wait:1996 /* Free the request and keep going */1997 mutex_unlock(&a->fs_api_mutex);1998 esas2r_free_request(a, (struct esas2r_request *)rq);1999 2000 /* Pick up possible error code from above */2001 if (count < 0)2002 return count;2003 }2004 2005 if (off > a->fs_api_buffer_size)2006 return 0;2007 2008 if (count + off > a->fs_api_buffer_size)2009 count = a->fs_api_buffer_size - off;2010 2011 if (count < 0)2012 return 0;2013 2014 memcpy(buf, a->fs_api_buffer + off, count);2015 2016 return count;2017}2018 2019/* Handle a call to write firmware via FS_API. */2020int esas2r_write_fs(struct esas2r_adapter *a, const char *buf, long off,2021 int count)2022{2023 if (off == 0) {2024 struct esas2r_ioctl_fs *fs = (struct esas2r_ioctl_fs *)buf;2025 u32 length = fs->command.length + offsetof(2026 struct esas2r_ioctl_fs,2027 data);2028 2029 /*2030 * Special case, for BEGIN commands, the length field2031 * is lying to us, so just get enough for the header.2032 */2033 2034 if (fs->command.command == ESAS2R_FS_CMD_BEGINW)2035 length = offsetof(struct esas2r_ioctl_fs, data);2036 2037 /*2038 * Beginning a command. We assume we'll get at least2039 * enough in the first write so we can look at the2040 * header and see how much we need to alloc.2041 */2042 2043 if (count < offsetof(struct esas2r_ioctl_fs, data))2044 return -EINVAL;2045 2046 /* Allocate a buffer or use the existing buffer. */2047 if (a->fs_api_buffer) {2048 if (a->fs_api_buffer_size < length) {2049 /* Free too-small buffer and get a new one */2050 dma_free_coherent(&a->pcid->dev,2051 (size_t)a->fs_api_buffer_size,2052 a->fs_api_buffer,2053 (dma_addr_t)a->ppfs_api_buffer);2054 2055 goto re_allocate_buffer;2056 }2057 } else {2058re_allocate_buffer:2059 a->fs_api_buffer_size = length;2060 2061 a->fs_api_buffer = dma_alloc_coherent(&a->pcid->dev,2062 (size_t)a->fs_api_buffer_size,2063 (dma_addr_t *)&a->ppfs_api_buffer,2064 GFP_KERNEL);2065 }2066 }2067 2068 if (!a->fs_api_buffer)2069 return -ENOMEM;2070 2071 if (off > a->fs_api_buffer_size)2072 return 0;2073 2074 if (count + off > a->fs_api_buffer_size)2075 count = a->fs_api_buffer_size - off;2076 2077 if (count < 1)2078 return 0;2079 2080 memcpy(a->fs_api_buffer + off, buf, count);2081 2082 return count;2083}2084