aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/hptiop.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/hptiop.c')
-rw-r--r--drivers/scsi/hptiop.c63
1 files changed, 48 insertions, 15 deletions
diff --git a/drivers/scsi/hptiop.c b/drivers/scsi/hptiop.c
index 0e579ca45814..8b384fa7f048 100644
--- a/drivers/scsi/hptiop.c
+++ b/drivers/scsi/hptiop.c
@@ -1,6 +1,6 @@
1/* 1/*
2 * HighPoint RR3xxx controller driver for Linux 2 * HighPoint RR3xxx controller driver for Linux
3 * Copyright (C) 2006 HighPoint Technologies, Inc. All Rights Reserved. 3 * Copyright (C) 2006-2007 HighPoint Technologies, Inc. All Rights Reserved.
4 * 4 *
5 * This program is free software; you can redistribute it and/or modify 5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by 6 * it under the terms of the GNU General Public License as published by
@@ -42,7 +42,7 @@ MODULE_DESCRIPTION("HighPoint RocketRAID 3xxx SATA Controller Driver");
42 42
43static char driver_name[] = "hptiop"; 43static char driver_name[] = "hptiop";
44static const char driver_name_long[] = "RocketRAID 3xxx SATA Controller driver"; 44static const char driver_name_long[] = "RocketRAID 3xxx SATA Controller driver";
45static const char driver_ver[] = "v1.0 (060426)"; 45static const char driver_ver[] = "v1.2 (070830)";
46 46
47static void hptiop_host_request_callback(struct hptiop_hba *hba, u32 tag); 47static void hptiop_host_request_callback(struct hptiop_hba *hba, u32 tag);
48static void hptiop_iop_request_callback(struct hptiop_hba *hba, u32 tag); 48static void hptiop_iop_request_callback(struct hptiop_hba *hba, u32 tag);
@@ -76,7 +76,7 @@ static int iop_wait_ready(struct hpt_iopmu __iomem *iop, u32 millisec)
76 76
77static void hptiop_request_callback(struct hptiop_hba *hba, u32 tag) 77static void hptiop_request_callback(struct hptiop_hba *hba, u32 tag)
78{ 78{
79 if ((tag & IOPMU_QUEUE_MASK_HOST_BITS) == IOPMU_QUEUE_ADDR_HOST_BIT) 79 if (tag & IOPMU_QUEUE_ADDR_HOST_BIT)
80 return hptiop_host_request_callback(hba, 80 return hptiop_host_request_callback(hba,
81 tag & ~IOPMU_QUEUE_ADDR_HOST_BIT); 81 tag & ~IOPMU_QUEUE_ADDR_HOST_BIT);
82 else 82 else
@@ -323,12 +323,22 @@ static inline void free_req(struct hptiop_hba *hba, struct hptiop_request *req)
323 hba->req_list = req; 323 hba->req_list = req;
324} 324}
325 325
326static void hptiop_host_request_callback(struct hptiop_hba *hba, u32 tag) 326static void hptiop_host_request_callback(struct hptiop_hba *hba, u32 _tag)
327{ 327{
328 struct hpt_iop_request_scsi_command *req; 328 struct hpt_iop_request_scsi_command *req;
329 struct scsi_cmnd *scp; 329 struct scsi_cmnd *scp;
330 u32 tag;
331
332 if (hba->iopintf_v2) {
333 tag = _tag & ~ IOPMU_QUEUE_REQUEST_RESULT_BIT;
334 req = hba->reqs[tag].req_virt;
335 if (likely(_tag & IOPMU_QUEUE_REQUEST_RESULT_BIT))
336 req->header.result = IOP_RESULT_SUCCESS;
337 } else {
338 tag = _tag;
339 req = hba->reqs[tag].req_virt;
340 }
330 341
331 req = (struct hpt_iop_request_scsi_command *)hba->reqs[tag].req_virt;
332 dprintk("hptiop_host_request_callback: req=%p, type=%d, " 342 dprintk("hptiop_host_request_callback: req=%p, type=%d, "
333 "result=%d, context=0x%x tag=%d\n", 343 "result=%d, context=0x%x tag=%d\n",
334 req, req->header.type, req->header.result, 344 req, req->header.type, req->header.result,
@@ -497,7 +507,7 @@ static int hptiop_queuecommand(struct scsi_cmnd *scp,
497 goto cmd_done; 507 goto cmd_done;
498 } 508 }
499 509
500 req = (struct hpt_iop_request_scsi_command *)_req->req_virt; 510 req = _req->req_virt;
501 511
502 /* build S/G table */ 512 /* build S/G table */
503 sg_count = hptiop_buildsgl(scp, req->sg_list); 513 sg_count = hptiop_buildsgl(scp, req->sg_list);
@@ -521,8 +531,19 @@ static int hptiop_queuecommand(struct scsi_cmnd *scp,
521 531
522 memcpy(req->cdb, scp->cmnd, sizeof(req->cdb)); 532 memcpy(req->cdb, scp->cmnd, sizeof(req->cdb));
523 533
524 writel(IOPMU_QUEUE_ADDR_HOST_BIT | _req->req_shifted_phy, 534 if (hba->iopintf_v2) {
525 &hba->iop->inbound_queue); 535 u32 size_bits;
536 if (req->header.size < 256)
537 size_bits = IOPMU_QUEUE_REQUEST_SIZE_BIT;
538 else if (req->header.size < 512)
539 size_bits = IOPMU_QUEUE_ADDR_HOST_BIT;
540 else
541 size_bits = IOPMU_QUEUE_REQUEST_SIZE_BIT |
542 IOPMU_QUEUE_ADDR_HOST_BIT;
543 writel(_req->req_shifted_phy | size_bits, &hba->iop->inbound_queue);
544 } else
545 writel(_req->req_shifted_phy | IOPMU_QUEUE_ADDR_HOST_BIT,
546 &hba->iop->inbound_queue);
526 547
527 return 0; 548 return 0;
528 549
@@ -688,6 +709,7 @@ static int __devinit hptiop_probe(struct pci_dev *pcidev,
688 hba->pcidev = pcidev; 709 hba->pcidev = pcidev;
689 hba->host = host; 710 hba->host = host;
690 hba->initialized = 0; 711 hba->initialized = 0;
712 hba->iopintf_v2 = 0;
691 713
692 atomic_set(&hba->resetting, 0); 714 atomic_set(&hba->resetting, 0);
693 atomic_set(&hba->reset_count, 0); 715 atomic_set(&hba->reset_count, 0);
@@ -722,8 +744,13 @@ static int __devinit hptiop_probe(struct pci_dev *pcidev,
722 hba->max_request_size = le32_to_cpu(iop_config.request_size); 744 hba->max_request_size = le32_to_cpu(iop_config.request_size);
723 hba->max_sg_descriptors = le32_to_cpu(iop_config.max_sg_count); 745 hba->max_sg_descriptors = le32_to_cpu(iop_config.max_sg_count);
724 hba->firmware_version = le32_to_cpu(iop_config.firmware_version); 746 hba->firmware_version = le32_to_cpu(iop_config.firmware_version);
747 hba->interface_version = le32_to_cpu(iop_config.interface_version);
725 hba->sdram_size = le32_to_cpu(iop_config.sdram_size); 748 hba->sdram_size = le32_to_cpu(iop_config.sdram_size);
726 749
750 if (hba->firmware_version > 0x01020000 ||
751 hba->interface_version > 0x01020000)
752 hba->iopintf_v2 = 1;
753
727 host->max_sectors = le32_to_cpu(iop_config.data_transfer_length) >> 9; 754 host->max_sectors = le32_to_cpu(iop_config.data_transfer_length) >> 9;
728 host->max_id = le32_to_cpu(iop_config.max_devices); 755 host->max_id = le32_to_cpu(iop_config.max_devices);
729 host->sg_tablesize = le32_to_cpu(iop_config.max_sg_count); 756 host->sg_tablesize = le32_to_cpu(iop_config.max_sg_count);
@@ -731,8 +758,15 @@ static int __devinit hptiop_probe(struct pci_dev *pcidev,
731 host->cmd_per_lun = le32_to_cpu(iop_config.max_requests); 758 host->cmd_per_lun = le32_to_cpu(iop_config.max_requests);
732 host->max_cmd_len = 16; 759 host->max_cmd_len = 16;
733 760
734 set_config.vbus_id = cpu_to_le32(host->host_no); 761 req_size = sizeof(struct hpt_iop_request_scsi_command)
762 + sizeof(struct hpt_iopsg) * (hba->max_sg_descriptors - 1);
763 if ((req_size & 0x1f) != 0)
764 req_size = (req_size + 0x1f) & ~0x1f;
765
766 memset(&set_config, 0, sizeof(struct hpt_iop_request_set_config));
735 set_config.iop_id = cpu_to_le32(host->host_no); 767 set_config.iop_id = cpu_to_le32(host->host_no);
768 set_config.vbus_id = cpu_to_le16(host->host_no);
769 set_config.max_host_request_size = cpu_to_le16(req_size);
736 770
737 if (iop_set_config(hba, &set_config)) { 771 if (iop_set_config(hba, &set_config)) {
738 printk(KERN_ERR "scsi%d: set config failed\n", 772 printk(KERN_ERR "scsi%d: set config failed\n",
@@ -750,10 +784,6 @@ static int __devinit hptiop_probe(struct pci_dev *pcidev,
750 } 784 }
751 785
752 /* Allocate request mem */ 786 /* Allocate request mem */
753 req_size = sizeof(struct hpt_iop_request_scsi_command)
754 + sizeof(struct hpt_iopsg) * (hba->max_sg_descriptors - 1);
755 if ((req_size& 0x1f) != 0)
756 req_size = (req_size + 0x1f) & ~0x1f;
757 787
758 dprintk("req_size=%d, max_requests=%d\n", req_size, hba->max_requests); 788 dprintk("req_size=%d, max_requests=%d\n", req_size, hba->max_requests);
759 789
@@ -879,8 +909,10 @@ static void hptiop_remove(struct pci_dev *pcidev)
879} 909}
880 910
881static struct pci_device_id hptiop_id_table[] = { 911static struct pci_device_id hptiop_id_table[] = {
882 { PCI_DEVICE(0x1103, 0x3220) }, 912 { PCI_VDEVICE(TTI, 0x3220) },
883 { PCI_DEVICE(0x1103, 0x3320) }, 913 { PCI_VDEVICE(TTI, 0x3320) },
914 { PCI_VDEVICE(TTI, 0x3520) },
915 { PCI_VDEVICE(TTI, 0x4320) },
884 {}, 916 {},
885}; 917};
886 918
@@ -910,3 +942,4 @@ module_init(hptiop_module_init);
910module_exit(hptiop_module_exit); 942module_exit(hptiop_module_exit);
911 943
912MODULE_LICENSE("GPL"); 944MODULE_LICENSE("GPL");
945