.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
---|
1 | 2 | /*************************************************************************** |
---|
2 | 3 | dpti.c - description |
---|
3 | 4 | ------------------- |
---|
.. | .. |
---|
7 | 8 | July 30, 2001 First version being submitted |
---|
8 | 9 | for inclusion in the kernel. V2.4 |
---|
9 | 10 | |
---|
10 | | - See Documentation/scsi/dpti.txt for history, notes, license info |
---|
| 11 | + See Documentation/scsi/dpti.rst for history, notes, license info |
---|
11 | 12 | and credits |
---|
12 | 13 | ***************************************************************************/ |
---|
13 | 14 | |
---|
14 | 15 | /*************************************************************************** |
---|
15 | 16 | * * |
---|
16 | | - * This program is free software; you can redistribute it and/or modify * |
---|
17 | | - * it under the terms of the GNU General Public License as published by * |
---|
18 | | - * the Free Software Foundation; either version 2 of the License, or * |
---|
19 | | - * (at your option) any later version. * |
---|
20 | 17 | * * |
---|
21 | 18 | ***************************************************************************/ |
---|
22 | 19 | /*************************************************************************** |
---|
.. | .. |
---|
30 | 27 | /*#define UARTDELAY 1 */ |
---|
31 | 28 | |
---|
32 | 29 | #include <linux/module.h> |
---|
| 30 | +#include <linux/pgtable.h> |
---|
33 | 31 | |
---|
34 | 32 | MODULE_AUTHOR("Deanna Bonds, with _lots_ of help from Mark Salyzyn"); |
---|
35 | 33 | MODULE_DESCRIPTION("Adaptec I2O RAID Driver"); |
---|
.. | .. |
---|
58 | 56 | #include <linux/mutex.h> |
---|
59 | 57 | |
---|
60 | 58 | #include <asm/processor.h> /* for boot_cpu_data */ |
---|
61 | | -#include <asm/pgtable.h> |
---|
62 | | -#include <asm/io.h> /* for virt_to_bus, etc. */ |
---|
| 59 | +#include <asm/io.h> |
---|
63 | 60 | |
---|
64 | 61 | #include <scsi/scsi.h> |
---|
65 | 62 | #include <scsi/scsi_cmnd.h> |
---|
.. | .. |
---|
411 | 408 | static int adpt_slave_configure(struct scsi_device * device) |
---|
412 | 409 | { |
---|
413 | 410 | struct Scsi_Host *host = device->host; |
---|
414 | | - adpt_hba* pHba; |
---|
415 | | - |
---|
416 | | - pHba = (adpt_hba *) host->hostdata[0]; |
---|
417 | 411 | |
---|
418 | 412 | if (host->can_queue && device->tagged_supported) { |
---|
419 | 413 | scsi_change_queue_depth(device, |
---|
.. | .. |
---|
588 | 582 | return 0; |
---|
589 | 583 | } |
---|
590 | 584 | |
---|
591 | | -/* |
---|
592 | | - * Turn a struct scsi_cmnd * into a unique 32 bit 'context'. |
---|
593 | | - */ |
---|
594 | | -static u32 adpt_cmd_to_context(struct scsi_cmnd *cmd) |
---|
595 | | -{ |
---|
596 | | - return (u32)cmd->serial_number; |
---|
597 | | -} |
---|
598 | | - |
---|
599 | | -/* |
---|
600 | | - * Go from a u32 'context' to a struct scsi_cmnd * . |
---|
601 | | - * This could probably be made more efficient. |
---|
602 | | - */ |
---|
603 | | -static struct scsi_cmnd * |
---|
604 | | - adpt_cmd_from_context(adpt_hba * pHba, u32 context) |
---|
605 | | -{ |
---|
606 | | - struct scsi_cmnd * cmd; |
---|
607 | | - struct scsi_device * d; |
---|
608 | | - |
---|
609 | | - if (context == 0) |
---|
610 | | - return NULL; |
---|
611 | | - |
---|
612 | | - spin_unlock(pHba->host->host_lock); |
---|
613 | | - shost_for_each_device(d, pHba->host) { |
---|
614 | | - unsigned long flags; |
---|
615 | | - spin_lock_irqsave(&d->list_lock, flags); |
---|
616 | | - list_for_each_entry(cmd, &d->cmd_list, list) { |
---|
617 | | - if (((u32)cmd->serial_number == context)) { |
---|
618 | | - spin_unlock_irqrestore(&d->list_lock, flags); |
---|
619 | | - scsi_device_put(d); |
---|
620 | | - spin_lock(pHba->host->host_lock); |
---|
621 | | - return cmd; |
---|
622 | | - } |
---|
623 | | - } |
---|
624 | | - spin_unlock_irqrestore(&d->list_lock, flags); |
---|
625 | | - } |
---|
626 | | - spin_lock(pHba->host->host_lock); |
---|
627 | | - |
---|
628 | | - return NULL; |
---|
629 | | -} |
---|
630 | | - |
---|
631 | | -/* |
---|
632 | | - * Turn a pointer to ioctl reply data into an u32 'context' |
---|
633 | | - */ |
---|
634 | | -static u32 adpt_ioctl_to_context(adpt_hba * pHba, void *reply) |
---|
635 | | -{ |
---|
636 | | -#if BITS_PER_LONG == 32 |
---|
637 | | - return (u32)(unsigned long)reply; |
---|
638 | | -#else |
---|
639 | | - ulong flags = 0; |
---|
640 | | - u32 nr, i; |
---|
641 | | - |
---|
642 | | - spin_lock_irqsave(pHba->host->host_lock, flags); |
---|
643 | | - nr = ARRAY_SIZE(pHba->ioctl_reply_context); |
---|
644 | | - for (i = 0; i < nr; i++) { |
---|
645 | | - if (pHba->ioctl_reply_context[i] == NULL) { |
---|
646 | | - pHba->ioctl_reply_context[i] = reply; |
---|
647 | | - break; |
---|
648 | | - } |
---|
649 | | - } |
---|
650 | | - spin_unlock_irqrestore(pHba->host->host_lock, flags); |
---|
651 | | - if (i >= nr) { |
---|
652 | | - printk(KERN_WARNING"%s: Too many outstanding " |
---|
653 | | - "ioctl commands\n", pHba->name); |
---|
654 | | - return (u32)-1; |
---|
655 | | - } |
---|
656 | | - |
---|
657 | | - return i; |
---|
658 | | -#endif |
---|
659 | | -} |
---|
660 | | - |
---|
661 | | -/* |
---|
662 | | - * Go from an u32 'context' to a pointer to ioctl reply data. |
---|
663 | | - */ |
---|
664 | | -static void *adpt_ioctl_from_context(adpt_hba *pHba, u32 context) |
---|
665 | | -{ |
---|
666 | | -#if BITS_PER_LONG == 32 |
---|
667 | | - return (void *)(unsigned long)context; |
---|
668 | | -#else |
---|
669 | | - void *p = pHba->ioctl_reply_context[context]; |
---|
670 | | - pHba->ioctl_reply_context[context] = NULL; |
---|
671 | | - |
---|
672 | | - return p; |
---|
673 | | -#endif |
---|
674 | | -} |
---|
675 | | - |
---|
676 | 585 | /*=========================================================================== |
---|
677 | 586 | * Error Handling routines |
---|
678 | 587 | *=========================================================================== |
---|
.. | .. |
---|
685 | 594 | u32 msg[5]; |
---|
686 | 595 | int rcode; |
---|
687 | 596 | |
---|
688 | | - if(cmd->serial_number == 0){ |
---|
689 | | - return FAILED; |
---|
690 | | - } |
---|
691 | 597 | pHba = (adpt_hba*) cmd->device->host->hostdata[0]; |
---|
692 | 598 | printk(KERN_INFO"%s: Trying to Abort\n",pHba->name); |
---|
693 | 599 | if ((dptdevice = (void*) (cmd->device->hostdata)) == NULL) { |
---|
.. | .. |
---|
699 | 605 | msg[0] = FIVE_WORD_MSG_SIZE|SGL_OFFSET_0; |
---|
700 | 606 | msg[1] = I2O_CMD_SCSI_ABORT<<24|HOST_TID<<12|dptdevice->tid; |
---|
701 | 607 | msg[2] = 0; |
---|
702 | | - msg[3]= 0; |
---|
703 | | - msg[4] = adpt_cmd_to_context(cmd); |
---|
| 608 | + msg[3]= 0; |
---|
| 609 | + /* Add 1 to avoid firmware treating it as invalid command */ |
---|
| 610 | + msg[4] = cmd->request->tag + 1; |
---|
704 | 611 | if (pHba->host) |
---|
705 | 612 | spin_lock_irq(pHba->host->host_lock); |
---|
706 | 613 | rcode = adpt_i2o_post_wait(pHba, msg, sizeof(msg), FOREVER); |
---|
.. | .. |
---|
862 | 769 | } |
---|
863 | 770 | pHba->state &= ~DPTI_STATE_RESET; |
---|
864 | 771 | |
---|
865 | | - adpt_fail_posted_scbs(pHba); |
---|
| 772 | + scsi_host_complete_all_commands(pHba->host, DID_RESET); |
---|
866 | 773 | return 0; /* return success */ |
---|
867 | 774 | } |
---|
868 | 775 | |
---|
.. | .. |
---|
877 | 784 | adpt_hba *pHba, *pNext; |
---|
878 | 785 | struct adpt_i2o_post_wait_data *p1, *old; |
---|
879 | 786 | |
---|
880 | | - printk(KERN_INFO"Shutting down Adaptec I2O controllers.\n"); |
---|
881 | | - printk(KERN_INFO" This could take a few minutes if there are many devices attached\n"); |
---|
| 787 | + printk(KERN_INFO "Shutting down Adaptec I2O controllers.\n"); |
---|
| 788 | + printk(KERN_INFO " This could take a few minutes if there are many devices attached\n"); |
---|
882 | 789 | /* Delete all IOPs from the controller chain */ |
---|
883 | 790 | /* They should have already been released by the |
---|
884 | 791 | * scsi-core |
---|
.. | .. |
---|
901 | 808 | // spin_unlock_irqrestore(&adpt_post_wait_lock, flags); |
---|
902 | 809 | adpt_post_wait_queue = NULL; |
---|
903 | 810 | |
---|
904 | | - printk(KERN_INFO "Adaptec I2O controllers down.\n"); |
---|
| 811 | + printk(KERN_INFO "Adaptec I2O controllers down.\n"); |
---|
905 | 812 | } |
---|
906 | 813 | |
---|
907 | 814 | static int adpt_install_hba(struct scsi_host_template* sht, struct pci_dev* pDev) |
---|
.. | .. |
---|
934 | 841 | * See if we should enable dma64 mode. |
---|
935 | 842 | */ |
---|
936 | 843 | if (sizeof(dma_addr_t) > 4 && |
---|
937 | | - pci_set_dma_mask(pDev, DMA_BIT_MASK(64)) == 0) { |
---|
938 | | - if (dma_get_required_mask(&pDev->dev) > DMA_BIT_MASK(32)) |
---|
939 | | - dma64 = 1; |
---|
940 | | - } |
---|
941 | | - if (!dma64 && pci_set_dma_mask(pDev, DMA_BIT_MASK(32)) != 0) |
---|
| 844 | + dma_get_required_mask(&pDev->dev) > DMA_BIT_MASK(32) && |
---|
| 845 | + dma_set_mask(&pDev->dev, DMA_BIT_MASK(64)) == 0) |
---|
| 846 | + dma64 = 1; |
---|
| 847 | + |
---|
| 848 | + if (!dma64 && dma_set_mask(&pDev->dev, DMA_BIT_MASK(32)) != 0) |
---|
942 | 849 | return -EINVAL; |
---|
943 | 850 | |
---|
944 | 851 | /* adapter only supports message blocks below 4GB */ |
---|
945 | | - pci_set_consistent_dma_mask(pDev, DMA_BIT_MASK(32)); |
---|
| 852 | + dma_set_coherent_mask(&pDev->dev, DMA_BIT_MASK(32)); |
---|
946 | 853 | |
---|
947 | 854 | base_addr0_phys = pci_resource_start(pDev,0); |
---|
948 | 855 | hba_map0_area_size = pci_resource_len(pDev,0); |
---|
.. | .. |
---|
1165 | 1072 | { |
---|
1166 | 1073 | struct adpt_device* d; |
---|
1167 | 1074 | |
---|
1168 | | - if(chan < 0 || chan >= MAX_CHANNEL) |
---|
| 1075 | + if (chan >= MAX_CHANNEL) |
---|
1169 | 1076 | return NULL; |
---|
1170 | 1077 | |
---|
1171 | 1078 | d = pHba->channel[chan].device[id]; |
---|
.. | .. |
---|
1376 | 1283 | printk(KERN_ERR"IOP reset failed - no free memory.\n"); |
---|
1377 | 1284 | return -ENOMEM; |
---|
1378 | 1285 | } |
---|
1379 | | - memset(status,0,4); |
---|
1380 | 1286 | |
---|
1381 | 1287 | msg[0]=EIGHT_WORD_MSG_SIZE|SGL_OFFSET_0; |
---|
1382 | 1288 | msg[1]=I2O_CMD_ADAPTER_RESET<<24|HOST_TID<<12|ADAPTER_TID; |
---|
.. | .. |
---|
1697 | 1603 | return 0; |
---|
1698 | 1604 | } |
---|
1699 | 1605 | |
---|
1700 | | - |
---|
1701 | | -static int adpt_i2o_passthru(adpt_hba* pHba, u32 __user *arg) |
---|
1702 | | -{ |
---|
1703 | | - u32 msg[MAX_MESSAGE_SIZE]; |
---|
1704 | | - u32* reply = NULL; |
---|
1705 | | - u32 size = 0; |
---|
1706 | | - u32 reply_size = 0; |
---|
1707 | | - u32 __user *user_msg = arg; |
---|
1708 | | - u32 __user * user_reply = NULL; |
---|
1709 | | - void **sg_list = NULL; |
---|
1710 | | - u32 sg_offset = 0; |
---|
1711 | | - u32 sg_count = 0; |
---|
1712 | | - int sg_index = 0; |
---|
1713 | | - u32 i = 0; |
---|
1714 | | - u32 rcode = 0; |
---|
1715 | | - void *p = NULL; |
---|
1716 | | - dma_addr_t addr; |
---|
1717 | | - ulong flags = 0; |
---|
1718 | | - |
---|
1719 | | - memset(&msg, 0, MAX_MESSAGE_SIZE*4); |
---|
1720 | | - // get user msg size in u32s |
---|
1721 | | - if(get_user(size, &user_msg[0])){ |
---|
1722 | | - return -EFAULT; |
---|
1723 | | - } |
---|
1724 | | - size = size>>16; |
---|
1725 | | - |
---|
1726 | | - user_reply = &user_msg[size]; |
---|
1727 | | - if(size > MAX_MESSAGE_SIZE){ |
---|
1728 | | - return -EFAULT; |
---|
1729 | | - } |
---|
1730 | | - size *= 4; // Convert to bytes |
---|
1731 | | - |
---|
1732 | | - /* Copy in the user's I2O command */ |
---|
1733 | | - if(copy_from_user(msg, user_msg, size)) { |
---|
1734 | | - return -EFAULT; |
---|
1735 | | - } |
---|
1736 | | - get_user(reply_size, &user_reply[0]); |
---|
1737 | | - reply_size = reply_size>>16; |
---|
1738 | | - if(reply_size > REPLY_FRAME_SIZE){ |
---|
1739 | | - reply_size = REPLY_FRAME_SIZE; |
---|
1740 | | - } |
---|
1741 | | - reply_size *= 4; |
---|
1742 | | - reply = kzalloc(REPLY_FRAME_SIZE*4, GFP_KERNEL); |
---|
1743 | | - if(reply == NULL) { |
---|
1744 | | - printk(KERN_WARNING"%s: Could not allocate reply buffer\n",pHba->name); |
---|
1745 | | - return -ENOMEM; |
---|
1746 | | - } |
---|
1747 | | - sg_offset = (msg[0]>>4)&0xf; |
---|
1748 | | - msg[2] = 0x40000000; // IOCTL context |
---|
1749 | | - msg[3] = adpt_ioctl_to_context(pHba, reply); |
---|
1750 | | - if (msg[3] == (u32)-1) { |
---|
1751 | | - rcode = -EBUSY; |
---|
1752 | | - goto free; |
---|
1753 | | - } |
---|
1754 | | - |
---|
1755 | | - sg_list = kcalloc(pHba->sg_tablesize, sizeof(*sg_list), GFP_KERNEL); |
---|
1756 | | - if (!sg_list) { |
---|
1757 | | - rcode = -ENOMEM; |
---|
1758 | | - goto free; |
---|
1759 | | - } |
---|
1760 | | - if(sg_offset) { |
---|
1761 | | - // TODO add 64 bit API |
---|
1762 | | - struct sg_simple_element *sg = (struct sg_simple_element*) (msg+sg_offset); |
---|
1763 | | - sg_count = (size - sg_offset*4) / sizeof(struct sg_simple_element); |
---|
1764 | | - if (sg_count > pHba->sg_tablesize){ |
---|
1765 | | - printk(KERN_DEBUG"%s:IOCTL SG List too large (%u)\n", pHba->name,sg_count); |
---|
1766 | | - rcode = -EINVAL; |
---|
1767 | | - goto free; |
---|
1768 | | - } |
---|
1769 | | - |
---|
1770 | | - for(i = 0; i < sg_count; i++) { |
---|
1771 | | - int sg_size; |
---|
1772 | | - |
---|
1773 | | - if (!(sg[i].flag_count & 0x10000000 /*I2O_SGL_FLAGS_SIMPLE_ADDRESS_ELEMENT*/)) { |
---|
1774 | | - printk(KERN_DEBUG"%s:Bad SG element %d - not simple (%x)\n",pHba->name,i, sg[i].flag_count); |
---|
1775 | | - rcode = -EINVAL; |
---|
1776 | | - goto cleanup; |
---|
1777 | | - } |
---|
1778 | | - sg_size = sg[i].flag_count & 0xffffff; |
---|
1779 | | - /* Allocate memory for the transfer */ |
---|
1780 | | - p = dma_alloc_coherent(&pHba->pDev->dev, sg_size, &addr, GFP_KERNEL); |
---|
1781 | | - if(!p) { |
---|
1782 | | - printk(KERN_DEBUG"%s: Could not allocate SG buffer - size = %d buffer number %d of %d\n", |
---|
1783 | | - pHba->name,sg_size,i,sg_count); |
---|
1784 | | - rcode = -ENOMEM; |
---|
1785 | | - goto cleanup; |
---|
1786 | | - } |
---|
1787 | | - sg_list[sg_index++] = p; // sglist indexed with input frame, not our internal frame. |
---|
1788 | | - /* Copy in the user's SG buffer if necessary */ |
---|
1789 | | - if(sg[i].flag_count & 0x04000000 /*I2O_SGL_FLAGS_DIR*/) { |
---|
1790 | | - // sg_simple_element API is 32 bit |
---|
1791 | | - if (copy_from_user(p,(void __user *)(ulong)sg[i].addr_bus, sg_size)) { |
---|
1792 | | - printk(KERN_DEBUG"%s: Could not copy SG buf %d FROM user\n",pHba->name,i); |
---|
1793 | | - rcode = -EFAULT; |
---|
1794 | | - goto cleanup; |
---|
1795 | | - } |
---|
1796 | | - } |
---|
1797 | | - /* sg_simple_element API is 32 bit, but addr < 4GB */ |
---|
1798 | | - sg[i].addr_bus = addr; |
---|
1799 | | - } |
---|
1800 | | - } |
---|
1801 | | - |
---|
1802 | | - do { |
---|
1803 | | - /* |
---|
1804 | | - * Stop any new commands from enterring the |
---|
1805 | | - * controller while processing the ioctl |
---|
1806 | | - */ |
---|
1807 | | - if (pHba->host) { |
---|
1808 | | - scsi_block_requests(pHba->host); |
---|
1809 | | - spin_lock_irqsave(pHba->host->host_lock, flags); |
---|
1810 | | - } |
---|
1811 | | - rcode = adpt_i2o_post_wait(pHba, msg, size, FOREVER); |
---|
1812 | | - if (rcode != 0) |
---|
1813 | | - printk("adpt_i2o_passthru: post wait failed %d %p\n", |
---|
1814 | | - rcode, reply); |
---|
1815 | | - if (pHba->host) { |
---|
1816 | | - spin_unlock_irqrestore(pHba->host->host_lock, flags); |
---|
1817 | | - scsi_unblock_requests(pHba->host); |
---|
1818 | | - } |
---|
1819 | | - } while (rcode == -ETIMEDOUT); |
---|
1820 | | - |
---|
1821 | | - if(rcode){ |
---|
1822 | | - goto cleanup; |
---|
1823 | | - } |
---|
1824 | | - |
---|
1825 | | - if(sg_offset) { |
---|
1826 | | - /* Copy back the Scatter Gather buffers back to user space */ |
---|
1827 | | - u32 j; |
---|
1828 | | - // TODO add 64 bit API |
---|
1829 | | - struct sg_simple_element* sg; |
---|
1830 | | - int sg_size; |
---|
1831 | | - |
---|
1832 | | - // re-acquire the original message to handle correctly the sg copy operation |
---|
1833 | | - memset(&msg, 0, MAX_MESSAGE_SIZE*4); |
---|
1834 | | - // get user msg size in u32s |
---|
1835 | | - if(get_user(size, &user_msg[0])){ |
---|
1836 | | - rcode = -EFAULT; |
---|
1837 | | - goto cleanup; |
---|
1838 | | - } |
---|
1839 | | - size = size>>16; |
---|
1840 | | - size *= 4; |
---|
1841 | | - if (size > MAX_MESSAGE_SIZE) { |
---|
1842 | | - rcode = -EINVAL; |
---|
1843 | | - goto cleanup; |
---|
1844 | | - } |
---|
1845 | | - /* Copy in the user's I2O command */ |
---|
1846 | | - if (copy_from_user (msg, user_msg, size)) { |
---|
1847 | | - rcode = -EFAULT; |
---|
1848 | | - goto cleanup; |
---|
1849 | | - } |
---|
1850 | | - sg_count = (size - sg_offset*4) / sizeof(struct sg_simple_element); |
---|
1851 | | - |
---|
1852 | | - // TODO add 64 bit API |
---|
1853 | | - sg = (struct sg_simple_element*)(msg + sg_offset); |
---|
1854 | | - for (j = 0; j < sg_count; j++) { |
---|
1855 | | - /* Copy out the SG list to user's buffer if necessary */ |
---|
1856 | | - if(! (sg[j].flag_count & 0x4000000 /*I2O_SGL_FLAGS_DIR*/)) { |
---|
1857 | | - sg_size = sg[j].flag_count & 0xffffff; |
---|
1858 | | - // sg_simple_element API is 32 bit |
---|
1859 | | - if (copy_to_user((void __user *)(ulong)sg[j].addr_bus,sg_list[j], sg_size)) { |
---|
1860 | | - printk(KERN_WARNING"%s: Could not copy %p TO user %x\n",pHba->name, sg_list[j], sg[j].addr_bus); |
---|
1861 | | - rcode = -EFAULT; |
---|
1862 | | - goto cleanup; |
---|
1863 | | - } |
---|
1864 | | - } |
---|
1865 | | - } |
---|
1866 | | - } |
---|
1867 | | - |
---|
1868 | | - /* Copy back the reply to user space */ |
---|
1869 | | - if (reply_size) { |
---|
1870 | | - // we wrote our own values for context - now restore the user supplied ones |
---|
1871 | | - if(copy_from_user(reply+2, user_msg+2, sizeof(u32)*2)) { |
---|
1872 | | - printk(KERN_WARNING"%s: Could not copy message context FROM user\n",pHba->name); |
---|
1873 | | - rcode = -EFAULT; |
---|
1874 | | - } |
---|
1875 | | - if(copy_to_user(user_reply, reply, reply_size)) { |
---|
1876 | | - printk(KERN_WARNING"%s: Could not copy reply TO user\n",pHba->name); |
---|
1877 | | - rcode = -EFAULT; |
---|
1878 | | - } |
---|
1879 | | - } |
---|
1880 | | - |
---|
1881 | | - |
---|
1882 | | -cleanup: |
---|
1883 | | - if (rcode != -ETIME && rcode != -EINTR) { |
---|
1884 | | - struct sg_simple_element *sg = |
---|
1885 | | - (struct sg_simple_element*) (msg +sg_offset); |
---|
1886 | | - while(sg_index) { |
---|
1887 | | - if(sg_list[--sg_index]) { |
---|
1888 | | - dma_free_coherent(&pHba->pDev->dev, |
---|
1889 | | - sg[sg_index].flag_count & 0xffffff, |
---|
1890 | | - sg_list[sg_index], |
---|
1891 | | - sg[sg_index].addr_bus); |
---|
1892 | | - } |
---|
1893 | | - } |
---|
1894 | | - } |
---|
1895 | | - |
---|
1896 | | -free: |
---|
1897 | | - kfree(sg_list); |
---|
1898 | | - kfree(reply); |
---|
1899 | | - return rcode; |
---|
1900 | | -} |
---|
1901 | | - |
---|
1902 | 1606 | #if defined __ia64__ |
---|
1903 | 1607 | static void adpt_ia64_info(sysInfo_S* si) |
---|
1904 | 1608 | { |
---|
.. | .. |
---|
2025 | 1729 | return -EFAULT; |
---|
2026 | 1730 | } |
---|
2027 | 1731 | break; |
---|
2028 | | - case I2OUSRCMD: |
---|
2029 | | - return adpt_i2o_passthru(pHba, argp); |
---|
2030 | 1732 | |
---|
2031 | 1733 | case DPT_CTRLINFO:{ |
---|
2032 | 1734 | drvrHBAinfo_S HbaInfo; |
---|
.. | .. |
---|
2163 | 1865 | } else { |
---|
2164 | 1866 | /* Ick, we should *never* be here */ |
---|
2165 | 1867 | printk(KERN_ERR "dpti: reply frame not from pool\n"); |
---|
2166 | | - reply = (u8 *)bus_to_virt(m); |
---|
| 1868 | + continue; |
---|
2167 | 1869 | } |
---|
2168 | 1870 | |
---|
2169 | 1871 | if (readl(reply) & MSG_FAIL) { |
---|
.. | .. |
---|
2183 | 1885 | adpt_send_nop(pHba, old_m); |
---|
2184 | 1886 | } |
---|
2185 | 1887 | context = readl(reply+8); |
---|
2186 | | - if(context & 0x40000000){ // IOCTL |
---|
2187 | | - void *p = adpt_ioctl_from_context(pHba, readl(reply+12)); |
---|
2188 | | - if( p != NULL) { |
---|
2189 | | - memcpy_fromio(p, reply, REPLY_FRAME_SIZE * 4); |
---|
2190 | | - } |
---|
2191 | | - // All IOCTLs will also be post wait |
---|
2192 | | - } |
---|
2193 | 1888 | if(context & 0x80000000){ // Post wait message |
---|
2194 | 1889 | status = readl(reply+16); |
---|
2195 | 1890 | if(status >> 24){ |
---|
.. | .. |
---|
2197 | 1892 | } else { |
---|
2198 | 1893 | status = I2O_POST_WAIT_OK; |
---|
2199 | 1894 | } |
---|
2200 | | - if(!(context & 0x40000000)) { |
---|
2201 | | - cmd = adpt_cmd_from_context(pHba, |
---|
2202 | | - readl(reply+12)); |
---|
2203 | | - if(cmd != NULL) { |
---|
2204 | | - printk(KERN_WARNING"%s: Apparent SCSI cmd in Post Wait Context - cmd=%p context=%x\n", pHba->name, cmd, context); |
---|
2205 | | - } |
---|
| 1895 | + /* |
---|
| 1896 | + * The request tag is one less than the command tag |
---|
| 1897 | + * as the firmware might treat a 0 tag as invalid |
---|
| 1898 | + */ |
---|
| 1899 | + cmd = scsi_host_find_tag(pHba->host, |
---|
| 1900 | + readl(reply + 12) - 1); |
---|
| 1901 | + if(cmd != NULL) { |
---|
| 1902 | + printk(KERN_WARNING"%s: Apparent SCSI cmd in Post Wait Context - cmd=%p context=%x\n", pHba->name, cmd, context); |
---|
2206 | 1903 | } |
---|
2207 | 1904 | adpt_i2o_post_wait_complete(context, status); |
---|
2208 | 1905 | } else { // SCSI message |
---|
2209 | | - cmd = adpt_cmd_from_context (pHba, readl(reply+12)); |
---|
| 1906 | + /* |
---|
| 1907 | + * The request tag is one less than the command tag |
---|
| 1908 | + * as the firmware might treat a 0 tag as invalid |
---|
| 1909 | + */ |
---|
| 1910 | + cmd = scsi_host_find_tag(pHba->host, |
---|
| 1911 | + readl(reply + 12) - 1); |
---|
2210 | 1912 | if(cmd != NULL){ |
---|
2211 | 1913 | scsi_dma_unmap(cmd); |
---|
2212 | | - if(cmd->serial_number != 0) { // If not timedout |
---|
2213 | | - adpt_i2o_to_scsi(reply, cmd); |
---|
2214 | | - } |
---|
| 1914 | + adpt_i2o_scsi_complete(reply, cmd); |
---|
2215 | 1915 | } |
---|
2216 | 1916 | } |
---|
2217 | 1917 | writel(m, pHba->reply_port); |
---|
.. | .. |
---|
2277 | 1977 | // I2O_CMD_SCSI_EXEC |
---|
2278 | 1978 | msg[1] = ((0xff<<24)|(HOST_TID<<12)|d->tid); |
---|
2279 | 1979 | msg[2] = 0; |
---|
2280 | | - msg[3] = adpt_cmd_to_context(cmd); /* Want SCSI control block back */ |
---|
| 1980 | + /* Add 1 to avoid firmware treating it as invalid command */ |
---|
| 1981 | + msg[3] = cmd->request->tag + 1; |
---|
2281 | 1982 | // Our cards use the transaction context as the tag for queueing |
---|
2282 | 1983 | // Adaptec/DPT Private stuff |
---|
2283 | 1984 | msg[4] = I2O_CMD_SCSI_EXEC|(DPT_ORGANIZATION_ID<<16); |
---|
.. | .. |
---|
2372 | 2073 | host->unique_id = (u32)sys_tbl_pa + pHba->unit; |
---|
2373 | 2074 | host->sg_tablesize = pHba->sg_tablesize; |
---|
2374 | 2075 | host->can_queue = pHba->post_fifo_size; |
---|
2375 | | - host->use_cmd_list = 1; |
---|
2376 | 2076 | |
---|
2377 | 2077 | return 0; |
---|
2378 | 2078 | } |
---|
2379 | 2079 | |
---|
2380 | 2080 | |
---|
2381 | | -static s32 adpt_i2o_to_scsi(void __iomem *reply, struct scsi_cmnd* cmd) |
---|
| 2081 | +static void adpt_i2o_scsi_complete(void __iomem *reply, struct scsi_cmnd *cmd) |
---|
2382 | 2082 | { |
---|
2383 | 2083 | adpt_hba* pHba; |
---|
2384 | 2084 | u32 hba_status; |
---|
.. | .. |
---|
2496 | 2196 | if(cmd->scsi_done != NULL){ |
---|
2497 | 2197 | cmd->scsi_done(cmd); |
---|
2498 | 2198 | } |
---|
2499 | | - return cmd->result; |
---|
2500 | 2199 | } |
---|
2501 | 2200 | |
---|
2502 | 2201 | |
---|
.. | .. |
---|
2684 | 2383 | return 0; |
---|
2685 | 2384 | } |
---|
2686 | 2385 | |
---|
2687 | | -static void adpt_fail_posted_scbs(adpt_hba* pHba) |
---|
2688 | | -{ |
---|
2689 | | - struct scsi_cmnd* cmd = NULL; |
---|
2690 | | - struct scsi_device* d = NULL; |
---|
2691 | | - |
---|
2692 | | - shost_for_each_device(d, pHba->host) { |
---|
2693 | | - unsigned long flags; |
---|
2694 | | - spin_lock_irqsave(&d->list_lock, flags); |
---|
2695 | | - list_for_each_entry(cmd, &d->cmd_list, list) { |
---|
2696 | | - if(cmd->serial_number == 0){ |
---|
2697 | | - continue; |
---|
2698 | | - } |
---|
2699 | | - cmd->result = (DID_OK << 16) | (QUEUE_FULL <<1); |
---|
2700 | | - cmd->scsi_done(cmd); |
---|
2701 | | - } |
---|
2702 | | - spin_unlock_irqrestore(&d->list_lock, flags); |
---|
2703 | | - } |
---|
2704 | | -} |
---|
2705 | | - |
---|
2706 | | - |
---|
2707 | 2386 | /*============================================================================ |
---|
2708 | 2387 | * Routines from i2o subsystem |
---|
2709 | 2388 | *============================================================================ |
---|
.. | .. |
---|
2843 | 2522 | pHba->name); |
---|
2844 | 2523 | return -ENOMEM; |
---|
2845 | 2524 | } |
---|
2846 | | - memset(status, 0, 4); |
---|
2847 | 2525 | |
---|
2848 | 2526 | writel(EIGHT_WORD_MSG_SIZE| SGL_OFFSET_6, &msg[0]); |
---|
2849 | 2527 | writel(I2O_CMD_OUTBOUND_INIT<<24 | HOST_TID<<12 | ADAPTER_TID, &msg[1]); |
---|
.. | .. |
---|
2897 | 2575 | printk(KERN_ERR "%s: Could not allocate reply pool\n", pHba->name); |
---|
2898 | 2576 | return -ENOMEM; |
---|
2899 | 2577 | } |
---|
2900 | | - memset(pHba->reply_pool, 0 , pHba->reply_fifo_size * REPLY_FRAME_SIZE * 4); |
---|
2901 | 2578 | |
---|
2902 | 2579 | for(i = 0; i < pHba->reply_fifo_size; i++) { |
---|
2903 | 2580 | writel(pHba->reply_pool_pa + (i * REPLY_FRAME_SIZE * 4), |
---|
.. | .. |
---|
3132 | 2809 | printk(KERN_WARNING "SysTab Set failed. Out of memory.\n"); |
---|
3133 | 2810 | return -ENOMEM; |
---|
3134 | 2811 | } |
---|
3135 | | - memset(sys_tbl, 0, sys_tbl_len); |
---|
3136 | 2812 | |
---|
3137 | 2813 | sys_tbl->num_entries = hba_count; |
---|
3138 | 2814 | sys_tbl->version = I2OVERSION; |
---|
.. | .. |
---|
3427 | 3103 | return -((res[1] >> 16) & 0xFF); /* -BlockStatus */ |
---|
3428 | 3104 | } |
---|
3429 | 3105 | |
---|
3430 | | - return 4 + ((res[1] & 0x0000FFFF) << 2); /* bytes used in resblk */ |
---|
| 3106 | + return 4 + ((res[1] & 0x0000FFFF) << 2); /* bytes used in resblk */ |
---|
3431 | 3107 | } |
---|
3432 | 3108 | |
---|
3433 | 3109 | |
---|
.. | .. |
---|
3500 | 3176 | |
---|
3501 | 3177 | static int adpt_i2o_systab_send(adpt_hba* pHba) |
---|
3502 | 3178 | { |
---|
3503 | | - u32 msg[12]; |
---|
3504 | | - int ret; |
---|
| 3179 | + u32 msg[12]; |
---|
| 3180 | + int ret; |
---|
3505 | 3181 | |
---|
3506 | 3182 | msg[0] = I2O_MESSAGE_SIZE(12) | SGL_OFFSET_6; |
---|
3507 | 3183 | msg[1] = I2O_CMD_SYS_TAB_SET<<24 | HOST_TID<<12 | ADAPTER_TID; |
---|
.. | .. |
---|
3569 | 3245 | .slave_configure = adpt_slave_configure, |
---|
3570 | 3246 | .can_queue = MAX_TO_IOP_MESSAGES, |
---|
3571 | 3247 | .this_id = 7, |
---|
3572 | | - .use_clustering = ENABLE_CLUSTERING, |
---|
3573 | 3248 | }; |
---|
3574 | 3249 | |
---|
3575 | 3250 | static int __init adpt_init(void) |
---|