aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/block
diff options
context:
space:
mode:
authorAsai Thambi S P <asamymuthupa@micron.com>2012-05-29 21:43:31 -0400
committerJens Axboe <axboe@kernel.dk>2012-05-31 02:46:50 -0400
commite602878fd89dab0af2af995a6bef0fbe97b20dc8 (patch)
tree26890181c7f897d0e1751f6c12c8204c7e23cde4 /drivers/block
parent0a07ab224afc56c497e2f1c48e853dbdf964d549 (diff)
mtip32xx: Fix to support more than one sector in exec_drive_command()
Fix to support more than one sector in exec_drive_command(). Signed-off-by: Asai Thambi S P <asamymuthupa@micron.com> Signed-off-by: Jens Axboe <axboe@kernel.dk>
Diffstat (limited to 'drivers/block')
-rw-r--r--drivers/block/mtip32xx/mtip32xx.c60
1 files changed, 44 insertions, 16 deletions
diff --git a/drivers/block/mtip32xx/mtip32xx.c b/drivers/block/mtip32xx/mtip32xx.c
index bfee50d1b319..cd271d5e1b73 100644
--- a/drivers/block/mtip32xx/mtip32xx.c
+++ b/drivers/block/mtip32xx/mtip32xx.c
@@ -1890,13 +1890,33 @@ static int exec_drive_command(struct mtip_port *port, u8 *command,
1890 void __user *user_buffer) 1890 void __user *user_buffer)
1891{ 1891{
1892 struct host_to_dev_fis fis; 1892 struct host_to_dev_fis fis;
1893 struct host_to_dev_fis *reply = (port->rxfis + RX_FIS_D2H_REG); 1893 struct host_to_dev_fis *reply;
1894 u8 *buf = NULL;
1895 dma_addr_t dma_addr = 0;
1896 int rv = 0, xfer_sz = command[3];
1897
1898 if (xfer_sz) {
1899 if (user_buffer)
1900 return -EFAULT;
1901
1902 buf = dmam_alloc_coherent(&port->dd->pdev->dev,
1903 ATA_SECT_SIZE * xfer_sz,
1904 &dma_addr,
1905 GFP_KERNEL);
1906 if (!buf) {
1907 dev_err(&port->dd->pdev->dev,
1908 "Memory allocation failed (%d bytes)\n",
1909 ATA_SECT_SIZE * xfer_sz);
1910 return -ENOMEM;
1911 }
1912 memset(buf, 0, ATA_SECT_SIZE * xfer_sz);
1913 }
1894 1914
1895 /* Build the FIS. */ 1915 /* Build the FIS. */
1896 memset(&fis, 0, sizeof(struct host_to_dev_fis)); 1916 memset(&fis, 0, sizeof(struct host_to_dev_fis));
1897 fis.type = 0x27; 1917 fis.type = 0x27;
1898 fis.opts = 1 << 7; 1918 fis.opts = 1 << 7;
1899 fis.command = command[0]; 1919 fis.command = command[0];
1900 fis.features = command[2]; 1920 fis.features = command[2];
1901 fis.sect_count = command[3]; 1921 fis.sect_count = command[3];
1902 if (fis.command == ATA_CMD_SMART) { 1922 if (fis.command == ATA_CMD_SMART) {
@@ -1905,6 +1925,11 @@ static int exec_drive_command(struct mtip_port *port, u8 *command,
1905 fis.cyl_hi = 0xC2; 1925 fis.cyl_hi = 0xC2;
1906 } 1926 }
1907 1927
1928 if (xfer_sz)
1929 reply = (port->rxfis + RX_FIS_PIO_SETUP);
1930 else
1931 reply = (port->rxfis + RX_FIS_D2H_REG);
1932
1908 dbg_printk(MTIP_DRV_NAME 1933 dbg_printk(MTIP_DRV_NAME
1909 " %s: User Command: cmd %x, sect %x, " 1934 " %s: User Command: cmd %x, sect %x, "
1910 "feat %x, sectcnt %x\n", 1935 "feat %x, sectcnt %x\n",
@@ -1914,43 +1939,46 @@ static int exec_drive_command(struct mtip_port *port, u8 *command,
1914 command[2], 1939 command[2],
1915 command[3]); 1940 command[3]);
1916 1941
1917 memset(port->sector_buffer, 0x00, ATA_SECT_SIZE);
1918
1919 /* Execute the command. */ 1942 /* Execute the command. */
1920 if (mtip_exec_internal_command(port, 1943 if (mtip_exec_internal_command(port,
1921 &fis, 1944 &fis,
1922 5, 1945 5,
1923 port->sector_buffer_dma, 1946 (xfer_sz ? dma_addr : 0),
1924 (command[3] != 0) ? ATA_SECT_SIZE : 0, 1947 (xfer_sz ? ATA_SECT_SIZE * xfer_sz : 0),
1925 0, 1948 0,
1926 GFP_KERNEL, 1949 GFP_KERNEL,
1927 MTIP_IOCTL_COMMAND_TIMEOUT_MS) 1950 MTIP_IOCTL_COMMAND_TIMEOUT_MS)
1928 < 0) { 1951 < 0) {
1929 return -1; 1952 rv = -EFAULT;
1953 goto exit_drive_command;
1930 } 1954 }
1931 1955
1932 /* Collect the completion status. */ 1956 /* Collect the completion status. */
1933 command[0] = reply->command; /* Status*/ 1957 command[0] = reply->command; /* Status*/
1934 command[1] = reply->features; /* Error*/ 1958 command[1] = reply->features; /* Error*/
1935 command[2] = command[3]; 1959 command[2] = reply->sect_count;
1936 1960
1937 dbg_printk(MTIP_DRV_NAME 1961 dbg_printk(MTIP_DRV_NAME
1938 " %s: Completion Status: stat %x, " 1962 " %s: Completion Status: stat %x, "
1939 "err %x, cmd %x\n", 1963 "err %x, nsect %x\n",
1940 __func__, 1964 __func__,
1941 command[0], 1965 command[0],
1942 command[1], 1966 command[1],
1943 command[2]); 1967 command[2]);
1944 1968
1945 if (user_buffer && command[3]) { 1969 if (xfer_sz) {
1946 if (copy_to_user(user_buffer, 1970 if (copy_to_user(user_buffer,
1947 port->sector_buffer, 1971 buf,
1948 ATA_SECT_SIZE * command[3])) { 1972 ATA_SECT_SIZE * command[3])) {
1949 return -EFAULT; 1973 rv = -EFAULT;
1974 goto exit_drive_command;
1950 } 1975 }
1951 } 1976 }
1952 1977exit_drive_command:
1953 return 0; 1978 if (buf)
1979 dmam_free_coherent(&port->dd->pdev->dev,
1980 ATA_SECT_SIZE * xfer_sz, buf, dma_addr);
1981 return rv;
1954} 1982}
1955 1983
1956/* 1984/*