aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/mpt2sas/mpt2sas_ctl.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/mpt2sas/mpt2sas_ctl.c')
-rw-r--r--drivers/scsi/mpt2sas/mpt2sas_ctl.c411
1 files changed, 353 insertions, 58 deletions
diff --git a/drivers/scsi/mpt2sas/mpt2sas_ctl.c b/drivers/scsi/mpt2sas/mpt2sas_ctl.c
index d88e9756d8f5..b774973f0765 100644
--- a/drivers/scsi/mpt2sas/mpt2sas_ctl.c
+++ b/drivers/scsi/mpt2sas/mpt2sas_ctl.c
@@ -80,6 +80,32 @@ enum block_state {
80 BLOCKING, 80 BLOCKING,
81}; 81};
82 82
83/**
84 * _ctl_sas_device_find_by_handle - sas device search
85 * @ioc: per adapter object
86 * @handle: sas device handle (assigned by firmware)
87 * Context: Calling function should acquire ioc->sas_device_lock
88 *
89 * This searches for sas_device based on sas_address, then return sas_device
90 * object.
91 */
92static struct _sas_device *
93_ctl_sas_device_find_by_handle(struct MPT2SAS_ADAPTER *ioc, u16 handle)
94{
95 struct _sas_device *sas_device, *r;
96
97 r = NULL;
98 list_for_each_entry(sas_device, &ioc->sas_device_list, list) {
99 if (sas_device->handle != handle)
100 continue;
101 r = sas_device;
102 goto out;
103 }
104
105 out:
106 return r;
107}
108
83#ifdef CONFIG_SCSI_MPT2SAS_LOGGING 109#ifdef CONFIG_SCSI_MPT2SAS_LOGGING
84/** 110/**
85 * _ctl_display_some_debug - debug routine 111 * _ctl_display_some_debug - debug routine
@@ -188,14 +214,14 @@ _ctl_display_some_debug(struct MPT2SAS_ADAPTER *ioc, u16 smid,
188 if (!desc) 214 if (!desc)
189 return; 215 return;
190 216
191 printk(MPT2SAS_DEBUG_FMT "%s: %s, smid(%d)\n", 217 printk(MPT2SAS_INFO_FMT "%s: %s, smid(%d)\n",
192 ioc->name, calling_function_name, desc, smid); 218 ioc->name, calling_function_name, desc, smid);
193 219
194 if (!mpi_reply) 220 if (!mpi_reply)
195 return; 221 return;
196 222
197 if (mpi_reply->IOCStatus || mpi_reply->IOCLogInfo) 223 if (mpi_reply->IOCStatus || mpi_reply->IOCLogInfo)
198 printk(MPT2SAS_DEBUG_FMT 224 printk(MPT2SAS_INFO_FMT
199 "\tiocstatus(0x%04x), loginfo(0x%08x)\n", 225 "\tiocstatus(0x%04x), loginfo(0x%08x)\n",
200 ioc->name, le16_to_cpu(mpi_reply->IOCStatus), 226 ioc->name, le16_to_cpu(mpi_reply->IOCStatus),
201 le32_to_cpu(mpi_reply->IOCLogInfo)); 227 le32_to_cpu(mpi_reply->IOCLogInfo));
@@ -205,8 +231,24 @@ _ctl_display_some_debug(struct MPT2SAS_ADAPTER *ioc, u16 smid,
205 MPI2_FUNCTION_RAID_SCSI_IO_PASSTHROUGH) { 231 MPI2_FUNCTION_RAID_SCSI_IO_PASSTHROUGH) {
206 Mpi2SCSIIOReply_t *scsi_reply = 232 Mpi2SCSIIOReply_t *scsi_reply =
207 (Mpi2SCSIIOReply_t *)mpi_reply; 233 (Mpi2SCSIIOReply_t *)mpi_reply;
234 struct _sas_device *sas_device = NULL;
235 unsigned long flags;
236
237 spin_lock_irqsave(&ioc->sas_device_lock, flags);
238 sas_device = _ctl_sas_device_find_by_handle(ioc,
239 le16_to_cpu(scsi_reply->DevHandle));
240 if (sas_device) {
241 printk(MPT2SAS_WARN_FMT "\tsas_address(0x%016llx), "
242 "phy(%d)\n", ioc->name, (unsigned long long)
243 sas_device->sas_address, sas_device->phy);
244 printk(MPT2SAS_WARN_FMT
245 "\tenclosure_logical_id(0x%016llx), slot(%d)\n",
246 ioc->name, sas_device->enclosure_logical_id,
247 sas_device->slot);
248 }
249 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
208 if (scsi_reply->SCSIState || scsi_reply->SCSIStatus) 250 if (scsi_reply->SCSIState || scsi_reply->SCSIStatus)
209 printk(MPT2SAS_DEBUG_FMT 251 printk(MPT2SAS_INFO_FMT
210 "\tscsi_state(0x%02x), scsi_status" 252 "\tscsi_state(0x%02x), scsi_status"
211 "(0x%02x)\n", ioc->name, 253 "(0x%02x)\n", ioc->name,
212 scsi_reply->SCSIState, 254 scsi_reply->SCSIState,
@@ -233,6 +275,9 @@ mpt2sas_ctl_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index,
233 u32 reply) 275 u32 reply)
234{ 276{
235 MPI2DefaultReply_t *mpi_reply; 277 MPI2DefaultReply_t *mpi_reply;
278 Mpi2SCSIIOReply_t *scsiio_reply;
279 const void *sense_data;
280 u32 sz;
236 281
237 if (ioc->ctl_cmds.status == MPT2_CMD_NOT_USED) 282 if (ioc->ctl_cmds.status == MPT2_CMD_NOT_USED)
238 return 1; 283 return 1;
@@ -243,6 +288,20 @@ mpt2sas_ctl_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index,
243 if (mpi_reply) { 288 if (mpi_reply) {
244 memcpy(ioc->ctl_cmds.reply, mpi_reply, mpi_reply->MsgLength*4); 289 memcpy(ioc->ctl_cmds.reply, mpi_reply, mpi_reply->MsgLength*4);
245 ioc->ctl_cmds.status |= MPT2_CMD_REPLY_VALID; 290 ioc->ctl_cmds.status |= MPT2_CMD_REPLY_VALID;
291 /* get sense data */
292 if (mpi_reply->Function == MPI2_FUNCTION_SCSI_IO_REQUEST ||
293 mpi_reply->Function ==
294 MPI2_FUNCTION_RAID_SCSI_IO_PASSTHROUGH) {
295 scsiio_reply = (Mpi2SCSIIOReply_t *)mpi_reply;
296 if (scsiio_reply->SCSIState &
297 MPI2_SCSI_STATE_AUTOSENSE_VALID) {
298 sz = min_t(u32, SCSI_SENSE_BUFFERSIZE,
299 le32_to_cpu(scsiio_reply->SenseCount));
300 sense_data = mpt2sas_base_get_sense_buffer(ioc,
301 smid);
302 memcpy(ioc->ctl_cmds.sense, sense_data, sz);
303 }
304 }
246 } 305 }
247#ifdef CONFIG_SCSI_MPT2SAS_LOGGING 306#ifdef CONFIG_SCSI_MPT2SAS_LOGGING
248 _ctl_display_some_debug(ioc, smid, "ctl_done", mpi_reply); 307 _ctl_display_some_debug(ioc, smid, "ctl_done", mpi_reply);
@@ -392,7 +451,7 @@ mpt2sas_ctl_reset_handler(struct MPT2SAS_ADAPTER *ioc, int reset_phase)
392 451
393 switch (reset_phase) { 452 switch (reset_phase) {
394 case MPT2_IOC_PRE_RESET: 453 case MPT2_IOC_PRE_RESET:
395 dtmprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: " 454 dtmprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: "
396 "MPT2_IOC_PRE_RESET\n", ioc->name, __func__)); 455 "MPT2_IOC_PRE_RESET\n", ioc->name, __func__));
397 for (i = 0; i < MPI2_DIAG_BUF_TYPE_COUNT; i++) { 456 for (i = 0; i < MPI2_DIAG_BUF_TYPE_COUNT; i++) {
398 if (!(ioc->diag_buffer_status[i] & 457 if (!(ioc->diag_buffer_status[i] &
@@ -405,7 +464,7 @@ mpt2sas_ctl_reset_handler(struct MPT2SAS_ADAPTER *ioc, int reset_phase)
405 } 464 }
406 break; 465 break;
407 case MPT2_IOC_AFTER_RESET: 466 case MPT2_IOC_AFTER_RESET:
408 dtmprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: " 467 dtmprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: "
409 "MPT2_IOC_AFTER_RESET\n", ioc->name, __func__)); 468 "MPT2_IOC_AFTER_RESET\n", ioc->name, __func__));
410 if (ioc->ctl_cmds.status & MPT2_CMD_PENDING) { 469 if (ioc->ctl_cmds.status & MPT2_CMD_PENDING) {
411 ioc->ctl_cmds.status |= MPT2_CMD_RESET; 470 ioc->ctl_cmds.status |= MPT2_CMD_RESET;
@@ -414,7 +473,7 @@ mpt2sas_ctl_reset_handler(struct MPT2SAS_ADAPTER *ioc, int reset_phase)
414 } 473 }
415 break; 474 break;
416 case MPT2_IOC_DONE_RESET: 475 case MPT2_IOC_DONE_RESET:
417 dtmprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: " 476 dtmprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: "
418 "MPT2_IOC_DONE_RESET\n", ioc->name, __func__)); 477 "MPT2_IOC_DONE_RESET\n", ioc->name, __func__));
419 478
420 for (i = 0; i < MPI2_DIAG_BUF_TYPE_COUNT; i++) { 479 for (i = 0; i < MPI2_DIAG_BUF_TYPE_COUNT; i++) {
@@ -531,7 +590,7 @@ _ctl_set_task_mid(struct MPT2SAS_ADAPTER *ioc, struct mpt2_ioctl_command *karg,
531 spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags); 590 spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
532 591
533 if (!found) { 592 if (!found) {
534 dctlprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: " 593 dctlprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: "
535 "handle(0x%04x), lun(%d), no active mid!!\n", ioc->name, 594 "handle(0x%04x), lun(%d), no active mid!!\n", ioc->name,
536 desc, le16_to_cpu(tm_request->DevHandle), lun)); 595 desc, le16_to_cpu(tm_request->DevHandle), lun));
537 tm_reply = ioc->ctl_cmds.reply; 596 tm_reply = ioc->ctl_cmds.reply;
@@ -549,7 +608,7 @@ _ctl_set_task_mid(struct MPT2SAS_ADAPTER *ioc, struct mpt2_ioctl_command *karg,
549 return 1; 608 return 1;
550 } 609 }
551 610
552 dctlprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: " 611 dctlprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: "
553 "handle(0x%04x), lun(%d), task_mid(%d)\n", ioc->name, 612 "handle(0x%04x), lun(%d), task_mid(%d)\n", ioc->name,
554 desc, le16_to_cpu(tm_request->DevHandle), lun, 613 desc, le16_to_cpu(tm_request->DevHandle), lun,
555 le16_to_cpu(tm_request->TaskMID))); 614 le16_to_cpu(tm_request->TaskMID)));
@@ -567,7 +626,7 @@ static long
567_ctl_do_mpt_command(struct MPT2SAS_ADAPTER *ioc, 626_ctl_do_mpt_command(struct MPT2SAS_ADAPTER *ioc,
568 struct mpt2_ioctl_command karg, void __user *mf, enum block_state state) 627 struct mpt2_ioctl_command karg, void __user *mf, enum block_state state)
569{ 628{
570 MPI2RequestHeader_t *mpi_request; 629 MPI2RequestHeader_t *mpi_request = NULL, *request;
571 MPI2DefaultReply_t *mpi_reply; 630 MPI2DefaultReply_t *mpi_reply;
572 u32 ioc_state; 631 u32 ioc_state;
573 u16 ioc_status; 632 u16 ioc_status;
@@ -576,7 +635,6 @@ _ctl_do_mpt_command(struct MPT2SAS_ADAPTER *ioc,
576 u8 issue_reset; 635 u8 issue_reset;
577 u32 sz; 636 u32 sz;
578 void *psge; 637 void *psge;
579 void *priv_sense = NULL;
580 void *data_out = NULL; 638 void *data_out = NULL;
581 dma_addr_t data_out_dma; 639 dma_addr_t data_out_dma;
582 size_t data_out_sz = 0; 640 size_t data_out_sz = 0;
@@ -621,31 +679,50 @@ _ctl_do_mpt_command(struct MPT2SAS_ADAPTER *ioc,
621 printk(MPT2SAS_INFO_FMT "%s: ioc is operational\n", 679 printk(MPT2SAS_INFO_FMT "%s: ioc is operational\n",
622 ioc->name, __func__); 680 ioc->name, __func__);
623 681
624 smid = mpt2sas_base_get_smid_scsiio(ioc, ioc->ctl_cb_idx, NULL); 682 mpi_request = kzalloc(ioc->request_sz, GFP_KERNEL);
625 if (!smid) { 683 if (!mpi_request) {
626 printk(MPT2SAS_ERR_FMT "%s: failed obtaining a smid\n", 684 printk(MPT2SAS_ERR_FMT "%s: failed obtaining a memory for "
627 ioc->name, __func__); 685 "mpi_request\n", ioc->name, __func__);
628 ret = -EAGAIN; 686 ret = -ENOMEM;
629 goto out; 687 goto out;
630 } 688 }
631 689
632 ret = 0;
633 ioc->ctl_cmds.status = MPT2_CMD_PENDING;
634 memset(ioc->ctl_cmds.reply, 0, ioc->reply_sz);
635 mpi_request = mpt2sas_base_get_msg_frame(ioc, smid);
636 ioc->ctl_cmds.smid = smid;
637 data_out_sz = karg.data_out_size;
638 data_in_sz = karg.data_in_size;
639
640 /* copy in request message frame from user */ 690 /* copy in request message frame from user */
641 if (copy_from_user(mpi_request, mf, karg.data_sge_offset*4)) { 691 if (copy_from_user(mpi_request, mf, karg.data_sge_offset*4)) {
642 printk(KERN_ERR "failure at %s:%d/%s()!\n", __FILE__, __LINE__, 692 printk(KERN_ERR "failure at %s:%d/%s()!\n", __FILE__, __LINE__,
643 __func__); 693 __func__);
644 ret = -EFAULT; 694 ret = -EFAULT;
645 mpt2sas_base_free_smid(ioc, smid);
646 goto out; 695 goto out;
647 } 696 }
648 697
698 if (mpi_request->Function == MPI2_FUNCTION_SCSI_TASK_MGMT) {
699 smid = mpt2sas_base_get_smid_hpr(ioc, ioc->ctl_cb_idx);
700 if (!smid) {
701 printk(MPT2SAS_ERR_FMT "%s: failed obtaining a smid\n",
702 ioc->name, __func__);
703 ret = -EAGAIN;
704 goto out;
705 }
706 } else {
707
708 smid = mpt2sas_base_get_smid_scsiio(ioc, ioc->ctl_cb_idx, NULL);
709 if (!smid) {
710 printk(MPT2SAS_ERR_FMT "%s: failed obtaining a smid\n",
711 ioc->name, __func__);
712 ret = -EAGAIN;
713 goto out;
714 }
715 }
716
717 ret = 0;
718 ioc->ctl_cmds.status = MPT2_CMD_PENDING;
719 memset(ioc->ctl_cmds.reply, 0, ioc->reply_sz);
720 request = mpt2sas_base_get_msg_frame(ioc, smid);
721 memcpy(request, mpi_request, karg.data_sge_offset*4);
722 ioc->ctl_cmds.smid = smid;
723 data_out_sz = karg.data_out_size;
724 data_in_sz = karg.data_in_size;
725
649 if (mpi_request->Function == MPI2_FUNCTION_SCSI_IO_REQUEST || 726 if (mpi_request->Function == MPI2_FUNCTION_SCSI_IO_REQUEST ||
650 mpi_request->Function == MPI2_FUNCTION_RAID_SCSI_IO_PASSTHROUGH) { 727 mpi_request->Function == MPI2_FUNCTION_RAID_SCSI_IO_PASSTHROUGH) {
651 if (!le16_to_cpu(mpi_request->FunctionDependent1) || 728 if (!le16_to_cpu(mpi_request->FunctionDependent1) ||
@@ -691,7 +768,7 @@ _ctl_do_mpt_command(struct MPT2SAS_ADAPTER *ioc,
691 } 768 }
692 769
693 /* add scatter gather elements */ 770 /* add scatter gather elements */
694 psge = (void *)mpi_request + (karg.data_sge_offset*4); 771 psge = (void *)request + (karg.data_sge_offset*4);
695 772
696 if (!data_out_sz && !data_in_sz) { 773 if (!data_out_sz && !data_in_sz) {
697 mpt2sas_base_build_zero_len_sge(ioc, psge); 774 mpt2sas_base_build_zero_len_sge(ioc, psge);
@@ -739,11 +816,11 @@ _ctl_do_mpt_command(struct MPT2SAS_ADAPTER *ioc,
739 case MPI2_FUNCTION_RAID_SCSI_IO_PASSTHROUGH: 816 case MPI2_FUNCTION_RAID_SCSI_IO_PASSTHROUGH:
740 { 817 {
741 Mpi2SCSIIORequest_t *scsiio_request = 818 Mpi2SCSIIORequest_t *scsiio_request =
742 (Mpi2SCSIIORequest_t *)mpi_request; 819 (Mpi2SCSIIORequest_t *)request;
820 scsiio_request->SenseBufferLength = SCSI_SENSE_BUFFERSIZE;
743 scsiio_request->SenseBufferLowAddress = 821 scsiio_request->SenseBufferLowAddress =
744 mpt2sas_base_get_sense_buffer_dma(ioc, smid); 822 mpt2sas_base_get_sense_buffer_dma(ioc, smid);
745 priv_sense = mpt2sas_base_get_sense_buffer(ioc, smid); 823 memset(ioc->ctl_cmds.sense, 0, SCSI_SENSE_BUFFERSIZE);
746 memset(priv_sense, 0, SCSI_SENSE_BUFFERSIZE);
747 if (mpi_request->Function == MPI2_FUNCTION_SCSI_IO_REQUEST) 824 if (mpi_request->Function == MPI2_FUNCTION_SCSI_IO_REQUEST)
748 mpt2sas_base_put_smid_scsi_io(ioc, smid, 825 mpt2sas_base_put_smid_scsi_io(ioc, smid,
749 le16_to_cpu(mpi_request->FunctionDependent1)); 826 le16_to_cpu(mpi_request->FunctionDependent1));
@@ -754,9 +831,9 @@ _ctl_do_mpt_command(struct MPT2SAS_ADAPTER *ioc,
754 case MPI2_FUNCTION_SCSI_TASK_MGMT: 831 case MPI2_FUNCTION_SCSI_TASK_MGMT:
755 { 832 {
756 Mpi2SCSITaskManagementRequest_t *tm_request = 833 Mpi2SCSITaskManagementRequest_t *tm_request =
757 (Mpi2SCSITaskManagementRequest_t *)mpi_request; 834 (Mpi2SCSITaskManagementRequest_t *)request;
758 835
759 dtmprintk(ioc, printk(MPT2SAS_DEBUG_FMT "TASK_MGMT: " 836 dtmprintk(ioc, printk(MPT2SAS_INFO_FMT "TASK_MGMT: "
760 "handle(0x%04x), task_type(0x%02x)\n", ioc->name, 837 "handle(0x%04x), task_type(0x%02x)\n", ioc->name,
761 le16_to_cpu(tm_request->DevHandle), tm_request->TaskType)); 838 le16_to_cpu(tm_request->DevHandle), tm_request->TaskType));
762 839
@@ -851,7 +928,7 @@ _ctl_do_mpt_command(struct MPT2SAS_ADAPTER *ioc,
851 Mpi2SCSITaskManagementReply_t *tm_reply = 928 Mpi2SCSITaskManagementReply_t *tm_reply =
852 (Mpi2SCSITaskManagementReply_t *)mpi_reply; 929 (Mpi2SCSITaskManagementReply_t *)mpi_reply;
853 930
854 printk(MPT2SAS_DEBUG_FMT "TASK_MGMT: " 931 printk(MPT2SAS_INFO_FMT "TASK_MGMT: "
855 "IOCStatus(0x%04x), IOCLogInfo(0x%08x), " 932 "IOCStatus(0x%04x), IOCLogInfo(0x%08x), "
856 "TerminationCount(0x%08x)\n", ioc->name, 933 "TerminationCount(0x%08x)\n", ioc->name,
857 le16_to_cpu(tm_reply->IOCStatus), 934 le16_to_cpu(tm_reply->IOCStatus),
@@ -887,7 +964,8 @@ _ctl_do_mpt_command(struct MPT2SAS_ADAPTER *ioc,
887 MPI2_FUNCTION_SCSI_IO_REQUEST || mpi_request->Function == 964 MPI2_FUNCTION_SCSI_IO_REQUEST || mpi_request->Function ==
888 MPI2_FUNCTION_RAID_SCSI_IO_PASSTHROUGH)) { 965 MPI2_FUNCTION_RAID_SCSI_IO_PASSTHROUGH)) {
889 sz = min_t(u32, karg.max_sense_bytes, SCSI_SENSE_BUFFERSIZE); 966 sz = min_t(u32, karg.max_sense_bytes, SCSI_SENSE_BUFFERSIZE);
890 if (copy_to_user(karg.sense_data_ptr, priv_sense, sz)) { 967 if (copy_to_user(karg.sense_data_ptr,
968 ioc->ctl_cmds.sense, sz)) {
891 printk(KERN_ERR "failure at %s:%d/%s()!\n", __FILE__, 969 printk(KERN_ERR "failure at %s:%d/%s()!\n", __FILE__,
892 __LINE__, __func__); 970 __LINE__, __func__);
893 ret = -ENODATA; 971 ret = -ENODATA;
@@ -926,6 +1004,7 @@ _ctl_do_mpt_command(struct MPT2SAS_ADAPTER *ioc,
926 pci_free_consistent(ioc->pdev, data_out_sz, data_out, 1004 pci_free_consistent(ioc->pdev, data_out_sz, data_out,
927 data_out_dma); 1005 data_out_dma);
928 1006
1007 kfree(mpi_request);
929 ioc->ctl_cmds.status = MPT2_CMD_NOT_USED; 1008 ioc->ctl_cmds.status = MPT2_CMD_NOT_USED;
930 mutex_unlock(&ioc->ctl_cmds.mutex); 1009 mutex_unlock(&ioc->ctl_cmds.mutex);
931 return ret; 1010 return ret;
@@ -950,7 +1029,7 @@ _ctl_getiocinfo(void __user *arg)
950 if (_ctl_verify_adapter(karg.hdr.ioc_number, &ioc) == -1 || !ioc) 1029 if (_ctl_verify_adapter(karg.hdr.ioc_number, &ioc) == -1 || !ioc)
951 return -ENODEV; 1030 return -ENODEV;
952 1031
953 dctlprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: enter\n", ioc->name, 1032 dctlprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: enter\n", ioc->name,
954 __func__)); 1033 __func__));
955 1034
956 memset(&karg, 0 , sizeof(karg)); 1035 memset(&karg, 0 , sizeof(karg));
@@ -998,7 +1077,7 @@ _ctl_eventquery(void __user *arg)
998 if (_ctl_verify_adapter(karg.hdr.ioc_number, &ioc) == -1 || !ioc) 1077 if (_ctl_verify_adapter(karg.hdr.ioc_number, &ioc) == -1 || !ioc)
999 return -ENODEV; 1078 return -ENODEV;
1000 1079
1001 dctlprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: enter\n", ioc->name, 1080 dctlprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: enter\n", ioc->name,
1002 __func__)); 1081 __func__));
1003 1082
1004 karg.event_entries = MPT2SAS_CTL_EVENT_LOG_SIZE; 1083 karg.event_entries = MPT2SAS_CTL_EVENT_LOG_SIZE;
@@ -1031,7 +1110,7 @@ _ctl_eventenable(void __user *arg)
1031 if (_ctl_verify_adapter(karg.hdr.ioc_number, &ioc) == -1 || !ioc) 1110 if (_ctl_verify_adapter(karg.hdr.ioc_number, &ioc) == -1 || !ioc)
1032 return -ENODEV; 1111 return -ENODEV;
1033 1112
1034 dctlprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: enter\n", ioc->name, 1113 dctlprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: enter\n", ioc->name,
1035 __func__)); 1114 __func__));
1036 1115
1037 if (ioc->event_log) 1116 if (ioc->event_log)
@@ -1073,7 +1152,7 @@ _ctl_eventreport(void __user *arg)
1073 if (_ctl_verify_adapter(karg.hdr.ioc_number, &ioc) == -1 || !ioc) 1152 if (_ctl_verify_adapter(karg.hdr.ioc_number, &ioc) == -1 || !ioc)
1074 return -ENODEV; 1153 return -ENODEV;
1075 1154
1076 dctlprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: enter\n", ioc->name, 1155 dctlprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: enter\n", ioc->name,
1077 __func__)); 1156 __func__));
1078 1157
1079 number_bytes = karg.hdr.max_data_size - 1158 number_bytes = karg.hdr.max_data_size -
@@ -1118,7 +1197,7 @@ _ctl_do_reset(void __user *arg)
1118 if (_ctl_verify_adapter(karg.hdr.ioc_number, &ioc) == -1 || !ioc) 1197 if (_ctl_verify_adapter(karg.hdr.ioc_number, &ioc) == -1 || !ioc)
1119 return -ENODEV; 1198 return -ENODEV;
1120 1199
1121 dctlprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: enter\n", ioc->name, 1200 dctlprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: enter\n", ioc->name,
1122 __func__)); 1201 __func__));
1123 1202
1124 retval = mpt2sas_base_hard_reset_handler(ioc, CAN_SLEEP, 1203 retval = mpt2sas_base_hard_reset_handler(ioc, CAN_SLEEP,
@@ -1219,7 +1298,7 @@ _ctl_btdh_mapping(void __user *arg)
1219 if (_ctl_verify_adapter(karg.hdr.ioc_number, &ioc) == -1 || !ioc) 1298 if (_ctl_verify_adapter(karg.hdr.ioc_number, &ioc) == -1 || !ioc)
1220 return -ENODEV; 1299 return -ENODEV;
1221 1300
1222 dctlprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s\n", ioc->name, 1301 dctlprintk(ioc, printk(MPT2SAS_INFO_FMT "%s\n", ioc->name,
1223 __func__)); 1302 __func__));
1224 1303
1225 rc = _ctl_btdh_search_sas_device(ioc, &karg); 1304 rc = _ctl_btdh_search_sas_device(ioc, &karg);
@@ -1288,7 +1367,7 @@ _ctl_diag_register_2(struct MPT2SAS_ADAPTER *ioc,
1288 u16 ioc_status; 1367 u16 ioc_status;
1289 u8 issue_reset = 0; 1368 u8 issue_reset = 0;
1290 1369
1291 dctlprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s\n", ioc->name, 1370 dctlprintk(ioc, printk(MPT2SAS_INFO_FMT "%s\n", ioc->name,
1292 __func__)); 1371 __func__));
1293 1372
1294 if (ioc->ctl_cmds.status != MPT2_CMD_NOT_USED) { 1373 if (ioc->ctl_cmds.status != MPT2_CMD_NOT_USED) {
@@ -1376,7 +1455,7 @@ _ctl_diag_register_2(struct MPT2SAS_ADAPTER *ioc,
1376 mpi_request->VF_ID = 0; /* TODO */ 1455 mpi_request->VF_ID = 0; /* TODO */
1377 mpi_request->VP_ID = 0; 1456 mpi_request->VP_ID = 0;
1378 1457
1379 dctlprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: diag_buffer(0x%p), " 1458 dctlprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: diag_buffer(0x%p), "
1380 "dma(0x%llx), sz(%d)\n", ioc->name, __func__, request_data, 1459 "dma(0x%llx), sz(%d)\n", ioc->name, __func__, request_data,
1381 (unsigned long long)request_data_dma, 1460 (unsigned long long)request_data_dma,
1382 le32_to_cpu(mpi_request->BufferLength))); 1461 le32_to_cpu(mpi_request->BufferLength)));
@@ -1414,10 +1493,10 @@ _ctl_diag_register_2(struct MPT2SAS_ADAPTER *ioc,
1414 if (ioc_status == MPI2_IOCSTATUS_SUCCESS) { 1493 if (ioc_status == MPI2_IOCSTATUS_SUCCESS) {
1415 ioc->diag_buffer_status[buffer_type] |= 1494 ioc->diag_buffer_status[buffer_type] |=
1416 MPT2_DIAG_BUFFER_IS_REGISTERED; 1495 MPT2_DIAG_BUFFER_IS_REGISTERED;
1417 dctlprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: success\n", 1496 dctlprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: success\n",
1418 ioc->name, __func__)); 1497 ioc->name, __func__));
1419 } else { 1498 } else {
1420 printk(MPT2SAS_DEBUG_FMT "%s: ioc_status(0x%04x) " 1499 printk(MPT2SAS_INFO_FMT "%s: ioc_status(0x%04x) "
1421 "log_info(0x%08x)\n", ioc->name, __func__, 1500 "log_info(0x%08x)\n", ioc->name, __func__,
1422 ioc_status, le32_to_cpu(mpi_reply->IOCLogInfo)); 1501 ioc_status, le32_to_cpu(mpi_reply->IOCLogInfo));
1423 rc = -EFAULT; 1502 rc = -EFAULT;
@@ -1541,7 +1620,7 @@ _ctl_diag_unregister(void __user *arg)
1541 if (_ctl_verify_adapter(karg.hdr.ioc_number, &ioc) == -1 || !ioc) 1620 if (_ctl_verify_adapter(karg.hdr.ioc_number, &ioc) == -1 || !ioc)
1542 return -ENODEV; 1621 return -ENODEV;
1543 1622
1544 dctlprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s\n", ioc->name, 1623 dctlprintk(ioc, printk(MPT2SAS_INFO_FMT "%s\n", ioc->name,
1545 __func__)); 1624 __func__));
1546 1625
1547 buffer_type = karg.unique_id & 0x000000ff; 1626 buffer_type = karg.unique_id & 0x000000ff;
@@ -1611,7 +1690,7 @@ _ctl_diag_query(void __user *arg)
1611 if (_ctl_verify_adapter(karg.hdr.ioc_number, &ioc) == -1 || !ioc) 1690 if (_ctl_verify_adapter(karg.hdr.ioc_number, &ioc) == -1 || !ioc)
1612 return -ENODEV; 1691 return -ENODEV;
1613 1692
1614 dctlprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s\n", ioc->name, 1693 dctlprintk(ioc, printk(MPT2SAS_INFO_FMT "%s\n", ioc->name,
1615 __func__)); 1694 __func__));
1616 1695
1617 karg.application_flags = 0; 1696 karg.application_flags = 0;
@@ -1689,7 +1768,7 @@ _ctl_send_release(struct MPT2SAS_ADAPTER *ioc, u8 buffer_type, u8 *issue_reset)
1689 int rc; 1768 int rc;
1690 unsigned long timeleft; 1769 unsigned long timeleft;
1691 1770
1692 dctlprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s\n", ioc->name, 1771 dctlprintk(ioc, printk(MPT2SAS_INFO_FMT "%s\n", ioc->name,
1693 __func__)); 1772 __func__));
1694 1773
1695 rc = 0; 1774 rc = 0;
@@ -1697,7 +1776,7 @@ _ctl_send_release(struct MPT2SAS_ADAPTER *ioc, u8 buffer_type, u8 *issue_reset)
1697 1776
1698 ioc_state = mpt2sas_base_get_iocstate(ioc, 1); 1777 ioc_state = mpt2sas_base_get_iocstate(ioc, 1);
1699 if (ioc_state != MPI2_IOC_STATE_OPERATIONAL) { 1778 if (ioc_state != MPI2_IOC_STATE_OPERATIONAL) {
1700 dctlprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: " 1779 dctlprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: "
1701 "skipping due to FAULT state\n", ioc->name, 1780 "skipping due to FAULT state\n", ioc->name,
1702 __func__)); 1781 __func__));
1703 rc = -EAGAIN; 1782 rc = -EAGAIN;
@@ -1759,10 +1838,10 @@ _ctl_send_release(struct MPT2SAS_ADAPTER *ioc, u8 buffer_type, u8 *issue_reset)
1759 if (ioc_status == MPI2_IOCSTATUS_SUCCESS) { 1838 if (ioc_status == MPI2_IOCSTATUS_SUCCESS) {
1760 ioc->diag_buffer_status[buffer_type] |= 1839 ioc->diag_buffer_status[buffer_type] |=
1761 MPT2_DIAG_BUFFER_IS_RELEASED; 1840 MPT2_DIAG_BUFFER_IS_RELEASED;
1762 dctlprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: success\n", 1841 dctlprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: success\n",
1763 ioc->name, __func__)); 1842 ioc->name, __func__));
1764 } else { 1843 } else {
1765 printk(MPT2SAS_DEBUG_FMT "%s: ioc_status(0x%04x) " 1844 printk(MPT2SAS_INFO_FMT "%s: ioc_status(0x%04x) "
1766 "log_info(0x%08x)\n", ioc->name, __func__, 1845 "log_info(0x%08x)\n", ioc->name, __func__,
1767 ioc_status, le32_to_cpu(mpi_reply->IOCLogInfo)); 1846 ioc_status, le32_to_cpu(mpi_reply->IOCLogInfo));
1768 rc = -EFAULT; 1847 rc = -EFAULT;
@@ -1800,7 +1879,7 @@ _ctl_diag_release(void __user *arg, enum block_state state)
1800 if (_ctl_verify_adapter(karg.hdr.ioc_number, &ioc) == -1 || !ioc) 1879 if (_ctl_verify_adapter(karg.hdr.ioc_number, &ioc) == -1 || !ioc)
1801 return -ENODEV; 1880 return -ENODEV;
1802 1881
1803 dctlprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s\n", ioc->name, 1882 dctlprintk(ioc, printk(MPT2SAS_INFO_FMT "%s\n", ioc->name,
1804 __func__)); 1883 __func__));
1805 1884
1806 buffer_type = karg.unique_id & 0x000000ff; 1885 buffer_type = karg.unique_id & 0x000000ff;
@@ -1896,7 +1975,7 @@ _ctl_diag_read_buffer(void __user *arg, enum block_state state)
1896 if (_ctl_verify_adapter(karg.hdr.ioc_number, &ioc) == -1 || !ioc) 1975 if (_ctl_verify_adapter(karg.hdr.ioc_number, &ioc) == -1 || !ioc)
1897 return -ENODEV; 1976 return -ENODEV;
1898 1977
1899 dctlprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s\n", ioc->name, 1978 dctlprintk(ioc, printk(MPT2SAS_INFO_FMT "%s\n", ioc->name,
1900 __func__)); 1979 __func__));
1901 1980
1902 buffer_type = karg.unique_id & 0x000000ff; 1981 buffer_type = karg.unique_id & 0x000000ff;
@@ -1927,7 +2006,7 @@ _ctl_diag_read_buffer(void __user *arg, enum block_state state)
1927 } 2006 }
1928 2007
1929 diag_data = (void *)(request_data + karg.starting_offset); 2008 diag_data = (void *)(request_data + karg.starting_offset);
1930 dctlprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: diag_buffer(%p), " 2009 dctlprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: diag_buffer(%p), "
1931 "offset(%d), sz(%d)\n", ioc->name, __func__, 2010 "offset(%d), sz(%d)\n", ioc->name, __func__,
1932 diag_data, karg.starting_offset, karg.bytes_to_read)); 2011 diag_data, karg.starting_offset, karg.bytes_to_read));
1933 2012
@@ -1942,11 +2021,11 @@ _ctl_diag_read_buffer(void __user *arg, enum block_state state)
1942 if ((karg.flags & MPT2_FLAGS_REREGISTER) == 0) 2021 if ((karg.flags & MPT2_FLAGS_REREGISTER) == 0)
1943 return 0; 2022 return 0;
1944 2023
1945 dctlprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: Reregister " 2024 dctlprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: Reregister "
1946 "buffer_type(0x%02x)\n", ioc->name, __func__, buffer_type)); 2025 "buffer_type(0x%02x)\n", ioc->name, __func__, buffer_type));
1947 if ((ioc->diag_buffer_status[buffer_type] & 2026 if ((ioc->diag_buffer_status[buffer_type] &
1948 MPT2_DIAG_BUFFER_IS_RELEASED) == 0) { 2027 MPT2_DIAG_BUFFER_IS_RELEASED) == 0) {
1949 dctlprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: " 2028 dctlprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: "
1950 "buffer_type(0x%02x) is still registered\n", ioc->name, 2029 "buffer_type(0x%02x) is still registered\n", ioc->name,
1951 __func__, buffer_type)); 2030 __func__, buffer_type));
1952 return 0; 2031 return 0;
@@ -2020,10 +2099,10 @@ _ctl_diag_read_buffer(void __user *arg, enum block_state state)
2020 if (ioc_status == MPI2_IOCSTATUS_SUCCESS) { 2099 if (ioc_status == MPI2_IOCSTATUS_SUCCESS) {
2021 ioc->diag_buffer_status[buffer_type] |= 2100 ioc->diag_buffer_status[buffer_type] |=
2022 MPT2_DIAG_BUFFER_IS_REGISTERED; 2101 MPT2_DIAG_BUFFER_IS_REGISTERED;
2023 dctlprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: success\n", 2102 dctlprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: success\n",
2024 ioc->name, __func__)); 2103 ioc->name, __func__));
2025 } else { 2104 } else {
2026 printk(MPT2SAS_DEBUG_FMT "%s: ioc_status(0x%04x) " 2105 printk(MPT2SAS_INFO_FMT "%s: ioc_status(0x%04x) "
2027 "log_info(0x%08x)\n", ioc->name, __func__, 2106 "log_info(0x%08x)\n", ioc->name, __func__,
2028 ioc_status, le32_to_cpu(mpi_reply->IOCLogInfo)); 2107 ioc_status, le32_to_cpu(mpi_reply->IOCLogInfo));
2029 rc = -EFAULT; 2108 rc = -EFAULT;
@@ -2077,7 +2156,7 @@ _ctl_ioctl_main(struct file *file, unsigned int cmd, void __user *arg)
2077 !ioc) 2156 !ioc)
2078 return -ENODEV; 2157 return -ENODEV;
2079 2158
2080 if (ioc->shost_recovery) 2159 if (ioc->shost_recovery || ioc->pci_error_recovery)
2081 return -EAGAIN; 2160 return -EAGAIN;
2082 2161
2083 if (_IOC_SIZE(cmd) == sizeof(struct mpt2_ioctl_command)) { 2162 if (_IOC_SIZE(cmd) == sizeof(struct mpt2_ioctl_command)) {
@@ -2140,7 +2219,7 @@ _ctl_ioctl_main(struct file *file, unsigned int cmd, void __user *arg)
2140 !ioc) 2219 !ioc)
2141 return -ENODEV; 2220 return -ENODEV;
2142 2221
2143 dctlprintk(ioc, printk(MPT2SAS_DEBUG_FMT 2222 dctlprintk(ioc, printk(MPT2SAS_INFO_FMT
2144 "unsupported ioctl opcode(0x%08x)\n", ioc->name, cmd)); 2223 "unsupported ioctl opcode(0x%08x)\n", ioc->name, cmd));
2145 break; 2224 break;
2146 } 2225 }
@@ -2196,7 +2275,7 @@ _ctl_compat_mpt_command(struct file *file, unsigned cmd, unsigned long arg)
2196 if (_ctl_verify_adapter(karg32.hdr.ioc_number, &ioc) == -1 || !ioc) 2275 if (_ctl_verify_adapter(karg32.hdr.ioc_number, &ioc) == -1 || !ioc)
2197 return -ENODEV; 2276 return -ENODEV;
2198 2277
2199 if (ioc->shost_recovery) 2278 if (ioc->shost_recovery || ioc->pci_error_recovery)
2200 return -EAGAIN; 2279 return -EAGAIN;
2201 2280
2202 memset(&karg, 0, sizeof(struct mpt2_ioctl_command)); 2281 memset(&karg, 0, sizeof(struct mpt2_ioctl_command));
@@ -2581,6 +2660,218 @@ _ctl_fwfault_debug_store(struct device *cdev,
2581static DEVICE_ATTR(fwfault_debug, S_IRUGO | S_IWUSR, 2660static DEVICE_ATTR(fwfault_debug, S_IRUGO | S_IWUSR,
2582 _ctl_fwfault_debug_show, _ctl_fwfault_debug_store); 2661 _ctl_fwfault_debug_show, _ctl_fwfault_debug_store);
2583 2662
2663
2664/**
2665 * _ctl_ioc_reset_count_show - ioc reset count
2666 * @cdev - pointer to embedded class device
2667 * @buf - the buffer returned
2668 *
2669 * This is firmware queue depth limit
2670 *
2671 * A sysfs 'read-only' shost attribute.
2672 */
2673static ssize_t
2674_ctl_ioc_reset_count_show(struct device *cdev, struct device_attribute *attr,
2675 char *buf)
2676{
2677 struct Scsi_Host *shost = class_to_shost(cdev);
2678 struct MPT2SAS_ADAPTER *ioc = shost_priv(shost);
2679
2680 return snprintf(buf, PAGE_SIZE, "%08d\n", ioc->ioc_reset_count);
2681}
2682static DEVICE_ATTR(ioc_reset_count, S_IRUGO,
2683 _ctl_ioc_reset_count_show, NULL);
2684
2685struct DIAG_BUFFER_START {
2686 u32 Size;
2687 u32 DiagVersion;
2688 u8 BufferType;
2689 u8 Reserved[3];
2690 u32 Reserved1;
2691 u32 Reserved2;
2692 u32 Reserved3;
2693};
2694/**
2695 * _ctl_host_trace_buffer_size_show - host buffer size (trace only)
2696 * @cdev - pointer to embedded class device
2697 * @buf - the buffer returned
2698 *
2699 * A sysfs 'read-only' shost attribute.
2700 */
2701static ssize_t
2702_ctl_host_trace_buffer_size_show(struct device *cdev,
2703 struct device_attribute *attr, char *buf)
2704{
2705 struct Scsi_Host *shost = class_to_shost(cdev);
2706 struct MPT2SAS_ADAPTER *ioc = shost_priv(shost);
2707 u32 size = 0;
2708 struct DIAG_BUFFER_START *request_data;
2709
2710 if (!ioc->diag_buffer[MPI2_DIAG_BUF_TYPE_TRACE]) {
2711 printk(MPT2SAS_ERR_FMT "%s: host_trace_buffer is not "
2712 "registered\n", ioc->name, __func__);
2713 return 0;
2714 }
2715
2716 if ((ioc->diag_buffer_status[MPI2_DIAG_BUF_TYPE_TRACE] &
2717 MPT2_DIAG_BUFFER_IS_REGISTERED) == 0) {
2718 printk(MPT2SAS_ERR_FMT "%s: host_trace_buffer is not "
2719 "registered\n", ioc->name, __func__);
2720 return 0;
2721 }
2722
2723 request_data = (struct DIAG_BUFFER_START *)
2724 ioc->diag_buffer[MPI2_DIAG_BUF_TYPE_TRACE];
2725 if ((le32_to_cpu(request_data->DiagVersion) == 0x00000000 ||
2726 le32_to_cpu(request_data->DiagVersion) == 0x01000000) &&
2727 le32_to_cpu(request_data->Reserved3) == 0x4742444c)
2728 size = le32_to_cpu(request_data->Size);
2729
2730 ioc->ring_buffer_sz = size;
2731 return snprintf(buf, PAGE_SIZE, "%d\n", size);
2732}
2733static DEVICE_ATTR(host_trace_buffer_size, S_IRUGO,
2734 _ctl_host_trace_buffer_size_show, NULL);
2735
2736/**
2737 * _ctl_host_trace_buffer_show - firmware ring buffer (trace only)
2738 * @cdev - pointer to embedded class device
2739 * @buf - the buffer returned
2740 *
2741 * A sysfs 'read/write' shost attribute.
2742 *
2743 * You will only be able to read 4k bytes of ring buffer at a time.
2744 * In order to read beyond 4k bytes, you will have to write out the
2745 * offset to the same attribute, it will move the pointer.
2746 */
2747static ssize_t
2748_ctl_host_trace_buffer_show(struct device *cdev, struct device_attribute *attr,
2749 char *buf)
2750{
2751 struct Scsi_Host *shost = class_to_shost(cdev);
2752 struct MPT2SAS_ADAPTER *ioc = shost_priv(shost);
2753 void *request_data;
2754 u32 size;
2755
2756 if (!ioc->diag_buffer[MPI2_DIAG_BUF_TYPE_TRACE]) {
2757 printk(MPT2SAS_ERR_FMT "%s: host_trace_buffer is not "
2758 "registered\n", ioc->name, __func__);
2759 return 0;
2760 }
2761
2762 if ((ioc->diag_buffer_status[MPI2_DIAG_BUF_TYPE_TRACE] &
2763 MPT2_DIAG_BUFFER_IS_REGISTERED) == 0) {
2764 printk(MPT2SAS_ERR_FMT "%s: host_trace_buffer is not "
2765 "registered\n", ioc->name, __func__);
2766 return 0;
2767 }
2768
2769 if (ioc->ring_buffer_offset > ioc->ring_buffer_sz)
2770 return 0;
2771
2772 size = ioc->ring_buffer_sz - ioc->ring_buffer_offset;
2773 size = (size > PAGE_SIZE) ? PAGE_SIZE : size;
2774 request_data = ioc->diag_buffer[0] + ioc->ring_buffer_offset;
2775 memcpy(buf, request_data, size);
2776 return size;
2777}
2778
2779static ssize_t
2780_ctl_host_trace_buffer_store(struct device *cdev, struct device_attribute *attr,
2781 const char *buf, size_t count)
2782{
2783 struct Scsi_Host *shost = class_to_shost(cdev);
2784 struct MPT2SAS_ADAPTER *ioc = shost_priv(shost);
2785 int val = 0;
2786
2787 if (sscanf(buf, "%d", &val) != 1)
2788 return -EINVAL;
2789
2790 ioc->ring_buffer_offset = val;
2791 return strlen(buf);
2792}
2793static DEVICE_ATTR(host_trace_buffer, S_IRUGO | S_IWUSR,
2794 _ctl_host_trace_buffer_show, _ctl_host_trace_buffer_store);
2795
2796/*****************************************/
2797
2798/**
2799 * _ctl_host_trace_buffer_enable_show - firmware ring buffer (trace only)
2800 * @cdev - pointer to embedded class device
2801 * @buf - the buffer returned
2802 *
2803 * A sysfs 'read/write' shost attribute.
2804 *
2805 * This is a mechnism to post/release host_trace_buffers
2806 */
2807static ssize_t
2808_ctl_host_trace_buffer_enable_show(struct device *cdev,
2809 struct device_attribute *attr, char *buf)
2810{
2811 struct Scsi_Host *shost = class_to_shost(cdev);
2812 struct MPT2SAS_ADAPTER *ioc = shost_priv(shost);
2813
2814 if ((!ioc->diag_buffer[MPI2_DIAG_BUF_TYPE_TRACE]) ||
2815 ((ioc->diag_buffer_status[MPI2_DIAG_BUF_TYPE_TRACE] &
2816 MPT2_DIAG_BUFFER_IS_REGISTERED) == 0))
2817 return snprintf(buf, PAGE_SIZE, "off\n");
2818 else if ((ioc->diag_buffer_status[MPI2_DIAG_BUF_TYPE_TRACE] &
2819 MPT2_DIAG_BUFFER_IS_RELEASED))
2820 return snprintf(buf, PAGE_SIZE, "release\n");
2821 else
2822 return snprintf(buf, PAGE_SIZE, "post\n");
2823}
2824
2825static ssize_t
2826_ctl_host_trace_buffer_enable_store(struct device *cdev,
2827 struct device_attribute *attr, const char *buf, size_t count)
2828{
2829 struct Scsi_Host *shost = class_to_shost(cdev);
2830 struct MPT2SAS_ADAPTER *ioc = shost_priv(shost);
2831 char str[10] = "";
2832 struct mpt2_diag_register diag_register;
2833 u8 issue_reset = 0;
2834
2835 if (sscanf(buf, "%s", str) != 1)
2836 return -EINVAL;
2837
2838 if (!strcmp(str, "post")) {
2839 /* exit out if host buffers are already posted */
2840 if ((ioc->diag_buffer[MPI2_DIAG_BUF_TYPE_TRACE]) &&
2841 (ioc->diag_buffer_status[MPI2_DIAG_BUF_TYPE_TRACE] &
2842 MPT2_DIAG_BUFFER_IS_REGISTERED) &&
2843 ((ioc->diag_buffer_status[MPI2_DIAG_BUF_TYPE_TRACE] &
2844 MPT2_DIAG_BUFFER_IS_RELEASED) == 0))
2845 goto out;
2846 memset(&diag_register, 0, sizeof(struct mpt2_diag_register));
2847 printk(MPT2SAS_INFO_FMT "posting host trace buffers\n",
2848 ioc->name);
2849 diag_register.buffer_type = MPI2_DIAG_BUF_TYPE_TRACE;
2850 diag_register.requested_buffer_size = (1024 * 1024);
2851 diag_register.unique_id = 0x7075900;
2852 ioc->diag_buffer_status[MPI2_DIAG_BUF_TYPE_TRACE] = 0;
2853 _ctl_diag_register_2(ioc, &diag_register);
2854 } else if (!strcmp(str, "release")) {
2855 /* exit out if host buffers are already released */
2856 if (!ioc->diag_buffer[MPI2_DIAG_BUF_TYPE_TRACE])
2857 goto out;
2858 if ((ioc->diag_buffer_status[MPI2_DIAG_BUF_TYPE_TRACE] &
2859 MPT2_DIAG_BUFFER_IS_REGISTERED) == 0)
2860 goto out;
2861 if ((ioc->diag_buffer_status[MPI2_DIAG_BUF_TYPE_TRACE] &
2862 MPT2_DIAG_BUFFER_IS_RELEASED))
2863 goto out;
2864 printk(MPT2SAS_INFO_FMT "releasing host trace buffer\n",
2865 ioc->name);
2866 _ctl_send_release(ioc, MPI2_DIAG_BUF_TYPE_TRACE, &issue_reset);
2867 }
2868
2869 out:
2870 return strlen(buf);
2871}
2872static DEVICE_ATTR(host_trace_buffer_enable, S_IRUGO | S_IWUSR,
2873 _ctl_host_trace_buffer_enable_show, _ctl_host_trace_buffer_enable_store);
2874
2584struct device_attribute *mpt2sas_host_attrs[] = { 2875struct device_attribute *mpt2sas_host_attrs[] = {
2585 &dev_attr_version_fw, 2876 &dev_attr_version_fw,
2586 &dev_attr_version_bios, 2877 &dev_attr_version_bios,
@@ -2597,6 +2888,10 @@ struct device_attribute *mpt2sas_host_attrs[] = {
2597 &dev_attr_fwfault_debug, 2888 &dev_attr_fwfault_debug,
2598 &dev_attr_fw_queue_depth, 2889 &dev_attr_fw_queue_depth,
2599 &dev_attr_host_sas_address, 2890 &dev_attr_host_sas_address,
2891 &dev_attr_ioc_reset_count,
2892 &dev_attr_host_trace_buffer_size,
2893 &dev_attr_host_trace_buffer,
2894 &dev_attr_host_trace_buffer_enable,
2600 NULL, 2895 NULL,
2601}; 2896};
2602 2897