hc
2024-12-19 9370bb92b2d16684ee45cf24e879c93c509162da
kernel/drivers/scsi/dpt_i2o.c
....@@ -56,7 +56,7 @@
5656 #include <linux/mutex.h>
5757
5858 #include <asm/processor.h> /* for boot_cpu_data */
59
-#include <asm/io.h> /* for virt_to_bus, etc. */
59
+#include <asm/io.h>
6060
6161 #include <scsi/scsi.h>
6262 #include <scsi/scsi_cmnd.h>
....@@ -580,51 +580,6 @@
580580 }
581581 }
582582 return 0;
583
-}
584
-
585
-/*
586
- * Turn a pointer to ioctl reply data into an u32 'context'
587
- */
588
-static u32 adpt_ioctl_to_context(adpt_hba * pHba, void *reply)
589
-{
590
-#if BITS_PER_LONG == 32
591
- return (u32)(unsigned long)reply;
592
-#else
593
- ulong flags = 0;
594
- u32 nr, i;
595
-
596
- spin_lock_irqsave(pHba->host->host_lock, flags);
597
- nr = ARRAY_SIZE(pHba->ioctl_reply_context);
598
- for (i = 0; i < nr; i++) {
599
- if (pHba->ioctl_reply_context[i] == NULL) {
600
- pHba->ioctl_reply_context[i] = reply;
601
- break;
602
- }
603
- }
604
- spin_unlock_irqrestore(pHba->host->host_lock, flags);
605
- if (i >= nr) {
606
- printk(KERN_WARNING"%s: Too many outstanding "
607
- "ioctl commands\n", pHba->name);
608
- return (u32)-1;
609
- }
610
-
611
- return i;
612
-#endif
613
-}
614
-
615
-/*
616
- * Go from an u32 'context' to a pointer to ioctl reply data.
617
- */
618
-static void *adpt_ioctl_from_context(adpt_hba *pHba, u32 context)
619
-{
620
-#if BITS_PER_LONG == 32
621
- return (void *)(unsigned long)context;
622
-#else
623
- void *p = pHba->ioctl_reply_context[context];
624
- pHba->ioctl_reply_context[context] = NULL;
625
-
626
- return p;
627
-#endif
628583 }
629584
630585 /*===========================================================================
....@@ -1648,208 +1603,6 @@
16481603 return 0;
16491604 }
16501605
1651
-
1652
-static int adpt_i2o_passthru(adpt_hba* pHba, u32 __user *arg)
1653
-{
1654
- u32 msg[MAX_MESSAGE_SIZE];
1655
- u32* reply = NULL;
1656
- u32 size = 0;
1657
- u32 reply_size = 0;
1658
- u32 __user *user_msg = arg;
1659
- u32 __user * user_reply = NULL;
1660
- void **sg_list = NULL;
1661
- u32 sg_offset = 0;
1662
- u32 sg_count = 0;
1663
- int sg_index = 0;
1664
- u32 i = 0;
1665
- u32 rcode = 0;
1666
- void *p = NULL;
1667
- dma_addr_t addr;
1668
- ulong flags = 0;
1669
-
1670
- memset(&msg, 0, MAX_MESSAGE_SIZE*4);
1671
- // get user msg size in u32s
1672
- if(get_user(size, &user_msg[0])){
1673
- return -EFAULT;
1674
- }
1675
- size = size>>16;
1676
-
1677
- user_reply = &user_msg[size];
1678
- if(size > MAX_MESSAGE_SIZE){
1679
- return -EFAULT;
1680
- }
1681
- size *= 4; // Convert to bytes
1682
-
1683
- /* Copy in the user's I2O command */
1684
- if(copy_from_user(msg, user_msg, size)) {
1685
- return -EFAULT;
1686
- }
1687
- get_user(reply_size, &user_reply[0]);
1688
- reply_size = reply_size>>16;
1689
- if(reply_size > REPLY_FRAME_SIZE){
1690
- reply_size = REPLY_FRAME_SIZE;
1691
- }
1692
- reply_size *= 4;
1693
- reply = kzalloc(REPLY_FRAME_SIZE*4, GFP_KERNEL);
1694
- if(reply == NULL) {
1695
- printk(KERN_WARNING"%s: Could not allocate reply buffer\n",pHba->name);
1696
- return -ENOMEM;
1697
- }
1698
- sg_offset = (msg[0]>>4)&0xf;
1699
- msg[2] = 0x40000000; // IOCTL context
1700
- msg[3] = adpt_ioctl_to_context(pHba, reply);
1701
- if (msg[3] == (u32)-1) {
1702
- rcode = -EBUSY;
1703
- goto free;
1704
- }
1705
-
1706
- sg_list = kcalloc(pHba->sg_tablesize, sizeof(*sg_list), GFP_KERNEL);
1707
- if (!sg_list) {
1708
- rcode = -ENOMEM;
1709
- goto free;
1710
- }
1711
- if(sg_offset) {
1712
- // TODO add 64 bit API
1713
- struct sg_simple_element *sg = (struct sg_simple_element*) (msg+sg_offset);
1714
- sg_count = (size - sg_offset*4) / sizeof(struct sg_simple_element);
1715
- if (sg_count > pHba->sg_tablesize){
1716
- printk(KERN_DEBUG"%s:IOCTL SG List too large (%u)\n", pHba->name,sg_count);
1717
- rcode = -EINVAL;
1718
- goto free;
1719
- }
1720
-
1721
- for(i = 0; i < sg_count; i++) {
1722
- int sg_size;
1723
-
1724
- if (!(sg[i].flag_count & 0x10000000 /*I2O_SGL_FLAGS_SIMPLE_ADDRESS_ELEMENT*/)) {
1725
- printk(KERN_DEBUG"%s:Bad SG element %d - not simple (%x)\n",pHba->name,i, sg[i].flag_count);
1726
- rcode = -EINVAL;
1727
- goto cleanup;
1728
- }
1729
- sg_size = sg[i].flag_count & 0xffffff;
1730
- /* Allocate memory for the transfer */
1731
- p = dma_alloc_coherent(&pHba->pDev->dev, sg_size, &addr, GFP_KERNEL);
1732
- if(!p) {
1733
- printk(KERN_DEBUG"%s: Could not allocate SG buffer - size = %d buffer number %d of %d\n",
1734
- pHba->name,sg_size,i,sg_count);
1735
- rcode = -ENOMEM;
1736
- goto cleanup;
1737
- }
1738
- sg_list[sg_index++] = p; // sglist indexed with input frame, not our internal frame.
1739
- /* Copy in the user's SG buffer if necessary */
1740
- if(sg[i].flag_count & 0x04000000 /*I2O_SGL_FLAGS_DIR*/) {
1741
- // sg_simple_element API is 32 bit
1742
- if (copy_from_user(p,(void __user *)(ulong)sg[i].addr_bus, sg_size)) {
1743
- printk(KERN_DEBUG"%s: Could not copy SG buf %d FROM user\n",pHba->name,i);
1744
- rcode = -EFAULT;
1745
- goto cleanup;
1746
- }
1747
- }
1748
- /* sg_simple_element API is 32 bit, but addr < 4GB */
1749
- sg[i].addr_bus = addr;
1750
- }
1751
- }
1752
-
1753
- do {
1754
- /*
1755
- * Stop any new commands from enterring the
1756
- * controller while processing the ioctl
1757
- */
1758
- if (pHba->host) {
1759
- scsi_block_requests(pHba->host);
1760
- spin_lock_irqsave(pHba->host->host_lock, flags);
1761
- }
1762
- rcode = adpt_i2o_post_wait(pHba, msg, size, FOREVER);
1763
- if (rcode != 0)
1764
- printk("adpt_i2o_passthru: post wait failed %d %p\n",
1765
- rcode, reply);
1766
- if (pHba->host) {
1767
- spin_unlock_irqrestore(pHba->host->host_lock, flags);
1768
- scsi_unblock_requests(pHba->host);
1769
- }
1770
- } while (rcode == -ETIMEDOUT);
1771
-
1772
- if(rcode){
1773
- goto cleanup;
1774
- }
1775
-
1776
- if(sg_offset) {
1777
- /* Copy back the Scatter Gather buffers back to user space */
1778
- u32 j;
1779
- // TODO add 64 bit API
1780
- struct sg_simple_element* sg;
1781
- int sg_size;
1782
-
1783
- // re-acquire the original message to handle correctly the sg copy operation
1784
- memset(&msg, 0, MAX_MESSAGE_SIZE*4);
1785
- // get user msg size in u32s
1786
- if(get_user(size, &user_msg[0])){
1787
- rcode = -EFAULT;
1788
- goto cleanup;
1789
- }
1790
- size = size>>16;
1791
- size *= 4;
1792
- if (size > MAX_MESSAGE_SIZE) {
1793
- rcode = -EINVAL;
1794
- goto cleanup;
1795
- }
1796
- /* Copy in the user's I2O command */
1797
- if (copy_from_user (msg, user_msg, size)) {
1798
- rcode = -EFAULT;
1799
- goto cleanup;
1800
- }
1801
- sg_count = (size - sg_offset*4) / sizeof(struct sg_simple_element);
1802
-
1803
- // TODO add 64 bit API
1804
- sg = (struct sg_simple_element*)(msg + sg_offset);
1805
- for (j = 0; j < sg_count; j++) {
1806
- /* Copy out the SG list to user's buffer if necessary */
1807
- if(! (sg[j].flag_count & 0x4000000 /*I2O_SGL_FLAGS_DIR*/)) {
1808
- sg_size = sg[j].flag_count & 0xffffff;
1809
- // sg_simple_element API is 32 bit
1810
- if (copy_to_user((void __user *)(ulong)sg[j].addr_bus,sg_list[j], sg_size)) {
1811
- printk(KERN_WARNING"%s: Could not copy %p TO user %x\n",pHba->name, sg_list[j], sg[j].addr_bus);
1812
- rcode = -EFAULT;
1813
- goto cleanup;
1814
- }
1815
- }
1816
- }
1817
- }
1818
-
1819
- /* Copy back the reply to user space */
1820
- if (reply_size) {
1821
- // we wrote our own values for context - now restore the user supplied ones
1822
- if(copy_from_user(reply+2, user_msg+2, sizeof(u32)*2)) {
1823
- printk(KERN_WARNING"%s: Could not copy message context FROM user\n",pHba->name);
1824
- rcode = -EFAULT;
1825
- }
1826
- if(copy_to_user(user_reply, reply, reply_size)) {
1827
- printk(KERN_WARNING"%s: Could not copy reply TO user\n",pHba->name);
1828
- rcode = -EFAULT;
1829
- }
1830
- }
1831
-
1832
-
1833
-cleanup:
1834
- if (rcode != -ETIME && rcode != -EINTR) {
1835
- struct sg_simple_element *sg =
1836
- (struct sg_simple_element*) (msg +sg_offset);
1837
- while(sg_index) {
1838
- if(sg_list[--sg_index]) {
1839
- dma_free_coherent(&pHba->pDev->dev,
1840
- sg[sg_index].flag_count & 0xffffff,
1841
- sg_list[sg_index],
1842
- sg[sg_index].addr_bus);
1843
- }
1844
- }
1845
- }
1846
-
1847
-free:
1848
- kfree(sg_list);
1849
- kfree(reply);
1850
- return rcode;
1851
-}
1852
-
18531606 #if defined __ia64__
18541607 static void adpt_ia64_info(sysInfo_S* si)
18551608 {
....@@ -1976,8 +1729,6 @@
19761729 return -EFAULT;
19771730 }
19781731 break;
1979
- case I2OUSRCMD:
1980
- return adpt_i2o_passthru(pHba, argp);
19811732
19821733 case DPT_CTRLINFO:{
19831734 drvrHBAinfo_S HbaInfo;
....@@ -2114,7 +1865,7 @@
21141865 } else {
21151866 /* Ick, we should *never* be here */
21161867 printk(KERN_ERR "dpti: reply frame not from pool\n");
2117
- reply = (u8 *)bus_to_virt(m);
1868
+ continue;
21181869 }
21191870
21201871 if (readl(reply) & MSG_FAIL) {
....@@ -2134,13 +1885,6 @@
21341885 adpt_send_nop(pHba, old_m);
21351886 }
21361887 context = readl(reply+8);
2137
- if(context & 0x40000000){ // IOCTL
2138
- void *p = adpt_ioctl_from_context(pHba, readl(reply+12));
2139
- if( p != NULL) {
2140
- memcpy_fromio(p, reply, REPLY_FRAME_SIZE * 4);
2141
- }
2142
- // All IOCTLs will also be post wait
2143
- }
21441888 if(context & 0x80000000){ // Post wait message
21451889 status = readl(reply+16);
21461890 if(status >> 24){
....@@ -2148,16 +1892,14 @@
21481892 } else {
21491893 status = I2O_POST_WAIT_OK;
21501894 }
2151
- if(!(context & 0x40000000)) {
2152
- /*
2153
- * The request tag is one less than the command tag
2154
- * as the firmware might treat a 0 tag as invalid
2155
- */
2156
- cmd = scsi_host_find_tag(pHba->host,
2157
- readl(reply + 12) - 1);
2158
- if(cmd != NULL) {
2159
- printk(KERN_WARNING"%s: Apparent SCSI cmd in Post Wait Context - cmd=%p context=%x\n", pHba->name, cmd, context);
2160
- }
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);
21611903 }
21621904 adpt_i2o_post_wait_complete(context, status);
21631905 } else { // SCSI message