diff options
Diffstat (limited to 'drivers/block')
-rw-r--r-- | drivers/block/cciss.c | 636 | ||||
-rw-r--r-- | drivers/block/cciss.h | 10 | ||||
-rw-r--r-- | drivers/block/cciss_cmd.h | 8 | ||||
-rw-r--r-- | drivers/block/cciss_scsi.c | 69 | ||||
-rw-r--r-- | drivers/block/ll_rw_blk.c | 38 | ||||
-rw-r--r-- | drivers/block/paride/pf.c | 22 | ||||
-rw-r--r-- | drivers/block/pktcdvd.c | 85 | ||||
-rw-r--r-- | drivers/block/scsi_ioctl.c | 1 | ||||
-rw-r--r-- | drivers/block/ub.c | 55 |
9 files changed, 591 insertions, 333 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); |
diff --git a/drivers/block/cciss.h b/drivers/block/cciss.h index 566587d0a500..ef277baee9fd 100644 --- a/drivers/block/cciss.h +++ b/drivers/block/cciss.h | |||
@@ -35,7 +35,13 @@ typedef struct _drive_info_struct | |||
35 | int heads; | 35 | int heads; |
36 | int sectors; | 36 | int sectors; |
37 | int cylinders; | 37 | int cylinders; |
38 | int raid_level; | 38 | int raid_level; /* set to -1 to indicate that |
39 | * the drive is not in use/configured | ||
40 | */ | ||
41 | int busy_configuring; /*This is set when the drive is being removed | ||
42 | *to prevent it from being opened or it's queue | ||
43 | *from being started. | ||
44 | */ | ||
39 | } drive_info_struct; | 45 | } drive_info_struct; |
40 | 46 | ||
41 | struct ctlr_info | 47 | struct ctlr_info |
@@ -83,6 +89,7 @@ struct ctlr_info | |||
83 | int nr_allocs; | 89 | int nr_allocs; |
84 | int nr_frees; | 90 | int nr_frees; |
85 | int busy_configuring; | 91 | int busy_configuring; |
92 | int busy_initializing; | ||
86 | 93 | ||
87 | /* This element holds the zero based queue number of the last | 94 | /* This element holds the zero based queue number of the last |
88 | * queue to be started. It is used for fairness. | 95 | * queue to be started. It is used for fairness. |
@@ -94,6 +101,7 @@ struct ctlr_info | |||
94 | #ifdef CONFIG_CISS_SCSI_TAPE | 101 | #ifdef CONFIG_CISS_SCSI_TAPE |
95 | void *scsi_ctlr; /* ptr to structure containing scsi related stuff */ | 102 | void *scsi_ctlr; /* ptr to structure containing scsi related stuff */ |
96 | #endif | 103 | #endif |
104 | unsigned char alive; | ||
97 | }; | 105 | }; |
98 | 106 | ||
99 | /* Defining the diffent access_menthods */ | 107 | /* Defining the diffent access_menthods */ |
diff --git a/drivers/block/cciss_cmd.h b/drivers/block/cciss_cmd.h index a88a88817623..53fea549ba8b 100644 --- a/drivers/block/cciss_cmd.h +++ b/drivers/block/cciss_cmd.h | |||
@@ -226,6 +226,10 @@ typedef struct _ErrorInfo_struct { | |||
226 | #define CMD_MSG_DONE 0x04 | 226 | #define CMD_MSG_DONE 0x04 |
227 | #define CMD_MSG_TIMEOUT 0x05 | 227 | #define CMD_MSG_TIMEOUT 0x05 |
228 | 228 | ||
229 | /* This structure needs to be divisible by 8 for new | ||
230 | * indexing method. | ||
231 | */ | ||
232 | #define PADSIZE (sizeof(long) - 4) | ||
229 | typedef struct _CommandList_struct { | 233 | typedef struct _CommandList_struct { |
230 | CommandListHeader_struct Header; | 234 | CommandListHeader_struct Header; |
231 | RequestBlock_struct Request; | 235 | RequestBlock_struct Request; |
@@ -236,14 +240,14 @@ typedef struct _CommandList_struct { | |||
236 | ErrorInfo_struct * err_info; /* pointer to the allocated mem */ | 240 | ErrorInfo_struct * err_info; /* pointer to the allocated mem */ |
237 | int ctlr; | 241 | int ctlr; |
238 | int cmd_type; | 242 | int cmd_type; |
243 | long cmdindex; | ||
239 | struct _CommandList_struct *prev; | 244 | struct _CommandList_struct *prev; |
240 | struct _CommandList_struct *next; | 245 | struct _CommandList_struct *next; |
241 | struct request * rq; | 246 | struct request * rq; |
242 | struct completion *waiting; | 247 | struct completion *waiting; |
243 | int retry_count; | 248 | int retry_count; |
244 | #ifdef CONFIG_CISS_SCSI_TAPE | ||
245 | void * scsi_cmd; | 249 | void * scsi_cmd; |
246 | #endif | 250 | char pad[PADSIZE]; |
247 | } CommandList_struct; | 251 | } CommandList_struct; |
248 | 252 | ||
249 | //Configuration Table Structure | 253 | //Configuration Table Structure |
diff --git a/drivers/block/cciss_scsi.c b/drivers/block/cciss_scsi.c index f16e3caed58a..e183a3ef7839 100644 --- a/drivers/block/cciss_scsi.c +++ b/drivers/block/cciss_scsi.c | |||
@@ -93,6 +93,7 @@ struct cciss_scsi_cmd_stack_elem_t { | |||
93 | CommandList_struct cmd; | 93 | CommandList_struct cmd; |
94 | ErrorInfo_struct Err; | 94 | ErrorInfo_struct Err; |
95 | __u32 busaddr; | 95 | __u32 busaddr; |
96 | __u32 pad; | ||
96 | }; | 97 | }; |
97 | 98 | ||
98 | #pragma pack() | 99 | #pragma pack() |
@@ -877,7 +878,7 @@ cciss_scsi_interpret_error(CommandList_struct *cp) | |||
877 | 878 | ||
878 | static int | 879 | static int |
879 | cciss_scsi_do_inquiry(ctlr_info_t *c, unsigned char *scsi3addr, | 880 | cciss_scsi_do_inquiry(ctlr_info_t *c, unsigned char *scsi3addr, |
880 | InquiryData_struct *buf) | 881 | unsigned char *buf, unsigned char bufsize) |
881 | { | 882 | { |
882 | int rc; | 883 | int rc; |
883 | CommandList_struct *cp; | 884 | CommandList_struct *cp; |
@@ -900,11 +901,10 @@ cciss_scsi_do_inquiry(ctlr_info_t *c, unsigned char *scsi3addr, | |||
900 | cdb[1] = 0; | 901 | cdb[1] = 0; |
901 | cdb[2] = 0; | 902 | cdb[2] = 0; |
902 | cdb[3] = 0; | 903 | cdb[3] = 0; |
903 | cdb[4] = sizeof(*buf) & 0xff; | 904 | cdb[4] = bufsize; |
904 | cdb[5] = 0; | 905 | cdb[5] = 0; |
905 | rc = cciss_scsi_do_simple_cmd(c, cp, scsi3addr, cdb, | 906 | rc = cciss_scsi_do_simple_cmd(c, cp, scsi3addr, cdb, |
906 | 6, (unsigned char *) buf, | 907 | 6, buf, bufsize, XFER_READ); |
907 | sizeof(*buf), XFER_READ); | ||
908 | 908 | ||
909 | if (rc != 0) return rc; /* something went wrong */ | 909 | if (rc != 0) return rc; /* something went wrong */ |
910 | 910 | ||
@@ -1000,9 +1000,10 @@ cciss_update_non_disk_devices(int cntl_num, int hostno) | |||
1000 | that though. | 1000 | that though. |
1001 | 1001 | ||
1002 | */ | 1002 | */ |
1003 | 1003 | #define OBDR_TAPE_INQ_SIZE 49 | |
1004 | #define OBDR_TAPE_SIG "$DR-10" | ||
1004 | ReportLunData_struct *ld_buff; | 1005 | ReportLunData_struct *ld_buff; |
1005 | InquiryData_struct *inq_buff; | 1006 | unsigned char *inq_buff; |
1006 | unsigned char scsi3addr[8]; | 1007 | unsigned char scsi3addr[8]; |
1007 | ctlr_info_t *c; | 1008 | ctlr_info_t *c; |
1008 | __u32 num_luns=0; | 1009 | __u32 num_luns=0; |
@@ -1020,7 +1021,7 @@ cciss_update_non_disk_devices(int cntl_num, int hostno) | |||
1020 | return; | 1021 | return; |
1021 | } | 1022 | } |
1022 | memset(ld_buff, 0, reportlunsize); | 1023 | memset(ld_buff, 0, reportlunsize); |
1023 | inq_buff = kmalloc(sizeof( InquiryData_struct), GFP_KERNEL); | 1024 | inq_buff = kmalloc(OBDR_TAPE_INQ_SIZE, GFP_KERNEL); |
1024 | if (inq_buff == NULL) { | 1025 | if (inq_buff == NULL) { |
1025 | printk(KERN_ERR "cciss: out of memory\n"); | 1026 | printk(KERN_ERR "cciss: out of memory\n"); |
1026 | kfree(ld_buff); | 1027 | kfree(ld_buff); |
@@ -1051,19 +1052,36 @@ cciss_update_non_disk_devices(int cntl_num, int hostno) | |||
1051 | 1052 | ||
1052 | /* for each physical lun, do an inquiry */ | 1053 | /* for each physical lun, do an inquiry */ |
1053 | if (ld_buff->LUN[i][3] & 0xC0) continue; | 1054 | if (ld_buff->LUN[i][3] & 0xC0) continue; |
1054 | memset(inq_buff, 0, sizeof(InquiryData_struct)); | 1055 | memset(inq_buff, 0, OBDR_TAPE_INQ_SIZE); |
1055 | memcpy(&scsi3addr[0], &ld_buff->LUN[i][0], 8); | 1056 | memcpy(&scsi3addr[0], &ld_buff->LUN[i][0], 8); |
1056 | 1057 | ||
1057 | if (cciss_scsi_do_inquiry(hba[cntl_num], | 1058 | if (cciss_scsi_do_inquiry(hba[cntl_num], scsi3addr, inq_buff, |
1058 | scsi3addr, inq_buff) != 0) | 1059 | (unsigned char) OBDR_TAPE_INQ_SIZE) != 0) { |
1059 | { | ||
1060 | /* Inquiry failed (msg printed already) */ | 1060 | /* Inquiry failed (msg printed already) */ |
1061 | devtype = 0; /* so we will skip this device. */ | 1061 | devtype = 0; /* so we will skip this device. */ |
1062 | } else /* what kind of device is this? */ | 1062 | } else /* what kind of device is this? */ |
1063 | devtype = (inq_buff->data_byte[0] & 0x1f); | 1063 | devtype = (inq_buff[0] & 0x1f); |
1064 | 1064 | ||
1065 | switch (devtype) | 1065 | switch (devtype) |
1066 | { | 1066 | { |
1067 | case 0x05: /* CD-ROM */ { | ||
1068 | |||
1069 | /* We don't *really* support actual CD-ROM devices, | ||
1070 | * just this "One Button Disaster Recovery" tape drive | ||
1071 | * which temporarily pretends to be a CD-ROM drive. | ||
1072 | * So we check that the device is really an OBDR tape | ||
1073 | * device by checking for "$DR-10" in bytes 43-48 of | ||
1074 | * the inquiry data. | ||
1075 | */ | ||
1076 | char obdr_sig[7]; | ||
1077 | |||
1078 | strncpy(obdr_sig, &inq_buff[43], 6); | ||
1079 | obdr_sig[6] = '\0'; | ||
1080 | if (strncmp(obdr_sig, OBDR_TAPE_SIG, 6) != 0) | ||
1081 | /* Not OBDR device, ignore it. */ | ||
1082 | break; | ||
1083 | } | ||
1084 | /* fall through . . . */ | ||
1067 | case 0x01: /* sequential access, (tape) */ | 1085 | case 0x01: /* sequential access, (tape) */ |
1068 | case 0x08: /* medium changer */ | 1086 | case 0x08: /* medium changer */ |
1069 | if (ncurrent >= CCISS_MAX_SCSI_DEVS_PER_HBA) { | 1087 | if (ncurrent >= CCISS_MAX_SCSI_DEVS_PER_HBA) { |
@@ -1126,6 +1144,7 @@ cciss_scsi_proc_info(struct Scsi_Host *sh, | |||
1126 | 1144 | ||
1127 | int buflen, datalen; | 1145 | int buflen, datalen; |
1128 | ctlr_info_t *ci; | 1146 | ctlr_info_t *ci; |
1147 | int i; | ||
1129 | int cntl_num; | 1148 | int cntl_num; |
1130 | 1149 | ||
1131 | 1150 | ||
@@ -1136,8 +1155,28 @@ cciss_scsi_proc_info(struct Scsi_Host *sh, | |||
1136 | cntl_num = ci->ctlr; /* Get our index into the hba[] array */ | 1155 | cntl_num = ci->ctlr; /* Get our index into the hba[] array */ |
1137 | 1156 | ||
1138 | if (func == 0) { /* User is reading from /proc/scsi/ciss*?/?* */ | 1157 | if (func == 0) { /* User is reading from /proc/scsi/ciss*?/?* */ |
1139 | buflen = sprintf(buffer, "hostnum=%d\n", sh->host_no); | 1158 | buflen = sprintf(buffer, "cciss%d: SCSI host: %d\n", |
1140 | 1159 | cntl_num, sh->host_no); | |
1160 | |||
1161 | /* this information is needed by apps to know which cciss | ||
1162 | device corresponds to which scsi host number without | ||
1163 | having to open a scsi target device node. The device | ||
1164 | information is not a duplicate of /proc/scsi/scsi because | ||
1165 | the two may be out of sync due to scsi hotplug, rather | ||
1166 | this info is for an app to be able to use to know how to | ||
1167 | get them back in sync. */ | ||
1168 | |||
1169 | for (i=0;i<ccissscsi[cntl_num].ndevices;i++) { | ||
1170 | struct cciss_scsi_dev_t *sd = &ccissscsi[cntl_num].dev[i]; | ||
1171 | buflen += sprintf(&buffer[buflen], "c%db%dt%dl%d %02d " | ||
1172 | "0x%02x%02x%02x%02x%02x%02x%02x%02x\n", | ||
1173 | sh->host_no, sd->bus, sd->target, sd->lun, | ||
1174 | sd->devtype, | ||
1175 | sd->scsi3addr[0], sd->scsi3addr[1], | ||
1176 | sd->scsi3addr[2], sd->scsi3addr[3], | ||
1177 | sd->scsi3addr[4], sd->scsi3addr[5], | ||
1178 | sd->scsi3addr[6], sd->scsi3addr[7]); | ||
1179 | } | ||
1141 | datalen = buflen - offset; | 1180 | datalen = buflen - offset; |
1142 | if (datalen < 0) { /* they're reading past EOF. */ | 1181 | if (datalen < 0) { /* they're reading past EOF. */ |
1143 | datalen = 0; | 1182 | datalen = 0; |
@@ -1399,7 +1438,7 @@ cciss_proc_tape_report(int ctlr, unsigned char *buffer, off_t *pos, off_t *len) | |||
1399 | 1438 | ||
1400 | CPQ_TAPE_LOCK(ctlr, flags); | 1439 | CPQ_TAPE_LOCK(ctlr, flags); |
1401 | size = sprintf(buffer + *len, | 1440 | size = sprintf(buffer + *len, |
1402 | " Sequential access devices: %d\n\n", | 1441 | "Sequential access devices: %d\n\n", |
1403 | ccissscsi[ctlr].ndevices); | 1442 | ccissscsi[ctlr].ndevices); |
1404 | CPQ_TAPE_UNLOCK(ctlr, flags); | 1443 | CPQ_TAPE_UNLOCK(ctlr, flags); |
1405 | *pos += size; *len += size; | 1444 | *pos += size; *len += size; |
diff --git a/drivers/block/ll_rw_blk.c b/drivers/block/ll_rw_blk.c index 483d71b10cf9..baedac522945 100644 --- a/drivers/block/ll_rw_blk.c +++ b/drivers/block/ll_rw_blk.c | |||
@@ -2373,44 +2373,6 @@ int blkdev_issue_flush(struct block_device *bdev, sector_t *error_sector) | |||
2373 | 2373 | ||
2374 | EXPORT_SYMBOL(blkdev_issue_flush); | 2374 | EXPORT_SYMBOL(blkdev_issue_flush); |
2375 | 2375 | ||
2376 | /** | ||
2377 | * blkdev_scsi_issue_flush_fn - issue flush for SCSI devices | ||
2378 | * @q: device queue | ||
2379 | * @disk: gendisk | ||
2380 | * @error_sector: error offset | ||
2381 | * | ||
2382 | * Description: | ||
2383 | * Devices understanding the SCSI command set, can use this function as | ||
2384 | * a helper for issuing a cache flush. Note: driver is required to store | ||
2385 | * the error offset (in case of error flushing) in ->sector of struct | ||
2386 | * request. | ||
2387 | */ | ||
2388 | int blkdev_scsi_issue_flush_fn(request_queue_t *q, struct gendisk *disk, | ||
2389 | sector_t *error_sector) | ||
2390 | { | ||
2391 | struct request *rq = blk_get_request(q, WRITE, __GFP_WAIT); | ||
2392 | int ret; | ||
2393 | |||
2394 | rq->flags |= REQ_BLOCK_PC | REQ_SOFTBARRIER; | ||
2395 | rq->sector = 0; | ||
2396 | memset(rq->cmd, 0, sizeof(rq->cmd)); | ||
2397 | rq->cmd[0] = 0x35; | ||
2398 | rq->cmd_len = 12; | ||
2399 | rq->data = NULL; | ||
2400 | rq->data_len = 0; | ||
2401 | rq->timeout = 60 * HZ; | ||
2402 | |||
2403 | ret = blk_execute_rq(q, disk, rq, 0); | ||
2404 | |||
2405 | if (ret && error_sector) | ||
2406 | *error_sector = rq->sector; | ||
2407 | |||
2408 | blk_put_request(rq); | ||
2409 | return ret; | ||
2410 | } | ||
2411 | |||
2412 | EXPORT_SYMBOL(blkdev_scsi_issue_flush_fn); | ||
2413 | |||
2414 | static void drive_stat_acct(struct request *rq, int nr_sectors, int new_io) | 2376 | static void drive_stat_acct(struct request *rq, int nr_sectors, int new_io) |
2415 | { | 2377 | { |
2416 | int rw = rq_data_dir(rq); | 2378 | int rw = rq_data_dir(rq); |
diff --git a/drivers/block/paride/pf.c b/drivers/block/paride/pf.c index 711d2f314ac3..94af920465b5 100644 --- a/drivers/block/paride/pf.c +++ b/drivers/block/paride/pf.c | |||
@@ -750,6 +750,14 @@ static int pf_ready(void) | |||
750 | 750 | ||
751 | static struct request_queue *pf_queue; | 751 | static struct request_queue *pf_queue; |
752 | 752 | ||
753 | static void pf_end_request(int uptodate) | ||
754 | { | ||
755 | if (pf_req) { | ||
756 | end_request(pf_req, uptodate); | ||
757 | pf_req = NULL; | ||
758 | } | ||
759 | } | ||
760 | |||
753 | static void do_pf_request(request_queue_t * q) | 761 | static void do_pf_request(request_queue_t * q) |
754 | { | 762 | { |
755 | if (pf_busy) | 763 | if (pf_busy) |
@@ -765,7 +773,7 @@ repeat: | |||
765 | pf_count = pf_req->current_nr_sectors; | 773 | pf_count = pf_req->current_nr_sectors; |
766 | 774 | ||
767 | if (pf_block + pf_count > get_capacity(pf_req->rq_disk)) { | 775 | if (pf_block + pf_count > get_capacity(pf_req->rq_disk)) { |
768 | end_request(pf_req, 0); | 776 | pf_end_request(0); |
769 | goto repeat; | 777 | goto repeat; |
770 | } | 778 | } |
771 | 779 | ||
@@ -780,7 +788,7 @@ repeat: | |||
780 | pi_do_claimed(pf_current->pi, do_pf_write); | 788 | pi_do_claimed(pf_current->pi, do_pf_write); |
781 | else { | 789 | else { |
782 | pf_busy = 0; | 790 | pf_busy = 0; |
783 | end_request(pf_req, 0); | 791 | pf_end_request(0); |
784 | goto repeat; | 792 | goto repeat; |
785 | } | 793 | } |
786 | } | 794 | } |
@@ -798,9 +806,11 @@ static int pf_next_buf(void) | |||
798 | if (!pf_count) | 806 | if (!pf_count) |
799 | return 1; | 807 | return 1; |
800 | spin_lock_irqsave(&pf_spin_lock, saved_flags); | 808 | spin_lock_irqsave(&pf_spin_lock, saved_flags); |
801 | end_request(pf_req, 1); | 809 | pf_end_request(1); |
802 | pf_count = pf_req->current_nr_sectors; | 810 | if (pf_req) { |
803 | pf_buf = pf_req->buffer; | 811 | pf_count = pf_req->current_nr_sectors; |
812 | pf_buf = pf_req->buffer; | ||
813 | } | ||
804 | spin_unlock_irqrestore(&pf_spin_lock, saved_flags); | 814 | spin_unlock_irqrestore(&pf_spin_lock, saved_flags); |
805 | return 1; | 815 | return 1; |
806 | } | 816 | } |
@@ -810,7 +820,7 @@ static inline void next_request(int success) | |||
810 | unsigned long saved_flags; | 820 | unsigned long saved_flags; |
811 | 821 | ||
812 | spin_lock_irqsave(&pf_spin_lock, saved_flags); | 822 | spin_lock_irqsave(&pf_spin_lock, saved_flags); |
813 | end_request(pf_req, success); | 823 | pf_end_request(success); |
814 | pf_busy = 0; | 824 | pf_busy = 0; |
815 | do_pf_request(pf_queue); | 825 | do_pf_request(pf_queue); |
816 | spin_unlock_irqrestore(&pf_spin_lock, saved_flags); | 826 | spin_unlock_irqrestore(&pf_spin_lock, saved_flags); |
diff --git a/drivers/block/pktcdvd.c b/drivers/block/pktcdvd.c index 7b838342f0a3..7e22a58926b8 100644 --- a/drivers/block/pktcdvd.c +++ b/drivers/block/pktcdvd.c | |||
@@ -5,29 +5,41 @@ | |||
5 | * May be copied or modified under the terms of the GNU General Public | 5 | * May be copied or modified under the terms of the GNU General Public |
6 | * License. See linux/COPYING for more information. | 6 | * License. See linux/COPYING for more information. |
7 | * | 7 | * |
8 | * Packet writing layer for ATAPI and SCSI CD-R, CD-RW, DVD-R, and | 8 | * Packet writing layer for ATAPI and SCSI CD-RW, DVD+RW, DVD-RW and |
9 | * DVD-RW devices (aka an exercise in block layer masturbation) | 9 | * DVD-RAM devices. |
10 | * | 10 | * |
11 | * Theory of operation: | ||
11 | * | 12 | * |
12 | * TODO: (circa order of when I will fix it) | 13 | * At the lowest level, there is the standard driver for the CD/DVD device, |
13 | * - Only able to write on CD-RW media right now. | 14 | * typically ide-cd.c or sr.c. This driver can handle read and write requests, |
14 | * - check host application code on media and set it in write page | 15 | * but it doesn't know anything about the special restrictions that apply to |
15 | * - interface for UDF <-> packet to negotiate a new location when a write | 16 | * packet writing. One restriction is that write requests must be aligned to |
16 | * fails. | 17 | * packet boundaries on the physical media, and the size of a write request |
17 | * - handle OPC, especially for -RW media | 18 | * must be equal to the packet size. Another restriction is that a |
19 | * GPCMD_FLUSH_CACHE command has to be issued to the drive before a read | ||
20 | * command, if the previous command was a write. | ||
18 | * | 21 | * |
19 | * Theory of operation: | 22 | * The purpose of the packet writing driver is to hide these restrictions from |
23 | * higher layers, such as file systems, and present a block device that can be | ||
24 | * randomly read and written using 2kB-sized blocks. | ||
25 | * | ||
26 | * The lowest layer in the packet writing driver is the packet I/O scheduler. | ||
27 | * Its data is defined by the struct packet_iosched and includes two bio | ||
28 | * queues with pending read and write requests. These queues are processed | ||
29 | * by the pkt_iosched_process_queue() function. The write requests in this | ||
30 | * queue are already properly aligned and sized. This layer is responsible for | ||
31 | * issuing the flush cache commands and scheduling the I/O in a good order. | ||
20 | * | 32 | * |
21 | * We use a custom make_request_fn function that forwards reads directly to | 33 | * The next layer transforms unaligned write requests to aligned writes. This |
22 | * the underlying CD device. Write requests are either attached directly to | 34 | * transformation requires reading missing pieces of data from the underlying |
23 | * a live packet_data object, or simply stored sequentially in a list for | 35 | * block device, assembling the pieces to full packets and queuing them to the |
24 | * later processing by the kcdrwd kernel thread. This driver doesn't use | 36 | * packet I/O scheduler. |
25 | * any elevator functionally as defined by the elevator_s struct, but the | ||
26 | * underlying CD device uses a standard elevator. | ||
27 | * | 37 | * |
28 | * This strategy makes it possible to do very late merging of IO requests. | 38 | * At the top layer there is a custom make_request_fn function that forwards |
29 | * A new bio sent to pkt_make_request can be merged with a live packet_data | 39 | * read requests directly to the iosched queue and puts write requests in the |
30 | * object even if the object is in the data gathering state. | 40 | * unaligned write queue. A kernel thread performs the necessary read |
41 | * gathering to convert the unaligned writes to aligned writes and then feeds | ||
42 | * them to the packet I/O scheduler. | ||
31 | * | 43 | * |
32 | *************************************************************************/ | 44 | *************************************************************************/ |
33 | 45 | ||
@@ -100,10 +112,9 @@ static struct bio *pkt_bio_alloc(int nr_iovecs) | |||
100 | goto no_bio; | 112 | goto no_bio; |
101 | bio_init(bio); | 113 | bio_init(bio); |
102 | 114 | ||
103 | bvl = kmalloc(nr_iovecs * sizeof(struct bio_vec), GFP_KERNEL); | 115 | bvl = kcalloc(nr_iovecs, sizeof(struct bio_vec), GFP_KERNEL); |
104 | if (!bvl) | 116 | if (!bvl) |
105 | goto no_bvl; | 117 | goto no_bvl; |
106 | memset(bvl, 0, nr_iovecs * sizeof(struct bio_vec)); | ||
107 | 118 | ||
108 | bio->bi_max_vecs = nr_iovecs; | 119 | bio->bi_max_vecs = nr_iovecs; |
109 | bio->bi_io_vec = bvl; | 120 | bio->bi_io_vec = bvl; |
@@ -125,10 +136,9 @@ static struct packet_data *pkt_alloc_packet_data(void) | |||
125 | int i; | 136 | int i; |
126 | struct packet_data *pkt; | 137 | struct packet_data *pkt; |
127 | 138 | ||
128 | pkt = kmalloc(sizeof(struct packet_data), GFP_KERNEL); | 139 | pkt = kzalloc(sizeof(struct packet_data), GFP_KERNEL); |
129 | if (!pkt) | 140 | if (!pkt) |
130 | goto no_pkt; | 141 | goto no_pkt; |
131 | memset(pkt, 0, sizeof(struct packet_data)); | ||
132 | 142 | ||
133 | pkt->w_bio = pkt_bio_alloc(PACKET_MAX_SIZE); | 143 | pkt->w_bio = pkt_bio_alloc(PACKET_MAX_SIZE); |
134 | if (!pkt->w_bio) | 144 | if (!pkt->w_bio) |
@@ -659,7 +669,6 @@ static void pkt_make_local_copy(struct packet_data *pkt, struct page **pages, in | |||
659 | } | 669 | } |
660 | offs += CD_FRAMESIZE; | 670 | offs += CD_FRAMESIZE; |
661 | if (offs >= PAGE_SIZE) { | 671 | if (offs >= PAGE_SIZE) { |
662 | BUG_ON(offs > PAGE_SIZE); | ||
663 | offs = 0; | 672 | offs = 0; |
664 | p++; | 673 | p++; |
665 | } | 674 | } |
@@ -724,12 +733,6 @@ static void pkt_gather_data(struct pktcdvd_device *pd, struct packet_data *pkt) | |||
724 | atomic_set(&pkt->io_wait, 0); | 733 | atomic_set(&pkt->io_wait, 0); |
725 | atomic_set(&pkt->io_errors, 0); | 734 | atomic_set(&pkt->io_errors, 0); |
726 | 735 | ||
727 | if (pkt->cache_valid) { | ||
728 | VPRINTK("pkt_gather_data: zone %llx cached\n", | ||
729 | (unsigned long long)pkt->sector); | ||
730 | goto out_account; | ||
731 | } | ||
732 | |||
733 | /* | 736 | /* |
734 | * Figure out which frames we need to read before we can write. | 737 | * Figure out which frames we need to read before we can write. |
735 | */ | 738 | */ |
@@ -738,6 +741,7 @@ static void pkt_gather_data(struct pktcdvd_device *pd, struct packet_data *pkt) | |||
738 | for (bio = pkt->orig_bios; bio; bio = bio->bi_next) { | 741 | for (bio = pkt->orig_bios; bio; bio = bio->bi_next) { |
739 | int first_frame = (bio->bi_sector - pkt->sector) / (CD_FRAMESIZE >> 9); | 742 | int first_frame = (bio->bi_sector - pkt->sector) / (CD_FRAMESIZE >> 9); |
740 | int num_frames = bio->bi_size / CD_FRAMESIZE; | 743 | int num_frames = bio->bi_size / CD_FRAMESIZE; |
744 | pd->stats.secs_w += num_frames * (CD_FRAMESIZE >> 9); | ||
741 | BUG_ON(first_frame < 0); | 745 | BUG_ON(first_frame < 0); |
742 | BUG_ON(first_frame + num_frames > pkt->frames); | 746 | BUG_ON(first_frame + num_frames > pkt->frames); |
743 | for (f = first_frame; f < first_frame + num_frames; f++) | 747 | for (f = first_frame; f < first_frame + num_frames; f++) |
@@ -745,6 +749,12 @@ static void pkt_gather_data(struct pktcdvd_device *pd, struct packet_data *pkt) | |||
745 | } | 749 | } |
746 | spin_unlock(&pkt->lock); | 750 | spin_unlock(&pkt->lock); |
747 | 751 | ||
752 | if (pkt->cache_valid) { | ||
753 | VPRINTK("pkt_gather_data: zone %llx cached\n", | ||
754 | (unsigned long long)pkt->sector); | ||
755 | goto out_account; | ||
756 | } | ||
757 | |||
748 | /* | 758 | /* |
749 | * Schedule reads for missing parts of the packet. | 759 | * Schedule reads for missing parts of the packet. |
750 | */ | 760 | */ |
@@ -778,7 +788,6 @@ out_account: | |||
778 | frames_read, (unsigned long long)pkt->sector); | 788 | frames_read, (unsigned long long)pkt->sector); |
779 | pd->stats.pkt_started++; | 789 | pd->stats.pkt_started++; |
780 | pd->stats.secs_rg += frames_read * (CD_FRAMESIZE >> 9); | 790 | pd->stats.secs_rg += frames_read * (CD_FRAMESIZE >> 9); |
781 | pd->stats.secs_w += pd->settings.size; | ||
782 | } | 791 | } |
783 | 792 | ||
784 | /* | 793 | /* |
@@ -794,10 +803,11 @@ static struct packet_data *pkt_get_packet_data(struct pktcdvd_device *pd, int zo | |||
794 | list_del_init(&pkt->list); | 803 | list_del_init(&pkt->list); |
795 | if (pkt->sector != zone) | 804 | if (pkt->sector != zone) |
796 | pkt->cache_valid = 0; | 805 | pkt->cache_valid = 0; |
797 | break; | 806 | return pkt; |
798 | } | 807 | } |
799 | } | 808 | } |
800 | return pkt; | 809 | BUG(); |
810 | return NULL; | ||
801 | } | 811 | } |
802 | 812 | ||
803 | static void pkt_put_packet_data(struct pktcdvd_device *pd, struct packet_data *pkt) | 813 | static void pkt_put_packet_data(struct pktcdvd_device *pd, struct packet_data *pkt) |
@@ -941,12 +951,10 @@ try_next_bio: | |||
941 | } | 951 | } |
942 | 952 | ||
943 | pkt = pkt_get_packet_data(pd, zone); | 953 | pkt = pkt_get_packet_data(pd, zone); |
944 | BUG_ON(!pkt); | ||
945 | 954 | ||
946 | pd->current_sector = zone + pd->settings.size; | 955 | pd->current_sector = zone + pd->settings.size; |
947 | pkt->sector = zone; | 956 | pkt->sector = zone; |
948 | pkt->frames = pd->settings.size >> 2; | 957 | pkt->frames = pd->settings.size >> 2; |
949 | BUG_ON(pkt->frames > PACKET_MAX_SIZE); | ||
950 | pkt->write_size = 0; | 958 | pkt->write_size = 0; |
951 | 959 | ||
952 | /* | 960 | /* |
@@ -1636,6 +1644,10 @@ static int pkt_probe_settings(struct pktcdvd_device *pd) | |||
1636 | printk("pktcdvd: detected zero packet size!\n"); | 1644 | printk("pktcdvd: detected zero packet size!\n"); |
1637 | pd->settings.size = 128; | 1645 | pd->settings.size = 128; |
1638 | } | 1646 | } |
1647 | if (pd->settings.size > PACKET_MAX_SECTORS) { | ||
1648 | printk("pktcdvd: packet size is too big\n"); | ||
1649 | return -ENXIO; | ||
1650 | } | ||
1639 | pd->settings.fp = ti.fp; | 1651 | pd->settings.fp = ti.fp; |
1640 | pd->offset = (be32_to_cpu(ti.track_start) << 2) & (pd->settings.size - 1); | 1652 | pd->offset = (be32_to_cpu(ti.track_start) << 2) & (pd->settings.size - 1); |
1641 | 1653 | ||
@@ -2198,7 +2210,6 @@ static int pkt_make_request(request_queue_t *q, struct bio *bio) | |||
2198 | * No matching packet found. Store the bio in the work queue. | 2210 | * No matching packet found. Store the bio in the work queue. |
2199 | */ | 2211 | */ |
2200 | node = mempool_alloc(pd->rb_pool, GFP_NOIO); | 2212 | node = mempool_alloc(pd->rb_pool, GFP_NOIO); |
2201 | BUG_ON(!node); | ||
2202 | node->bio = bio; | 2213 | node->bio = bio; |
2203 | spin_lock(&pd->lock); | 2214 | spin_lock(&pd->lock); |
2204 | BUG_ON(pd->bio_queue_size < 0); | 2215 | BUG_ON(pd->bio_queue_size < 0); |
@@ -2406,7 +2417,6 @@ static int pkt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, u | |||
2406 | struct pktcdvd_device *pd = inode->i_bdev->bd_disk->private_data; | 2417 | struct pktcdvd_device *pd = inode->i_bdev->bd_disk->private_data; |
2407 | 2418 | ||
2408 | VPRINTK("pkt_ioctl: cmd %x, dev %d:%d\n", cmd, imajor(inode), iminor(inode)); | 2419 | VPRINTK("pkt_ioctl: cmd %x, dev %d:%d\n", cmd, imajor(inode), iminor(inode)); |
2409 | BUG_ON(!pd); | ||
2410 | 2420 | ||
2411 | switch (cmd) { | 2421 | switch (cmd) { |
2412 | /* | 2422 | /* |
@@ -2477,10 +2487,9 @@ static int pkt_setup_dev(struct pkt_ctrl_command *ctrl_cmd) | |||
2477 | return -EBUSY; | 2487 | return -EBUSY; |
2478 | } | 2488 | } |
2479 | 2489 | ||
2480 | pd = kmalloc(sizeof(struct pktcdvd_device), GFP_KERNEL); | 2490 | pd = kzalloc(sizeof(struct pktcdvd_device), GFP_KERNEL); |
2481 | if (!pd) | 2491 | if (!pd) |
2482 | return ret; | 2492 | return ret; |
2483 | memset(pd, 0, sizeof(struct pktcdvd_device)); | ||
2484 | 2493 | ||
2485 | pd->rb_pool = mempool_create(PKT_RB_POOL_SIZE, pkt_rb_alloc, pkt_rb_free, NULL); | 2494 | pd->rb_pool = mempool_create(PKT_RB_POOL_SIZE, pkt_rb_alloc, pkt_rb_free, NULL); |
2486 | if (!pd->rb_pool) | 2495 | if (!pd->rb_pool) |
diff --git a/drivers/block/scsi_ioctl.c b/drivers/block/scsi_ioctl.c index 856c2278e9d0..079ec344eb47 100644 --- a/drivers/block/scsi_ioctl.c +++ b/drivers/block/scsi_ioctl.c | |||
@@ -168,6 +168,7 @@ static int verify_command(struct file *file, unsigned char *cmd) | |||
168 | safe_for_write(WRITE_VERIFY_12), | 168 | safe_for_write(WRITE_VERIFY_12), |
169 | safe_for_write(WRITE_16), | 169 | safe_for_write(WRITE_16), |
170 | safe_for_write(WRITE_LONG), | 170 | safe_for_write(WRITE_LONG), |
171 | safe_for_write(WRITE_LONG_2), | ||
171 | safe_for_write(ERASE), | 172 | safe_for_write(ERASE), |
172 | safe_for_write(GPCMD_MODE_SELECT_10), | 173 | safe_for_write(GPCMD_MODE_SELECT_10), |
173 | safe_for_write(MODE_SELECT), | 174 | safe_for_write(MODE_SELECT), |
diff --git a/drivers/block/ub.c b/drivers/block/ub.c index aa0bf7ee008d..ed4d5006fe62 100644 --- a/drivers/block/ub.c +++ b/drivers/block/ub.c | |||
@@ -172,7 +172,7 @@ struct bulk_cs_wrap { | |||
172 | */ | 172 | */ |
173 | struct ub_dev; | 173 | struct ub_dev; |
174 | 174 | ||
175 | #define UB_MAX_REQ_SG 4 | 175 | #define UB_MAX_REQ_SG 9 /* cdrecord requires 32KB and maybe a header */ |
176 | #define UB_MAX_SECTORS 64 | 176 | #define UB_MAX_SECTORS 64 |
177 | 177 | ||
178 | /* | 178 | /* |
@@ -387,7 +387,7 @@ struct ub_dev { | |||
387 | struct bulk_cs_wrap work_bcs; | 387 | struct bulk_cs_wrap work_bcs; |
388 | struct usb_ctrlrequest work_cr; | 388 | struct usb_ctrlrequest work_cr; |
389 | 389 | ||
390 | int sg_stat[UB_MAX_REQ_SG+1]; | 390 | int sg_stat[6]; |
391 | struct ub_scsi_trace tr; | 391 | struct ub_scsi_trace tr; |
392 | }; | 392 | }; |
393 | 393 | ||
@@ -525,12 +525,13 @@ static ssize_t ub_diag_show(struct device *dev, struct device_attribute *attr, | |||
525 | "qlen %d qmax %d\n", | 525 | "qlen %d qmax %d\n", |
526 | sc->cmd_queue.qlen, sc->cmd_queue.qmax); | 526 | sc->cmd_queue.qlen, sc->cmd_queue.qmax); |
527 | cnt += sprintf(page + cnt, | 527 | cnt += sprintf(page + cnt, |
528 | "sg %d %d %d %d %d\n", | 528 | "sg %d %d %d %d %d .. %d\n", |
529 | sc->sg_stat[0], | 529 | sc->sg_stat[0], |
530 | sc->sg_stat[1], | 530 | sc->sg_stat[1], |
531 | sc->sg_stat[2], | 531 | sc->sg_stat[2], |
532 | sc->sg_stat[3], | 532 | sc->sg_stat[3], |
533 | sc->sg_stat[4]); | 533 | sc->sg_stat[4], |
534 | sc->sg_stat[5]); | ||
534 | 535 | ||
535 | list_for_each (p, &sc->luns) { | 536 | list_for_each (p, &sc->luns) { |
536 | lun = list_entry(p, struct ub_lun, link); | 537 | lun = list_entry(p, struct ub_lun, link); |
@@ -835,7 +836,7 @@ static int ub_cmd_build_block(struct ub_dev *sc, struct ub_lun *lun, | |||
835 | return -1; | 836 | return -1; |
836 | } | 837 | } |
837 | cmd->nsg = n_elem; | 838 | cmd->nsg = n_elem; |
838 | sc->sg_stat[n_elem]++; | 839 | sc->sg_stat[n_elem < 5 ? n_elem : 5]++; |
839 | 840 | ||
840 | /* | 841 | /* |
841 | * build the command | 842 | * build the command |
@@ -891,7 +892,7 @@ static int ub_cmd_build_packet(struct ub_dev *sc, struct ub_lun *lun, | |||
891 | return -1; | 892 | return -1; |
892 | } | 893 | } |
893 | cmd->nsg = n_elem; | 894 | cmd->nsg = n_elem; |
894 | sc->sg_stat[n_elem]++; | 895 | sc->sg_stat[n_elem < 5 ? n_elem : 5]++; |
895 | 896 | ||
896 | memcpy(&cmd->cdb, rq->cmd, rq->cmd_len); | 897 | memcpy(&cmd->cdb, rq->cmd, rq->cmd_len); |
897 | cmd->cdb_len = rq->cmd_len; | 898 | cmd->cdb_len = rq->cmd_len; |
@@ -1010,7 +1011,6 @@ static int ub_scsi_cmd_start(struct ub_dev *sc, struct ub_scsi_cmd *cmd) | |||
1010 | sc->last_pipe = sc->send_bulk_pipe; | 1011 | sc->last_pipe = sc->send_bulk_pipe; |
1011 | usb_fill_bulk_urb(&sc->work_urb, sc->dev, sc->send_bulk_pipe, | 1012 | usb_fill_bulk_urb(&sc->work_urb, sc->dev, sc->send_bulk_pipe, |
1012 | bcb, US_BULK_CB_WRAP_LEN, ub_urb_complete, sc); | 1013 | bcb, US_BULK_CB_WRAP_LEN, ub_urb_complete, sc); |
1013 | sc->work_urb.transfer_flags = 0; | ||
1014 | 1014 | ||
1015 | /* Fill what we shouldn't be filling, because usb-storage did so. */ | 1015 | /* Fill what we shouldn't be filling, because usb-storage did so. */ |
1016 | sc->work_urb.actual_length = 0; | 1016 | sc->work_urb.actual_length = 0; |
@@ -1019,7 +1019,6 @@ static int ub_scsi_cmd_start(struct ub_dev *sc, struct ub_scsi_cmd *cmd) | |||
1019 | 1019 | ||
1020 | if ((rc = usb_submit_urb(&sc->work_urb, GFP_ATOMIC)) != 0) { | 1020 | if ((rc = usb_submit_urb(&sc->work_urb, GFP_ATOMIC)) != 0) { |
1021 | /* XXX Clear stalls */ | 1021 | /* XXX Clear stalls */ |
1022 | printk("ub: cmd #%d start failed (%d)\n", cmd->tag, rc); /* P3 */ | ||
1023 | ub_complete(&sc->work_done); | 1022 | ub_complete(&sc->work_done); |
1024 | return rc; | 1023 | return rc; |
1025 | } | 1024 | } |
@@ -1190,11 +1189,9 @@ static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd) | |||
1190 | return; | 1189 | return; |
1191 | } | 1190 | } |
1192 | if (urb->status != 0) { | 1191 | if (urb->status != 0) { |
1193 | printk("ub: cmd #%d cmd status (%d)\n", cmd->tag, urb->status); /* P3 */ | ||
1194 | goto Bad_End; | 1192 | goto Bad_End; |
1195 | } | 1193 | } |
1196 | if (urb->actual_length != US_BULK_CB_WRAP_LEN) { | 1194 | if (urb->actual_length != US_BULK_CB_WRAP_LEN) { |
1197 | printk("ub: cmd #%d xferred %d\n", cmd->tag, urb->actual_length); /* P3 */ | ||
1198 | /* XXX Must do reset here to unconfuse the device */ | 1195 | /* XXX Must do reset here to unconfuse the device */ |
1199 | goto Bad_End; | 1196 | goto Bad_End; |
1200 | } | 1197 | } |
@@ -1395,14 +1392,12 @@ static void ub_data_start(struct ub_dev *sc, struct ub_scsi_cmd *cmd) | |||
1395 | usb_fill_bulk_urb(&sc->work_urb, sc->dev, pipe, | 1392 | usb_fill_bulk_urb(&sc->work_urb, sc->dev, pipe, |
1396 | page_address(sg->page) + sg->offset, sg->length, | 1393 | page_address(sg->page) + sg->offset, sg->length, |
1397 | ub_urb_complete, sc); | 1394 | ub_urb_complete, sc); |
1398 | sc->work_urb.transfer_flags = 0; | ||
1399 | sc->work_urb.actual_length = 0; | 1395 | sc->work_urb.actual_length = 0; |
1400 | sc->work_urb.error_count = 0; | 1396 | sc->work_urb.error_count = 0; |
1401 | sc->work_urb.status = 0; | 1397 | sc->work_urb.status = 0; |
1402 | 1398 | ||
1403 | if ((rc = usb_submit_urb(&sc->work_urb, GFP_ATOMIC)) != 0) { | 1399 | if ((rc = usb_submit_urb(&sc->work_urb, GFP_ATOMIC)) != 0) { |
1404 | /* XXX Clear stalls */ | 1400 | /* XXX Clear stalls */ |
1405 | printk("ub: data #%d submit failed (%d)\n", cmd->tag, rc); /* P3 */ | ||
1406 | ub_complete(&sc->work_done); | 1401 | ub_complete(&sc->work_done); |
1407 | ub_state_done(sc, cmd, rc); | 1402 | ub_state_done(sc, cmd, rc); |
1408 | return; | 1403 | return; |
@@ -1442,7 +1437,6 @@ static int __ub_state_stat(struct ub_dev *sc, struct ub_scsi_cmd *cmd) | |||
1442 | sc->last_pipe = sc->recv_bulk_pipe; | 1437 | sc->last_pipe = sc->recv_bulk_pipe; |
1443 | usb_fill_bulk_urb(&sc->work_urb, sc->dev, sc->recv_bulk_pipe, | 1438 | usb_fill_bulk_urb(&sc->work_urb, sc->dev, sc->recv_bulk_pipe, |
1444 | &sc->work_bcs, US_BULK_CS_WRAP_LEN, ub_urb_complete, sc); | 1439 | &sc->work_bcs, US_BULK_CS_WRAP_LEN, ub_urb_complete, sc); |
1445 | sc->work_urb.transfer_flags = 0; | ||
1446 | sc->work_urb.actual_length = 0; | 1440 | sc->work_urb.actual_length = 0; |
1447 | sc->work_urb.error_count = 0; | 1441 | sc->work_urb.error_count = 0; |
1448 | sc->work_urb.status = 0; | 1442 | sc->work_urb.status = 0; |
@@ -1563,7 +1557,6 @@ static int ub_submit_clear_stall(struct ub_dev *sc, struct ub_scsi_cmd *cmd, | |||
1563 | 1557 | ||
1564 | usb_fill_control_urb(&sc->work_urb, sc->dev, sc->send_ctrl_pipe, | 1558 | usb_fill_control_urb(&sc->work_urb, sc->dev, sc->send_ctrl_pipe, |
1565 | (unsigned char*) cr, NULL, 0, ub_urb_complete, sc); | 1559 | (unsigned char*) cr, NULL, 0, ub_urb_complete, sc); |
1566 | sc->work_urb.transfer_flags = 0; | ||
1567 | sc->work_urb.actual_length = 0; | 1560 | sc->work_urb.actual_length = 0; |
1568 | sc->work_urb.error_count = 0; | 1561 | sc->work_urb.error_count = 0; |
1569 | sc->work_urb.status = 0; | 1562 | sc->work_urb.status = 0; |
@@ -2000,17 +1993,16 @@ static int ub_sync_getmaxlun(struct ub_dev *sc) | |||
2000 | 1993 | ||
2001 | usb_fill_control_urb(&sc->work_urb, sc->dev, sc->recv_ctrl_pipe, | 1994 | usb_fill_control_urb(&sc->work_urb, sc->dev, sc->recv_ctrl_pipe, |
2002 | (unsigned char*) cr, p, 1, ub_probe_urb_complete, &compl); | 1995 | (unsigned char*) cr, p, 1, ub_probe_urb_complete, &compl); |
2003 | sc->work_urb.transfer_flags = 0; | ||
2004 | sc->work_urb.actual_length = 0; | 1996 | sc->work_urb.actual_length = 0; |
2005 | sc->work_urb.error_count = 0; | 1997 | sc->work_urb.error_count = 0; |
2006 | sc->work_urb.status = 0; | 1998 | sc->work_urb.status = 0; |
2007 | 1999 | ||
2008 | if ((rc = usb_submit_urb(&sc->work_urb, GFP_KERNEL)) != 0) { | 2000 | if ((rc = usb_submit_urb(&sc->work_urb, GFP_KERNEL)) != 0) { |
2009 | if (rc == -EPIPE) { | 2001 | if (rc == -EPIPE) { |
2010 | printk("%s: Stall at GetMaxLUN, using 1 LUN\n", | 2002 | printk("%s: Stall submitting GetMaxLUN, using 1 LUN\n", |
2011 | sc->name); /* P3 */ | 2003 | sc->name); /* P3 */ |
2012 | } else { | 2004 | } else { |
2013 | printk(KERN_WARNING | 2005 | printk(KERN_NOTICE |
2014 | "%s: Unable to submit GetMaxLUN (%d)\n", | 2006 | "%s: Unable to submit GetMaxLUN (%d)\n", |
2015 | sc->name, rc); | 2007 | sc->name, rc); |
2016 | } | 2008 | } |
@@ -2028,6 +2020,18 @@ static int ub_sync_getmaxlun(struct ub_dev *sc) | |||
2028 | del_timer_sync(&timer); | 2020 | del_timer_sync(&timer); |
2029 | usb_kill_urb(&sc->work_urb); | 2021 | usb_kill_urb(&sc->work_urb); |
2030 | 2022 | ||
2023 | if ((rc = sc->work_urb.status) < 0) { | ||
2024 | if (rc == -EPIPE) { | ||
2025 | printk("%s: Stall at GetMaxLUN, using 1 LUN\n", | ||
2026 | sc->name); /* P3 */ | ||
2027 | } else { | ||
2028 | printk(KERN_NOTICE | ||
2029 | "%s: Error at GetMaxLUN (%d)\n", | ||
2030 | sc->name, rc); | ||
2031 | } | ||
2032 | goto err_io; | ||
2033 | } | ||
2034 | |||
2031 | if (sc->work_urb.actual_length != 1) { | 2035 | if (sc->work_urb.actual_length != 1) { |
2032 | printk("%s: GetMaxLUN returned %d bytes\n", sc->name, | 2036 | printk("%s: GetMaxLUN returned %d bytes\n", sc->name, |
2033 | sc->work_urb.actual_length); /* P3 */ | 2037 | sc->work_urb.actual_length); /* P3 */ |
@@ -2048,6 +2052,7 @@ static int ub_sync_getmaxlun(struct ub_dev *sc) | |||
2048 | kfree(p); | 2052 | kfree(p); |
2049 | return nluns; | 2053 | return nluns; |
2050 | 2054 | ||
2055 | err_io: | ||
2051 | err_submit: | 2056 | err_submit: |
2052 | kfree(p); | 2057 | kfree(p); |
2053 | err_alloc: | 2058 | err_alloc: |
@@ -2080,7 +2085,6 @@ static int ub_probe_clear_stall(struct ub_dev *sc, int stalled_pipe) | |||
2080 | 2085 | ||
2081 | usb_fill_control_urb(&sc->work_urb, sc->dev, sc->send_ctrl_pipe, | 2086 | usb_fill_control_urb(&sc->work_urb, sc->dev, sc->send_ctrl_pipe, |
2082 | (unsigned char*) cr, NULL, 0, ub_probe_urb_complete, &compl); | 2087 | (unsigned char*) cr, NULL, 0, ub_probe_urb_complete, &compl); |
2083 | sc->work_urb.transfer_flags = 0; | ||
2084 | sc->work_urb.actual_length = 0; | 2088 | sc->work_urb.actual_length = 0; |
2085 | sc->work_urb.error_count = 0; | 2089 | sc->work_urb.error_count = 0; |
2086 | sc->work_urb.status = 0; | 2090 | sc->work_urb.status = 0; |
@@ -2213,8 +2217,10 @@ static int ub_probe(struct usb_interface *intf, | |||
2213 | * This is needed to clear toggles. It is a problem only if we do | 2217 | * This is needed to clear toggles. It is a problem only if we do |
2214 | * `rmmod ub && modprobe ub` without disconnects, but we like that. | 2218 | * `rmmod ub && modprobe ub` without disconnects, but we like that. |
2215 | */ | 2219 | */ |
2220 | #if 0 /* iPod Mini fails if we do this (big white iPod works) */ | ||
2216 | ub_probe_clear_stall(sc, sc->recv_bulk_pipe); | 2221 | ub_probe_clear_stall(sc, sc->recv_bulk_pipe); |
2217 | ub_probe_clear_stall(sc, sc->send_bulk_pipe); | 2222 | ub_probe_clear_stall(sc, sc->send_bulk_pipe); |
2223 | #endif | ||
2218 | 2224 | ||
2219 | /* | 2225 | /* |
2220 | * The way this is used by the startup code is a little specific. | 2226 | * The way this is used by the startup code is a little specific. |
@@ -2241,10 +2247,10 @@ static int ub_probe(struct usb_interface *intf, | |||
2241 | for (i = 0; i < 3; i++) { | 2247 | for (i = 0; i < 3; i++) { |
2242 | if ((rc = ub_sync_getmaxlun(sc)) < 0) { | 2248 | if ((rc = ub_sync_getmaxlun(sc)) < 0) { |
2243 | /* | 2249 | /* |
2244 | * Some devices (i.e. Iomega Zip100) need this -- | 2250 | * This segment is taken from usb-storage. They say |
2245 | * apparently the bulk pipes get STALLed when the | 2251 | * that ZIP-100 needs this, but my own ZIP-100 works |
2246 | * GetMaxLUN request is processed. | 2252 | * fine without this. |
2247 | * XXX I have a ZIP-100, verify it does this. | 2253 | * Still, it does not seem to hurt anything. |
2248 | */ | 2254 | */ |
2249 | if (rc == -EPIPE) { | 2255 | if (rc == -EPIPE) { |
2250 | ub_probe_clear_stall(sc, sc->recv_bulk_pipe); | 2256 | ub_probe_clear_stall(sc, sc->recv_bulk_pipe); |
@@ -2313,7 +2319,7 @@ static int ub_probe_lun(struct ub_dev *sc, int lnum) | |||
2313 | disk->first_minor = lun->id * UB_MINORS_PER_MAJOR; | 2319 | disk->first_minor = lun->id * UB_MINORS_PER_MAJOR; |
2314 | disk->fops = &ub_bd_fops; | 2320 | disk->fops = &ub_bd_fops; |
2315 | disk->private_data = lun; | 2321 | disk->private_data = lun; |
2316 | disk->driverfs_dev = &sc->intf->dev; /* XXX Many to one ok? */ | 2322 | disk->driverfs_dev = &sc->intf->dev; |
2317 | 2323 | ||
2318 | rc = -ENOMEM; | 2324 | rc = -ENOMEM; |
2319 | if ((q = blk_init_queue(ub_request_fn, &sc->lock)) == NULL) | 2325 | if ((q = blk_init_queue(ub_request_fn, &sc->lock)) == NULL) |
@@ -2466,9 +2472,6 @@ static int __init ub_init(void) | |||
2466 | { | 2472 | { |
2467 | int rc; | 2473 | int rc; |
2468 | 2474 | ||
2469 | /* P3 */ printk("ub: sizeof ub_scsi_cmd %zu ub_dev %zu ub_lun %zu\n", | ||
2470 | sizeof(struct ub_scsi_cmd), sizeof(struct ub_dev), sizeof(struct ub_lun)); | ||
2471 | |||
2472 | if ((rc = register_blkdev(UB_MAJOR, DRV_NAME)) != 0) | 2475 | if ((rc = register_blkdev(UB_MAJOR, DRV_NAME)) != 0) |
2473 | goto err_regblkdev; | 2476 | goto err_regblkdev; |
2474 | devfs_mk_dir(DEVFS_NAME); | 2477 | devfs_mk_dir(DEVFS_NAME); |