diff options
Diffstat (limited to 'drivers/scsi/hptiop.c')
-rw-r--r-- | drivers/scsi/hptiop.c | 63 |
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 | ||
43 | static char driver_name[] = "hptiop"; | 43 | static char driver_name[] = "hptiop"; |
44 | static const char driver_name_long[] = "RocketRAID 3xxx SATA Controller driver"; | 44 | static const char driver_name_long[] = "RocketRAID 3xxx SATA Controller driver"; |
45 | static const char driver_ver[] = "v1.0 (060426)"; | 45 | static const char driver_ver[] = "v1.2 (070830)"; |
46 | 46 | ||
47 | static void hptiop_host_request_callback(struct hptiop_hba *hba, u32 tag); | 47 | static void hptiop_host_request_callback(struct hptiop_hba *hba, u32 tag); |
48 | static void hptiop_iop_request_callback(struct hptiop_hba *hba, u32 tag); | 48 | static 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 | ||
77 | static void hptiop_request_callback(struct hptiop_hba *hba, u32 tag) | 77 | static 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 | ||
326 | static void hptiop_host_request_callback(struct hptiop_hba *hba, u32 tag) | 326 | static 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 | ||
881 | static struct pci_device_id hptiop_id_table[] = { | 911 | static 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); | |||
910 | module_exit(hptiop_module_exit); | 942 | module_exit(hptiop_module_exit); |
911 | 943 | ||
912 | MODULE_LICENSE("GPL"); | 944 | MODULE_LICENSE("GPL"); |
945 | |||