aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/pmcraid.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/pmcraid.c')
-rw-r--r--drivers/scsi/pmcraid.c137
1 files changed, 116 insertions, 21 deletions
diff --git a/drivers/scsi/pmcraid.c b/drivers/scsi/pmcraid.c
index 4b8765785aeb..300d59f389da 100644
--- a/drivers/scsi/pmcraid.c
+++ b/drivers/scsi/pmcraid.c
@@ -62,6 +62,7 @@
62static unsigned int pmcraid_debug_log; 62static unsigned int pmcraid_debug_log;
63static unsigned int pmcraid_disable_aen; 63static unsigned int pmcraid_disable_aen;
64static unsigned int pmcraid_log_level = IOASC_LOG_LEVEL_MUST; 64static unsigned int pmcraid_log_level = IOASC_LOG_LEVEL_MUST;
65static unsigned int pmcraid_enable_msix;
65 66
66/* 67/*
67 * Data structures to support multiple adapters by the LLD. 68 * Data structures to support multiple adapters by the LLD.
@@ -1594,10 +1595,12 @@ static void pmcraid_handle_config_change(struct pmcraid_instance *pinstance)
1594 cfg_entry = &ccn_hcam->cfg_entry; 1595 cfg_entry = &ccn_hcam->cfg_entry;
1595 fw_version = be16_to_cpu(pinstance->inq_data->fw_version); 1596 fw_version = be16_to_cpu(pinstance->inq_data->fw_version);
1596 1597
1597 pmcraid_info 1598 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", 1599 res: %x:%x:%x:%x\n",
1599 pinstance->ccn.hcam->ilid, 1600 pinstance->ccn.hcam->ilid,
1600 pinstance->ccn.hcam->op_code, 1601 pinstance->ccn.hcam->op_code,
1602 ((pinstance->ccn.hcam->timestamp1) |
1603 ((pinstance->ccn.hcam->timestamp2 & 0xffffffffLL) << 32)),
1601 pinstance->ccn.hcam->notification_type, 1604 pinstance->ccn.hcam->notification_type,
1602 pinstance->ccn.hcam->notification_lost, 1605 pinstance->ccn.hcam->notification_lost,
1603 pinstance->ccn.hcam->flags, 1606 pinstance->ccn.hcam->flags,
@@ -1850,6 +1853,7 @@ static void pmcraid_process_ccn(struct pmcraid_cmd *cmd)
1850 * none 1853 * none
1851 */ 1854 */
1852static void pmcraid_initiate_reset(struct pmcraid_instance *); 1855static void pmcraid_initiate_reset(struct pmcraid_instance *);
1856static void pmcraid_set_timestamp(struct pmcraid_cmd *cmd);
1853 1857
1854static void pmcraid_process_ldn(struct pmcraid_cmd *cmd) 1858static void pmcraid_process_ldn(struct pmcraid_cmd *cmd)
1855{ 1859{
@@ -1881,6 +1885,10 @@ static void pmcraid_process_ldn(struct pmcraid_cmd *cmd)
1881 lock_flags); 1885 lock_flags);
1882 return; 1886 return;
1883 } 1887 }
1888 if (fd_ioasc == PMCRAID_IOASC_TIME_STAMP_OUT_OF_SYNC) {
1889 pinstance->timestamp_error = 1;
1890 pmcraid_set_timestamp(cmd);
1891 }
1884 } else { 1892 } else {
1885 dev_info(&pinstance->pdev->dev, 1893 dev_info(&pinstance->pdev->dev,
1886 "Host RCB(LDN) failed with IOASC: 0x%08X\n", ioasc); 1894 "Host RCB(LDN) failed with IOASC: 0x%08X\n", ioasc);
@@ -3363,7 +3371,7 @@ static struct pmcraid_sglist *pmcraid_alloc_sglist(int buflen)
3363 sg_size = buflen; 3371 sg_size = buflen;
3364 3372
3365 for (i = 0; i < num_elem; i++) { 3373 for (i = 0; i < num_elem; i++) {
3366 page = alloc_pages(GFP_KERNEL|GFP_DMA, order); 3374 page = alloc_pages(GFP_KERNEL|GFP_DMA|__GFP_ZERO, order);
3367 if (!page) { 3375 if (!page) {
3368 for (j = i - 1; j >= 0; j--) 3376 for (j = i - 1; j >= 0; j--)
3369 __free_pages(sg_page(&scatterlist[j]), order); 3377 __free_pages(sg_page(&scatterlist[j]), order);
@@ -3471,7 +3479,7 @@ static int pmcraid_copy_sglist(
3471 * SCSI_MLQUEUE_DEVICE_BUSY if device is busy 3479 * SCSI_MLQUEUE_DEVICE_BUSY if device is busy
3472 * SCSI_MLQUEUE_HOST_BUSY if host is busy 3480 * SCSI_MLQUEUE_HOST_BUSY if host is busy
3473 */ 3481 */
3474static int pmcraid_queuecommand( 3482static int pmcraid_queuecommand_lck(
3475 struct scsi_cmnd *scsi_cmd, 3483 struct scsi_cmnd *scsi_cmd,
3476 void (*done) (struct scsi_cmnd *) 3484 void (*done) (struct scsi_cmnd *)
3477) 3485)
@@ -3577,6 +3585,8 @@ static int pmcraid_queuecommand(
3577 return rc; 3585 return rc;
3578} 3586}
3579 3587
3588static DEF_SCSI_QCMD(pmcraid_queuecommand)
3589
3580/** 3590/**
3581 * pmcraid_open -char node "open" entry, allowed only users with admin access 3591 * pmcraid_open -char node "open" entry, allowed only users with admin access
3582 */ 3592 */
@@ -3739,6 +3749,7 @@ static long pmcraid_ioctl_passthrough(
3739 unsigned long request_buffer; 3749 unsigned long request_buffer;
3740 unsigned long request_offset; 3750 unsigned long request_offset;
3741 unsigned long lock_flags; 3751 unsigned long lock_flags;
3752 void *ioasa;
3742 u32 ioasc; 3753 u32 ioasc;
3743 int request_size; 3754 int request_size;
3744 int buffer_size; 3755 int buffer_size;
@@ -3780,6 +3791,11 @@ static long pmcraid_ioctl_passthrough(
3780 rc = __copy_from_user(buffer, 3791 rc = __copy_from_user(buffer,
3781 (struct pmcraid_passthrough_ioctl_buffer *) arg, 3792 (struct pmcraid_passthrough_ioctl_buffer *) arg,
3782 sizeof(struct pmcraid_passthrough_ioctl_buffer)); 3793 sizeof(struct pmcraid_passthrough_ioctl_buffer));
3794
3795 ioasa =
3796 (void *)(arg +
3797 offsetof(struct pmcraid_passthrough_ioctl_buffer, ioasa));
3798
3783 if (rc) { 3799 if (rc) {
3784 pmcraid_err("ioctl: can't copy passthrough buffer\n"); 3800 pmcraid_err("ioctl: can't copy passthrough buffer\n");
3785 rc = -EFAULT; 3801 rc = -EFAULT;
@@ -3947,22 +3963,14 @@ static long pmcraid_ioctl_passthrough(
3947 } 3963 }
3948 3964
3949out_handle_response: 3965out_handle_response:
3950 /* If the command failed for any reason, copy entire IOASA buffer and 3966 /* copy entire IOASA buffer and return IOCTL success.
3951 * return IOCTL success. If copying IOASA to user-buffer fails, return 3967 * If copying IOASA to user-buffer fails, return
3952 * EFAULT 3968 * EFAULT
3953 */ 3969 */
3954 if (PMCRAID_IOASC_SENSE_KEY(le32_to_cpu(cmd->ioa_cb->ioasa.ioasc))) { 3970 if (copy_to_user(ioasa, &cmd->ioa_cb->ioasa,
3955 void *ioasa = 3971 sizeof(struct pmcraid_ioasa))) {
3956 (void *)(arg + 3972 pmcraid_err("failed to copy ioasa buffer to user\n");
3957 offsetof(struct pmcraid_passthrough_ioctl_buffer, ioasa)); 3973 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 } 3974 }
3967 3975
3968 /* If the data transfer was from device, copy the data onto user 3976 /* If the data transfer was from device, copy the data onto user
@@ -4684,7 +4692,8 @@ pmcraid_register_interrupt_handler(struct pmcraid_instance *pinstance)
4684 int rc; 4692 int rc;
4685 struct pci_dev *pdev = pinstance->pdev; 4693 struct pci_dev *pdev = pinstance->pdev;
4686 4694
4687 if (pci_find_capability(pdev, PCI_CAP_ID_MSIX)) { 4695 if ((pmcraid_enable_msix) &&
4696 (pci_find_capability(pdev, PCI_CAP_ID_MSIX))) {
4688 int num_hrrq = PMCRAID_NUM_MSIX_VECTORS; 4697 int num_hrrq = PMCRAID_NUM_MSIX_VECTORS;
4689 struct msix_entry entries[PMCRAID_NUM_MSIX_VECTORS]; 4698 struct msix_entry entries[PMCRAID_NUM_MSIX_VECTORS];
4690 int i; 4699 int i;
@@ -5147,6 +5156,16 @@ static void pmcraid_release_buffers(struct pmcraid_instance *pinstance)
5147 pinstance->inq_data = NULL; 5156 pinstance->inq_data = NULL;
5148 pinstance->inq_data_baddr = 0; 5157 pinstance->inq_data_baddr = 0;
5149 } 5158 }
5159
5160 if (pinstance->timestamp_data != NULL) {
5161 pci_free_consistent(pinstance->pdev,
5162 sizeof(struct pmcraid_timestamp_data),
5163 pinstance->timestamp_data,
5164 pinstance->timestamp_data_baddr);
5165
5166 pinstance->timestamp_data = NULL;
5167 pinstance->timestamp_data_baddr = 0;
5168 }
5150} 5169}
5151 5170
5152/** 5171/**
@@ -5205,6 +5224,20 @@ static int __devinit pmcraid_init_buffers(struct pmcraid_instance *pinstance)
5205 return -ENOMEM; 5224 return -ENOMEM;
5206 } 5225 }
5207 5226
5227 /* allocate DMAable memory for set timestamp data buffer */
5228 pinstance->timestamp_data = pci_alloc_consistent(
5229 pinstance->pdev,
5230 sizeof(struct pmcraid_timestamp_data),
5231 &pinstance->timestamp_data_baddr);
5232
5233 if (pinstance->timestamp_data == NULL) {
5234 pmcraid_err("couldn't allocate DMA memory for \
5235 set time_stamp \n");
5236 pmcraid_release_buffers(pinstance);
5237 return -ENOMEM;
5238 }
5239
5240
5208 /* Initialize all the command blocks and add them to free pool. No 5241 /* 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 5242 * need to lock (free_pool_lock) as this is done in initialization
5210 * itself 5243 * itself
@@ -5610,6 +5643,68 @@ static void pmcraid_set_supported_devs(struct pmcraid_cmd *cmd)
5610} 5643}
5611 5644
5612/** 5645/**
5646 * pmcraid_set_timestamp - set the timestamp to IOAFP
5647 *
5648 * @cmd: pointer to pmcraid_cmd structure
5649 *
5650 * Return Value
5651 * 0 for success or non-zero for failure cases
5652 */
5653static void pmcraid_set_timestamp(struct pmcraid_cmd *cmd)
5654{
5655 struct pmcraid_instance *pinstance = cmd->drv_inst;
5656 struct pmcraid_ioarcb *ioarcb = &cmd->ioa_cb->ioarcb;
5657 __be32 time_stamp_len = cpu_to_be32(PMCRAID_TIMESTAMP_LEN);
5658 struct pmcraid_ioadl_desc *ioadl = ioarcb->add_data.u.ioadl;
5659
5660 struct timeval tv;
5661 __le64 timestamp;
5662
5663 do_gettimeofday(&tv);
5664 timestamp = tv.tv_sec * 1000;
5665
5666 pinstance->timestamp_data->timestamp[0] = (__u8)(timestamp);
5667 pinstance->timestamp_data->timestamp[1] = (__u8)((timestamp) >> 8);
5668 pinstance->timestamp_data->timestamp[2] = (__u8)((timestamp) >> 16);
5669 pinstance->timestamp_data->timestamp[3] = (__u8)((timestamp) >> 24);
5670 pinstance->timestamp_data->timestamp[4] = (__u8)((timestamp) >> 32);
5671 pinstance->timestamp_data->timestamp[5] = (__u8)((timestamp) >> 40);
5672
5673 pmcraid_reinit_cmdblk(cmd);
5674 ioarcb->request_type = REQ_TYPE_SCSI;
5675 ioarcb->resource_handle = cpu_to_le32(PMCRAID_IOA_RES_HANDLE);
5676 ioarcb->cdb[0] = PMCRAID_SCSI_SET_TIMESTAMP;
5677 ioarcb->cdb[1] = PMCRAID_SCSI_SERVICE_ACTION;
5678 memcpy(&(ioarcb->cdb[6]), &time_stamp_len, sizeof(time_stamp_len));
5679
5680 ioarcb->ioadl_bus_addr = cpu_to_le64((cmd->ioa_cb_bus_addr) +
5681 offsetof(struct pmcraid_ioarcb,
5682 add_data.u.ioadl[0]));
5683 ioarcb->ioadl_length = cpu_to_le32(sizeof(struct pmcraid_ioadl_desc));
5684 ioarcb->ioarcb_bus_addr &= ~(0x1FULL);
5685
5686 ioarcb->request_flags0 |= NO_LINK_DESCS;
5687 ioarcb->request_flags0 |= TRANSFER_DIR_WRITE;
5688 ioarcb->data_transfer_length =
5689 cpu_to_le32(sizeof(struct pmcraid_timestamp_data));
5690 ioadl = &(ioarcb->add_data.u.ioadl[0]);
5691 ioadl->flags = IOADL_FLAGS_LAST_DESC;
5692 ioadl->address = cpu_to_le64(pinstance->timestamp_data_baddr);
5693 ioadl->data_len = cpu_to_le32(sizeof(struct pmcraid_timestamp_data));
5694
5695 if (!pinstance->timestamp_error) {
5696 pinstance->timestamp_error = 0;
5697 pmcraid_send_cmd(cmd, pmcraid_set_supported_devs,
5698 PMCRAID_INTERNAL_TIMEOUT, pmcraid_timeout_handler);
5699 } else {
5700 pmcraid_send_cmd(cmd, pmcraid_return_cmd,
5701 PMCRAID_INTERNAL_TIMEOUT, pmcraid_timeout_handler);
5702 return;
5703 }
5704}
5705
5706
5707/**
5613 * pmcraid_init_res_table - Initialize the resource table 5708 * pmcraid_init_res_table - Initialize the resource table
5614 * @cmd: pointer to pmcraid command struct 5709 * @cmd: pointer to pmcraid command struct
5615 * 5710 *
@@ -5720,7 +5815,7 @@ static void pmcraid_init_res_table(struct pmcraid_cmd *cmd)
5720 5815
5721 /* release the resource list lock */ 5816 /* release the resource list lock */
5722 spin_unlock_irqrestore(&pinstance->resource_lock, lock_flags); 5817 spin_unlock_irqrestore(&pinstance->resource_lock, lock_flags);
5723 pmcraid_set_supported_devs(cmd); 5818 pmcraid_set_timestamp(cmd);
5724} 5819}
5725 5820
5726/** 5821/**
@@ -6054,10 +6149,10 @@ out_init:
6054static void __exit pmcraid_exit(void) 6149static void __exit pmcraid_exit(void)
6055{ 6150{
6056 pmcraid_netlink_release(); 6151 pmcraid_netlink_release();
6057 class_destroy(pmcraid_class);
6058 unregister_chrdev_region(MKDEV(pmcraid_major, 0), 6152 unregister_chrdev_region(MKDEV(pmcraid_major, 0),
6059 PMCRAID_MAX_ADAPTERS); 6153 PMCRAID_MAX_ADAPTERS);
6060 pci_unregister_driver(&pmcraid_driver); 6154 pci_unregister_driver(&pmcraid_driver);
6155 class_destroy(pmcraid_class);
6061} 6156}
6062 6157
6063module_init(pmcraid_init); 6158module_init(pmcraid_init);