aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi
diff options
context:
space:
mode:
authorAnil Ravindranath <anil_ravindranath@pmc-sierra.com>2010-10-13 17:11:02 -0400
committerJames Bottomley <James.Bottomley@suse.de>2010-10-29 13:03:01 -0400
commit592488a32b87daf27b92d2c1c5cdc440d1a1beae (patch)
treea556d44e55c800936b5750f4ee97164221e05feb /drivers/scsi
parentdf30e5059681ed0671c9cc6ff702fe9ca7f20042 (diff)
[SCSI] pmcraid: add support for set timestamp command and other fixes
The following are the fixes in this patch: 1. Added support of set timestamp command in the driver 2. Pass all status code to mgmt application. Earlier we were passing only failed ones. 3. Call class_destroy after unregister_chrdev and pci_unregister_driver Signed-off-by: Anil Ravindranath <anil_ravindranath@pmc-sierra.com> Signed-off-by: James Bottomley <James.Bottomley@suse.de>
Diffstat (limited to 'drivers/scsi')
-rw-r--r--drivers/scsi/pmcraid.c129
-rw-r--r--drivers/scsi/pmcraid.h22
2 files changed, 129 insertions, 22 deletions
diff --git a/drivers/scsi/pmcraid.c b/drivers/scsi/pmcraid.c
index 4b8765785aeb..cf89091e4c3d 100644
--- a/drivers/scsi/pmcraid.c
+++ b/drivers/scsi/pmcraid.c
@@ -1594,10 +1594,12 @@ static void pmcraid_handle_config_change(struct pmcraid_instance *pinstance)
1594 cfg_entry = &ccn_hcam->cfg_entry; 1594 cfg_entry = &ccn_hcam->cfg_entry;
1595 fw_version = be16_to_cpu(pinstance->inq_data->fw_version); 1595 fw_version = be16_to_cpu(pinstance->inq_data->fw_version);
1596 1596
1597 pmcraid_info 1597 pmcraid_info("CCN(%x): %x timestamp: %llx type: %x lost: %x flags: %x \
1598 ("CCN(%x): %x type: %x lost: %x flags: %x res: %x:%x:%x:%x\n", 1598 res: %x:%x:%x:%x\n",
1599 pinstance->ccn.hcam->ilid, 1599 pinstance->ccn.hcam->ilid,
1600 pinstance->ccn.hcam->op_code, 1600 pinstance->ccn.hcam->op_code,
1601 ((pinstance->ccn.hcam->timestamp1) |
1602 ((pinstance->ccn.hcam->timestamp2 & 0xffffffffLL) << 32)),
1601 pinstance->ccn.hcam->notification_type, 1603 pinstance->ccn.hcam->notification_type,
1602 pinstance->ccn.hcam->notification_lost, 1604 pinstance->ccn.hcam->notification_lost,
1603 pinstance->ccn.hcam->flags, 1605 pinstance->ccn.hcam->flags,
@@ -1850,6 +1852,7 @@ static void pmcraid_process_ccn(struct pmcraid_cmd *cmd)
1850 * none 1852 * none
1851 */ 1853 */
1852static void pmcraid_initiate_reset(struct pmcraid_instance *); 1854static void pmcraid_initiate_reset(struct pmcraid_instance *);
1855static void pmcraid_set_timestamp(struct pmcraid_cmd *cmd);
1853 1856
1854static void pmcraid_process_ldn(struct pmcraid_cmd *cmd) 1857static void pmcraid_process_ldn(struct pmcraid_cmd *cmd)
1855{ 1858{
@@ -1881,6 +1884,10 @@ static void pmcraid_process_ldn(struct pmcraid_cmd *cmd)
1881 lock_flags); 1884 lock_flags);
1882 return; 1885 return;
1883 } 1886 }
1887 if (fd_ioasc == PMCRAID_IOASC_TIME_STAMP_OUT_OF_SYNC) {
1888 pinstance->timestamp_error = 1;
1889 pmcraid_set_timestamp(cmd);
1890 }
1884 } else { 1891 } else {
1885 dev_info(&pinstance->pdev->dev, 1892 dev_info(&pinstance->pdev->dev,
1886 "Host RCB(LDN) failed with IOASC: 0x%08X\n", ioasc); 1893 "Host RCB(LDN) failed with IOASC: 0x%08X\n", ioasc);
@@ -3363,7 +3370,7 @@ static struct pmcraid_sglist *pmcraid_alloc_sglist(int buflen)
3363 sg_size = buflen; 3370 sg_size = buflen;
3364 3371
3365 for (i = 0; i < num_elem; i++) { 3372 for (i = 0; i < num_elem; i++) {
3366 page = alloc_pages(GFP_KERNEL|GFP_DMA, order); 3373 page = alloc_pages(GFP_KERNEL|GFP_DMA|__GFP_ZERO, order);
3367 if (!page) { 3374 if (!page) {
3368 for (j = i - 1; j >= 0; j--) 3375 for (j = i - 1; j >= 0; j--)
3369 __free_pages(sg_page(&scatterlist[j]), order); 3376 __free_pages(sg_page(&scatterlist[j]), order);
@@ -3739,6 +3746,7 @@ static long pmcraid_ioctl_passthrough(
3739 unsigned long request_buffer; 3746 unsigned long request_buffer;
3740 unsigned long request_offset; 3747 unsigned long request_offset;
3741 unsigned long lock_flags; 3748 unsigned long lock_flags;
3749 void *ioasa;
3742 u32 ioasc; 3750 u32 ioasc;
3743 int request_size; 3751 int request_size;
3744 int buffer_size; 3752 int buffer_size;
@@ -3780,6 +3788,11 @@ static long pmcraid_ioctl_passthrough(
3780 rc = __copy_from_user(buffer, 3788 rc = __copy_from_user(buffer,
3781 (struct pmcraid_passthrough_ioctl_buffer *) arg, 3789 (struct pmcraid_passthrough_ioctl_buffer *) arg,
3782 sizeof(struct pmcraid_passthrough_ioctl_buffer)); 3790 sizeof(struct pmcraid_passthrough_ioctl_buffer));
3791
3792 ioasa =
3793 (void *)(arg +
3794 offsetof(struct pmcraid_passthrough_ioctl_buffer, ioasa));
3795
3783 if (rc) { 3796 if (rc) {
3784 pmcraid_err("ioctl: can't copy passthrough buffer\n"); 3797 pmcraid_err("ioctl: can't copy passthrough buffer\n");
3785 rc = -EFAULT; 3798 rc = -EFAULT;
@@ -3947,22 +3960,14 @@ static long pmcraid_ioctl_passthrough(
3947 } 3960 }
3948 3961
3949out_handle_response: 3962out_handle_response:
3950 /* If the command failed for any reason, copy entire IOASA buffer and 3963 /* copy entire IOASA buffer and return IOCTL success.
3951 * return IOCTL success. If copying IOASA to user-buffer fails, return 3964 * If copying IOASA to user-buffer fails, return
3952 * EFAULT 3965 * EFAULT
3953 */ 3966 */
3954 if (PMCRAID_IOASC_SENSE_KEY(le32_to_cpu(cmd->ioa_cb->ioasa.ioasc))) { 3967 if (copy_to_user(ioasa, &cmd->ioa_cb->ioasa,
3955 void *ioasa = 3968 sizeof(struct pmcraid_ioasa))) {
3956 (void *)(arg + 3969 pmcraid_err("failed to copy ioasa buffer to user\n");
3957 offsetof(struct pmcraid_passthrough_ioctl_buffer, ioasa)); 3970 rc = -EFAULT;
3958
3959 pmcraid_info("command failed with %x\n",
3960 le32_to_cpu(cmd->ioa_cb->ioasa.ioasc));
3961 if (copy_to_user(ioasa, &cmd->ioa_cb->ioasa,
3962 sizeof(struct pmcraid_ioasa))) {
3963 pmcraid_err("failed to copy ioasa buffer to user\n");
3964 rc = -EFAULT;
3965 }
3966 } 3971 }
3967 3972
3968 /* If the data transfer was from device, copy the data onto user 3973 /* If the data transfer was from device, copy the data onto user
@@ -5147,6 +5152,16 @@ static void pmcraid_release_buffers(struct pmcraid_instance *pinstance)
5147 pinstance->inq_data = NULL; 5152 pinstance->inq_data = NULL;
5148 pinstance->inq_data_baddr = 0; 5153 pinstance->inq_data_baddr = 0;
5149 } 5154 }
5155
5156 if (pinstance->timestamp_data != NULL) {
5157 pci_free_consistent(pinstance->pdev,
5158 sizeof(struct pmcraid_timestamp_data),
5159 pinstance->timestamp_data,
5160 pinstance->timestamp_data_baddr);
5161
5162 pinstance->timestamp_data = NULL;
5163 pinstance->timestamp_data_baddr = 0;
5164 }
5150} 5165}
5151 5166
5152/** 5167/**
@@ -5205,6 +5220,20 @@ static int __devinit pmcraid_init_buffers(struct pmcraid_instance *pinstance)
5205 return -ENOMEM; 5220 return -ENOMEM;
5206 } 5221 }
5207 5222
5223 /* allocate DMAable memory for set timestamp data buffer */
5224 pinstance->timestamp_data = pci_alloc_consistent(
5225 pinstance->pdev,
5226 sizeof(struct pmcraid_timestamp_data),
5227 &pinstance->timestamp_data_baddr);
5228
5229 if (pinstance->timestamp_data == NULL) {
5230 pmcraid_err("couldn't allocate DMA memory for \
5231 set time_stamp \n");
5232 pmcraid_release_buffers(pinstance);
5233 return -ENOMEM;
5234 }
5235
5236
5208 /* Initialize all the command blocks and add them to free pool. No 5237 /* Initialize all the command blocks and add them to free pool. No
5209 * need to lock (free_pool_lock) as this is done in initialization 5238 * need to lock (free_pool_lock) as this is done in initialization
5210 * itself 5239 * itself
@@ -5610,6 +5639,68 @@ static void pmcraid_set_supported_devs(struct pmcraid_cmd *cmd)
5610} 5639}
5611 5640
5612/** 5641/**
5642 * pmcraid_set_timestamp - set the timestamp to IOAFP
5643 *
5644 * @cmd: pointer to pmcraid_cmd structure
5645 *
5646 * Return Value
5647 * 0 for success or non-zero for failure cases
5648 */
5649static void pmcraid_set_timestamp(struct pmcraid_cmd *cmd)
5650{
5651 struct pmcraid_instance *pinstance = cmd->drv_inst;
5652 struct pmcraid_ioarcb *ioarcb = &cmd->ioa_cb->ioarcb;
5653 __be32 time_stamp_len = cpu_to_be32(PMCRAID_TIMESTAMP_LEN);
5654 struct pmcraid_ioadl_desc *ioadl = ioarcb->add_data.u.ioadl;
5655
5656 struct timeval tv;
5657 __le64 timestamp;
5658
5659 do_gettimeofday(&tv);
5660 timestamp = tv.tv_sec * 1000;
5661
5662 pinstance->timestamp_data->timestamp[0] = (__u8)(timestamp);
5663 pinstance->timestamp_data->timestamp[1] = (__u8)((timestamp) >> 8);
5664 pinstance->timestamp_data->timestamp[2] = (__u8)((timestamp) >> 16);
5665 pinstance->timestamp_data->timestamp[3] = (__u8)((timestamp) >> 24);
5666 pinstance->timestamp_data->timestamp[4] = (__u8)((timestamp) >> 32);
5667 pinstance->timestamp_data->timestamp[5] = (__u8)((timestamp) >> 40);
5668
5669 pmcraid_reinit_cmdblk(cmd);
5670 ioarcb->request_type = REQ_TYPE_SCSI;
5671 ioarcb->resource_handle = cpu_to_le32(PMCRAID_IOA_RES_HANDLE);
5672 ioarcb->cdb[0] = PMCRAID_SCSI_SET_TIMESTAMP;
5673 ioarcb->cdb[1] = PMCRAID_SCSI_SERVICE_ACTION;
5674 memcpy(&(ioarcb->cdb[6]), &time_stamp_len, sizeof(time_stamp_len));
5675
5676 ioarcb->ioadl_bus_addr = cpu_to_le64((cmd->ioa_cb_bus_addr) +
5677 offsetof(struct pmcraid_ioarcb,
5678 add_data.u.ioadl[0]));
5679 ioarcb->ioadl_length = cpu_to_le32(sizeof(struct pmcraid_ioadl_desc));
5680 ioarcb->ioarcb_bus_addr &= ~(0x1FULL);
5681
5682 ioarcb->request_flags0 |= NO_LINK_DESCS;
5683 ioarcb->request_flags0 |= TRANSFER_DIR_WRITE;
5684 ioarcb->data_transfer_length =
5685 cpu_to_le32(sizeof(struct pmcraid_timestamp_data));
5686 ioadl = &(ioarcb->add_data.u.ioadl[0]);
5687 ioadl->flags = IOADL_FLAGS_LAST_DESC;
5688 ioadl->address = cpu_to_le64(pinstance->timestamp_data_baddr);
5689 ioadl->data_len = cpu_to_le32(sizeof(struct pmcraid_timestamp_data));
5690
5691 if (!pinstance->timestamp_error) {
5692 pinstance->timestamp_error = 0;
5693 pmcraid_send_cmd(cmd, pmcraid_set_supported_devs,
5694 PMCRAID_INTERNAL_TIMEOUT, pmcraid_timeout_handler);
5695 } else {
5696 pmcraid_send_cmd(cmd, pmcraid_return_cmd,
5697 PMCRAID_INTERNAL_TIMEOUT, pmcraid_timeout_handler);
5698 return;
5699 }
5700}
5701
5702
5703/**
5613 * pmcraid_init_res_table - Initialize the resource table 5704 * pmcraid_init_res_table - Initialize the resource table
5614 * @cmd: pointer to pmcraid command struct 5705 * @cmd: pointer to pmcraid command struct
5615 * 5706 *
@@ -5720,7 +5811,7 @@ static void pmcraid_init_res_table(struct pmcraid_cmd *cmd)
5720 5811
5721 /* release the resource list lock */ 5812 /* release the resource list lock */
5722 spin_unlock_irqrestore(&pinstance->resource_lock, lock_flags); 5813 spin_unlock_irqrestore(&pinstance->resource_lock, lock_flags);
5723 pmcraid_set_supported_devs(cmd); 5814 pmcraid_set_timestamp(cmd);
5724} 5815}
5725 5816
5726/** 5817/**
@@ -6054,10 +6145,10 @@ out_init:
6054static void __exit pmcraid_exit(void) 6145static void __exit pmcraid_exit(void)
6055{ 6146{
6056 pmcraid_netlink_release(); 6147 pmcraid_netlink_release();
6057 class_destroy(pmcraid_class);
6058 unregister_chrdev_region(MKDEV(pmcraid_major, 0), 6148 unregister_chrdev_region(MKDEV(pmcraid_major, 0),
6059 PMCRAID_MAX_ADAPTERS); 6149 PMCRAID_MAX_ADAPTERS);
6060 pci_unregister_driver(&pmcraid_driver); 6150 pci_unregister_driver(&pmcraid_driver);
6151 class_destroy(pmcraid_class);
6061} 6152}
6062 6153
6063module_init(pmcraid_init); 6154module_init(pmcraid_init);
diff --git a/drivers/scsi/pmcraid.h b/drivers/scsi/pmcraid.h
index dd78f9e8eb9b..1134279604e8 100644
--- a/drivers/scsi/pmcraid.h
+++ b/drivers/scsi/pmcraid.h
@@ -42,7 +42,7 @@
42 */ 42 */
43#define PMCRAID_DRIVER_NAME "PMC MaxRAID" 43#define PMCRAID_DRIVER_NAME "PMC MaxRAID"
44#define PMCRAID_DEVFILE "pmcsas" 44#define PMCRAID_DEVFILE "pmcsas"
45#define PMCRAID_DRIVER_VERSION "2.0.2" 45#define PMCRAID_DRIVER_VERSION "2.0.3"
46#define PMCRAID_DRIVER_DATE __DATE__ 46#define PMCRAID_DRIVER_DATE __DATE__
47 47
48#define PMCRAID_FW_VERSION_1 0x002 48#define PMCRAID_FW_VERSION_1 0x002
@@ -184,6 +184,7 @@
184#define PMCRAID_IOASC_IR_INVALID_RESOURCE_HANDLE 0x05250000 184#define PMCRAID_IOASC_IR_INVALID_RESOURCE_HANDLE 0x05250000
185#define PMCRAID_IOASC_AC_TERMINATED_BY_HOST 0x0B5A0000 185#define PMCRAID_IOASC_AC_TERMINATED_BY_HOST 0x0B5A0000
186#define PMCRAID_IOASC_UA_BUS_WAS_RESET 0x06290000 186#define PMCRAID_IOASC_UA_BUS_WAS_RESET 0x06290000
187#define PMCRAID_IOASC_TIME_STAMP_OUT_OF_SYNC 0x06908B00
187#define PMCRAID_IOASC_UA_BUS_WAS_RESET_BY_OTHER 0x06298000 188#define PMCRAID_IOASC_UA_BUS_WAS_RESET_BY_OTHER 0x06298000
188 189
189/* Driver defined IOASCs */ 190/* Driver defined IOASCs */
@@ -561,6 +562,17 @@ struct pmcraid_inquiry_data {
561 __u8 reserved3[16]; 562 __u8 reserved3[16];
562}; 563};
563 564
565#define PMCRAID_TIMESTAMP_LEN 12
566#define PMCRAID_REQ_TM_STR_LEN 6
567#define PMCRAID_SCSI_SET_TIMESTAMP 0xA4
568#define PMCRAID_SCSI_SERVICE_ACTION 0x0F
569
570struct pmcraid_timestamp_data {
571 __u8 reserved1[4];
572 __u8 timestamp[PMCRAID_REQ_TM_STR_LEN]; /* current time value */
573 __u8 reserved2[2];
574};
575
564/* pmcraid_cmd - LLD representation of SCSI command */ 576/* pmcraid_cmd - LLD representation of SCSI command */
565struct pmcraid_cmd { 577struct pmcraid_cmd {
566 578
@@ -704,6 +716,9 @@ struct pmcraid_instance {
704 struct pmcraid_inquiry_data *inq_data; 716 struct pmcraid_inquiry_data *inq_data;
705 dma_addr_t inq_data_baddr; 717 dma_addr_t inq_data_baddr;
706 718
719 struct pmcraid_timestamp_data *timestamp_data;
720 dma_addr_t timestamp_data_baddr;
721
707 /* size of configuration table entry, varies based on the firmware */ 722 /* size of configuration table entry, varies based on the firmware */
708 u32 config_table_entry_size; 723 u32 config_table_entry_size;
709 724
@@ -790,6 +805,7 @@ struct pmcraid_instance {
790#define SHUTDOWN_NONE 0x0 805#define SHUTDOWN_NONE 0x0
791#define SHUTDOWN_NORMAL 0x1 806#define SHUTDOWN_NORMAL 0x1
792#define SHUTDOWN_ABBREV 0x2 807#define SHUTDOWN_ABBREV 0x2
808 u32 timestamp_error:1; /* indicate set timestamp for out of sync */
793 809
794}; 810};
795 811
@@ -1055,10 +1071,10 @@ struct pmcraid_passthrough_ioctl_buffer {
1055#define PMCRAID_PASSTHROUGH_IOCTL 'F' 1071#define PMCRAID_PASSTHROUGH_IOCTL 'F'
1056 1072
1057#define DRV_IOCTL(n, size) \ 1073#define DRV_IOCTL(n, size) \
1058 _IOC(_IOC_READ|_IOC_WRITE, PMCRAID_DRIVER_IOCTL, (n), (size)) 1074 _IOC(_IOC_READ|_IOC_WRITE, PMCRAID_DRIVER_IOCTL, (n), (size))
1059 1075
1060#define FMW_IOCTL(n, size) \ 1076#define FMW_IOCTL(n, size) \
1061 _IOC(_IOC_READ|_IOC_WRITE, PMCRAID_PASSTHROUGH_IOCTL, (n), (size)) 1077 _IOC(_IOC_READ|_IOC_WRITE, PMCRAID_PASSTHROUGH_IOCTL, (n), (size))
1062 1078
1063/* 1079/*
1064 * _ARGSIZE: macro that gives size of the argument type passed to an IOCTL cmd. 1080 * _ARGSIZE: macro that gives size of the argument type passed to an IOCTL cmd.