diff options
Diffstat (limited to 'drivers/block/cciss.c')
-rw-r--r-- | drivers/block/cciss.c | 636 |
1 files changed, 429 insertions, 207 deletions
diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c index 28f2c177a541..486b6e1c7dfb 100644 --- a/drivers/block/cciss.c +++ b/drivers/block/cciss.c | |||
@@ -47,14 +47,14 @@ | |||
47 | #include <linux/completion.h> | 47 | #include <linux/completion.h> |
48 | 48 | ||
49 | #define CCISS_DRIVER_VERSION(maj,min,submin) ((maj<<16)|(min<<8)|(submin)) | 49 | #define CCISS_DRIVER_VERSION(maj,min,submin) ((maj<<16)|(min<<8)|(submin)) |
50 | #define DRIVER_NAME "HP CISS Driver (v 2.6.6)" | 50 | #define DRIVER_NAME "HP CISS Driver (v 2.6.8)" |
51 | #define DRIVER_VERSION CCISS_DRIVER_VERSION(2,6,6) | 51 | #define DRIVER_VERSION CCISS_DRIVER_VERSION(2,6,8) |
52 | 52 | ||
53 | /* Embedded module documentation macros - see modules.h */ | 53 | /* Embedded module documentation macros - see modules.h */ |
54 | MODULE_AUTHOR("Hewlett-Packard Company"); | 54 | MODULE_AUTHOR("Hewlett-Packard Company"); |
55 | MODULE_DESCRIPTION("Driver for HP Controller SA5xxx SA6xxx version 2.6.6"); | 55 | MODULE_DESCRIPTION("Driver for HP Controller SA5xxx SA6xxx version 2.6.8"); |
56 | MODULE_SUPPORTED_DEVICE("HP SA5i SA5i+ SA532 SA5300 SA5312 SA641 SA642 SA6400" | 56 | MODULE_SUPPORTED_DEVICE("HP SA5i SA5i+ SA532 SA5300 SA5312 SA641 SA642 SA6400" |
57 | " SA6i P600 P800 E400 E300"); | 57 | " SA6i P600 P800 P400 P400i E200 E200i"); |
58 | MODULE_LICENSE("GPL"); | 58 | MODULE_LICENSE("GPL"); |
59 | 59 | ||
60 | #include "cciss_cmd.h" | 60 | #include "cciss_cmd.h" |
@@ -83,12 +83,22 @@ static const struct pci_device_id cciss_pci_device_id[] = { | |||
83 | 0x0E11, 0x4091, 0, 0, 0}, | 83 | 0x0E11, 0x4091, 0, 0, 0}, |
84 | { PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSA, | 84 | { PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSA, |
85 | 0x103C, 0x3225, 0, 0, 0}, | 85 | 0x103C, 0x3225, 0, 0, 0}, |
86 | { PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSB, | 86 | { PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSC, |
87 | 0x103c, 0x3223, 0, 0, 0}, | 87 | 0x103c, 0x3223, 0, 0, 0}, |
88 | { PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSC, | 88 | { PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSC, |
89 | 0x103c, 0x3231, 0, 0, 0}, | 89 | 0x103c, 0x3234, 0, 0, 0}, |
90 | { PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSC, | 90 | { PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSC, |
91 | 0x103c, 0x3233, 0, 0, 0}, | 91 | 0x103c, 0x3235, 0, 0, 0}, |
92 | { PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSD, | ||
93 | 0x103c, 0x3211, 0, 0, 0}, | ||
94 | { PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSD, | ||
95 | 0x103c, 0x3212, 0, 0, 0}, | ||
96 | { PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSD, | ||
97 | 0x103c, 0x3213, 0, 0, 0}, | ||
98 | { PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSD, | ||
99 | 0x103c, 0x3214, 0, 0, 0}, | ||
100 | { PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSD, | ||
101 | 0x103c, 0x3215, 0, 0, 0}, | ||
92 | {0,} | 102 | {0,} |
93 | }; | 103 | }; |
94 | MODULE_DEVICE_TABLE(pci, cciss_pci_device_id); | 104 | MODULE_DEVICE_TABLE(pci, cciss_pci_device_id); |
@@ -111,8 +121,13 @@ static struct board_type products[] = { | |||
111 | { 0x40910E11, "Smart Array 6i", &SA5_access}, | 121 | { 0x40910E11, "Smart Array 6i", &SA5_access}, |
112 | { 0x3225103C, "Smart Array P600", &SA5_access}, | 122 | { 0x3225103C, "Smart Array P600", &SA5_access}, |
113 | { 0x3223103C, "Smart Array P800", &SA5_access}, | 123 | { 0x3223103C, "Smart Array P800", &SA5_access}, |
114 | { 0x3231103C, "Smart Array E400", &SA5_access}, | 124 | { 0x3234103C, "Smart Array P400", &SA5_access}, |
115 | { 0x3233103C, "Smart Array E300", &SA5_access}, | 125 | { 0x3235103C, "Smart Array P400i", &SA5_access}, |
126 | { 0x3211103C, "Smart Array E200i", &SA5_access}, | ||
127 | { 0x3212103C, "Smart Array E200", &SA5_access}, | ||
128 | { 0x3213103C, "Smart Array E200i", &SA5_access}, | ||
129 | { 0x3214103C, "Smart Array E200i", &SA5_access}, | ||
130 | { 0x3215103C, "Smart Array E200i", &SA5_access}, | ||
116 | }; | 131 | }; |
117 | 132 | ||
118 | /* How long to wait (in millesconds) for board to go into simple mode */ | 133 | /* How long to wait (in millesconds) for board to go into simple mode */ |
@@ -140,15 +155,26 @@ static int cciss_ioctl(struct inode *inode, struct file *filep, | |||
140 | 155 | ||
141 | static int revalidate_allvol(ctlr_info_t *host); | 156 | static int revalidate_allvol(ctlr_info_t *host); |
142 | static int cciss_revalidate(struct gendisk *disk); | 157 | static int cciss_revalidate(struct gendisk *disk); |
143 | static int deregister_disk(struct gendisk *disk); | 158 | static int rebuild_lun_table(ctlr_info_t *h, struct gendisk *del_disk); |
144 | static int register_new_disk(ctlr_info_t *h); | 159 | static int deregister_disk(struct gendisk *disk, drive_info_struct *drv, int clear_all); |
145 | 160 | ||
161 | static void cciss_read_capacity(int ctlr, int logvol, ReadCapdata_struct *buf, | ||
162 | int withirq, unsigned int *total_size, unsigned int *block_size); | ||
163 | static void cciss_geometry_inquiry(int ctlr, int logvol, | ||
164 | int withirq, unsigned int total_size, | ||
165 | unsigned int block_size, InquiryData_struct *inq_buff, | ||
166 | drive_info_struct *drv); | ||
146 | static void cciss_getgeometry(int cntl_num); | 167 | static void cciss_getgeometry(int cntl_num); |
147 | 168 | ||
148 | static void start_io( ctlr_info_t *h); | 169 | static void start_io( ctlr_info_t *h); |
149 | static int sendcmd( __u8 cmd, int ctlr, void *buff, size_t size, | 170 | static int sendcmd( __u8 cmd, int ctlr, void *buff, size_t size, |
150 | unsigned int use_unit_num, unsigned int log_unit, __u8 page_code, | 171 | unsigned int use_unit_num, unsigned int log_unit, __u8 page_code, |
151 | unsigned char *scsi3addr, int cmd_type); | 172 | unsigned char *scsi3addr, int cmd_type); |
173 | static int sendcmd_withirq(__u8 cmd, int ctlr, void *buff, size_t size, | ||
174 | unsigned int use_unit_num, unsigned int log_unit, __u8 page_code, | ||
175 | int cmd_type); | ||
176 | |||
177 | static void fail_all_cmds(unsigned long ctlr); | ||
152 | 178 | ||
153 | #ifdef CONFIG_PROC_FS | 179 | #ifdef CONFIG_PROC_FS |
154 | static int cciss_proc_get_info(char *buffer, char **start, off_t offset, | 180 | static int cciss_proc_get_info(char *buffer, char **start, off_t offset, |
@@ -265,7 +291,7 @@ static int cciss_proc_get_info(char *buffer, char **start, off_t offset, | |||
265 | for(i=0; i<=h->highest_lun; i++) { | 291 | for(i=0; i<=h->highest_lun; i++) { |
266 | 292 | ||
267 | drv = &h->drv[i]; | 293 | drv = &h->drv[i]; |
268 | if (drv->block_size == 0) | 294 | if (drv->heads == 0) |
269 | continue; | 295 | continue; |
270 | 296 | ||
271 | vol_sz = drv->nr_blocks; | 297 | vol_sz = drv->nr_blocks; |
@@ -363,6 +389,8 @@ static CommandList_struct * cmd_alloc(ctlr_info_t *h, int get_from_pool) | |||
363 | return NULL; | 389 | return NULL; |
364 | memset(c, 0, sizeof(CommandList_struct)); | 390 | memset(c, 0, sizeof(CommandList_struct)); |
365 | 391 | ||
392 | c->cmdindex = -1; | ||
393 | |||
366 | c->err_info = (ErrorInfo_struct *)pci_alloc_consistent( | 394 | c->err_info = (ErrorInfo_struct *)pci_alloc_consistent( |
367 | h->pdev, sizeof(ErrorInfo_struct), | 395 | h->pdev, sizeof(ErrorInfo_struct), |
368 | &err_dma_handle); | 396 | &err_dma_handle); |
@@ -393,6 +421,8 @@ static CommandList_struct * cmd_alloc(ctlr_info_t *h, int get_from_pool) | |||
393 | err_dma_handle = h->errinfo_pool_dhandle | 421 | err_dma_handle = h->errinfo_pool_dhandle |
394 | + i*sizeof(ErrorInfo_struct); | 422 | + i*sizeof(ErrorInfo_struct); |
395 | h->nr_allocs++; | 423 | h->nr_allocs++; |
424 | |||
425 | c->cmdindex = i; | ||
396 | } | 426 | } |
397 | 427 | ||
398 | c->busaddr = (__u32) cmd_dma_handle; | 428 | c->busaddr = (__u32) cmd_dma_handle; |
@@ -453,6 +483,8 @@ static int cciss_open(struct inode *inode, struct file *filep) | |||
453 | printk(KERN_DEBUG "cciss_open %s\n", inode->i_bdev->bd_disk->disk_name); | 483 | printk(KERN_DEBUG "cciss_open %s\n", inode->i_bdev->bd_disk->disk_name); |
454 | #endif /* CCISS_DEBUG */ | 484 | #endif /* CCISS_DEBUG */ |
455 | 485 | ||
486 | if (host->busy_initializing || drv->busy_configuring) | ||
487 | return -EBUSY; | ||
456 | /* | 488 | /* |
457 | * Root is allowed to open raw volume zero even if it's not configured | 489 | * Root is allowed to open raw volume zero even if it's not configured |
458 | * so array config can still work. Root is also allowed to open any | 490 | * so array config can still work. Root is also allowed to open any |
@@ -796,10 +828,10 @@ static int cciss_ioctl(struct inode *inode, struct file *filep, | |||
796 | return(0); | 828 | return(0); |
797 | } | 829 | } |
798 | case CCISS_DEREGDISK: | 830 | case CCISS_DEREGDISK: |
799 | return deregister_disk(disk); | 831 | return rebuild_lun_table(host, disk); |
800 | 832 | ||
801 | case CCISS_REGNEWD: | 833 | case CCISS_REGNEWD: |
802 | return register_new_disk(host); | 834 | return rebuild_lun_table(host, NULL); |
803 | 835 | ||
804 | case CCISS_PASSTHRU: | 836 | case CCISS_PASSTHRU: |
805 | { | 837 | { |
@@ -1143,48 +1175,323 @@ static int revalidate_allvol(ctlr_info_t *host) | |||
1143 | return 0; | 1175 | return 0; |
1144 | } | 1176 | } |
1145 | 1177 | ||
1146 | static int deregister_disk(struct gendisk *disk) | 1178 | /* This function will check the usage_count of the drive to be updated/added. |
1179 | * If the usage_count is zero then the drive information will be updated and | ||
1180 | * the disk will be re-registered with the kernel. If not then it will be | ||
1181 | * left alone for the next reboot. The exception to this is disk 0 which | ||
1182 | * will always be left registered with the kernel since it is also the | ||
1183 | * controller node. Any changes to disk 0 will show up on the next | ||
1184 | * reboot. | ||
1185 | */ | ||
1186 | static void cciss_update_drive_info(int ctlr, int drv_index) | ||
1187 | { | ||
1188 | ctlr_info_t *h = hba[ctlr]; | ||
1189 | struct gendisk *disk; | ||
1190 | ReadCapdata_struct *size_buff = NULL; | ||
1191 | InquiryData_struct *inq_buff = NULL; | ||
1192 | unsigned int block_size; | ||
1193 | unsigned int total_size; | ||
1194 | unsigned long flags = 0; | ||
1195 | int ret = 0; | ||
1196 | |||
1197 | /* if the disk already exists then deregister it before proceeding*/ | ||
1198 | if (h->drv[drv_index].raid_level != -1){ | ||
1199 | spin_lock_irqsave(CCISS_LOCK(h->ctlr), flags); | ||
1200 | h->drv[drv_index].busy_configuring = 1; | ||
1201 | spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags); | ||
1202 | ret = deregister_disk(h->gendisk[drv_index], | ||
1203 | &h->drv[drv_index], 0); | ||
1204 | h->drv[drv_index].busy_configuring = 0; | ||
1205 | } | ||
1206 | |||
1207 | /* If the disk is in use return */ | ||
1208 | if (ret) | ||
1209 | return; | ||
1210 | |||
1211 | |||
1212 | /* Get information about the disk and modify the driver sturcture */ | ||
1213 | size_buff = kmalloc(sizeof( ReadCapdata_struct), GFP_KERNEL); | ||
1214 | if (size_buff == NULL) | ||
1215 | goto mem_msg; | ||
1216 | inq_buff = kmalloc(sizeof( InquiryData_struct), GFP_KERNEL); | ||
1217 | if (inq_buff == NULL) | ||
1218 | goto mem_msg; | ||
1219 | |||
1220 | cciss_read_capacity(ctlr, drv_index, size_buff, 1, | ||
1221 | &total_size, &block_size); | ||
1222 | cciss_geometry_inquiry(ctlr, drv_index, 1, total_size, block_size, | ||
1223 | inq_buff, &h->drv[drv_index]); | ||
1224 | |||
1225 | ++h->num_luns; | ||
1226 | disk = h->gendisk[drv_index]; | ||
1227 | set_capacity(disk, h->drv[drv_index].nr_blocks); | ||
1228 | |||
1229 | |||
1230 | /* if it's the controller it's already added */ | ||
1231 | if (drv_index){ | ||
1232 | disk->queue = blk_init_queue(do_cciss_request, &h->lock); | ||
1233 | |||
1234 | /* Set up queue information */ | ||
1235 | disk->queue->backing_dev_info.ra_pages = READ_AHEAD; | ||
1236 | blk_queue_bounce_limit(disk->queue, hba[ctlr]->pdev->dma_mask); | ||
1237 | |||
1238 | /* This is a hardware imposed limit. */ | ||
1239 | blk_queue_max_hw_segments(disk->queue, MAXSGENTRIES); | ||
1240 | |||
1241 | /* This is a limit in the driver and could be eliminated. */ | ||
1242 | blk_queue_max_phys_segments(disk->queue, MAXSGENTRIES); | ||
1243 | |||
1244 | blk_queue_max_sectors(disk->queue, 512); | ||
1245 | |||
1246 | disk->queue->queuedata = hba[ctlr]; | ||
1247 | |||
1248 | blk_queue_hardsect_size(disk->queue, | ||
1249 | hba[ctlr]->drv[drv_index].block_size); | ||
1250 | |||
1251 | h->drv[drv_index].queue = disk->queue; | ||
1252 | add_disk(disk); | ||
1253 | } | ||
1254 | |||
1255 | freeret: | ||
1256 | kfree(size_buff); | ||
1257 | kfree(inq_buff); | ||
1258 | return; | ||
1259 | mem_msg: | ||
1260 | printk(KERN_ERR "cciss: out of memory\n"); | ||
1261 | goto freeret; | ||
1262 | } | ||
1263 | |||
1264 | /* This function will find the first index of the controllers drive array | ||
1265 | * that has a -1 for the raid_level and will return that index. This is | ||
1266 | * where new drives will be added. If the index to be returned is greater | ||
1267 | * than the highest_lun index for the controller then highest_lun is set | ||
1268 | * to this new index. If there are no available indexes then -1 is returned. | ||
1269 | */ | ||
1270 | static int cciss_find_free_drive_index(int ctlr) | ||
1147 | { | 1271 | { |
1272 | int i; | ||
1273 | |||
1274 | for (i=0; i < CISS_MAX_LUN; i++){ | ||
1275 | if (hba[ctlr]->drv[i].raid_level == -1){ | ||
1276 | if (i > hba[ctlr]->highest_lun) | ||
1277 | hba[ctlr]->highest_lun = i; | ||
1278 | return i; | ||
1279 | } | ||
1280 | } | ||
1281 | return -1; | ||
1282 | } | ||
1283 | |||
1284 | /* This function will add and remove logical drives from the Logical | ||
1285 | * drive array of the controller and maintain persistancy of ordering | ||
1286 | * so that mount points are preserved until the next reboot. This allows | ||
1287 | * for the removal of logical drives in the middle of the drive array | ||
1288 | * without a re-ordering of those drives. | ||
1289 | * INPUT | ||
1290 | * h = The controller to perform the operations on | ||
1291 | * del_disk = The disk to remove if specified. If the value given | ||
1292 | * is NULL then no disk is removed. | ||
1293 | */ | ||
1294 | static int rebuild_lun_table(ctlr_info_t *h, struct gendisk *del_disk) | ||
1295 | { | ||
1296 | int ctlr = h->ctlr; | ||
1297 | int num_luns; | ||
1298 | ReportLunData_struct *ld_buff = NULL; | ||
1299 | drive_info_struct *drv = NULL; | ||
1300 | int return_code; | ||
1301 | int listlength = 0; | ||
1302 | int i; | ||
1303 | int drv_found; | ||
1304 | int drv_index = 0; | ||
1305 | __u32 lunid = 0; | ||
1148 | unsigned long flags; | 1306 | unsigned long flags; |
1307 | |||
1308 | /* Set busy_configuring flag for this operation */ | ||
1309 | spin_lock_irqsave(CCISS_LOCK(h->ctlr), flags); | ||
1310 | if (h->num_luns >= CISS_MAX_LUN){ | ||
1311 | spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags); | ||
1312 | return -EINVAL; | ||
1313 | } | ||
1314 | |||
1315 | if (h->busy_configuring){ | ||
1316 | spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags); | ||
1317 | return -EBUSY; | ||
1318 | } | ||
1319 | h->busy_configuring = 1; | ||
1320 | |||
1321 | /* if del_disk is NULL then we are being called to add a new disk | ||
1322 | * and update the logical drive table. If it is not NULL then | ||
1323 | * we will check if the disk is in use or not. | ||
1324 | */ | ||
1325 | if (del_disk != NULL){ | ||
1326 | drv = get_drv(del_disk); | ||
1327 | drv->busy_configuring = 1; | ||
1328 | spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags); | ||
1329 | return_code = deregister_disk(del_disk, drv, 1); | ||
1330 | drv->busy_configuring = 0; | ||
1331 | h->busy_configuring = 0; | ||
1332 | return return_code; | ||
1333 | } else { | ||
1334 | spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags); | ||
1335 | if (!capable(CAP_SYS_RAWIO)) | ||
1336 | return -EPERM; | ||
1337 | |||
1338 | ld_buff = kzalloc(sizeof(ReportLunData_struct), GFP_KERNEL); | ||
1339 | if (ld_buff == NULL) | ||
1340 | goto mem_msg; | ||
1341 | |||
1342 | return_code = sendcmd_withirq(CISS_REPORT_LOG, ctlr, ld_buff, | ||
1343 | sizeof(ReportLunData_struct), 0, 0, 0, | ||
1344 | TYPE_CMD); | ||
1345 | |||
1346 | if (return_code == IO_OK){ | ||
1347 | listlength |= (0xff & (unsigned int)(ld_buff->LUNListLength[0])) << 24; | ||
1348 | listlength |= (0xff & (unsigned int)(ld_buff->LUNListLength[1])) << 16; | ||
1349 | listlength |= (0xff & (unsigned int)(ld_buff->LUNListLength[2])) << 8; | ||
1350 | listlength |= 0xff & (unsigned int)(ld_buff->LUNListLength[3]); | ||
1351 | } else{ /* reading number of logical volumes failed */ | ||
1352 | printk(KERN_WARNING "cciss: report logical volume" | ||
1353 | " command failed\n"); | ||
1354 | listlength = 0; | ||
1355 | goto freeret; | ||
1356 | } | ||
1357 | |||
1358 | num_luns = listlength / 8; /* 8 bytes per entry */ | ||
1359 | if (num_luns > CISS_MAX_LUN){ | ||
1360 | num_luns = CISS_MAX_LUN; | ||
1361 | printk(KERN_WARNING "cciss: more luns configured" | ||
1362 | " on controller than can be handled by" | ||
1363 | " this driver.\n"); | ||
1364 | } | ||
1365 | |||
1366 | /* Compare controller drive array to drivers drive array. | ||
1367 | * Check for updates in the drive information and any new drives | ||
1368 | * on the controller. | ||
1369 | */ | ||
1370 | for (i=0; i < num_luns; i++){ | ||
1371 | int j; | ||
1372 | |||
1373 | drv_found = 0; | ||
1374 | |||
1375 | lunid = (0xff & | ||
1376 | (unsigned int)(ld_buff->LUN[i][3])) << 24; | ||
1377 | lunid |= (0xff & | ||
1378 | (unsigned int)(ld_buff->LUN[i][2])) << 16; | ||
1379 | lunid |= (0xff & | ||
1380 | (unsigned int)(ld_buff->LUN[i][1])) << 8; | ||
1381 | lunid |= 0xff & | ||
1382 | (unsigned int)(ld_buff->LUN[i][0]); | ||
1383 | |||
1384 | /* Find if the LUN is already in the drive array | ||
1385 | * of the controller. If so then update its info | ||
1386 | * if not is use. If it does not exist then find | ||
1387 | * the first free index and add it. | ||
1388 | */ | ||
1389 | for (j=0; j <= h->highest_lun; j++){ | ||
1390 | if (h->drv[j].LunID == lunid){ | ||
1391 | drv_index = j; | ||
1392 | drv_found = 1; | ||
1393 | } | ||
1394 | } | ||
1395 | |||
1396 | /* check if the drive was found already in the array */ | ||
1397 | if (!drv_found){ | ||
1398 | drv_index = cciss_find_free_drive_index(ctlr); | ||
1399 | if (drv_index == -1) | ||
1400 | goto freeret; | ||
1401 | |||
1402 | } | ||
1403 | h->drv[drv_index].LunID = lunid; | ||
1404 | cciss_update_drive_info(ctlr, drv_index); | ||
1405 | } /* end for */ | ||
1406 | } /* end else */ | ||
1407 | |||
1408 | freeret: | ||
1409 | kfree(ld_buff); | ||
1410 | h->busy_configuring = 0; | ||
1411 | /* We return -1 here to tell the ACU that we have registered/updated | ||
1412 | * all of the drives that we can and to keep it from calling us | ||
1413 | * additional times. | ||
1414 | */ | ||
1415 | return -1; | ||
1416 | mem_msg: | ||
1417 | printk(KERN_ERR "cciss: out of memory\n"); | ||
1418 | goto freeret; | ||
1419 | } | ||
1420 | |||
1421 | /* This function will deregister the disk and it's queue from the | ||
1422 | * kernel. It must be called with the controller lock held and the | ||
1423 | * drv structures busy_configuring flag set. It's parameters are: | ||
1424 | * | ||
1425 | * disk = This is the disk to be deregistered | ||
1426 | * drv = This is the drive_info_struct associated with the disk to be | ||
1427 | * deregistered. It contains information about the disk used | ||
1428 | * by the driver. | ||
1429 | * clear_all = This flag determines whether or not the disk information | ||
1430 | * is going to be completely cleared out and the highest_lun | ||
1431 | * reset. Sometimes we want to clear out information about | ||
1432 | * the disk in preperation for re-adding it. In this case | ||
1433 | * the highest_lun should be left unchanged and the LunID | ||
1434 | * should not be cleared. | ||
1435 | */ | ||
1436 | static int deregister_disk(struct gendisk *disk, drive_info_struct *drv, | ||
1437 | int clear_all) | ||
1438 | { | ||
1149 | ctlr_info_t *h = get_host(disk); | 1439 | ctlr_info_t *h = get_host(disk); |
1150 | drive_info_struct *drv = get_drv(disk); | ||
1151 | int ctlr = h->ctlr; | ||
1152 | 1440 | ||
1153 | if (!capable(CAP_SYS_RAWIO)) | 1441 | if (!capable(CAP_SYS_RAWIO)) |
1154 | return -EPERM; | 1442 | return -EPERM; |
1155 | 1443 | ||
1156 | spin_lock_irqsave(CCISS_LOCK(ctlr), flags); | ||
1157 | /* make sure logical volume is NOT is use */ | 1444 | /* make sure logical volume is NOT is use */ |
1158 | if( drv->usage_count > 1) { | 1445 | if(clear_all || (h->gendisk[0] == disk)) { |
1159 | spin_unlock_irqrestore(CCISS_LOCK(ctlr), flags); | 1446 | if (drv->usage_count > 1) |
1160 | return -EBUSY; | 1447 | return -EBUSY; |
1161 | } | 1448 | } |
1162 | drv->usage_count++; | 1449 | else |
1163 | spin_unlock_irqrestore(CCISS_LOCK(ctlr), flags); | 1450 | if( drv->usage_count > 0 ) |
1451 | return -EBUSY; | ||
1164 | 1452 | ||
1165 | /* invalidate the devices and deregister the disk */ | 1453 | /* invalidate the devices and deregister the disk. If it is disk |
1166 | if (disk->flags & GENHD_FL_UP) | 1454 | * zero do not deregister it but just zero out it's values. This |
1455 | * allows us to delete disk zero but keep the controller registered. | ||
1456 | */ | ||
1457 | if (h->gendisk[0] != disk){ | ||
1458 | if (disk->flags & GENHD_FL_UP){ | ||
1459 | blk_cleanup_queue(disk->queue); | ||
1167 | del_gendisk(disk); | 1460 | del_gendisk(disk); |
1461 | drv->queue = NULL; | ||
1462 | } | ||
1463 | } | ||
1464 | |||
1465 | --h->num_luns; | ||
1466 | /* zero out the disk size info */ | ||
1467 | drv->nr_blocks = 0; | ||
1468 | drv->block_size = 0; | ||
1469 | drv->heads = 0; | ||
1470 | drv->sectors = 0; | ||
1471 | drv->cylinders = 0; | ||
1472 | drv->raid_level = -1; /* This can be used as a flag variable to | ||
1473 | * indicate that this element of the drive | ||
1474 | * array is free. | ||
1475 | */ | ||
1476 | |||
1477 | if (clear_all){ | ||
1168 | /* check to see if it was the last disk */ | 1478 | /* check to see if it was the last disk */ |
1169 | if (drv == h->drv + h->highest_lun) { | 1479 | if (drv == h->drv + h->highest_lun) { |
1170 | /* if so, find the new hightest lun */ | 1480 | /* if so, find the new hightest lun */ |
1171 | int i, newhighest =-1; | 1481 | int i, newhighest =-1; |
1172 | for(i=0; i<h->highest_lun; i++) { | 1482 | for(i=0; i<h->highest_lun; i++) { |
1173 | /* if the disk has size > 0, it is available */ | 1483 | /* if the disk has size > 0, it is available */ |
1174 | if (h->drv[i].nr_blocks) | 1484 | if (h->drv[i].heads) |
1175 | newhighest = i; | 1485 | newhighest = i; |
1176 | } | 1486 | } |
1177 | h->highest_lun = newhighest; | 1487 | h->highest_lun = newhighest; |
1178 | |||
1179 | } | 1488 | } |
1180 | --h->num_luns; | 1489 | |
1181 | /* zero out the disk size info */ | ||
1182 | drv->nr_blocks = 0; | ||
1183 | drv->block_size = 0; | ||
1184 | drv->cylinders = 0; | ||
1185 | drv->LunID = 0; | 1490 | drv->LunID = 0; |
1491 | } | ||
1186 | return(0); | 1492 | return(0); |
1187 | } | 1493 | } |
1494 | |||
1188 | static int fill_cmd(CommandList_struct *c, __u8 cmd, int ctlr, void *buff, | 1495 | static int fill_cmd(CommandList_struct *c, __u8 cmd, int ctlr, void *buff, |
1189 | size_t size, | 1496 | size_t size, |
1190 | unsigned int use_unit_num, /* 0: address the controller, | 1497 | unsigned int use_unit_num, /* 0: address the controller, |
@@ -1420,8 +1727,10 @@ case CMD_HARDWARE_ERR: | |||
1420 | } | 1727 | } |
1421 | } | 1728 | } |
1422 | /* unlock the buffers from DMA */ | 1729 | /* unlock the buffers from DMA */ |
1730 | buff_dma_handle.val32.lower = c->SG[0].Addr.lower; | ||
1731 | buff_dma_handle.val32.upper = c->SG[0].Addr.upper; | ||
1423 | pci_unmap_single( h->pdev, (dma_addr_t) buff_dma_handle.val, | 1732 | pci_unmap_single( h->pdev, (dma_addr_t) buff_dma_handle.val, |
1424 | size, PCI_DMA_BIDIRECTIONAL); | 1733 | c->SG[0].Len, PCI_DMA_BIDIRECTIONAL); |
1425 | cmd_free(h, c, 0); | 1734 | cmd_free(h, c, 0); |
1426 | return(return_status); | 1735 | return(return_status); |
1427 | 1736 | ||
@@ -1495,164 +1804,6 @@ cciss_read_capacity(int ctlr, int logvol, ReadCapdata_struct *buf, | |||
1495 | return; | 1804 | return; |
1496 | } | 1805 | } |
1497 | 1806 | ||
1498 | static int register_new_disk(ctlr_info_t *h) | ||
1499 | { | ||
1500 | struct gendisk *disk; | ||
1501 | int ctlr = h->ctlr; | ||
1502 | int i; | ||
1503 | int num_luns; | ||
1504 | int logvol; | ||
1505 | int new_lun_found = 0; | ||
1506 | int new_lun_index = 0; | ||
1507 | int free_index_found = 0; | ||
1508 | int free_index = 0; | ||
1509 | ReportLunData_struct *ld_buff = NULL; | ||
1510 | ReadCapdata_struct *size_buff = NULL; | ||
1511 | InquiryData_struct *inq_buff = NULL; | ||
1512 | int return_code; | ||
1513 | int listlength = 0; | ||
1514 | __u32 lunid = 0; | ||
1515 | unsigned int block_size; | ||
1516 | unsigned int total_size; | ||
1517 | |||
1518 | if (!capable(CAP_SYS_RAWIO)) | ||
1519 | return -EPERM; | ||
1520 | /* if we have no space in our disk array left to add anything */ | ||
1521 | if( h->num_luns >= CISS_MAX_LUN) | ||
1522 | return -EINVAL; | ||
1523 | |||
1524 | ld_buff = kmalloc(sizeof(ReportLunData_struct), GFP_KERNEL); | ||
1525 | if (ld_buff == NULL) | ||
1526 | goto mem_msg; | ||
1527 | memset(ld_buff, 0, sizeof(ReportLunData_struct)); | ||
1528 | size_buff = kmalloc(sizeof( ReadCapdata_struct), GFP_KERNEL); | ||
1529 | if (size_buff == NULL) | ||
1530 | goto mem_msg; | ||
1531 | inq_buff = kmalloc(sizeof( InquiryData_struct), GFP_KERNEL); | ||
1532 | if (inq_buff == NULL) | ||
1533 | goto mem_msg; | ||
1534 | |||
1535 | return_code = sendcmd_withirq(CISS_REPORT_LOG, ctlr, ld_buff, | ||
1536 | sizeof(ReportLunData_struct), 0, 0, 0, TYPE_CMD); | ||
1537 | |||
1538 | if( return_code == IO_OK) | ||
1539 | { | ||
1540 | |||
1541 | // printk("LUN Data\n--------------------------\n"); | ||
1542 | |||
1543 | listlength |= (0xff & (unsigned int)(ld_buff->LUNListLength[0])) << 24; | ||
1544 | listlength |= (0xff & (unsigned int)(ld_buff->LUNListLength[1])) << 16; | ||
1545 | listlength |= (0xff & (unsigned int)(ld_buff->LUNListLength[2])) << 8; | ||
1546 | listlength |= 0xff & (unsigned int)(ld_buff->LUNListLength[3]); | ||
1547 | } else /* reading number of logical volumes failed */ | ||
1548 | { | ||
1549 | printk(KERN_WARNING "cciss: report logical volume" | ||
1550 | " command failed\n"); | ||
1551 | listlength = 0; | ||
1552 | goto free_err; | ||
1553 | } | ||
1554 | num_luns = listlength / 8; // 8 bytes pre entry | ||
1555 | if (num_luns > CISS_MAX_LUN) | ||
1556 | { | ||
1557 | num_luns = CISS_MAX_LUN; | ||
1558 | } | ||
1559 | #ifdef CCISS_DEBUG | ||
1560 | printk(KERN_DEBUG "Length = %x %x %x %x = %d\n", ld_buff->LUNListLength[0], | ||
1561 | ld_buff->LUNListLength[1], ld_buff->LUNListLength[2], | ||
1562 | ld_buff->LUNListLength[3], num_luns); | ||
1563 | #endif | ||
1564 | for(i=0; i< num_luns; i++) | ||
1565 | { | ||
1566 | int j; | ||
1567 | int lunID_found = 0; | ||
1568 | |||
1569 | lunid = (0xff & (unsigned int)(ld_buff->LUN[i][3])) << 24; | ||
1570 | lunid |= (0xff & (unsigned int)(ld_buff->LUN[i][2])) << 16; | ||
1571 | lunid |= (0xff & (unsigned int)(ld_buff->LUN[i][1])) << 8; | ||
1572 | lunid |= 0xff & (unsigned int)(ld_buff->LUN[i][0]); | ||
1573 | |||
1574 | /* check to see if this is a new lun */ | ||
1575 | for(j=0; j <= h->highest_lun; j++) | ||
1576 | { | ||
1577 | #ifdef CCISS_DEBUG | ||
1578 | printk("Checking %d %x against %x\n", j,h->drv[j].LunID, | ||
1579 | lunid); | ||
1580 | #endif /* CCISS_DEBUG */ | ||
1581 | if (h->drv[j].LunID == lunid) | ||
1582 | { | ||
1583 | lunID_found = 1; | ||
1584 | break; | ||
1585 | } | ||
1586 | |||
1587 | } | ||
1588 | if( lunID_found == 1) | ||
1589 | continue; | ||
1590 | else | ||
1591 | { /* It is the new lun we have been looking for */ | ||
1592 | #ifdef CCISS_DEBUG | ||
1593 | printk("new lun found at %d\n", i); | ||
1594 | #endif /* CCISS_DEBUG */ | ||
1595 | new_lun_index = i; | ||
1596 | new_lun_found = 1; | ||
1597 | break; | ||
1598 | } | ||
1599 | } | ||
1600 | if (!new_lun_found) | ||
1601 | { | ||
1602 | printk(KERN_WARNING "cciss: New Logical Volume not found\n"); | ||
1603 | goto free_err; | ||
1604 | } | ||
1605 | /* Now find the free index */ | ||
1606 | for(i=0; i <CISS_MAX_LUN; i++) | ||
1607 | { | ||
1608 | #ifdef CCISS_DEBUG | ||
1609 | printk("Checking Index %d\n", i); | ||
1610 | #endif /* CCISS_DEBUG */ | ||
1611 | if(h->drv[i].LunID == 0) | ||
1612 | { | ||
1613 | #ifdef CCISS_DEBUG | ||
1614 | printk("free index found at %d\n", i); | ||
1615 | #endif /* CCISS_DEBUG */ | ||
1616 | free_index_found = 1; | ||
1617 | free_index = i; | ||
1618 | break; | ||
1619 | } | ||
1620 | } | ||
1621 | if (!free_index_found) | ||
1622 | { | ||
1623 | printk(KERN_WARNING "cciss: unable to find free slot for disk\n"); | ||
1624 | goto free_err; | ||
1625 | } | ||
1626 | |||
1627 | logvol = free_index; | ||
1628 | h->drv[logvol].LunID = lunid; | ||
1629 | /* there could be gaps in lun numbers, track hightest */ | ||
1630 | if(h->highest_lun < lunid) | ||
1631 | h->highest_lun = logvol; | ||
1632 | cciss_read_capacity(ctlr, logvol, size_buff, 1, | ||
1633 | &total_size, &block_size); | ||
1634 | cciss_geometry_inquiry(ctlr, logvol, 1, total_size, block_size, | ||
1635 | inq_buff, &h->drv[logvol]); | ||
1636 | h->drv[logvol].usage_count = 0; | ||
1637 | ++h->num_luns; | ||
1638 | /* setup partitions per disk */ | ||
1639 | disk = h->gendisk[logvol]; | ||
1640 | set_capacity(disk, h->drv[logvol].nr_blocks); | ||
1641 | /* if it's the controller it's already added */ | ||
1642 | if(logvol) | ||
1643 | add_disk(disk); | ||
1644 | freeret: | ||
1645 | kfree(ld_buff); | ||
1646 | kfree(size_buff); | ||
1647 | kfree(inq_buff); | ||
1648 | return (logvol); | ||
1649 | mem_msg: | ||
1650 | printk(KERN_ERR "cciss: out of memory\n"); | ||
1651 | free_err: | ||
1652 | logvol = -1; | ||
1653 | goto freeret; | ||
1654 | } | ||
1655 | |||
1656 | static int cciss_revalidate(struct gendisk *disk) | 1807 | static int cciss_revalidate(struct gendisk *disk) |
1657 | { | 1808 | { |
1658 | ctlr_info_t *h = get_host(disk); | 1809 | ctlr_info_t *h = get_host(disk); |
@@ -1859,8 +2010,10 @@ resend_cmd1: | |||
1859 | 2010 | ||
1860 | cleanup1: | 2011 | cleanup1: |
1861 | /* unlock the data buffer from DMA */ | 2012 | /* unlock the data buffer from DMA */ |
2013 | buff_dma_handle.val32.lower = c->SG[0].Addr.lower; | ||
2014 | buff_dma_handle.val32.upper = c->SG[0].Addr.upper; | ||
1862 | pci_unmap_single(info_p->pdev, (dma_addr_t) buff_dma_handle.val, | 2015 | pci_unmap_single(info_p->pdev, (dma_addr_t) buff_dma_handle.val, |
1863 | size, PCI_DMA_BIDIRECTIONAL); | 2016 | c->SG[0].Len, PCI_DMA_BIDIRECTIONAL); |
1864 | cmd_free(info_p, c, 1); | 2017 | cmd_free(info_p, c, 1); |
1865 | return (status); | 2018 | return (status); |
1866 | } | 2019 | } |
@@ -2111,7 +2264,11 @@ queue: | |||
2111 | /* fill in the request */ | 2264 | /* fill in the request */ |
2112 | drv = creq->rq_disk->private_data; | 2265 | drv = creq->rq_disk->private_data; |
2113 | c->Header.ReplyQueue = 0; // unused in simple mode | 2266 | c->Header.ReplyQueue = 0; // unused in simple mode |
2114 | c->Header.Tag.lower = c->busaddr; // use the physical address the cmd block for tag | 2267 | /* got command from pool, so use the command block index instead */ |
2268 | /* for direct lookups. */ | ||
2269 | /* The first 2 bits are reserved for controller error reporting. */ | ||
2270 | c->Header.Tag.lower = (c->cmdindex << 3); | ||
2271 | c->Header.Tag.lower |= 0x04; /* flag for direct lookup. */ | ||
2115 | c->Header.LUN.LogDev.VolId= drv->LunID; | 2272 | c->Header.LUN.LogDev.VolId= drv->LunID; |
2116 | c->Header.LUN.LogDev.Mode = 1; | 2273 | c->Header.LUN.LogDev.Mode = 1; |
2117 | c->Request.CDBLen = 10; // 12 byte commands not in FW yet; | 2274 | c->Request.CDBLen = 10; // 12 byte commands not in FW yet; |
@@ -2186,7 +2343,7 @@ static irqreturn_t do_cciss_intr(int irq, void *dev_id, struct pt_regs *regs) | |||
2186 | ctlr_info_t *h = dev_id; | 2343 | ctlr_info_t *h = dev_id; |
2187 | CommandList_struct *c; | 2344 | CommandList_struct *c; |
2188 | unsigned long flags; | 2345 | unsigned long flags; |
2189 | __u32 a, a1; | 2346 | __u32 a, a1, a2; |
2190 | int j; | 2347 | int j; |
2191 | int start_queue = h->next_to_run; | 2348 | int start_queue = h->next_to_run; |
2192 | 2349 | ||
@@ -2204,10 +2361,21 @@ static irqreturn_t do_cciss_intr(int irq, void *dev_id, struct pt_regs *regs) | |||
2204 | while((a = h->access.command_completed(h)) != FIFO_EMPTY) | 2361 | while((a = h->access.command_completed(h)) != FIFO_EMPTY) |
2205 | { | 2362 | { |
2206 | a1 = a; | 2363 | a1 = a; |
2364 | if ((a & 0x04)) { | ||
2365 | a2 = (a >> 3); | ||
2366 | if (a2 >= NR_CMDS) { | ||
2367 | printk(KERN_WARNING "cciss: controller cciss%d failed, stopping.\n", h->ctlr); | ||
2368 | fail_all_cmds(h->ctlr); | ||
2369 | return IRQ_HANDLED; | ||
2370 | } | ||
2371 | |||
2372 | c = h->cmd_pool + a2; | ||
2373 | a = c->busaddr; | ||
2374 | |||
2375 | } else { | ||
2207 | a &= ~3; | 2376 | a &= ~3; |
2208 | if ((c = h->cmpQ) == NULL) | 2377 | if ((c = h->cmpQ) == NULL) { |
2209 | { | 2378 | printk(KERN_WARNING "cciss: Completion of %08x ignored\n", a1); |
2210 | printk(KERN_WARNING "cciss: Completion of %08lx ignored\n", (unsigned long)a1); | ||
2211 | continue; | 2379 | continue; |
2212 | } | 2380 | } |
2213 | while(c->busaddr != a) { | 2381 | while(c->busaddr != a) { |
@@ -2215,6 +2383,7 @@ static irqreturn_t do_cciss_intr(int irq, void *dev_id, struct pt_regs *regs) | |||
2215 | if (c == h->cmpQ) | 2383 | if (c == h->cmpQ) |
2216 | break; | 2384 | break; |
2217 | } | 2385 | } |
2386 | } | ||
2218 | /* | 2387 | /* |
2219 | * If we've found the command, take it off the | 2388 | * If we've found the command, take it off the |
2220 | * completion Q and free it | 2389 | * completion Q and free it |
@@ -2634,12 +2803,16 @@ static void cciss_getgeometry(int cntl_num) | |||
2634 | #endif /* CCISS_DEBUG */ | 2803 | #endif /* CCISS_DEBUG */ |
2635 | 2804 | ||
2636 | hba[cntl_num]->highest_lun = hba[cntl_num]->num_luns-1; | 2805 | hba[cntl_num]->highest_lun = hba[cntl_num]->num_luns-1; |
2637 | for(i=0; i< hba[cntl_num]->num_luns; i++) | 2806 | // for(i=0; i< hba[cntl_num]->num_luns; i++) |
2807 | for(i=0; i < CISS_MAX_LUN; i++) | ||
2638 | { | 2808 | { |
2639 | 2809 | if (i < hba[cntl_num]->num_luns){ | |
2640 | lunid = (0xff & (unsigned int)(ld_buff->LUN[i][3])) << 24; | 2810 | lunid = (0xff & (unsigned int)(ld_buff->LUN[i][3])) |
2641 | lunid |= (0xff & (unsigned int)(ld_buff->LUN[i][2])) << 16; | 2811 | << 24; |
2642 | lunid |= (0xff & (unsigned int)(ld_buff->LUN[i][1])) << 8; | 2812 | lunid |= (0xff & (unsigned int)(ld_buff->LUN[i][2])) |
2813 | << 16; | ||
2814 | lunid |= (0xff & (unsigned int)(ld_buff->LUN[i][1])) | ||
2815 | << 8; | ||
2643 | lunid |= 0xff & (unsigned int)(ld_buff->LUN[i][0]); | 2816 | lunid |= 0xff & (unsigned int)(ld_buff->LUN[i][0]); |
2644 | 2817 | ||
2645 | hba[cntl_num]->drv[i].LunID = lunid; | 2818 | hba[cntl_num]->drv[i].LunID = lunid; |
@@ -2647,13 +2820,18 @@ static void cciss_getgeometry(int cntl_num) | |||
2647 | 2820 | ||
2648 | #ifdef CCISS_DEBUG | 2821 | #ifdef CCISS_DEBUG |
2649 | printk(KERN_DEBUG "LUN[%d]: %x %x %x %x = %x\n", i, | 2822 | printk(KERN_DEBUG "LUN[%d]: %x %x %x %x = %x\n", i, |
2650 | ld_buff->LUN[i][0], ld_buff->LUN[i][1],ld_buff->LUN[i][2], | 2823 | ld_buff->LUN[i][0], ld_buff->LUN[i][1], |
2651 | ld_buff->LUN[i][3], hba[cntl_num]->drv[i].LunID); | 2824 | ld_buff->LUN[i][2], ld_buff->LUN[i][3], |
2825 | hba[cntl_num]->drv[i].LunID); | ||
2652 | #endif /* CCISS_DEBUG */ | 2826 | #endif /* CCISS_DEBUG */ |
2653 | cciss_read_capacity(cntl_num, i, size_buff, 0, | 2827 | cciss_read_capacity(cntl_num, i, size_buff, 0, |
2654 | &total_size, &block_size); | 2828 | &total_size, &block_size); |
2655 | cciss_geometry_inquiry(cntl_num, i, 0, total_size, block_size, | 2829 | cciss_geometry_inquiry(cntl_num, i, 0, total_size, |
2656 | inq_buff, &hba[cntl_num]->drv[i]); | 2830 | block_size, inq_buff, &hba[cntl_num]->drv[i]); |
2831 | } else { | ||
2832 | /* initialize raid_level to indicate a free space */ | ||
2833 | hba[cntl_num]->drv[i].raid_level = -1; | ||
2834 | } | ||
2657 | } | 2835 | } |
2658 | kfree(ld_buff); | 2836 | kfree(ld_buff); |
2659 | kfree(size_buff); | 2837 | kfree(size_buff); |
@@ -2727,6 +2905,9 @@ static int __devinit cciss_init_one(struct pci_dev *pdev, | |||
2727 | i = alloc_cciss_hba(); | 2905 | i = alloc_cciss_hba(); |
2728 | if(i < 0) | 2906 | if(i < 0) |
2729 | return (-1); | 2907 | return (-1); |
2908 | |||
2909 | hba[i]->busy_initializing = 1; | ||
2910 | |||
2730 | if (cciss_pci_init(hba[i], pdev) != 0) | 2911 | if (cciss_pci_init(hba[i], pdev) != 0) |
2731 | goto clean1; | 2912 | goto clean1; |
2732 | 2913 | ||
@@ -2807,6 +2988,7 @@ static int __devinit cciss_init_one(struct pci_dev *pdev, | |||
2807 | hba[i]->access.set_intr_mask(hba[i], CCISS_INTR_ON); | 2988 | hba[i]->access.set_intr_mask(hba[i], CCISS_INTR_ON); |
2808 | 2989 | ||
2809 | cciss_procinit(i); | 2990 | cciss_procinit(i); |
2991 | hba[i]->busy_initializing = 0; | ||
2810 | 2992 | ||
2811 | for(j=0; j < NWD; j++) { /* mfm */ | 2993 | for(j=0; j < NWD; j++) { /* mfm */ |
2812 | drive_info_struct *drv = &(hba[i]->drv[j]); | 2994 | drive_info_struct *drv = &(hba[i]->drv[j]); |
@@ -2869,6 +3051,7 @@ clean2: | |||
2869 | clean1: | 3051 | clean1: |
2870 | release_io_mem(hba[i]); | 3052 | release_io_mem(hba[i]); |
2871 | free_hba(i); | 3053 | free_hba(i); |
3054 | hba[i]->busy_initializing = 0; | ||
2872 | return(-1); | 3055 | return(-1); |
2873 | } | 3056 | } |
2874 | 3057 | ||
@@ -2913,9 +3096,10 @@ static void __devexit cciss_remove_one (struct pci_dev *pdev) | |||
2913 | /* remove it from the disk list */ | 3096 | /* remove it from the disk list */ |
2914 | for (j = 0; j < NWD; j++) { | 3097 | for (j = 0; j < NWD; j++) { |
2915 | struct gendisk *disk = hba[i]->gendisk[j]; | 3098 | struct gendisk *disk = hba[i]->gendisk[j]; |
2916 | if (disk->flags & GENHD_FL_UP) | 3099 | if (disk->flags & GENHD_FL_UP) { |
2917 | blk_cleanup_queue(disk->queue); | ||
2918 | del_gendisk(disk); | 3100 | del_gendisk(disk); |
3101 | blk_cleanup_queue(disk->queue); | ||
3102 | } | ||
2919 | } | 3103 | } |
2920 | 3104 | ||
2921 | pci_free_consistent(hba[i]->pdev, NR_CMDS * sizeof(CommandList_struct), | 3105 | pci_free_consistent(hba[i]->pdev, NR_CMDS * sizeof(CommandList_struct), |
@@ -2964,5 +3148,43 @@ static void __exit cciss_cleanup(void) | |||
2964 | remove_proc_entry("cciss", proc_root_driver); | 3148 | remove_proc_entry("cciss", proc_root_driver); |
2965 | } | 3149 | } |
2966 | 3150 | ||
3151 | static void fail_all_cmds(unsigned long ctlr) | ||
3152 | { | ||
3153 | /* If we get here, the board is apparently dead. */ | ||
3154 | ctlr_info_t *h = hba[ctlr]; | ||
3155 | CommandList_struct *c; | ||
3156 | unsigned long flags; | ||
3157 | |||
3158 | printk(KERN_WARNING "cciss%d: controller not responding.\n", h->ctlr); | ||
3159 | h->alive = 0; /* the controller apparently died... */ | ||
3160 | |||
3161 | spin_lock_irqsave(CCISS_LOCK(ctlr), flags); | ||
3162 | |||
3163 | pci_disable_device(h->pdev); /* Make sure it is really dead. */ | ||
3164 | |||
3165 | /* move everything off the request queue onto the completed queue */ | ||
3166 | while( (c = h->reqQ) != NULL ) { | ||
3167 | removeQ(&(h->reqQ), c); | ||
3168 | h->Qdepth--; | ||
3169 | addQ (&(h->cmpQ), c); | ||
3170 | } | ||
3171 | |||
3172 | /* Now, fail everything on the completed queue with a HW error */ | ||
3173 | while( (c = h->cmpQ) != NULL ) { | ||
3174 | removeQ(&h->cmpQ, c); | ||
3175 | c->err_info->CommandStatus = CMD_HARDWARE_ERR; | ||
3176 | if (c->cmd_type == CMD_RWREQ) { | ||
3177 | complete_command(h, c, 0); | ||
3178 | } else if (c->cmd_type == CMD_IOCTL_PEND) | ||
3179 | complete(c->waiting); | ||
3180 | #ifdef CONFIG_CISS_SCSI_TAPE | ||
3181 | else if (c->cmd_type == CMD_SCSI) | ||
3182 | complete_scsi_command(c, 0, 0); | ||
3183 | #endif | ||
3184 | } | ||
3185 | spin_unlock_irqrestore(CCISS_LOCK(ctlr), flags); | ||
3186 | return; | ||
3187 | } | ||
3188 | |||
2967 | module_init(cciss_init); | 3189 | module_init(cciss_init); |
2968 | module_exit(cciss_cleanup); | 3190 | module_exit(cciss_cleanup); |