diff options
| -rw-r--r-- | Documentation/ABI/testing/sysfs-block-rssd | 12 | ||||
| -rw-r--r-- | block/blk-ioc.c | 6 | ||||
| -rw-r--r-- | drivers/block/mtip32xx/mtip32xx.c | 276 | ||||
| -rw-r--r-- | drivers/block/mtip32xx/mtip32xx.h | 48 |
4 files changed, 212 insertions, 130 deletions
diff --git a/Documentation/ABI/testing/sysfs-block-rssd b/Documentation/ABI/testing/sysfs-block-rssd index d535757799fe..679ce3543122 100644 --- a/Documentation/ABI/testing/sysfs-block-rssd +++ b/Documentation/ABI/testing/sysfs-block-rssd | |||
| @@ -6,13 +6,21 @@ Description: This is a read-only file. Dumps below driver information and | |||
| 6 | hardware registers. | 6 | hardware registers. |
| 7 | - S ACTive | 7 | - S ACTive |
| 8 | - Command Issue | 8 | - Command Issue |
| 9 | - Allocated | ||
| 10 | - Completed | 9 | - Completed |
| 11 | - PORT IRQ STAT | 10 | - PORT IRQ STAT |
| 12 | - HOST IRQ STAT | 11 | - HOST IRQ STAT |
| 12 | - Allocated | ||
| 13 | - Commands in Q | ||
| 13 | 14 | ||
| 14 | What: /sys/block/rssd*/status | 15 | What: /sys/block/rssd*/status |
| 15 | Date: April 2012 | 16 | Date: April 2012 |
| 16 | KernelVersion: 3.4 | 17 | KernelVersion: 3.4 |
| 17 | Contact: Asai Thambi S P <asamymuthupa@micron.com> | 18 | Contact: Asai Thambi S P <asamymuthupa@micron.com> |
| 18 | Description: This is a read-only file. Indicates the status of the device. | 19 | Description: This is a read-only file. Indicates the status of the device. |
| 20 | |||
| 21 | What: /sys/block/rssd*/flags | ||
| 22 | Date: May 2012 | ||
| 23 | KernelVersion: 3.5 | ||
| 24 | Contact: Asai Thambi S P <asamymuthupa@micron.com> | ||
| 25 | Description: This is a read-only file. Dumps the flags in port and driver | ||
| 26 | data structure | ||
diff --git a/block/blk-ioc.c b/block/blk-ioc.c index 1e2d53b04858..893b8007c657 100644 --- a/block/blk-ioc.c +++ b/block/blk-ioc.c | |||
| @@ -235,6 +235,7 @@ void ioc_clear_queue(struct request_queue *q) | |||
| 235 | int create_task_io_context(struct task_struct *task, gfp_t gfp_flags, int node) | 235 | int create_task_io_context(struct task_struct *task, gfp_t gfp_flags, int node) |
| 236 | { | 236 | { |
| 237 | struct io_context *ioc; | 237 | struct io_context *ioc; |
| 238 | int ret; | ||
| 238 | 239 | ||
| 239 | ioc = kmem_cache_alloc_node(iocontext_cachep, gfp_flags | __GFP_ZERO, | 240 | ioc = kmem_cache_alloc_node(iocontext_cachep, gfp_flags | __GFP_ZERO, |
| 240 | node); | 241 | node); |
| @@ -262,9 +263,12 @@ int create_task_io_context(struct task_struct *task, gfp_t gfp_flags, int node) | |||
| 262 | task->io_context = ioc; | 263 | task->io_context = ioc; |
| 263 | else | 264 | else |
| 264 | kmem_cache_free(iocontext_cachep, ioc); | 265 | kmem_cache_free(iocontext_cachep, ioc); |
| 266 | |||
| 267 | ret = task->io_context ? 0 : -EBUSY; | ||
| 268 | |||
| 265 | task_unlock(task); | 269 | task_unlock(task); |
| 266 | 270 | ||
| 267 | return 0; | 271 | return ret; |
| 268 | } | 272 | } |
| 269 | 273 | ||
| 270 | /** | 274 | /** |
diff --git a/drivers/block/mtip32xx/mtip32xx.c b/drivers/block/mtip32xx/mtip32xx.c index 304000c3d433..264bc77dcb91 100644 --- a/drivers/block/mtip32xx/mtip32xx.c +++ b/drivers/block/mtip32xx/mtip32xx.c | |||
| @@ -294,18 +294,16 @@ static int hba_reset_nosleep(struct driver_data *dd) | |||
| 294 | */ | 294 | */ |
| 295 | static inline void mtip_issue_ncq_command(struct mtip_port *port, int tag) | 295 | static inline void mtip_issue_ncq_command(struct mtip_port *port, int tag) |
| 296 | { | 296 | { |
| 297 | unsigned long flags = 0; | ||
| 298 | |||
| 299 | atomic_set(&port->commands[tag].active, 1); | 297 | atomic_set(&port->commands[tag].active, 1); |
| 300 | 298 | ||
| 301 | spin_lock_irqsave(&port->cmd_issue_lock, flags); | 299 | spin_lock(&port->cmd_issue_lock); |
| 302 | 300 | ||
| 303 | writel((1 << MTIP_TAG_BIT(tag)), | 301 | writel((1 << MTIP_TAG_BIT(tag)), |
| 304 | port->s_active[MTIP_TAG_INDEX(tag)]); | 302 | port->s_active[MTIP_TAG_INDEX(tag)]); |
| 305 | writel((1 << MTIP_TAG_BIT(tag)), | 303 | writel((1 << MTIP_TAG_BIT(tag)), |
| 306 | port->cmd_issue[MTIP_TAG_INDEX(tag)]); | 304 | port->cmd_issue[MTIP_TAG_INDEX(tag)]); |
| 307 | 305 | ||
| 308 | spin_unlock_irqrestore(&port->cmd_issue_lock, flags); | 306 | spin_unlock(&port->cmd_issue_lock); |
| 309 | 307 | ||
| 310 | /* Set the command's timeout value.*/ | 308 | /* Set the command's timeout value.*/ |
| 311 | port->commands[tag].comp_time = jiffies + msecs_to_jiffies( | 309 | port->commands[tag].comp_time = jiffies + msecs_to_jiffies( |
| @@ -436,8 +434,7 @@ static void mtip_init_port(struct mtip_port *port) | |||
| 436 | writel(0xFFFFFFFF, port->completed[i]); | 434 | writel(0xFFFFFFFF, port->completed[i]); |
| 437 | 435 | ||
| 438 | /* Clear any pending interrupts for this port */ | 436 | /* Clear any pending interrupts for this port */ |
| 439 | writel(readl(port->dd->mmio + PORT_IRQ_STAT), | 437 | writel(readl(port->mmio + PORT_IRQ_STAT), port->mmio + PORT_IRQ_STAT); |
| 440 | port->dd->mmio + PORT_IRQ_STAT); | ||
| 441 | 438 | ||
| 442 | /* Clear any pending interrupts on the HBA. */ | 439 | /* Clear any pending interrupts on the HBA. */ |
| 443 | writel(readl(port->dd->mmio + HOST_IRQ_STAT), | 440 | writel(readl(port->dd->mmio + HOST_IRQ_STAT), |
| @@ -782,13 +779,24 @@ static void mtip_handle_tfe(struct driver_data *dd) | |||
| 782 | 779 | ||
| 783 | /* Stop the timer to prevent command timeouts. */ | 780 | /* Stop the timer to prevent command timeouts. */ |
| 784 | del_timer(&port->cmd_timer); | 781 | del_timer(&port->cmd_timer); |
| 782 | set_bit(MTIP_PF_EH_ACTIVE_BIT, &port->flags); | ||
| 783 | |||
| 784 | if (test_bit(MTIP_PF_IC_ACTIVE_BIT, &port->flags) && | ||
| 785 | test_bit(MTIP_TAG_INTERNAL, port->allocated)) { | ||
| 786 | cmd = &port->commands[MTIP_TAG_INTERNAL]; | ||
| 787 | dbg_printk(MTIP_DRV_NAME " TFE for the internal command\n"); | ||
| 788 | |||
| 789 | atomic_inc(&cmd->active); /* active > 1 indicates error */ | ||
| 790 | if (cmd->comp_data && cmd->comp_func) { | ||
| 791 | cmd->comp_func(port, MTIP_TAG_INTERNAL, | ||
| 792 | cmd->comp_data, PORT_IRQ_TF_ERR); | ||
| 793 | } | ||
| 794 | goto handle_tfe_exit; | ||
| 795 | } | ||
| 785 | 796 | ||
| 786 | /* clear the tag accumulator */ | 797 | /* clear the tag accumulator */ |
| 787 | memset(tagaccum, 0, SLOTBITS_IN_LONGS * sizeof(long)); | 798 | memset(tagaccum, 0, SLOTBITS_IN_LONGS * sizeof(long)); |
| 788 | 799 | ||
| 789 | /* Set eh_active */ | ||
| 790 | set_bit(MTIP_PF_EH_ACTIVE_BIT, &port->flags); | ||
| 791 | |||
| 792 | /* Loop through all the groups */ | 800 | /* Loop through all the groups */ |
| 793 | for (group = 0; group < dd->slot_groups; group++) { | 801 | for (group = 0; group < dd->slot_groups; group++) { |
| 794 | completed = readl(port->completed[group]); | 802 | completed = readl(port->completed[group]); |
| @@ -940,6 +948,7 @@ static void mtip_handle_tfe(struct driver_data *dd) | |||
| 940 | } | 948 | } |
| 941 | print_tags(dd, "reissued (TFE)", tagaccum, cmd_cnt); | 949 | print_tags(dd, "reissued (TFE)", tagaccum, cmd_cnt); |
| 942 | 950 | ||
| 951 | handle_tfe_exit: | ||
| 943 | /* clear eh_active */ | 952 | /* clear eh_active */ |
| 944 | clear_bit(MTIP_PF_EH_ACTIVE_BIT, &port->flags); | 953 | clear_bit(MTIP_PF_EH_ACTIVE_BIT, &port->flags); |
| 945 | wake_up_interruptible(&port->svc_wait); | 954 | wake_up_interruptible(&port->svc_wait); |
| @@ -961,6 +970,8 @@ static inline void mtip_process_sdbf(struct driver_data *dd) | |||
| 961 | /* walk all bits in all slot groups */ | 970 | /* walk all bits in all slot groups */ |
| 962 | for (group = 0; group < dd->slot_groups; group++) { | 971 | for (group = 0; group < dd->slot_groups; group++) { |
| 963 | completed = readl(port->completed[group]); | 972 | completed = readl(port->completed[group]); |
| 973 | if (!completed) | ||
| 974 | continue; | ||
| 964 | 975 | ||
| 965 | /* clear completed status register in the hardware.*/ | 976 | /* clear completed status register in the hardware.*/ |
| 966 | writel(completed, port->completed[group]); | 977 | writel(completed, port->completed[group]); |
| @@ -1329,22 +1340,6 @@ static int mtip_exec_internal_command(struct mtip_port *port, | |||
| 1329 | } | 1340 | } |
| 1330 | rv = -EAGAIN; | 1341 | rv = -EAGAIN; |
| 1331 | } | 1342 | } |
| 1332 | |||
| 1333 | if (readl(port->cmd_issue[MTIP_TAG_INTERNAL]) | ||
| 1334 | & (1 << MTIP_TAG_INTERNAL)) { | ||
| 1335 | dev_warn(&port->dd->pdev->dev, | ||
| 1336 | "Retiring internal command but CI is 1.\n"); | ||
| 1337 | if (test_bit(MTIP_DDF_REMOVE_PENDING_BIT, | ||
| 1338 | &port->dd->dd_flag)) { | ||
| 1339 | hba_reset_nosleep(port->dd); | ||
| 1340 | rv = -ENXIO; | ||
| 1341 | } else { | ||
| 1342 | mtip_restart_port(port); | ||
| 1343 | rv = -EAGAIN; | ||
| 1344 | } | ||
| 1345 | goto exec_ic_exit; | ||
| 1346 | } | ||
| 1347 | |||
| 1348 | } else { | 1343 | } else { |
| 1349 | /* Spin for <timeout> checking if command still outstanding */ | 1344 | /* Spin for <timeout> checking if command still outstanding */ |
| 1350 | timeout = jiffies + msecs_to_jiffies(timeout); | 1345 | timeout = jiffies + msecs_to_jiffies(timeout); |
| @@ -1361,21 +1356,25 @@ static int mtip_exec_internal_command(struct mtip_port *port, | |||
| 1361 | rv = -ENXIO; | 1356 | rv = -ENXIO; |
| 1362 | goto exec_ic_exit; | 1357 | goto exec_ic_exit; |
| 1363 | } | 1358 | } |
| 1359 | if (readl(port->mmio + PORT_IRQ_STAT) & PORT_IRQ_ERR) { | ||
| 1360 | atomic_inc(&int_cmd->active); /* error */ | ||
| 1361 | break; | ||
| 1362 | } | ||
| 1364 | } | 1363 | } |
| 1364 | } | ||
| 1365 | 1365 | ||
| 1366 | if (readl(port->cmd_issue[MTIP_TAG_INTERNAL]) | 1366 | if (atomic_read(&int_cmd->active) > 1) { |
| 1367 | dev_err(&port->dd->pdev->dev, | ||
| 1368 | "Internal command [%02X] failed\n", fis->command); | ||
| 1369 | rv = -EIO; | ||
| 1370 | } | ||
| 1371 | if (readl(port->cmd_issue[MTIP_TAG_INTERNAL]) | ||
| 1367 | & (1 << MTIP_TAG_INTERNAL)) { | 1372 | & (1 << MTIP_TAG_INTERNAL)) { |
| 1368 | dev_err(&port->dd->pdev->dev, | 1373 | rv = -ENXIO; |
| 1369 | "Internal command did not complete [atomic]\n"); | 1374 | if (!test_bit(MTIP_DDF_REMOVE_PENDING_BIT, |
| 1375 | &port->dd->dd_flag)) { | ||
| 1376 | mtip_restart_port(port); | ||
| 1370 | rv = -EAGAIN; | 1377 | rv = -EAGAIN; |
| 1371 | if (test_bit(MTIP_DDF_REMOVE_PENDING_BIT, | ||
| 1372 | &port->dd->dd_flag)) { | ||
| 1373 | hba_reset_nosleep(port->dd); | ||
| 1374 | rv = -ENXIO; | ||
| 1375 | } else { | ||
| 1376 | mtip_restart_port(port); | ||
| 1377 | rv = -EAGAIN; | ||
| 1378 | } | ||
| 1379 | } | 1378 | } |
| 1380 | } | 1379 | } |
| 1381 | exec_ic_exit: | 1380 | exec_ic_exit: |
| @@ -1893,13 +1892,33 @@ static int exec_drive_command(struct mtip_port *port, u8 *command, | |||
| 1893 | void __user *user_buffer) | 1892 | void __user *user_buffer) |
| 1894 | { | 1893 | { |
| 1895 | struct host_to_dev_fis fis; | 1894 | struct host_to_dev_fis fis; |
| 1896 | struct host_to_dev_fis *reply = (port->rxfis + RX_FIS_D2H_REG); | 1895 | struct host_to_dev_fis *reply; |
| 1896 | u8 *buf = NULL; | ||
| 1897 | dma_addr_t dma_addr = 0; | ||
| 1898 | int rv = 0, xfer_sz = command[3]; | ||
| 1899 | |||
| 1900 | if (xfer_sz) { | ||
| 1901 | if (user_buffer) | ||
| 1902 | return -EFAULT; | ||
| 1903 | |||
| 1904 | buf = dmam_alloc_coherent(&port->dd->pdev->dev, | ||
| 1905 | ATA_SECT_SIZE * xfer_sz, | ||
| 1906 | &dma_addr, | ||
| 1907 | GFP_KERNEL); | ||
| 1908 | if (!buf) { | ||
| 1909 | dev_err(&port->dd->pdev->dev, | ||
| 1910 | "Memory allocation failed (%d bytes)\n", | ||
| 1911 | ATA_SECT_SIZE * xfer_sz); | ||
| 1912 | return -ENOMEM; | ||
| 1913 | } | ||
| 1914 | memset(buf, 0, ATA_SECT_SIZE * xfer_sz); | ||
| 1915 | } | ||
| 1897 | 1916 | ||
| 1898 | /* Build the FIS. */ | 1917 | /* Build the FIS. */ |
| 1899 | memset(&fis, 0, sizeof(struct host_to_dev_fis)); | 1918 | memset(&fis, 0, sizeof(struct host_to_dev_fis)); |
| 1900 | fis.type = 0x27; | 1919 | fis.type = 0x27; |
| 1901 | fis.opts = 1 << 7; | 1920 | fis.opts = 1 << 7; |
| 1902 | fis.command = command[0]; | 1921 | fis.command = command[0]; |
| 1903 | fis.features = command[2]; | 1922 | fis.features = command[2]; |
| 1904 | fis.sect_count = command[3]; | 1923 | fis.sect_count = command[3]; |
| 1905 | if (fis.command == ATA_CMD_SMART) { | 1924 | if (fis.command == ATA_CMD_SMART) { |
| @@ -1908,6 +1927,11 @@ static int exec_drive_command(struct mtip_port *port, u8 *command, | |||
| 1908 | fis.cyl_hi = 0xC2; | 1927 | fis.cyl_hi = 0xC2; |
| 1909 | } | 1928 | } |
| 1910 | 1929 | ||
| 1930 | if (xfer_sz) | ||
| 1931 | reply = (port->rxfis + RX_FIS_PIO_SETUP); | ||
| 1932 | else | ||
| 1933 | reply = (port->rxfis + RX_FIS_D2H_REG); | ||
| 1934 | |||
| 1911 | dbg_printk(MTIP_DRV_NAME | 1935 | dbg_printk(MTIP_DRV_NAME |
| 1912 | " %s: User Command: cmd %x, sect %x, " | 1936 | " %s: User Command: cmd %x, sect %x, " |
| 1913 | "feat %x, sectcnt %x\n", | 1937 | "feat %x, sectcnt %x\n", |
| @@ -1917,43 +1941,46 @@ static int exec_drive_command(struct mtip_port *port, u8 *command, | |||
| 1917 | command[2], | 1941 | command[2], |
| 1918 | command[3]); | 1942 | command[3]); |
| 1919 | 1943 | ||
| 1920 | memset(port->sector_buffer, 0x00, ATA_SECT_SIZE); | ||
| 1921 | |||
| 1922 | /* Execute the command. */ | 1944 | /* Execute the command. */ |
| 1923 | if (mtip_exec_internal_command(port, | 1945 | if (mtip_exec_internal_command(port, |
| 1924 | &fis, | 1946 | &fis, |
| 1925 | 5, | 1947 | 5, |
| 1926 | port->sector_buffer_dma, | 1948 | (xfer_sz ? dma_addr : 0), |
| 1927 | (command[3] != 0) ? ATA_SECT_SIZE : 0, | 1949 | (xfer_sz ? ATA_SECT_SIZE * xfer_sz : 0), |
| 1928 | 0, | 1950 | 0, |
| 1929 | GFP_KERNEL, | 1951 | GFP_KERNEL, |
| 1930 | MTIP_IOCTL_COMMAND_TIMEOUT_MS) | 1952 | MTIP_IOCTL_COMMAND_TIMEOUT_MS) |
| 1931 | < 0) { | 1953 | < 0) { |
| 1932 | return -1; | 1954 | rv = -EFAULT; |
| 1955 | goto exit_drive_command; | ||
| 1933 | } | 1956 | } |
| 1934 | 1957 | ||
| 1935 | /* Collect the completion status. */ | 1958 | /* Collect the completion status. */ |
| 1936 | command[0] = reply->command; /* Status*/ | 1959 | command[0] = reply->command; /* Status*/ |
| 1937 | command[1] = reply->features; /* Error*/ | 1960 | command[1] = reply->features; /* Error*/ |
| 1938 | command[2] = command[3]; | 1961 | command[2] = reply->sect_count; |
| 1939 | 1962 | ||
| 1940 | dbg_printk(MTIP_DRV_NAME | 1963 | dbg_printk(MTIP_DRV_NAME |
| 1941 | " %s: Completion Status: stat %x, " | 1964 | " %s: Completion Status: stat %x, " |
| 1942 | "err %x, cmd %x\n", | 1965 | "err %x, nsect %x\n", |
| 1943 | __func__, | 1966 | __func__, |
| 1944 | command[0], | 1967 | command[0], |
| 1945 | command[1], | 1968 | command[1], |
| 1946 | command[2]); | 1969 | command[2]); |
| 1947 | 1970 | ||
| 1948 | if (user_buffer && command[3]) { | 1971 | if (xfer_sz) { |
| 1949 | if (copy_to_user(user_buffer, | 1972 | if (copy_to_user(user_buffer, |
| 1950 | port->sector_buffer, | 1973 | buf, |
| 1951 | ATA_SECT_SIZE * command[3])) { | 1974 | ATA_SECT_SIZE * command[3])) { |
| 1952 | return -EFAULT; | 1975 | rv = -EFAULT; |
| 1976 | goto exit_drive_command; | ||
| 1953 | } | 1977 | } |
| 1954 | } | 1978 | } |
| 1955 | 1979 | exit_drive_command: | |
| 1956 | return 0; | 1980 | if (buf) |
| 1981 | dmam_free_coherent(&port->dd->pdev->dev, | ||
| 1982 | ATA_SECT_SIZE * xfer_sz, buf, dma_addr); | ||
| 1983 | return rv; | ||
| 1957 | } | 1984 | } |
| 1958 | 1985 | ||
| 1959 | /* | 1986 | /* |
| @@ -2003,6 +2030,32 @@ static unsigned int implicit_sector(unsigned char command, | |||
| 2003 | return rv; | 2030 | return rv; |
| 2004 | } | 2031 | } |
| 2005 | 2032 | ||
| 2033 | static void mtip_set_timeout(struct host_to_dev_fis *fis, unsigned int *timeout) | ||
| 2034 | { | ||
| 2035 | switch (fis->command) { | ||
| 2036 | case ATA_CMD_DOWNLOAD_MICRO: | ||
| 2037 | *timeout = 120000; /* 2 minutes */ | ||
| 2038 | break; | ||
| 2039 | case ATA_CMD_SEC_ERASE_UNIT: | ||
| 2040 | case 0xFC: | ||
| 2041 | *timeout = 240000; /* 4 minutes */ | ||
| 2042 | break; | ||
| 2043 | case ATA_CMD_STANDBYNOW1: | ||
| 2044 | *timeout = 10000; /* 10 seconds */ | ||
| 2045 | break; | ||
| 2046 | case 0xF7: | ||
| 2047 | case 0xFA: | ||
| 2048 | *timeout = 60000; /* 60 seconds */ | ||
| 2049 | break; | ||
| 2050 | case ATA_CMD_SMART: | ||
| 2051 | *timeout = 15000; /* 15 seconds */ | ||
| 2052 | break; | ||
| 2053 | default: | ||
| 2054 | *timeout = MTIP_IOCTL_COMMAND_TIMEOUT_MS; | ||
| 2055 | break; | ||
| 2056 | } | ||
| 2057 | } | ||
| 2058 | |||
| 2006 | /* | 2059 | /* |
| 2007 | * Executes a taskfile | 2060 | * Executes a taskfile |
| 2008 | * See ide_taskfile_ioctl() for derivation | 2061 | * See ide_taskfile_ioctl() for derivation |
| @@ -2023,7 +2076,7 @@ static int exec_drive_taskfile(struct driver_data *dd, | |||
| 2023 | unsigned int taskin = 0; | 2076 | unsigned int taskin = 0; |
| 2024 | unsigned int taskout = 0; | 2077 | unsigned int taskout = 0; |
| 2025 | u8 nsect = 0; | 2078 | u8 nsect = 0; |
| 2026 | unsigned int timeout = MTIP_IOCTL_COMMAND_TIMEOUT_MS; | 2079 | unsigned int timeout; |
| 2027 | unsigned int force_single_sector; | 2080 | unsigned int force_single_sector; |
| 2028 | unsigned int transfer_size; | 2081 | unsigned int transfer_size; |
| 2029 | unsigned long task_file_data; | 2082 | unsigned long task_file_data; |
| @@ -2153,32 +2206,7 @@ static int exec_drive_taskfile(struct driver_data *dd, | |||
| 2153 | fis.lba_hi, | 2206 | fis.lba_hi, |
| 2154 | fis.device); | 2207 | fis.device); |
| 2155 | 2208 | ||
| 2156 | switch (fis.command) { | 2209 | mtip_set_timeout(&fis, &timeout); |
| 2157 | case ATA_CMD_DOWNLOAD_MICRO: | ||
| 2158 | /* Change timeout for Download Microcode to 2 minutes */ | ||
| 2159 | timeout = 120000; | ||
| 2160 | break; | ||
| 2161 | case ATA_CMD_SEC_ERASE_UNIT: | ||
| 2162 | /* Change timeout for Security Erase Unit to 4 minutes.*/ | ||
| 2163 | timeout = 240000; | ||
| 2164 | break; | ||
| 2165 | case ATA_CMD_STANDBYNOW1: | ||
| 2166 | /* Change timeout for standby immediate to 10 seconds.*/ | ||
| 2167 | timeout = 10000; | ||
| 2168 | break; | ||
| 2169 | case 0xF7: | ||
| 2170 | case 0xFA: | ||
| 2171 | /* Change timeout for vendor unique command to 10 secs */ | ||
| 2172 | timeout = 10000; | ||
| 2173 | break; | ||
| 2174 | case ATA_CMD_SMART: | ||
| 2175 | /* Change timeout for vendor unique command to 15 secs */ | ||
| 2176 | timeout = 15000; | ||
| 2177 | break; | ||
| 2178 | default: | ||
| 2179 | timeout = MTIP_IOCTL_COMMAND_TIMEOUT_MS; | ||
| 2180 | break; | ||
| 2181 | } | ||
| 2182 | 2210 | ||
| 2183 | /* Determine the correct transfer size.*/ | 2211 | /* Determine the correct transfer size.*/ |
| 2184 | if (force_single_sector) | 2212 | if (force_single_sector) |
| @@ -2295,13 +2323,12 @@ static int mtip_hw_ioctl(struct driver_data *dd, unsigned int cmd, | |||
| 2295 | { | 2323 | { |
| 2296 | switch (cmd) { | 2324 | switch (cmd) { |
| 2297 | case HDIO_GET_IDENTITY: | 2325 | case HDIO_GET_IDENTITY: |
| 2298 | if (mtip_get_identify(dd->port, (void __user *) arg) < 0) { | 2326 | { |
| 2299 | dev_warn(&dd->pdev->dev, | 2327 | if (copy_to_user((void __user *)arg, dd->port->identify, |
| 2300 | "Unable to read identity\n"); | 2328 | sizeof(u16) * ATA_ID_WORDS)) |
| 2301 | return -EIO; | 2329 | return -EFAULT; |
| 2302 | } | ||
| 2303 | |||
| 2304 | break; | 2330 | break; |
| 2331 | } | ||
| 2305 | case HDIO_DRIVE_CMD: | 2332 | case HDIO_DRIVE_CMD: |
| 2306 | { | 2333 | { |
| 2307 | u8 drive_command[4]; | 2334 | u8 drive_command[4]; |
| @@ -2537,40 +2564,58 @@ static ssize_t mtip_hw_show_registers(struct device *dev, | |||
| 2537 | int size = 0; | 2564 | int size = 0; |
| 2538 | int n; | 2565 | int n; |
| 2539 | 2566 | ||
| 2540 | size += sprintf(&buf[size], "S ACTive:\n"); | 2567 | size += sprintf(&buf[size], "Hardware\n--------\n"); |
| 2568 | size += sprintf(&buf[size], "S ACTive : [ 0x"); | ||
| 2541 | 2569 | ||
| 2542 | for (n = 0; n < dd->slot_groups; n++) | 2570 | for (n = dd->slot_groups-1; n >= 0; n--) |
| 2543 | size += sprintf(&buf[size], "0x%08x\n", | 2571 | size += sprintf(&buf[size], "%08X ", |
| 2544 | readl(dd->port->s_active[n])); | 2572 | readl(dd->port->s_active[n])); |
| 2545 | 2573 | ||
| 2546 | size += sprintf(&buf[size], "Command Issue:\n"); | 2574 | size += sprintf(&buf[size], "]\n"); |
| 2575 | size += sprintf(&buf[size], "Command Issue : [ 0x"); | ||
| 2547 | 2576 | ||
| 2548 | for (n = 0; n < dd->slot_groups; n++) | 2577 | for (n = dd->slot_groups-1; n >= 0; n--) |
| 2549 | size += sprintf(&buf[size], "0x%08x\n", | 2578 | size += sprintf(&buf[size], "%08X ", |
| 2550 | readl(dd->port->cmd_issue[n])); | 2579 | readl(dd->port->cmd_issue[n])); |
| 2551 | 2580 | ||
| 2552 | size += sprintf(&buf[size], "Allocated:\n"); | 2581 | size += sprintf(&buf[size], "]\n"); |
| 2582 | size += sprintf(&buf[size], "Completed : [ 0x"); | ||
| 2583 | |||
| 2584 | for (n = dd->slot_groups-1; n >= 0; n--) | ||
| 2585 | size += sprintf(&buf[size], "%08X ", | ||
| 2586 | readl(dd->port->completed[n])); | ||
| 2587 | |||
| 2588 | size += sprintf(&buf[size], "]\n"); | ||
| 2589 | size += sprintf(&buf[size], "PORT IRQ STAT : [ 0x%08X ]\n", | ||
| 2590 | readl(dd->port->mmio + PORT_IRQ_STAT)); | ||
| 2591 | size += sprintf(&buf[size], "HOST IRQ STAT : [ 0x%08X ]\n", | ||
| 2592 | readl(dd->mmio + HOST_IRQ_STAT)); | ||
| 2593 | size += sprintf(&buf[size], "\n"); | ||
| 2553 | 2594 | ||
| 2554 | for (n = 0; n < dd->slot_groups; n++) { | 2595 | size += sprintf(&buf[size], "Local\n-----\n"); |
| 2596 | size += sprintf(&buf[size], "Allocated : [ 0x"); | ||
| 2597 | |||
| 2598 | for (n = dd->slot_groups-1; n >= 0; n--) { | ||
| 2555 | if (sizeof(long) > sizeof(u32)) | 2599 | if (sizeof(long) > sizeof(u32)) |
| 2556 | group_allocated = | 2600 | group_allocated = |
| 2557 | dd->port->allocated[n/2] >> (32*(n&1)); | 2601 | dd->port->allocated[n/2] >> (32*(n&1)); |
| 2558 | else | 2602 | else |
| 2559 | group_allocated = dd->port->allocated[n]; | 2603 | group_allocated = dd->port->allocated[n]; |
| 2560 | size += sprintf(&buf[size], "0x%08x\n", | 2604 | size += sprintf(&buf[size], "%08X ", group_allocated); |
| 2561 | group_allocated); | ||
| 2562 | } | 2605 | } |
| 2606 | size += sprintf(&buf[size], "]\n"); | ||
| 2563 | 2607 | ||
| 2564 | size += sprintf(&buf[size], "Completed:\n"); | 2608 | size += sprintf(&buf[size], "Commands in Q: [ 0x"); |
| 2565 | |||
| 2566 | for (n = 0; n < dd->slot_groups; n++) | ||
| 2567 | size += sprintf(&buf[size], "0x%08x\n", | ||
| 2568 | readl(dd->port->completed[n])); | ||
| 2569 | 2609 | ||
| 2570 | size += sprintf(&buf[size], "PORT IRQ STAT : 0x%08x\n", | 2610 | for (n = dd->slot_groups-1; n >= 0; n--) { |
| 2571 | readl(dd->port->mmio + PORT_IRQ_STAT)); | 2611 | if (sizeof(long) > sizeof(u32)) |
| 2572 | size += sprintf(&buf[size], "HOST IRQ STAT : 0x%08x\n", | 2612 | group_allocated = |
| 2573 | readl(dd->mmio + HOST_IRQ_STAT)); | 2613 | dd->port->cmds_to_issue[n/2] >> (32*(n&1)); |
| 2614 | else | ||
| 2615 | group_allocated = dd->port->cmds_to_issue[n]; | ||
| 2616 | size += sprintf(&buf[size], "%08X ", group_allocated); | ||
| 2617 | } | ||
| 2618 | size += sprintf(&buf[size], "]\n"); | ||
| 2574 | 2619 | ||
| 2575 | return size; | 2620 | return size; |
| 2576 | } | 2621 | } |
| @@ -2592,8 +2637,24 @@ static ssize_t mtip_hw_show_status(struct device *dev, | |||
| 2592 | return size; | 2637 | return size; |
| 2593 | } | 2638 | } |
| 2594 | 2639 | ||
| 2640 | static ssize_t mtip_hw_show_flags(struct device *dev, | ||
| 2641 | struct device_attribute *attr, | ||
| 2642 | char *buf) | ||
| 2643 | { | ||
| 2644 | struct driver_data *dd = dev_to_disk(dev)->private_data; | ||
| 2645 | int size = 0; | ||
| 2646 | |||
| 2647 | size += sprintf(&buf[size], "Flag in port struct : [ %08lX ]\n", | ||
| 2648 | dd->port->flags); | ||
| 2649 | size += sprintf(&buf[size], "Flag in dd struct : [ %08lX ]\n", | ||
| 2650 | dd->dd_flag); | ||
| 2651 | |||
| 2652 | return size; | ||
| 2653 | } | ||
| 2654 | |||
| 2595 | static DEVICE_ATTR(registers, S_IRUGO, mtip_hw_show_registers, NULL); | 2655 | static DEVICE_ATTR(registers, S_IRUGO, mtip_hw_show_registers, NULL); |
| 2596 | static DEVICE_ATTR(status, S_IRUGO, mtip_hw_show_status, NULL); | 2656 | static DEVICE_ATTR(status, S_IRUGO, mtip_hw_show_status, NULL); |
| 2657 | static DEVICE_ATTR(flags, S_IRUGO, mtip_hw_show_flags, NULL); | ||
| 2597 | 2658 | ||
| 2598 | /* | 2659 | /* |
| 2599 | * Create the sysfs related attributes. | 2660 | * Create the sysfs related attributes. |
| @@ -2616,6 +2677,9 @@ static int mtip_hw_sysfs_init(struct driver_data *dd, struct kobject *kobj) | |||
| 2616 | if (sysfs_create_file(kobj, &dev_attr_status.attr)) | 2677 | if (sysfs_create_file(kobj, &dev_attr_status.attr)) |
| 2617 | dev_warn(&dd->pdev->dev, | 2678 | dev_warn(&dd->pdev->dev, |
| 2618 | "Error creating 'status' sysfs entry\n"); | 2679 | "Error creating 'status' sysfs entry\n"); |
| 2680 | if (sysfs_create_file(kobj, &dev_attr_flags.attr)) | ||
| 2681 | dev_warn(&dd->pdev->dev, | ||
| 2682 | "Error creating 'flags' sysfs entry\n"); | ||
| 2619 | return 0; | 2683 | return 0; |
| 2620 | } | 2684 | } |
| 2621 | 2685 | ||
| @@ -2636,6 +2700,7 @@ static int mtip_hw_sysfs_exit(struct driver_data *dd, struct kobject *kobj) | |||
| 2636 | 2700 | ||
| 2637 | sysfs_remove_file(kobj, &dev_attr_registers.attr); | 2701 | sysfs_remove_file(kobj, &dev_attr_registers.attr); |
| 2638 | sysfs_remove_file(kobj, &dev_attr_status.attr); | 2702 | sysfs_remove_file(kobj, &dev_attr_status.attr); |
| 2703 | sysfs_remove_file(kobj, &dev_attr_flags.attr); | ||
| 2639 | 2704 | ||
| 2640 | return 0; | 2705 | return 0; |
| 2641 | } | 2706 | } |
| @@ -3634,7 +3699,10 @@ skip_create_disk: | |||
| 3634 | set_bit(QUEUE_FLAG_NONROT, &dd->queue->queue_flags); | 3699 | set_bit(QUEUE_FLAG_NONROT, &dd->queue->queue_flags); |
| 3635 | blk_queue_max_segments(dd->queue, MTIP_MAX_SG); | 3700 | blk_queue_max_segments(dd->queue, MTIP_MAX_SG); |
| 3636 | blk_queue_physical_block_size(dd->queue, 4096); | 3701 | blk_queue_physical_block_size(dd->queue, 4096); |
| 3702 | blk_queue_max_hw_sectors(dd->queue, 0xffff); | ||
| 3703 | blk_queue_max_segment_size(dd->queue, 0x400000); | ||
| 3637 | blk_queue_io_min(dd->queue, 4096); | 3704 | blk_queue_io_min(dd->queue, 4096); |
| 3705 | |||
| 3638 | /* | 3706 | /* |
| 3639 | * write back cache is not supported in the device. FUA depends on | 3707 | * write back cache is not supported in the device. FUA depends on |
| 3640 | * write back cache support, hence setting flush support to zero. | 3708 | * write back cache support, hence setting flush support to zero. |
diff --git a/drivers/block/mtip32xx/mtip32xx.h b/drivers/block/mtip32xx/mtip32xx.h index 4ef58336310a..b2c88da26b2a 100644 --- a/drivers/block/mtip32xx/mtip32xx.h +++ b/drivers/block/mtip32xx/mtip32xx.h | |||
| @@ -113,33 +113,35 @@ | |||
| 113 | 113 | ||
| 114 | #define __force_bit2int (unsigned int __force) | 114 | #define __force_bit2int (unsigned int __force) |
| 115 | 115 | ||
| 116 | /* below are bit numbers in 'flags' defined in mtip_port */ | 116 | enum { |
| 117 | #define MTIP_PF_IC_ACTIVE_BIT 0 /* pio/ioctl */ | 117 | /* below are bit numbers in 'flags' defined in mtip_port */ |
| 118 | #define MTIP_PF_EH_ACTIVE_BIT 1 /* error handling */ | 118 | MTIP_PF_IC_ACTIVE_BIT = 0, /* pio/ioctl */ |
| 119 | #define MTIP_PF_SE_ACTIVE_BIT 2 /* secure erase */ | 119 | MTIP_PF_EH_ACTIVE_BIT = 1, /* error handling */ |
| 120 | #define MTIP_PF_DM_ACTIVE_BIT 3 /* download microcde */ | 120 | MTIP_PF_SE_ACTIVE_BIT = 2, /* secure erase */ |
| 121 | #define MTIP_PF_PAUSE_IO ((1 << MTIP_PF_IC_ACTIVE_BIT) | \ | 121 | MTIP_PF_DM_ACTIVE_BIT = 3, /* download microcde */ |
| 122 | MTIP_PF_PAUSE_IO = ((1 << MTIP_PF_IC_ACTIVE_BIT) | \ | ||
| 122 | (1 << MTIP_PF_EH_ACTIVE_BIT) | \ | 123 | (1 << MTIP_PF_EH_ACTIVE_BIT) | \ |
| 123 | (1 << MTIP_PF_SE_ACTIVE_BIT) | \ | 124 | (1 << MTIP_PF_SE_ACTIVE_BIT) | \ |
| 124 | (1 << MTIP_PF_DM_ACTIVE_BIT)) | 125 | (1 << MTIP_PF_DM_ACTIVE_BIT)), |
| 125 | 126 | ||
| 126 | #define MTIP_PF_SVC_THD_ACTIVE_BIT 4 | 127 | MTIP_PF_SVC_THD_ACTIVE_BIT = 4, |
| 127 | #define MTIP_PF_ISSUE_CMDS_BIT 5 | 128 | MTIP_PF_ISSUE_CMDS_BIT = 5, |
| 128 | #define MTIP_PF_REBUILD_BIT 6 | 129 | MTIP_PF_REBUILD_BIT = 6, |
| 129 | #define MTIP_PF_SVC_THD_STOP_BIT 8 | 130 | MTIP_PF_SVC_THD_STOP_BIT = 8, |
| 130 | 131 | ||
| 131 | /* below are bit numbers in 'dd_flag' defined in driver_data */ | 132 | /* below are bit numbers in 'dd_flag' defined in driver_data */ |
| 132 | #define MTIP_DDF_REMOVE_PENDING_BIT 1 | 133 | MTIP_DDF_REMOVE_PENDING_BIT = 1, |
| 133 | #define MTIP_DDF_OVER_TEMP_BIT 2 | 134 | MTIP_DDF_OVER_TEMP_BIT = 2, |
| 134 | #define MTIP_DDF_WRITE_PROTECT_BIT 3 | 135 | MTIP_DDF_WRITE_PROTECT_BIT = 3, |
| 135 | #define MTIP_DDF_STOP_IO ((1 << MTIP_DDF_REMOVE_PENDING_BIT) | \ | 136 | MTIP_DDF_STOP_IO = ((1 << MTIP_DDF_REMOVE_PENDING_BIT) | \ |
| 136 | (1 << MTIP_DDF_OVER_TEMP_BIT) | \ | 137 | (1 << MTIP_DDF_OVER_TEMP_BIT) | \ |
| 137 | (1 << MTIP_DDF_WRITE_PROTECT_BIT)) | 138 | (1 << MTIP_DDF_WRITE_PROTECT_BIT)), |
| 138 | 139 | ||
| 139 | #define MTIP_DDF_CLEANUP_BIT 5 | 140 | MTIP_DDF_CLEANUP_BIT = 5, |
| 140 | #define MTIP_DDF_RESUME_BIT 6 | 141 | MTIP_DDF_RESUME_BIT = 6, |
| 141 | #define MTIP_DDF_INIT_DONE_BIT 7 | 142 | MTIP_DDF_INIT_DONE_BIT = 7, |
| 142 | #define MTIP_DDF_REBUILD_FAILED_BIT 8 | 143 | MTIP_DDF_REBUILD_FAILED_BIT = 8, |
| 144 | }; | ||
| 143 | 145 | ||
| 144 | __packed struct smart_attr{ | 146 | __packed struct smart_attr{ |
| 145 | u8 attr_id; | 147 | u8 attr_id; |
