Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
fork

Configure Feed

Select the types of activity you want to include in your feed.

[PATCH] cciss: bug fix for crash when running hpacucli

Fix a crash when running hpacucli with multiple logical volumes on a cciss
controller. We were not properly initializing the disk->queue and causing
a fault.

Thanks to Hasso Tepper for reporting the problem. Thanks to Steve Cameron
for root causing the problem. Most of the patch just moves things around.
The fix is a one-liner.

Signed-off-by: Mike Miller <mike.miller@hp.com>
Signed-off-by: Stephen Cameron <steve.cameron@hp.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>

authored by

Mike Miller and committed by
Greg Kroah-Hartman
ca1e0484 75616cf9

+49 -47
+49 -47
drivers/block/cciss.c
··· 1180 1180 return 0; 1181 1181 } 1182 1182 1183 + static inline void complete_buffers(struct bio *bio, int status) 1184 + { 1185 + while (bio) { 1186 + struct bio *xbh = bio->bi_next; 1187 + int nr_sectors = bio_sectors(bio); 1188 + 1189 + bio->bi_next = NULL; 1190 + blk_finished_io(len); 1191 + bio_endio(bio, nr_sectors << 9, status ? 0 : -EIO); 1192 + bio = xbh; 1193 + } 1194 + 1195 + } 1196 + 1197 + static void cciss_softirq_done(struct request *rq) 1198 + { 1199 + CommandList_struct *cmd = rq->completion_data; 1200 + ctlr_info_t *h = hba[cmd->ctlr]; 1201 + unsigned long flags; 1202 + u64bit temp64; 1203 + int i, ddir; 1204 + 1205 + if (cmd->Request.Type.Direction == XFER_READ) 1206 + ddir = PCI_DMA_FROMDEVICE; 1207 + else 1208 + ddir = PCI_DMA_TODEVICE; 1209 + 1210 + /* command did not need to be retried */ 1211 + /* unmap the DMA mapping for all the scatter gather elements */ 1212 + for(i=0; i<cmd->Header.SGList; i++) { 1213 + temp64.val32.lower = cmd->SG[i].Addr.lower; 1214 + temp64.val32.upper = cmd->SG[i].Addr.upper; 1215 + pci_unmap_page(h->pdev, temp64.val, cmd->SG[i].Len, ddir); 1216 + } 1217 + 1218 + complete_buffers(rq->bio, rq->errors); 1219 + 1220 + #ifdef CCISS_DEBUG 1221 + printk("Done with %p\n", rq); 1222 + #endif /* CCISS_DEBUG */ 1223 + 1224 + spin_lock_irqsave(&h->lock, flags); 1225 + end_that_request_last(rq, rq->errors); 1226 + cmd_free(h, cmd,1); 1227 + spin_unlock_irqrestore(&h->lock, flags); 1228 + } 1229 + 1183 1230 /* This function will check the usage_count of the drive to be updated/added. 1184 1231 * If the usage_count is zero then the drive information will be updated and 1185 1232 * the disk will be re-registered with the kernel. If not then it will be ··· 1294 1247 blk_queue_max_phys_segments(disk->queue, MAXSGENTRIES); 1295 1248 1296 1249 blk_queue_max_sectors(disk->queue, 512); 1250 + 1251 + blk_queue_softirq_done(disk->queue, cciss_softirq_done); 1297 1252 1298 1253 disk->queue->queuedata = hba[ctlr]; 1299 1254 ··· 2196 2147 addQ (&(h->cmpQ), c); 2197 2148 } 2198 2149 } 2199 - 2200 - static inline void complete_buffers(struct bio *bio, int status) 2201 - { 2202 - while (bio) { 2203 - struct bio *xbh = bio->bi_next; 2204 - int nr_sectors = bio_sectors(bio); 2205 - 2206 - bio->bi_next = NULL; 2207 - blk_finished_io(len); 2208 - bio_endio(bio, nr_sectors << 9, status ? 0 : -EIO); 2209 - bio = xbh; 2210 - } 2211 - 2212 - } 2213 2150 /* Assumes that CCISS_LOCK(h->ctlr) is held. */ 2214 2151 /* Zeros out the error record and then resends the command back */ 2215 2152 /* to the controller */ ··· 2211 2176 h->maxQsinceinit = h->Qdepth; 2212 2177 2213 2178 start_io(h); 2214 - } 2215 - 2216 - static void cciss_softirq_done(struct request *rq) 2217 - { 2218 - CommandList_struct *cmd = rq->completion_data; 2219 - ctlr_info_t *h = hba[cmd->ctlr]; 2220 - unsigned long flags; 2221 - u64bit temp64; 2222 - int i, ddir; 2223 - 2224 - if (cmd->Request.Type.Direction == XFER_READ) 2225 - ddir = PCI_DMA_FROMDEVICE; 2226 - else 2227 - ddir = PCI_DMA_TODEVICE; 2228 - 2229 - /* command did not need to be retried */ 2230 - /* unmap the DMA mapping for all the scatter gather elements */ 2231 - for(i=0; i<cmd->Header.SGList; i++) { 2232 - temp64.val32.lower = cmd->SG[i].Addr.lower; 2233 - temp64.val32.upper = cmd->SG[i].Addr.upper; 2234 - pci_unmap_page(h->pdev, temp64.val, cmd->SG[i].Len, ddir); 2235 - } 2236 - 2237 - complete_buffers(rq->bio, rq->errors); 2238 - 2239 - #ifdef CCISS_DEBUG 2240 - printk("Done with %p\n", rq); 2241 - #endif /* CCISS_DEBUG */ 2242 - 2243 - spin_lock_irqsave(&h->lock, flags); 2244 - end_that_request_last(rq, rq->errors); 2245 - cmd_free(h, cmd,1); 2246 - spin_unlock_irqrestore(&h->lock, flags); 2247 2179 } 2248 2180 2249 2181 /* checks the status of the job and calls complete buffers to mark all