diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-05-31 15:00:09 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-05-31 15:00:09 -0400 |
commit | 5b461209d07ab9a9284760f6ffe696de558031a3 (patch) | |
tree | 0d21496c0b85b96c16aee52b024252baf1d8fb93 /drivers | |
parent | fde86d310886372a377213251e72fb87aaa406c9 (diff) | |
parent | 3c9c708c9fc967e389f85bc735e4c1f65d67334e (diff) |
Merge branch 'for-linus' of git://git.kernel.dk/linux-block
Pull follow-up block updates from Jens Axboe:
"Includes the fix from Eric to resolve the infinite loop in looking up
or creating an IO context for an exiting task.
Also a bunch of mtip32xx patches. Fairly trivial stuff. It's fairly
new though, but no point in keeping it out of the tree until 3.6 imho.
I've thrown it through basic testing locally as well, works fine. The
one contentious part is the patch that Greg complained about (sysfs
file with multiple values, should be a debugfs file), which is
perfectly valid, but not a regression from what the file contains now.
That will be fixed up separately."
* 'for-linus' of git://git.kernel.dk/linux-block:
block: avoid infinite loop in get_task_io_context()
mtip32xx: Changes to sysfs entries
mtip32xx: Convert macro definitions for flag bits to enum
mtip32xx: minor performance tweak
mtip32xx: Fix to support more than one sector in exec_drive_command()
mtip32xx: Use plain spinlock for 'cmd_issue_lock'
mtip32xx: Set block queue boundary variables
mtip32xx: Fix to handle TFE for PIO(IOCTL/internal) commands
mtip32xx: Change HDIO_GET_IDENTITY to return stored data
mtip32xx: Set custom timeouts for PIO commands
mtip32xx: fix clearing an incorrect register in mtip_init_port
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/block/mtip32xx/mtip32xx.c | 276 | ||||
-rw-r--r-- | drivers/block/mtip32xx/mtip32xx.h | 48 |
2 files changed, 197 insertions, 127 deletions
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; |