diff options
| -rw-r--r-- | drivers/scsi/pm8001/pm8001_hwi.c | 40 |
1 files changed, 35 insertions, 5 deletions
diff --git a/drivers/scsi/pm8001/pm8001_hwi.c b/drivers/scsi/pm8001/pm8001_hwi.c index a3de306b9045..68695b72e1ef 100644 --- a/drivers/scsi/pm8001/pm8001_hwi.c +++ b/drivers/scsi/pm8001/pm8001_hwi.c | |||
| @@ -1901,7 +1901,7 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb) | |||
| 1901 | { | 1901 | { |
| 1902 | struct sas_task *t; | 1902 | struct sas_task *t; |
| 1903 | struct pm8001_ccb_info *ccb; | 1903 | struct pm8001_ccb_info *ccb; |
| 1904 | unsigned long flags; | 1904 | unsigned long flags = 0; |
| 1905 | u32 param; | 1905 | u32 param; |
| 1906 | u32 status; | 1906 | u32 status; |
| 1907 | u32 tag; | 1907 | u32 tag; |
| @@ -2040,7 +2040,9 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb) | |||
| 2040 | ts->stat = SAS_QUEUE_FULL; | 2040 | ts->stat = SAS_QUEUE_FULL; |
| 2041 | pm8001_ccb_task_free(pm8001_ha, t, ccb, tag); | 2041 | pm8001_ccb_task_free(pm8001_ha, t, ccb, tag); |
| 2042 | mb();/*in order to force CPU ordering*/ | 2042 | mb();/*in order to force CPU ordering*/ |
| 2043 | spin_unlock_irqrestore(&pm8001_ha->lock, flags); | ||
| 2043 | t->task_done(t); | 2044 | t->task_done(t); |
| 2045 | spin_lock_irqsave(&pm8001_ha->lock, flags); | ||
| 2044 | return; | 2046 | return; |
| 2045 | } | 2047 | } |
| 2046 | break; | 2048 | break; |
| @@ -2058,7 +2060,9 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb) | |||
| 2058 | ts->stat = SAS_QUEUE_FULL; | 2060 | ts->stat = SAS_QUEUE_FULL; |
| 2059 | pm8001_ccb_task_free(pm8001_ha, t, ccb, tag); | 2061 | pm8001_ccb_task_free(pm8001_ha, t, ccb, tag); |
| 2060 | mb();/*ditto*/ | 2062 | mb();/*ditto*/ |
| 2063 | spin_unlock_irqrestore(&pm8001_ha->lock, flags); | ||
| 2061 | t->task_done(t); | 2064 | t->task_done(t); |
| 2065 | spin_lock_irqsave(&pm8001_ha->lock, flags); | ||
| 2062 | return; | 2066 | return; |
| 2063 | } | 2067 | } |
| 2064 | break; | 2068 | break; |
| @@ -2084,7 +2088,9 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb) | |||
| 2084 | ts->stat = SAS_QUEUE_FULL; | 2088 | ts->stat = SAS_QUEUE_FULL; |
| 2085 | pm8001_ccb_task_free(pm8001_ha, t, ccb, tag); | 2089 | pm8001_ccb_task_free(pm8001_ha, t, ccb, tag); |
| 2086 | mb();/* ditto*/ | 2090 | mb();/* ditto*/ |
| 2091 | spin_unlock_irqrestore(&pm8001_ha->lock, flags); | ||
| 2087 | t->task_done(t); | 2092 | t->task_done(t); |
| 2093 | spin_lock_irqsave(&pm8001_ha->lock, flags); | ||
| 2088 | return; | 2094 | return; |
| 2089 | } | 2095 | } |
| 2090 | break; | 2096 | break; |
| @@ -2149,7 +2155,9 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb) | |||
| 2149 | ts->stat = SAS_QUEUE_FULL; | 2155 | ts->stat = SAS_QUEUE_FULL; |
| 2150 | pm8001_ccb_task_free(pm8001_ha, t, ccb, tag); | 2156 | pm8001_ccb_task_free(pm8001_ha, t, ccb, tag); |
| 2151 | mb();/*ditto*/ | 2157 | mb();/*ditto*/ |
| 2158 | spin_unlock_irqrestore(&pm8001_ha->lock, flags); | ||
| 2152 | t->task_done(t); | 2159 | t->task_done(t); |
| 2160 | spin_lock_irqsave(&pm8001_ha->lock, flags); | ||
| 2153 | return; | 2161 | return; |
| 2154 | } | 2162 | } |
| 2155 | break; | 2163 | break; |
| @@ -2171,7 +2179,9 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb) | |||
| 2171 | ts->stat = SAS_QUEUE_FULL; | 2179 | ts->stat = SAS_QUEUE_FULL; |
| 2172 | pm8001_ccb_task_free(pm8001_ha, t, ccb, tag); | 2180 | pm8001_ccb_task_free(pm8001_ha, t, ccb, tag); |
| 2173 | mb();/*ditto*/ | 2181 | mb();/*ditto*/ |
| 2182 | spin_unlock_irqrestore(&pm8001_ha->lock, flags); | ||
| 2174 | t->task_done(t); | 2183 | t->task_done(t); |
| 2184 | spin_lock_irqsave(&pm8001_ha->lock, flags); | ||
| 2175 | return; | 2185 | return; |
| 2176 | } | 2186 | } |
| 2177 | break; | 2187 | break; |
| @@ -2200,11 +2210,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", | 2210 | " resp 0x%x stat 0x%x but aborted by upper layer!\n", |
| 2201 | t, status, ts->resp, ts->stat)); | 2211 | t, status, ts->resp, ts->stat)); |
| 2202 | pm8001_ccb_task_free(pm8001_ha, t, ccb, tag); | 2212 | pm8001_ccb_task_free(pm8001_ha, t, ccb, tag); |
| 2203 | } else { | 2213 | } else if (t->uldd_task) { |
| 2204 | spin_unlock_irqrestore(&t->task_state_lock, flags); | 2214 | spin_unlock_irqrestore(&t->task_state_lock, flags); |
| 2205 | pm8001_ccb_task_free(pm8001_ha, t, ccb, tag); | 2215 | pm8001_ccb_task_free(pm8001_ha, t, ccb, tag); |
| 2206 | mb();/* ditto */ | 2216 | mb();/* ditto */ |
| 2217 | spin_unlock_irqrestore(&pm8001_ha->lock, flags); | ||
| 2218 | t->task_done(t); | ||
| 2219 | spin_lock_irqsave(&pm8001_ha->lock, flags); | ||
| 2220 | } else if (!t->uldd_task) { | ||
| 2221 | spin_unlock_irqrestore(&t->task_state_lock, flags); | ||
| 2222 | pm8001_ccb_task_free(pm8001_ha, t, ccb, tag); | ||
| 2223 | mb();/*ditto*/ | ||
| 2224 | spin_unlock_irqrestore(&pm8001_ha->lock, flags); | ||
| 2207 | t->task_done(t); | 2225 | t->task_done(t); |
| 2226 | spin_lock_irqsave(&pm8001_ha->lock, flags); | ||
| 2208 | } | 2227 | } |
| 2209 | } | 2228 | } |
| 2210 | 2229 | ||
| @@ -2212,7 +2231,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) | 2231 | static void mpi_sata_event(struct pm8001_hba_info *pm8001_ha , void *piomb) |
| 2213 | { | 2232 | { |
| 2214 | struct sas_task *t; | 2233 | struct sas_task *t; |
| 2215 | unsigned long flags; | 2234 | unsigned long flags = 0; |
| 2216 | struct task_status_struct *ts; | 2235 | struct task_status_struct *ts; |
| 2217 | struct pm8001_ccb_info *ccb; | 2236 | struct pm8001_ccb_info *ccb; |
| 2218 | struct pm8001_device *pm8001_dev; | 2237 | struct pm8001_device *pm8001_dev; |
| @@ -2292,7 +2311,9 @@ static void mpi_sata_event(struct pm8001_hba_info *pm8001_ha , void *piomb) | |||
| 2292 | ts->stat = SAS_QUEUE_FULL; | 2311 | ts->stat = SAS_QUEUE_FULL; |
| 2293 | pm8001_ccb_task_free(pm8001_ha, t, ccb, tag); | 2312 | pm8001_ccb_task_free(pm8001_ha, t, ccb, tag); |
| 2294 | mb();/*ditto*/ | 2313 | mb();/*ditto*/ |
| 2314 | spin_unlock_irqrestore(&pm8001_ha->lock, flags); | ||
| 2295 | t->task_done(t); | 2315 | t->task_done(t); |
| 2316 | spin_lock_irqsave(&pm8001_ha->lock, flags); | ||
| 2296 | return; | 2317 | return; |
| 2297 | } | 2318 | } |
| 2298 | break; | 2319 | break; |
| @@ -2401,11 +2422,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", | 2422 | " resp 0x%x stat 0x%x but aborted by upper layer!\n", |
| 2402 | t, event, ts->resp, ts->stat)); | 2423 | t, event, ts->resp, ts->stat)); |
| 2403 | pm8001_ccb_task_free(pm8001_ha, t, ccb, tag); | 2424 | pm8001_ccb_task_free(pm8001_ha, t, ccb, tag); |
| 2404 | } else { | 2425 | } else if (t->uldd_task) { |
| 2405 | spin_unlock_irqrestore(&t->task_state_lock, flags); | 2426 | spin_unlock_irqrestore(&t->task_state_lock, flags); |
| 2406 | pm8001_ccb_task_free(pm8001_ha, t, ccb, tag); | 2427 | pm8001_ccb_task_free(pm8001_ha, t, ccb, tag); |
| 2407 | mb();/* in order to force CPU ordering */ | 2428 | mb();/* ditto */ |
| 2429 | spin_unlock_irqrestore(&pm8001_ha->lock, flags); | ||
| 2430 | t->task_done(t); | ||
| 2431 | spin_lock_irqsave(&pm8001_ha->lock, flags); | ||
| 2432 | } else if (!t->uldd_task) { | ||
| 2433 | spin_unlock_irqrestore(&t->task_state_lock, flags); | ||
| 2434 | pm8001_ccb_task_free(pm8001_ha, t, ccb, tag); | ||
| 2435 | mb();/*ditto*/ | ||
| 2436 | spin_unlock_irqrestore(&pm8001_ha->lock, flags); | ||
| 2408 | t->task_done(t); | 2437 | t->task_done(t); |
| 2438 | spin_lock_irqsave(&pm8001_ha->lock, flags); | ||
| 2409 | } | 2439 | } |
| 2410 | } | 2440 | } |
| 2411 | 2441 | ||
