diff options
Diffstat (limited to 'drivers/scsi/pm8001')
| -rw-r--r-- | drivers/scsi/pm8001/pm8001_ctl.h | 10 | ||||
| -rw-r--r-- | drivers/scsi/pm8001/pm8001_hwi.c | 149 | ||||
| -rw-r--r-- | drivers/scsi/pm8001/pm8001_hwi.h | 3 | ||||
| -rw-r--r-- | drivers/scsi/pm8001/pm8001_init.c | 19 | ||||
| -rw-r--r-- | drivers/scsi/pm8001/pm8001_sas.c | 57 | ||||
| -rw-r--r-- | drivers/scsi/pm8001/pm8001_sas.h | 32 |
6 files changed, 184 insertions, 86 deletions
diff --git a/drivers/scsi/pm8001/pm8001_ctl.h b/drivers/scsi/pm8001/pm8001_ctl.h index 22644de2639..63ad4aa0c42 100644 --- a/drivers/scsi/pm8001/pm8001_ctl.h +++ b/drivers/scsi/pm8001/pm8001_ctl.h | |||
| @@ -45,16 +45,6 @@ | |||
| 45 | #define HEADER_LEN 28 | 45 | #define HEADER_LEN 28 |
| 46 | #define SIZE_OFFSET 16 | 46 | #define SIZE_OFFSET 16 |
| 47 | 47 | ||
| 48 | struct pm8001_ioctl_payload { | ||
| 49 | u32 signature; | ||
| 50 | u16 major_function; | ||
| 51 | u16 minor_function; | ||
| 52 | u16 length; | ||
| 53 | u16 status; | ||
| 54 | u16 offset; | ||
| 55 | u16 id; | ||
| 56 | u8 func_specific[1]; | ||
| 57 | }; | ||
| 58 | 48 | ||
| 59 | #define FLASH_OK 0x000000 | 49 | #define FLASH_OK 0x000000 |
| 60 | #define FAIL_OPEN_BIOS_FILE 0x000100 | 50 | #define FAIL_OPEN_BIOS_FILE 0x000100 |
diff --git a/drivers/scsi/pm8001/pm8001_hwi.c b/drivers/scsi/pm8001/pm8001_hwi.c index a3de306b904..9b44c6f1b10 100644 --- a/drivers/scsi/pm8001/pm8001_hwi.c +++ b/drivers/scsi/pm8001/pm8001_hwi.c | |||
| @@ -373,10 +373,7 @@ static int bar4_shift(struct pm8001_hba_info *pm8001_ha, u32 shiftValue) | |||
| 373 | static void __devinit | 373 | static void __devinit |
| 374 | mpi_set_phys_g3_with_ssc(struct pm8001_hba_info *pm8001_ha, u32 SSCbit) | 374 | mpi_set_phys_g3_with_ssc(struct pm8001_hba_info *pm8001_ha, u32 SSCbit) |
| 375 | { | 375 | { |
| 376 | u32 offset; | 376 | u32 value, offset, i; |
| 377 | u32 value; | ||
| 378 | u32 i, j; | ||
| 379 | u32 bit_cnt; | ||
| 380 | 377 | ||
| 381 | #define SAS2_SETTINGS_LOCAL_PHY_0_3_SHIFT_ADDR 0x00030000 | 378 | #define SAS2_SETTINGS_LOCAL_PHY_0_3_SHIFT_ADDR 0x00030000 |
| 382 | #define SAS2_SETTINGS_LOCAL_PHY_4_7_SHIFT_ADDR 0x00040000 | 379 | #define SAS2_SETTINGS_LOCAL_PHY_4_7_SHIFT_ADDR 0x00040000 |
| @@ -392,55 +389,35 @@ mpi_set_phys_g3_with_ssc(struct pm8001_hba_info *pm8001_ha, u32 SSCbit) | |||
| 392 | */ | 389 | */ |
| 393 | if (-1 == bar4_shift(pm8001_ha, SAS2_SETTINGS_LOCAL_PHY_0_3_SHIFT_ADDR)) | 390 | if (-1 == bar4_shift(pm8001_ha, SAS2_SETTINGS_LOCAL_PHY_0_3_SHIFT_ADDR)) |
| 394 | return; | 391 | return; |
| 395 | /* set SSC bit of PHY 0 - 3 */ | 392 | |
| 396 | for (i = 0; i < 4; i++) { | 393 | for (i = 0; i < 4; i++) { |
| 397 | offset = SAS2_SETTINGS_LOCAL_PHY_0_3_OFFSET + 0x4000 * i; | 394 | offset = SAS2_SETTINGS_LOCAL_PHY_0_3_OFFSET + 0x4000 * i; |
| 398 | value = pm8001_cr32(pm8001_ha, 2, offset); | 395 | pm8001_cw32(pm8001_ha, 2, offset, 0x80001501); |
| 399 | if (SSCbit) { | ||
| 400 | value |= 0x00000001 << PHY_G3_WITH_SSC_BIT_SHIFT; | ||
| 401 | value &= ~(0x00000001 << PHY_G3_WITHOUT_SSC_BIT_SHIFT); | ||
| 402 | } else { | ||
| 403 | value |= 0x00000001 << PHY_G3_WITHOUT_SSC_BIT_SHIFT; | ||
| 404 | value &= ~(0x00000001 << PHY_G3_WITH_SSC_BIT_SHIFT); | ||
| 405 | } | ||
| 406 | bit_cnt = 0; | ||
| 407 | for (j = 0; j < 31; j++) | ||
| 408 | if ((value >> j) & 0x00000001) | ||
| 409 | bit_cnt++; | ||
| 410 | if (bit_cnt % 2) | ||
| 411 | value &= ~(0x00000001 << SNW3_PHY_CAPABILITIES_PARITY); | ||
| 412 | else | ||
| 413 | value |= 0x00000001 << SNW3_PHY_CAPABILITIES_PARITY; | ||
| 414 | |||
| 415 | pm8001_cw32(pm8001_ha, 2, offset, value); | ||
| 416 | } | 396 | } |
| 417 | |||
| 418 | /* shift membase 3 for SAS2_SETTINGS_LOCAL_PHY 4 - 7 */ | 397 | /* shift membase 3 for SAS2_SETTINGS_LOCAL_PHY 4 - 7 */ |
| 419 | if (-1 == bar4_shift(pm8001_ha, SAS2_SETTINGS_LOCAL_PHY_4_7_SHIFT_ADDR)) | 398 | if (-1 == bar4_shift(pm8001_ha, SAS2_SETTINGS_LOCAL_PHY_4_7_SHIFT_ADDR)) |
| 420 | return; | 399 | return; |
| 421 | |||
| 422 | /* set SSC bit of PHY 4 - 7 */ | ||
| 423 | for (i = 4; i < 8; i++) { | 400 | for (i = 4; i < 8; i++) { |
| 424 | offset = SAS2_SETTINGS_LOCAL_PHY_4_7_OFFSET + 0x4000 * (i-4); | 401 | offset = SAS2_SETTINGS_LOCAL_PHY_4_7_OFFSET + 0x4000 * (i-4); |
| 425 | value = pm8001_cr32(pm8001_ha, 2, offset); | 402 | pm8001_cw32(pm8001_ha, 2, offset, 0x80001501); |
| 426 | if (SSCbit) { | ||
| 427 | value |= 0x00000001 << PHY_G3_WITH_SSC_BIT_SHIFT; | ||
| 428 | value &= ~(0x00000001 << PHY_G3_WITHOUT_SSC_BIT_SHIFT); | ||
| 429 | } else { | ||
| 430 | value |= 0x00000001 << PHY_G3_WITHOUT_SSC_BIT_SHIFT; | ||
| 431 | value &= ~(0x00000001 << PHY_G3_WITH_SSC_BIT_SHIFT); | ||
| 432 | } | ||
| 433 | bit_cnt = 0; | ||
| 434 | for (j = 0; j < 31; j++) | ||
| 435 | if ((value >> j) & 0x00000001) | ||
| 436 | bit_cnt++; | ||
| 437 | if (bit_cnt % 2) | ||
| 438 | value &= ~(0x00000001 << SNW3_PHY_CAPABILITIES_PARITY); | ||
| 439 | else | ||
| 440 | value |= 0x00000001 << SNW3_PHY_CAPABILITIES_PARITY; | ||
| 441 | |||
| 442 | pm8001_cw32(pm8001_ha, 2, offset, value); | ||
| 443 | } | 403 | } |
| 404 | /************************************************************* | ||
| 405 | Change the SSC upspreading value to 0x0 so that upspreading is disabled. | ||
| 406 | Device MABC SMOD0 Controls | ||
| 407 | Address: (via MEMBASE-III): | ||
| 408 | Using shifted destination address 0x0_0000: with Offset 0xD8 | ||
| 409 | |||
| 410 | 31:28 R/W Reserved Do not change | ||
| 411 | 27:24 R/W SAS_SMOD_SPRDUP 0000 | ||
| 412 | 23:20 R/W SAS_SMOD_SPRDDN 0000 | ||
| 413 | 19:0 R/W Reserved Do not change | ||
| 414 | Upon power-up this register will read as 0x8990c016, | ||
| 415 | and I would like you to change the SAS_SMOD_SPRDUP bits to 0b0000 | ||
| 416 | so that the written value will be 0x8090c016. | ||
| 417 | This will ensure only down-spreading SSC is enabled on the SPC. | ||
| 418 | *************************************************************/ | ||
| 419 | value = pm8001_cr32(pm8001_ha, 2, 0xd8); | ||
| 420 | pm8001_cw32(pm8001_ha, 2, 0xd8, 0x8000C016); | ||
| 444 | 421 | ||
| 445 | /*set the shifted destination address to 0x0 to avoid error operation */ | 422 | /*set the shifted destination address to 0x0 to avoid error operation */ |
| 446 | bar4_shift(pm8001_ha, 0x0); | 423 | bar4_shift(pm8001_ha, 0x0); |
| @@ -1901,7 +1878,7 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb) | |||
| 1901 | { | 1878 | { |
| 1902 | struct sas_task *t; | 1879 | struct sas_task *t; |
| 1903 | struct pm8001_ccb_info *ccb; | 1880 | struct pm8001_ccb_info *ccb; |
| 1904 | unsigned long flags; | 1881 | unsigned long flags = 0; |
| 1905 | u32 param; | 1882 | u32 param; |
| 1906 | u32 status; | 1883 | u32 status; |
| 1907 | u32 tag; | 1884 | u32 tag; |
| @@ -2040,7 +2017,9 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb) | |||
| 2040 | ts->stat = SAS_QUEUE_FULL; | 2017 | ts->stat = SAS_QUEUE_FULL; |
| 2041 | pm8001_ccb_task_free(pm8001_ha, t, ccb, tag); | 2018 | pm8001_ccb_task_free(pm8001_ha, t, ccb, tag); |
| 2042 | mb();/*in order to force CPU ordering*/ | 2019 | mb();/*in order to force CPU ordering*/ |
| 2020 | spin_unlock_irqrestore(&pm8001_ha->lock, flags); | ||
| 2043 | t->task_done(t); | 2021 | t->task_done(t); |
| 2022 | spin_lock_irqsave(&pm8001_ha->lock, flags); | ||
| 2044 | return; | 2023 | return; |
| 2045 | } | 2024 | } |
| 2046 | break; | 2025 | break; |
| @@ -2058,7 +2037,9 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb) | |||
| 2058 | ts->stat = SAS_QUEUE_FULL; | 2037 | ts->stat = SAS_QUEUE_FULL; |
| 2059 | pm8001_ccb_task_free(pm8001_ha, t, ccb, tag); | 2038 | pm8001_ccb_task_free(pm8001_ha, t, ccb, tag); |
| 2060 | mb();/*ditto*/ | 2039 | mb();/*ditto*/ |
| 2040 | spin_unlock_irqrestore(&pm8001_ha->lock, flags); | ||
| 2061 | t->task_done(t); | 2041 | t->task_done(t); |
| 2042 | spin_lock_irqsave(&pm8001_ha->lock, flags); | ||
| 2062 | return; | 2043 | return; |
| 2063 | } | 2044 | } |
| 2064 | break; | 2045 | break; |
| @@ -2084,7 +2065,9 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb) | |||
| 2084 | ts->stat = SAS_QUEUE_FULL; | 2065 | ts->stat = SAS_QUEUE_FULL; |
| 2085 | pm8001_ccb_task_free(pm8001_ha, t, ccb, tag); | 2066 | pm8001_ccb_task_free(pm8001_ha, t, ccb, tag); |
| 2086 | mb();/* ditto*/ | 2067 | mb();/* ditto*/ |
| 2068 | spin_unlock_irqrestore(&pm8001_ha->lock, flags); | ||
| 2087 | t->task_done(t); | 2069 | t->task_done(t); |
| 2070 | spin_lock_irqsave(&pm8001_ha->lock, flags); | ||
| 2088 | return; | 2071 | return; |
| 2089 | } | 2072 | } |
| 2090 | break; | 2073 | break; |
| @@ -2149,7 +2132,9 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb) | |||
| 2149 | ts->stat = SAS_QUEUE_FULL; | 2132 | ts->stat = SAS_QUEUE_FULL; |
| 2150 | pm8001_ccb_task_free(pm8001_ha, t, ccb, tag); | 2133 | pm8001_ccb_task_free(pm8001_ha, t, ccb, tag); |
| 2151 | mb();/*ditto*/ | 2134 | mb();/*ditto*/ |
| 2135 | spin_unlock_irqrestore(&pm8001_ha->lock, flags); | ||
| 2152 | t->task_done(t); | 2136 | t->task_done(t); |
| 2137 | spin_lock_irqsave(&pm8001_ha->lock, flags); | ||
| 2153 | return; | 2138 | return; |
| 2154 | } | 2139 | } |
| 2155 | break; | 2140 | break; |
| @@ -2171,7 +2156,9 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb) | |||
| 2171 | ts->stat = SAS_QUEUE_FULL; | 2156 | ts->stat = SAS_QUEUE_FULL; |
| 2172 | pm8001_ccb_task_free(pm8001_ha, t, ccb, tag); | 2157 | pm8001_ccb_task_free(pm8001_ha, t, ccb, tag); |
| 2173 | mb();/*ditto*/ | 2158 | mb();/*ditto*/ |
| 2159 | spin_unlock_irqrestore(&pm8001_ha->lock, flags); | ||
| 2174 | t->task_done(t); | 2160 | t->task_done(t); |
| 2161 | spin_lock_irqsave(&pm8001_ha->lock, flags); | ||
| 2175 | return; | 2162 | return; |
| 2176 | } | 2163 | } |
| 2177 | break; | 2164 | break; |
| @@ -2200,11 +2187,20 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb) | |||
| 2200 | " resp 0x%x stat 0x%x but aborted by upper layer!\n", | 2187 | " resp 0x%x stat 0x%x but aborted by upper layer!\n", |
| 2201 | t, status, ts->resp, ts->stat)); | 2188 | t, status, ts->resp, ts->stat)); |
| 2202 | pm8001_ccb_task_free(pm8001_ha, t, ccb, tag); | 2189 | pm8001_ccb_task_free(pm8001_ha, t, ccb, tag); |
| 2203 | } else { | 2190 | } else if (t->uldd_task) { |
| 2204 | spin_unlock_irqrestore(&t->task_state_lock, flags); | 2191 | spin_unlock_irqrestore(&t->task_state_lock, flags); |
| 2205 | pm8001_ccb_task_free(pm8001_ha, t, ccb, tag); | 2192 | pm8001_ccb_task_free(pm8001_ha, t, ccb, tag); |
| 2206 | mb();/* ditto */ | 2193 | mb();/* ditto */ |
| 2194 | spin_unlock_irqrestore(&pm8001_ha->lock, flags); | ||
| 2207 | t->task_done(t); | 2195 | t->task_done(t); |
| 2196 | spin_lock_irqsave(&pm8001_ha->lock, flags); | ||
| 2197 | } else if (!t->uldd_task) { | ||
| 2198 | spin_unlock_irqrestore(&t->task_state_lock, flags); | ||
| 2199 | pm8001_ccb_task_free(pm8001_ha, t, ccb, tag); | ||
| 2200 | mb();/*ditto*/ | ||
| 2201 | spin_unlock_irqrestore(&pm8001_ha->lock, flags); | ||
| 2202 | t->task_done(t); | ||
| 2203 | spin_lock_irqsave(&pm8001_ha->lock, flags); | ||
| 2208 | } | 2204 | } |
| 2209 | } | 2205 | } |
| 2210 | 2206 | ||
| @@ -2212,7 +2208,7 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb) | |||
| 2212 | static void mpi_sata_event(struct pm8001_hba_info *pm8001_ha , void *piomb) | 2208 | static void mpi_sata_event(struct pm8001_hba_info *pm8001_ha , void *piomb) |
| 2213 | { | 2209 | { |
| 2214 | struct sas_task *t; | 2210 | struct sas_task *t; |
| 2215 | unsigned long flags; | 2211 | unsigned long flags = 0; |
| 2216 | struct task_status_struct *ts; | 2212 | struct task_status_struct *ts; |
| 2217 | struct pm8001_ccb_info *ccb; | 2213 | struct pm8001_ccb_info *ccb; |
| 2218 | struct pm8001_device *pm8001_dev; | 2214 | struct pm8001_device *pm8001_dev; |
| @@ -2292,7 +2288,9 @@ static void mpi_sata_event(struct pm8001_hba_info *pm8001_ha , void *piomb) | |||
| 2292 | ts->stat = SAS_QUEUE_FULL; | 2288 | ts->stat = SAS_QUEUE_FULL; |
| 2293 | pm8001_ccb_task_free(pm8001_ha, t, ccb, tag); | 2289 | pm8001_ccb_task_free(pm8001_ha, t, ccb, tag); |
| 2294 | mb();/*ditto*/ | 2290 | mb();/*ditto*/ |
| 2291 | spin_unlock_irqrestore(&pm8001_ha->lock, flags); | ||
| 2295 | t->task_done(t); | 2292 | t->task_done(t); |
| 2293 | spin_lock_irqsave(&pm8001_ha->lock, flags); | ||
| 2296 | return; | 2294 | return; |
| 2297 | } | 2295 | } |
| 2298 | break; | 2296 | break; |
| @@ -2401,11 +2399,20 @@ static void mpi_sata_event(struct pm8001_hba_info *pm8001_ha , void *piomb) | |||
| 2401 | " resp 0x%x stat 0x%x but aborted by upper layer!\n", | 2399 | " resp 0x%x stat 0x%x but aborted by upper layer!\n", |
| 2402 | t, event, ts->resp, ts->stat)); | 2400 | t, event, ts->resp, ts->stat)); |
| 2403 | pm8001_ccb_task_free(pm8001_ha, t, ccb, tag); | 2401 | pm8001_ccb_task_free(pm8001_ha, t, ccb, tag); |
| 2404 | } else { | 2402 | } else if (t->uldd_task) { |
| 2405 | spin_unlock_irqrestore(&t->task_state_lock, flags); | 2403 | spin_unlock_irqrestore(&t->task_state_lock, flags); |
| 2406 | pm8001_ccb_task_free(pm8001_ha, t, ccb, tag); | 2404 | pm8001_ccb_task_free(pm8001_ha, t, ccb, tag); |
| 2407 | mb();/* in order to force CPU ordering */ | 2405 | mb();/* ditto */ |
| 2406 | spin_unlock_irqrestore(&pm8001_ha->lock, flags); | ||
| 2408 | t->task_done(t); | 2407 | t->task_done(t); |
| 2408 | spin_lock_irqsave(&pm8001_ha->lock, flags); | ||
| 2409 | } else if (!t->uldd_task) { | ||
| 2410 | spin_unlock_irqrestore(&t->task_state_lock, flags); | ||
| 2411 | pm8001_ccb_task_free(pm8001_ha, t, ccb, tag); | ||
| 2412 | mb();/*ditto*/ | ||
| 2413 | spin_unlock_irqrestore(&pm8001_ha->lock, flags); | ||
| 2414 | t->task_done(t); | ||
| 2415 | spin_lock_irqsave(&pm8001_ha->lock, flags); | ||
| 2409 | } | 2416 | } |
| 2410 | } | 2417 | } |
| 2411 | 2418 | ||
| @@ -2876,15 +2883,20 @@ hw_event_sas_phy_up(struct pm8001_hba_info *pm8001_ha, void *piomb) | |||
| 2876 | le32_to_cpu(pPayload->lr_evt_status_phyid_portid); | 2883 | le32_to_cpu(pPayload->lr_evt_status_phyid_portid); |
| 2877 | u8 link_rate = | 2884 | u8 link_rate = |
| 2878 | (u8)((lr_evt_status_phyid_portid & 0xF0000000) >> 28); | 2885 | (u8)((lr_evt_status_phyid_portid & 0xF0000000) >> 28); |
| 2886 | u8 port_id = (u8)(lr_evt_status_phyid_portid & 0x0000000F); | ||
| 2879 | u8 phy_id = | 2887 | u8 phy_id = |
| 2880 | (u8)((lr_evt_status_phyid_portid & 0x000000F0) >> 4); | 2888 | (u8)((lr_evt_status_phyid_portid & 0x000000F0) >> 4); |
| 2889 | u32 npip_portstate = le32_to_cpu(pPayload->npip_portstate); | ||
| 2890 | u8 portstate = (u8)(npip_portstate & 0x0000000F); | ||
| 2891 | struct pm8001_port *port = &pm8001_ha->port[port_id]; | ||
| 2881 | struct sas_ha_struct *sas_ha = pm8001_ha->sas; | 2892 | struct sas_ha_struct *sas_ha = pm8001_ha->sas; |
| 2882 | struct pm8001_phy *phy = &pm8001_ha->phy[phy_id]; | 2893 | struct pm8001_phy *phy = &pm8001_ha->phy[phy_id]; |
| 2883 | unsigned long flags; | 2894 | unsigned long flags; |
| 2884 | u8 deviceType = pPayload->sas_identify.dev_type; | 2895 | u8 deviceType = pPayload->sas_identify.dev_type; |
| 2885 | 2896 | port->port_state = portstate; | |
| 2886 | PM8001_MSG_DBG(pm8001_ha, | 2897 | PM8001_MSG_DBG(pm8001_ha, |
| 2887 | pm8001_printk("HW_EVENT_SAS_PHY_UP \n")); | 2898 | pm8001_printk("HW_EVENT_SAS_PHY_UP port id = %d, phy id = %d\n", |
| 2899 | port_id, phy_id)); | ||
| 2888 | 2900 | ||
| 2889 | switch (deviceType) { | 2901 | switch (deviceType) { |
| 2890 | case SAS_PHY_UNUSED: | 2902 | case SAS_PHY_UNUSED: |
| @@ -2895,16 +2907,19 @@ hw_event_sas_phy_up(struct pm8001_hba_info *pm8001_ha, void *piomb) | |||
| 2895 | PM8001_MSG_DBG(pm8001_ha, pm8001_printk("end device.\n")); | 2907 | PM8001_MSG_DBG(pm8001_ha, pm8001_printk("end device.\n")); |
| 2896 | pm8001_chip_phy_ctl_req(pm8001_ha, phy_id, | 2908 | pm8001_chip_phy_ctl_req(pm8001_ha, phy_id, |
| 2897 | PHY_NOTIFY_ENABLE_SPINUP); | 2909 | PHY_NOTIFY_ENABLE_SPINUP); |
| 2910 | port->port_attached = 1; | ||
| 2898 | get_lrate_mode(phy, link_rate); | 2911 | get_lrate_mode(phy, link_rate); |
| 2899 | break; | 2912 | break; |
| 2900 | case SAS_EDGE_EXPANDER_DEVICE: | 2913 | case SAS_EDGE_EXPANDER_DEVICE: |
| 2901 | PM8001_MSG_DBG(pm8001_ha, | 2914 | PM8001_MSG_DBG(pm8001_ha, |
| 2902 | pm8001_printk("expander device.\n")); | 2915 | pm8001_printk("expander device.\n")); |
| 2916 | port->port_attached = 1; | ||
| 2903 | get_lrate_mode(phy, link_rate); | 2917 | get_lrate_mode(phy, link_rate); |
| 2904 | break; | 2918 | break; |
| 2905 | case SAS_FANOUT_EXPANDER_DEVICE: | 2919 | case SAS_FANOUT_EXPANDER_DEVICE: |
| 2906 | PM8001_MSG_DBG(pm8001_ha, | 2920 | PM8001_MSG_DBG(pm8001_ha, |
| 2907 | pm8001_printk("fanout expander device.\n")); | 2921 | pm8001_printk("fanout expander device.\n")); |
| 2922 | port->port_attached = 1; | ||
| 2908 | get_lrate_mode(phy, link_rate); | 2923 | get_lrate_mode(phy, link_rate); |
| 2909 | break; | 2924 | break; |
| 2910 | default: | 2925 | default: |
| @@ -2946,11 +2961,20 @@ hw_event_sata_phy_up(struct pm8001_hba_info *pm8001_ha, void *piomb) | |||
| 2946 | le32_to_cpu(pPayload->lr_evt_status_phyid_portid); | 2961 | le32_to_cpu(pPayload->lr_evt_status_phyid_portid); |
| 2947 | u8 link_rate = | 2962 | u8 link_rate = |
| 2948 | (u8)((lr_evt_status_phyid_portid & 0xF0000000) >> 28); | 2963 | (u8)((lr_evt_status_phyid_portid & 0xF0000000) >> 28); |
| 2964 | u8 port_id = (u8)(lr_evt_status_phyid_portid & 0x0000000F); | ||
| 2949 | u8 phy_id = | 2965 | u8 phy_id = |
| 2950 | (u8)((lr_evt_status_phyid_portid & 0x000000F0) >> 4); | 2966 | (u8)((lr_evt_status_phyid_portid & 0x000000F0) >> 4); |
| 2967 | u32 npip_portstate = le32_to_cpu(pPayload->npip_portstate); | ||
| 2968 | u8 portstate = (u8)(npip_portstate & 0x0000000F); | ||
| 2969 | struct pm8001_port *port = &pm8001_ha->port[port_id]; | ||
| 2951 | struct sas_ha_struct *sas_ha = pm8001_ha->sas; | 2970 | struct sas_ha_struct *sas_ha = pm8001_ha->sas; |
| 2952 | struct pm8001_phy *phy = &pm8001_ha->phy[phy_id]; | 2971 | struct pm8001_phy *phy = &pm8001_ha->phy[phy_id]; |
| 2953 | unsigned long flags; | 2972 | unsigned long flags; |
| 2973 | PM8001_MSG_DBG(pm8001_ha, | ||
| 2974 | pm8001_printk("HW_EVENT_SATA_PHY_UP port id = %d," | ||
| 2975 | " phy id = %d\n", port_id, phy_id)); | ||
| 2976 | port->port_state = portstate; | ||
| 2977 | port->port_attached = 1; | ||
| 2954 | get_lrate_mode(phy, link_rate); | 2978 | get_lrate_mode(phy, link_rate); |
| 2955 | phy->phy_type |= PORT_TYPE_SATA; | 2979 | phy->phy_type |= PORT_TYPE_SATA; |
| 2956 | phy->phy_attached = 1; | 2980 | phy->phy_attached = 1; |
| @@ -2984,7 +3008,13 @@ hw_event_phy_down(struct pm8001_hba_info *pm8001_ha, void *piomb) | |||
| 2984 | (u8)((lr_evt_status_phyid_portid & 0x000000F0) >> 4); | 3008 | (u8)((lr_evt_status_phyid_portid & 0x000000F0) >> 4); |
| 2985 | u32 npip_portstate = le32_to_cpu(pPayload->npip_portstate); | 3009 | u32 npip_portstate = le32_to_cpu(pPayload->npip_portstate); |
| 2986 | u8 portstate = (u8)(npip_portstate & 0x0000000F); | 3010 | u8 portstate = (u8)(npip_portstate & 0x0000000F); |
| 2987 | 3011 | struct pm8001_port *port = &pm8001_ha->port[port_id]; | |
| 3012 | struct pm8001_phy *phy = &pm8001_ha->phy[phy_id]; | ||
| 3013 | port->port_state = portstate; | ||
| 3014 | phy->phy_type = 0; | ||
| 3015 | phy->identify.device_type = 0; | ||
| 3016 | phy->phy_attached = 0; | ||
| 3017 | memset(&phy->dev_sas_addr, 0, SAS_ADDR_SIZE); | ||
| 2988 | switch (portstate) { | 3018 | switch (portstate) { |
| 2989 | case PORT_VALID: | 3019 | case PORT_VALID: |
| 2990 | break; | 3020 | break; |
| @@ -2993,26 +3023,30 @@ hw_event_phy_down(struct pm8001_hba_info *pm8001_ha, void *piomb) | |||
| 2993 | pm8001_printk(" PortInvalid portID %d \n", port_id)); | 3023 | pm8001_printk(" PortInvalid portID %d \n", port_id)); |
| 2994 | PM8001_MSG_DBG(pm8001_ha, | 3024 | PM8001_MSG_DBG(pm8001_ha, |
| 2995 | pm8001_printk(" Last phy Down and port invalid\n")); | 3025 | pm8001_printk(" Last phy Down and port invalid\n")); |
| 3026 | port->port_attached = 0; | ||
| 2996 | pm8001_hw_event_ack_req(pm8001_ha, 0, HW_EVENT_PHY_DOWN, | 3027 | pm8001_hw_event_ack_req(pm8001_ha, 0, HW_EVENT_PHY_DOWN, |
| 2997 | port_id, phy_id, 0, 0); | 3028 | port_id, phy_id, 0, 0); |
| 2998 | break; | 3029 | break; |
| 2999 | case PORT_IN_RESET: | 3030 | case PORT_IN_RESET: |
| 3000 | PM8001_MSG_DBG(pm8001_ha, | 3031 | PM8001_MSG_DBG(pm8001_ha, |
| 3001 | pm8001_printk(" PortInReset portID %d \n", port_id)); | 3032 | pm8001_printk(" Port In Reset portID %d \n", port_id)); |
| 3002 | break; | 3033 | break; |
| 3003 | case PORT_NOT_ESTABLISHED: | 3034 | case PORT_NOT_ESTABLISHED: |
| 3004 | PM8001_MSG_DBG(pm8001_ha, | 3035 | PM8001_MSG_DBG(pm8001_ha, |
| 3005 | pm8001_printk(" phy Down and PORT_NOT_ESTABLISHED\n")); | 3036 | pm8001_printk(" phy Down and PORT_NOT_ESTABLISHED\n")); |
| 3037 | port->port_attached = 0; | ||
| 3006 | break; | 3038 | break; |
| 3007 | case PORT_LOSTCOMM: | 3039 | case PORT_LOSTCOMM: |
| 3008 | PM8001_MSG_DBG(pm8001_ha, | 3040 | PM8001_MSG_DBG(pm8001_ha, |
| 3009 | pm8001_printk(" phy Down and PORT_LOSTCOMM\n")); | 3041 | pm8001_printk(" phy Down and PORT_LOSTCOMM\n")); |
| 3010 | PM8001_MSG_DBG(pm8001_ha, | 3042 | PM8001_MSG_DBG(pm8001_ha, |
| 3011 | pm8001_printk(" Last phy Down and port invalid\n")); | 3043 | pm8001_printk(" Last phy Down and port invalid\n")); |
| 3044 | port->port_attached = 0; | ||
| 3012 | pm8001_hw_event_ack_req(pm8001_ha, 0, HW_EVENT_PHY_DOWN, | 3045 | pm8001_hw_event_ack_req(pm8001_ha, 0, HW_EVENT_PHY_DOWN, |
| 3013 | port_id, phy_id, 0, 0); | 3046 | port_id, phy_id, 0, 0); |
| 3014 | break; | 3047 | break; |
| 3015 | default: | 3048 | default: |
| 3049 | port->port_attached = 0; | ||
| 3016 | PM8001_MSG_DBG(pm8001_ha, | 3050 | PM8001_MSG_DBG(pm8001_ha, |
| 3017 | pm8001_printk(" phy Down and(default) = %x\n", | 3051 | pm8001_printk(" phy Down and(default) = %x\n", |
| 3018 | portstate)); | 3052 | portstate)); |
| @@ -3770,7 +3804,8 @@ static int pm8001_chip_ssp_io_req(struct pm8001_hba_info *pm8001_ha, | |||
| 3770 | u32 opc = OPC_INB_SSPINIIOSTART; | 3804 | u32 opc = OPC_INB_SSPINIIOSTART; |
| 3771 | memset(&ssp_cmd, 0, sizeof(ssp_cmd)); | 3805 | memset(&ssp_cmd, 0, sizeof(ssp_cmd)); |
| 3772 | memcpy(ssp_cmd.ssp_iu.lun, task->ssp_task.LUN, 8); | 3806 | memcpy(ssp_cmd.ssp_iu.lun, task->ssp_task.LUN, 8); |
| 3773 | ssp_cmd.dir_m_tlr = data_dir_flags[task->data_dir] << 8 | 0x0;/*0 for | 3807 | ssp_cmd.dir_m_tlr = |
| 3808 | cpu_to_le32(data_dir_flags[task->data_dir] << 8 | 0x0);/*0 for | ||
| 3774 | SAS 1.1 compatible TLR*/ | 3809 | SAS 1.1 compatible TLR*/ |
| 3775 | ssp_cmd.data_len = cpu_to_le32(task->total_xfer_len); | 3810 | ssp_cmd.data_len = cpu_to_le32(task->total_xfer_len); |
| 3776 | ssp_cmd.device_id = cpu_to_le32(pm8001_dev->device_id); | 3811 | ssp_cmd.device_id = cpu_to_le32(pm8001_dev->device_id); |
| @@ -3841,7 +3876,7 @@ static int pm8001_chip_sata_req(struct pm8001_hba_info *pm8001_ha, | |||
| 3841 | } | 3876 | } |
| 3842 | } | 3877 | } |
| 3843 | if (task->ata_task.use_ncq && pm8001_get_ncq_tag(task, &hdr_tag)) | 3878 | if (task->ata_task.use_ncq && pm8001_get_ncq_tag(task, &hdr_tag)) |
| 3844 | ncg_tag = cpu_to_le32(hdr_tag); | 3879 | ncg_tag = hdr_tag; |
| 3845 | dir = data_dir_flags[task->data_dir] << 8; | 3880 | dir = data_dir_flags[task->data_dir] << 8; |
| 3846 | sata_cmd.tag = cpu_to_le32(tag); | 3881 | sata_cmd.tag = cpu_to_le32(tag); |
| 3847 | sata_cmd.device_id = cpu_to_le32(pm8001_ha_dev->device_id); | 3882 | sata_cmd.device_id = cpu_to_le32(pm8001_ha_dev->device_id); |
| @@ -3986,7 +4021,7 @@ static int pm8001_chip_reg_dev_req(struct pm8001_hba_info *pm8001_ha, | |||
| 3986 | ((stp_sspsmp_sata & 0x03) * 0x10000000)); | 4021 | ((stp_sspsmp_sata & 0x03) * 0x10000000)); |
| 3987 | payload.firstburstsize_ITNexustimeout = | 4022 | payload.firstburstsize_ITNexustimeout = |
| 3988 | cpu_to_le32(ITNT | (firstBurstSize * 0x10000)); | 4023 | cpu_to_le32(ITNT | (firstBurstSize * 0x10000)); |
| 3989 | memcpy(&payload.sas_addr_hi, pm8001_dev->sas_device->sas_addr, | 4024 | memcpy(payload.sas_addr, pm8001_dev->sas_device->sas_addr, |
| 3990 | SAS_ADDR_SIZE); | 4025 | SAS_ADDR_SIZE); |
| 3991 | rc = mpi_build_cmd(pm8001_ha, circularQ, opc, &payload); | 4026 | rc = mpi_build_cmd(pm8001_ha, circularQ, opc, &payload); |
| 3992 | return rc; | 4027 | return rc; |
| @@ -4027,7 +4062,7 @@ static int pm8001_chip_phy_ctl_req(struct pm8001_hba_info *pm8001_ha, | |||
| 4027 | struct inbound_queue_table *circularQ; | 4062 | struct inbound_queue_table *circularQ; |
| 4028 | int ret; | 4063 | int ret; |
| 4029 | u32 opc = OPC_INB_LOCAL_PHY_CONTROL; | 4064 | u32 opc = OPC_INB_LOCAL_PHY_CONTROL; |
| 4030 | memset((u8 *)&payload, 0, sizeof(payload)); | 4065 | memset(&payload, 0, sizeof(payload)); |
| 4031 | circularQ = &pm8001_ha->inbnd_q_tbl[0]; | 4066 | circularQ = &pm8001_ha->inbnd_q_tbl[0]; |
| 4032 | payload.tag = 1; | 4067 | payload.tag = 1; |
| 4033 | payload.phyop_phyid = | 4068 | payload.phyop_phyid = |
diff --git a/drivers/scsi/pm8001/pm8001_hwi.h b/drivers/scsi/pm8001/pm8001_hwi.h index 96e4daa68b8..833a5201eda 100644 --- a/drivers/scsi/pm8001/pm8001_hwi.h +++ b/drivers/scsi/pm8001/pm8001_hwi.h | |||
| @@ -242,8 +242,7 @@ struct reg_dev_req { | |||
| 242 | __le32 phyid_portid; | 242 | __le32 phyid_portid; |
| 243 | __le32 dtype_dlr_retry; | 243 | __le32 dtype_dlr_retry; |
| 244 | __le32 firstburstsize_ITNexustimeout; | 244 | __le32 firstburstsize_ITNexustimeout; |
| 245 | u32 sas_addr_hi; | 245 | u8 sas_addr[SAS_ADDR_SIZE]; |
| 246 | u32 sas_addr_low; | ||
| 247 | __le32 upper_device_id; | 246 | __le32 upper_device_id; |
| 248 | u32 reserved[8]; | 247 | u32 reserved[8]; |
| 249 | } __attribute__((packed, aligned(4))); | 248 | } __attribute__((packed, aligned(4))); |
diff --git a/drivers/scsi/pm8001/pm8001_init.c b/drivers/scsi/pm8001/pm8001_init.c index 42ebe725d5a..c2f1032496c 100644 --- a/drivers/scsi/pm8001/pm8001_init.c +++ b/drivers/scsi/pm8001/pm8001_init.c | |||
| @@ -200,8 +200,13 @@ static int __devinit pm8001_alloc(struct pm8001_hba_info *pm8001_ha) | |||
| 200 | { | 200 | { |
| 201 | int i; | 201 | int i; |
| 202 | spin_lock_init(&pm8001_ha->lock); | 202 | spin_lock_init(&pm8001_ha->lock); |
| 203 | for (i = 0; i < pm8001_ha->chip->n_phy; i++) | 203 | for (i = 0; i < pm8001_ha->chip->n_phy; i++) { |
| 204 | pm8001_phy_init(pm8001_ha, i); | 204 | pm8001_phy_init(pm8001_ha, i); |
| 205 | pm8001_ha->port[i].wide_port_phymap = 0; | ||
| 206 | pm8001_ha->port[i].port_attached = 0; | ||
| 207 | pm8001_ha->port[i].port_state = 0; | ||
| 208 | INIT_LIST_HEAD(&pm8001_ha->port[i].list); | ||
| 209 | } | ||
| 205 | 210 | ||
| 206 | pm8001_ha->tags = kzalloc(PM8001_MAX_CCB, GFP_KERNEL); | 211 | pm8001_ha->tags = kzalloc(PM8001_MAX_CCB, GFP_KERNEL); |
| 207 | if (!pm8001_ha->tags) | 212 | if (!pm8001_ha->tags) |
| @@ -511,19 +516,23 @@ static void pm8001_init_sas_add(struct pm8001_hba_info *pm8001_ha) | |||
| 511 | u8 i; | 516 | u8 i; |
| 512 | #ifdef PM8001_READ_VPD | 517 | #ifdef PM8001_READ_VPD |
| 513 | DECLARE_COMPLETION_ONSTACK(completion); | 518 | DECLARE_COMPLETION_ONSTACK(completion); |
| 519 | struct pm8001_ioctl_payload payload; | ||
| 514 | pm8001_ha->nvmd_completion = &completion; | 520 | pm8001_ha->nvmd_completion = &completion; |
| 515 | PM8001_CHIP_DISP->get_nvmd_req(pm8001_ha, 0, 0); | 521 | payload.minor_function = 0; |
| 522 | payload.length = 128; | ||
| 523 | payload.func_specific = kzalloc(128, GFP_KERNEL); | ||
| 524 | PM8001_CHIP_DISP->get_nvmd_req(pm8001_ha, &payload); | ||
| 516 | wait_for_completion(&completion); | 525 | wait_for_completion(&completion); |
| 517 | for (i = 0; i < pm8001_ha->chip->n_phy; i++) { | 526 | for (i = 0; i < pm8001_ha->chip->n_phy; i++) { |
| 518 | memcpy(&pm8001_ha->phy[i].dev_sas_addr, pm8001_ha->sas_addr, | 527 | memcpy(&pm8001_ha->phy[i].dev_sas_addr, pm8001_ha->sas_addr, |
| 519 | SAS_ADDR_SIZE); | 528 | SAS_ADDR_SIZE); |
| 520 | PM8001_INIT_DBG(pm8001_ha, | 529 | PM8001_INIT_DBG(pm8001_ha, |
| 521 | pm8001_printk("phy %d sas_addr = %x \n", i, | 530 | pm8001_printk("phy %d sas_addr = %016llx \n", i, |
| 522 | (u64)pm8001_ha->phy[i].dev_sas_addr)); | 531 | pm8001_ha->phy[i].dev_sas_addr)); |
| 523 | } | 532 | } |
| 524 | #else | 533 | #else |
| 525 | for (i = 0; i < pm8001_ha->chip->n_phy; i++) { | 534 | for (i = 0; i < pm8001_ha->chip->n_phy; i++) { |
| 526 | pm8001_ha->phy[i].dev_sas_addr = 0x500e004010000004ULL; | 535 | pm8001_ha->phy[i].dev_sas_addr = 0x50010c600047f9d0ULL; |
| 527 | pm8001_ha->phy[i].dev_sas_addr = | 536 | pm8001_ha->phy[i].dev_sas_addr = |
| 528 | cpu_to_be64((u64) | 537 | cpu_to_be64((u64) |
| 529 | (*(u64 *)&pm8001_ha->phy[i].dev_sas_addr)); | 538 | (*(u64 *)&pm8001_ha->phy[i].dev_sas_addr)); |
diff --git a/drivers/scsi/pm8001/pm8001_sas.c b/drivers/scsi/pm8001/pm8001_sas.c index 1f767a0e727..7f9c83a7639 100644 --- a/drivers/scsi/pm8001/pm8001_sas.c +++ b/drivers/scsi/pm8001/pm8001_sas.c | |||
| @@ -329,6 +329,23 @@ int pm8001_slave_configure(struct scsi_device *sdev) | |||
| 329 | } | 329 | } |
| 330 | return 0; | 330 | return 0; |
| 331 | } | 331 | } |
| 332 | /* Find the local port id that's attached to this device */ | ||
| 333 | static int sas_find_local_port_id(struct domain_device *dev) | ||
| 334 | { | ||
| 335 | struct domain_device *pdev = dev->parent; | ||
| 336 | |||
| 337 | /* Directly attached device */ | ||
| 338 | if (!pdev) | ||
| 339 | return dev->port->id; | ||
| 340 | while (pdev) { | ||
| 341 | struct domain_device *pdev_p = pdev->parent; | ||
| 342 | if (!pdev_p) | ||
| 343 | return pdev->port->id; | ||
| 344 | pdev = pdev->parent; | ||
| 345 | } | ||
| 346 | return 0; | ||
| 347 | } | ||
| 348 | |||
| 332 | /** | 349 | /** |
| 333 | * pm8001_task_exec - queue the task(ssp, smp && ata) to the hardware. | 350 | * pm8001_task_exec - queue the task(ssp, smp && ata) to the hardware. |
| 334 | * @task: the task to be execute. | 351 | * @task: the task to be execute. |
| @@ -346,11 +363,12 @@ static int pm8001_task_exec(struct sas_task *task, const int num, | |||
| 346 | struct domain_device *dev = task->dev; | 363 | struct domain_device *dev = task->dev; |
| 347 | struct pm8001_hba_info *pm8001_ha; | 364 | struct pm8001_hba_info *pm8001_ha; |
| 348 | struct pm8001_device *pm8001_dev; | 365 | struct pm8001_device *pm8001_dev; |
| 366 | struct pm8001_port *port = NULL; | ||
| 349 | struct sas_task *t = task; | 367 | struct sas_task *t = task; |
| 350 | struct pm8001_ccb_info *ccb; | 368 | struct pm8001_ccb_info *ccb; |
| 351 | u32 tag = 0xdeadbeef, rc, n_elem = 0; | 369 | u32 tag = 0xdeadbeef, rc, n_elem = 0; |
| 352 | u32 n = num; | 370 | u32 n = num; |
| 353 | unsigned long flags = 0; | 371 | unsigned long flags = 0, flags_libsas = 0; |
| 354 | 372 | ||
| 355 | if (!dev->port) { | 373 | if (!dev->port) { |
| 356 | struct task_status_struct *tsm = &t->task_status; | 374 | struct task_status_struct *tsm = &t->task_status; |
| @@ -379,6 +397,35 @@ static int pm8001_task_exec(struct sas_task *task, const int num, | |||
| 379 | rc = SAS_PHY_DOWN; | 397 | rc = SAS_PHY_DOWN; |
| 380 | goto out_done; | 398 | goto out_done; |
| 381 | } | 399 | } |
| 400 | port = &pm8001_ha->port[sas_find_local_port_id(dev)]; | ||
| 401 | if (!port->port_attached) { | ||
| 402 | if (sas_protocol_ata(t->task_proto)) { | ||
| 403 | struct task_status_struct *ts = &t->task_status; | ||
| 404 | ts->resp = SAS_TASK_UNDELIVERED; | ||
| 405 | ts->stat = SAS_PHY_DOWN; | ||
| 406 | |||
| 407 | spin_unlock_irqrestore(&pm8001_ha->lock, flags); | ||
| 408 | spin_unlock_irqrestore(dev->sata_dev.ap->lock, | ||
| 409 | flags_libsas); | ||
| 410 | t->task_done(t); | ||
| 411 | spin_lock_irqsave(dev->sata_dev.ap->lock, | ||
| 412 | flags_libsas); | ||
| 413 | spin_lock_irqsave(&pm8001_ha->lock, flags); | ||
| 414 | if (n > 1) | ||
| 415 | t = list_entry(t->list.next, | ||
| 416 | struct sas_task, list); | ||
| 417 | continue; | ||
| 418 | } else { | ||
| 419 | struct task_status_struct *ts = &t->task_status; | ||
| 420 | ts->resp = SAS_TASK_UNDELIVERED; | ||
| 421 | ts->stat = SAS_PHY_DOWN; | ||
| 422 | t->task_done(t); | ||
| 423 | if (n > 1) | ||
| 424 | t = list_entry(t->list.next, | ||
| 425 | struct sas_task, list); | ||
| 426 | continue; | ||
| 427 | } | ||
| 428 | } | ||
| 382 | rc = pm8001_tag_alloc(pm8001_ha, &tag); | 429 | rc = pm8001_tag_alloc(pm8001_ha, &tag); |
| 383 | if (rc) | 430 | if (rc) |
| 384 | goto err_out; | 431 | goto err_out; |
| @@ -569,11 +616,11 @@ static int pm8001_dev_found_notify(struct domain_device *dev) | |||
| 569 | spin_lock_irqsave(&pm8001_ha->lock, flags); | 616 | spin_lock_irqsave(&pm8001_ha->lock, flags); |
| 570 | 617 | ||
| 571 | pm8001_device = pm8001_alloc_dev(pm8001_ha); | 618 | pm8001_device = pm8001_alloc_dev(pm8001_ha); |
| 572 | pm8001_device->sas_device = dev; | ||
| 573 | if (!pm8001_device) { | 619 | if (!pm8001_device) { |
| 574 | res = -1; | 620 | res = -1; |
| 575 | goto found_out; | 621 | goto found_out; |
| 576 | } | 622 | } |
| 623 | pm8001_device->sas_device = dev; | ||
| 577 | dev->lldd_dev = pm8001_device; | 624 | dev->lldd_dev = pm8001_device; |
| 578 | pm8001_device->dev_type = dev->dev_type; | 625 | pm8001_device->dev_type = dev->dev_type; |
| 579 | pm8001_device->dcompletion = &completion; | 626 | pm8001_device->dcompletion = &completion; |
| @@ -609,7 +656,7 @@ static int pm8001_dev_found_notify(struct domain_device *dev) | |||
| 609 | wait_for_completion(&completion); | 656 | wait_for_completion(&completion); |
| 610 | if (dev->dev_type == SAS_END_DEV) | 657 | if (dev->dev_type == SAS_END_DEV) |
| 611 | msleep(50); | 658 | msleep(50); |
| 612 | pm8001_ha->flags = PM8001F_RUN_TIME ; | 659 | pm8001_ha->flags |= PM8001F_RUN_TIME ; |
| 613 | return 0; | 660 | return 0; |
| 614 | found_out: | 661 | found_out: |
| 615 | spin_unlock_irqrestore(&pm8001_ha->lock, flags); | 662 | spin_unlock_irqrestore(&pm8001_ha->lock, flags); |
| @@ -772,7 +819,7 @@ pm8001_exec_internal_task_abort(struct pm8001_hba_info *pm8001_ha, | |||
| 772 | task->task_done = pm8001_task_done; | 819 | task->task_done = pm8001_task_done; |
| 773 | task->timer.data = (unsigned long)task; | 820 | task->timer.data = (unsigned long)task; |
| 774 | task->timer.function = pm8001_tmf_timedout; | 821 | task->timer.function = pm8001_tmf_timedout; |
| 775 | task->timer.expires = jiffies + PM8001_TASK_TIMEOUT*HZ; | 822 | task->timer.expires = jiffies + PM8001_TASK_TIMEOUT * HZ; |
| 776 | add_timer(&task->timer); | 823 | add_timer(&task->timer); |
| 777 | 824 | ||
| 778 | res = pm8001_tag_alloc(pm8001_ha, &ccb_tag); | 825 | res = pm8001_tag_alloc(pm8001_ha, &ccb_tag); |
| @@ -897,6 +944,8 @@ int pm8001_I_T_nexus_reset(struct domain_device *dev) | |||
| 897 | 944 | ||
| 898 | if (dev_is_sata(dev)) { | 945 | if (dev_is_sata(dev)) { |
| 899 | DECLARE_COMPLETION_ONSTACK(completion_setstate); | 946 | DECLARE_COMPLETION_ONSTACK(completion_setstate); |
| 947 | if (scsi_is_sas_phy_local(phy)) | ||
| 948 | return 0; | ||
| 900 | rc = sas_phy_reset(phy, 1); | 949 | rc = sas_phy_reset(phy, 1); |
| 901 | msleep(2000); | 950 | msleep(2000); |
| 902 | rc = pm8001_exec_internal_task_abort(pm8001_ha, pm8001_dev , | 951 | rc = pm8001_exec_internal_task_abort(pm8001_ha, pm8001_dev , |
diff --git a/drivers/scsi/pm8001/pm8001_sas.h b/drivers/scsi/pm8001/pm8001_sas.h index 30f2ede55a7..8e38ca8cd10 100644 --- a/drivers/scsi/pm8001/pm8001_sas.h +++ b/drivers/scsi/pm8001/pm8001_sas.h | |||
| @@ -59,11 +59,11 @@ | |||
| 59 | 59 | ||
| 60 | #define DRV_NAME "pm8001" | 60 | #define DRV_NAME "pm8001" |
| 61 | #define DRV_VERSION "0.1.36" | 61 | #define DRV_VERSION "0.1.36" |
| 62 | #define PM8001_FAIL_LOGGING 0x01 /* libsas EH function logging */ | 62 | #define PM8001_FAIL_LOGGING 0x01 /* Error message logging */ |
| 63 | #define PM8001_INIT_LOGGING 0x02 /* driver init logging */ | 63 | #define PM8001_INIT_LOGGING 0x02 /* driver init logging */ |
| 64 | #define PM8001_DISC_LOGGING 0x04 /* discovery layer logging */ | 64 | #define PM8001_DISC_LOGGING 0x04 /* discovery layer logging */ |
| 65 | #define PM8001_IO_LOGGING 0x08 /* I/O path logging */ | 65 | #define PM8001_IO_LOGGING 0x08 /* I/O path logging */ |
| 66 | #define PM8001_EH_LOGGING 0x10 /* Error message logging */ | 66 | #define PM8001_EH_LOGGING 0x10 /* libsas EH function logging*/ |
| 67 | #define PM8001_IOCTL_LOGGING 0x20 /* IOCTL message logging */ | 67 | #define PM8001_IOCTL_LOGGING 0x20 /* IOCTL message logging */ |
| 68 | #define PM8001_MSG_LOGGING 0x40 /* misc message logging */ | 68 | #define PM8001_MSG_LOGGING 0x40 /* misc message logging */ |
| 69 | #define pm8001_printk(format, arg...) printk(KERN_INFO "%s %d:" format,\ | 69 | #define pm8001_printk(format, arg...) printk(KERN_INFO "%s %d:" format,\ |
| @@ -100,6 +100,7 @@ do { \ | |||
| 100 | 100 | ||
| 101 | #define PM8001_USE_TASKLET | 101 | #define PM8001_USE_TASKLET |
| 102 | #define PM8001_USE_MSIX | 102 | #define PM8001_USE_MSIX |
| 103 | #define PM8001_READ_VPD | ||
| 103 | 104 | ||
| 104 | 105 | ||
| 105 | #define DEV_IS_EXPANDER(type) ((type == EDGE_DEV) || (type == FANOUT_DEV)) | 106 | #define DEV_IS_EXPANDER(type) ((type == EDGE_DEV) || (type == FANOUT_DEV)) |
| @@ -111,7 +112,22 @@ extern const struct pm8001_dispatch pm8001_8001_dispatch; | |||
| 111 | struct pm8001_hba_info; | 112 | struct pm8001_hba_info; |
| 112 | struct pm8001_ccb_info; | 113 | struct pm8001_ccb_info; |
| 113 | struct pm8001_device; | 114 | struct pm8001_device; |
| 114 | struct pm8001_tmf_task; | 115 | /* define task management IU */ |
| 116 | struct pm8001_tmf_task { | ||
| 117 | u8 tmf; | ||
| 118 | u32 tag_of_task_to_be_managed; | ||
| 119 | }; | ||
| 120 | struct pm8001_ioctl_payload { | ||
| 121 | u32 signature; | ||
| 122 | u16 major_function; | ||
| 123 | u16 minor_function; | ||
| 124 | u16 length; | ||
| 125 | u16 status; | ||
| 126 | u16 offset; | ||
| 127 | u16 id; | ||
| 128 | u8 *func_specific; | ||
| 129 | }; | ||
| 130 | |||
| 115 | struct pm8001_dispatch { | 131 | struct pm8001_dispatch { |
| 116 | char *name; | 132 | char *name; |
| 117 | int (*chip_init)(struct pm8001_hba_info *pm8001_ha); | 133 | int (*chip_init)(struct pm8001_hba_info *pm8001_ha); |
| @@ -164,6 +180,10 @@ struct pm8001_chip_info { | |||
| 164 | 180 | ||
| 165 | struct pm8001_port { | 181 | struct pm8001_port { |
| 166 | struct asd_sas_port sas_port; | 182 | struct asd_sas_port sas_port; |
| 183 | u8 port_attached; | ||
| 184 | u8 wide_port_phymap; | ||
| 185 | u8 port_state; | ||
| 186 | struct list_head list; | ||
| 167 | }; | 187 | }; |
| 168 | 188 | ||
| 169 | struct pm8001_phy { | 189 | struct pm8001_phy { |
| @@ -386,11 +406,7 @@ struct pm8001_fw_image_header { | |||
| 386 | __be32 startup_entry; | 406 | __be32 startup_entry; |
| 387 | } __attribute__((packed, aligned(4))); | 407 | } __attribute__((packed, aligned(4))); |
| 388 | 408 | ||
| 389 | /* define task management IU */ | 409 | |
| 390 | struct pm8001_tmf_task { | ||
| 391 | u8 tmf; | ||
| 392 | u32 tag_of_task_to_be_managed; | ||
| 393 | }; | ||
| 394 | /** | 410 | /** |
| 395 | * FW Flash Update status values | 411 | * FW Flash Update status values |
| 396 | */ | 412 | */ |
