diff options
Diffstat (limited to 'drivers/scsi/pmcraid.c')
-rw-r--r-- | drivers/scsi/pmcraid.c | 57 |
1 files changed, 39 insertions, 18 deletions
diff --git a/drivers/scsi/pmcraid.c b/drivers/scsi/pmcraid.c index f7c70e2a8224..e7d2688fbeba 100644 --- a/drivers/scsi/pmcraid.c +++ b/drivers/scsi/pmcraid.c | |||
@@ -1,7 +1,8 @@ | |||
1 | /* | 1 | /* |
2 | * pmcraid.c -- driver for PMC Sierra MaxRAID controller adapters | 2 | * pmcraid.c -- driver for PMC Sierra MaxRAID controller adapters |
3 | * | 3 | * |
4 | * Written By: PMC Sierra Corporation | 4 | * Written By: Anil Ravindranath<anil_ravindranath@pmc-sierra.com> |
5 | * PMC-Sierra Inc | ||
5 | * | 6 | * |
6 | * Copyright (C) 2008, 2009 PMC Sierra Inc | 7 | * Copyright (C) 2008, 2009 PMC Sierra Inc |
7 | * | 8 | * |
@@ -79,7 +80,7 @@ DECLARE_BITMAP(pmcraid_minor, PMCRAID_MAX_ADAPTERS); | |||
79 | /* | 80 | /* |
80 | * Module parameters | 81 | * Module parameters |
81 | */ | 82 | */ |
82 | MODULE_AUTHOR("PMC Sierra Corporation, anil_ravindranath@pmc-sierra.com"); | 83 | MODULE_AUTHOR("Anil Ravindranath<anil_ravindranath@pmc-sierra.com>"); |
83 | MODULE_DESCRIPTION("PMC Sierra MaxRAID Controller Driver"); | 84 | MODULE_DESCRIPTION("PMC Sierra MaxRAID Controller Driver"); |
84 | MODULE_LICENSE("GPL"); | 85 | MODULE_LICENSE("GPL"); |
85 | MODULE_VERSION(PMCRAID_DRIVER_VERSION); | 86 | MODULE_VERSION(PMCRAID_DRIVER_VERSION); |
@@ -162,10 +163,10 @@ static int pmcraid_slave_alloc(struct scsi_device *scsi_dev) | |||
162 | spin_lock_irqsave(&pinstance->resource_lock, lock_flags); | 163 | spin_lock_irqsave(&pinstance->resource_lock, lock_flags); |
163 | list_for_each_entry(temp, &pinstance->used_res_q, queue) { | 164 | list_for_each_entry(temp, &pinstance->used_res_q, queue) { |
164 | 165 | ||
165 | /* do not expose VSETs with order-ids >= 240 */ | 166 | /* do not expose VSETs with order-ids > MAX_VSET_TARGETS */ |
166 | if (RES_IS_VSET(temp->cfg_entry)) { | 167 | if (RES_IS_VSET(temp->cfg_entry)) { |
167 | target = temp->cfg_entry.unique_flags1; | 168 | target = temp->cfg_entry.unique_flags1; |
168 | if (target >= PMCRAID_MAX_VSET_TARGETS) | 169 | if (target > PMCRAID_MAX_VSET_TARGETS) |
169 | continue; | 170 | continue; |
170 | bus = PMCRAID_VSET_BUS_ID; | 171 | bus = PMCRAID_VSET_BUS_ID; |
171 | lun = 0; | 172 | lun = 0; |
@@ -278,12 +279,17 @@ static void pmcraid_slave_destroy(struct scsi_device *scsi_dev) | |||
278 | * pmcraid_change_queue_depth - Change the device's queue depth | 279 | * pmcraid_change_queue_depth - Change the device's queue depth |
279 | * @scsi_dev: scsi device struct | 280 | * @scsi_dev: scsi device struct |
280 | * @depth: depth to set | 281 | * @depth: depth to set |
282 | * @reason: calling context | ||
281 | * | 283 | * |
282 | * Return value | 284 | * Return value |
283 | * actual depth set | 285 | * actual depth set |
284 | */ | 286 | */ |
285 | static int pmcraid_change_queue_depth(struct scsi_device *scsi_dev, int depth) | 287 | static int pmcraid_change_queue_depth(struct scsi_device *scsi_dev, int depth, |
288 | int reason) | ||
286 | { | 289 | { |
290 | if (reason != SCSI_QDEPTH_DEFAULT) | ||
291 | return -EOPNOTSUPP; | ||
292 | |||
287 | if (depth > PMCRAID_MAX_CMD_PER_LUN) | 293 | if (depth > PMCRAID_MAX_CMD_PER_LUN) |
288 | depth = PMCRAID_MAX_CMD_PER_LUN; | 294 | depth = PMCRAID_MAX_CMD_PER_LUN; |
289 | 295 | ||
@@ -1071,7 +1077,7 @@ static struct pmcraid_cmd *pmcraid_init_hcam | |||
1071 | 1077 | ||
1072 | ioarcb->data_transfer_length = cpu_to_le32(rcb_size); | 1078 | ioarcb->data_transfer_length = cpu_to_le32(rcb_size); |
1073 | 1079 | ||
1074 | ioadl[0].flags |= cpu_to_le32(IOADL_FLAGS_READ_LAST); | 1080 | ioadl[0].flags |= IOADL_FLAGS_READ_LAST; |
1075 | ioadl[0].data_len = cpu_to_le32(rcb_size); | 1081 | ioadl[0].data_len = cpu_to_le32(rcb_size); |
1076 | ioadl[0].address = cpu_to_le32(dma); | 1082 | ioadl[0].address = cpu_to_le32(dma); |
1077 | 1083 | ||
@@ -1205,7 +1211,7 @@ static int pmcraid_expose_resource(struct pmcraid_config_table_entry *cfgte) | |||
1205 | int retval = 0; | 1211 | int retval = 0; |
1206 | 1212 | ||
1207 | if (cfgte->resource_type == RES_TYPE_VSET) | 1213 | if (cfgte->resource_type == RES_TYPE_VSET) |
1208 | retval = ((cfgte->unique_flags1 & 0xFF) < 0xFE); | 1214 | retval = ((cfgte->unique_flags1 & 0x80) == 0); |
1209 | else if (cfgte->resource_type == RES_TYPE_GSCSI) | 1215 | else if (cfgte->resource_type == RES_TYPE_GSCSI) |
1210 | retval = (RES_BUS(cfgte->resource_address) != | 1216 | retval = (RES_BUS(cfgte->resource_address) != |
1211 | PMCRAID_VIRTUAL_ENCL_BUS_ID); | 1217 | PMCRAID_VIRTUAL_ENCL_BUS_ID); |
@@ -1356,6 +1362,7 @@ static int pmcraid_notify_aen(struct pmcraid_instance *pinstance, u8 type) | |||
1356 | * Return value: | 1362 | * Return value: |
1357 | * none | 1363 | * none |
1358 | */ | 1364 | */ |
1365 | |||
1359 | static void pmcraid_handle_config_change(struct pmcraid_instance *pinstance) | 1366 | static void pmcraid_handle_config_change(struct pmcraid_instance *pinstance) |
1360 | { | 1367 | { |
1361 | struct pmcraid_config_table_entry *cfg_entry; | 1368 | struct pmcraid_config_table_entry *cfg_entry; |
@@ -1363,9 +1370,10 @@ static void pmcraid_handle_config_change(struct pmcraid_instance *pinstance) | |||
1363 | struct pmcraid_cmd *cmd; | 1370 | struct pmcraid_cmd *cmd; |
1364 | struct pmcraid_cmd *cfgcmd; | 1371 | struct pmcraid_cmd *cfgcmd; |
1365 | struct pmcraid_resource_entry *res = NULL; | 1372 | struct pmcraid_resource_entry *res = NULL; |
1366 | u32 new_entry = 1; | ||
1367 | unsigned long lock_flags; | 1373 | unsigned long lock_flags; |
1368 | unsigned long host_lock_flags; | 1374 | unsigned long host_lock_flags; |
1375 | u32 new_entry = 1; | ||
1376 | u32 hidden_entry = 0; | ||
1369 | int rc; | 1377 | int rc; |
1370 | 1378 | ||
1371 | ccn_hcam = (struct pmcraid_hcam_ccn *)pinstance->ccn.hcam; | 1379 | ccn_hcam = (struct pmcraid_hcam_ccn *)pinstance->ccn.hcam; |
@@ -1401,9 +1409,15 @@ static void pmcraid_handle_config_change(struct pmcraid_instance *pinstance) | |||
1401 | } | 1409 | } |
1402 | 1410 | ||
1403 | /* If this resource is not going to be added to mid-layer, just notify | 1411 | /* If this resource is not going to be added to mid-layer, just notify |
1404 | * applications and return | 1412 | * applications and return. If this notification is about hiding a VSET |
1413 | * resource, check if it was exposed already. | ||
1405 | */ | 1414 | */ |
1406 | if (!pmcraid_expose_resource(cfg_entry)) | 1415 | if (pinstance->ccn.hcam->notification_type == |
1416 | NOTIFICATION_TYPE_ENTRY_CHANGED && | ||
1417 | cfg_entry->resource_type == RES_TYPE_VSET && | ||
1418 | cfg_entry->unique_flags1 & 0x80) { | ||
1419 | hidden_entry = 1; | ||
1420 | } else if (!pmcraid_expose_resource(cfg_entry)) | ||
1407 | goto out_notify_apps; | 1421 | goto out_notify_apps; |
1408 | 1422 | ||
1409 | spin_lock_irqsave(&pinstance->resource_lock, lock_flags); | 1423 | spin_lock_irqsave(&pinstance->resource_lock, lock_flags); |
@@ -1419,6 +1433,12 @@ static void pmcraid_handle_config_change(struct pmcraid_instance *pinstance) | |||
1419 | 1433 | ||
1420 | if (new_entry) { | 1434 | if (new_entry) { |
1421 | 1435 | ||
1436 | if (hidden_entry) { | ||
1437 | spin_unlock_irqrestore(&pinstance->resource_lock, | ||
1438 | lock_flags); | ||
1439 | goto out_notify_apps; | ||
1440 | } | ||
1441 | |||
1422 | /* If there are more number of resources than what driver can | 1442 | /* If there are more number of resources than what driver can |
1423 | * manage, do not notify the applications about the CCN. Just | 1443 | * manage, do not notify the applications about the CCN. Just |
1424 | * ignore this notifications and re-register the same HCAM | 1444 | * ignore this notifications and re-register the same HCAM |
@@ -1449,8 +1469,9 @@ static void pmcraid_handle_config_change(struct pmcraid_instance *pinstance) | |||
1449 | sizeof(struct pmcraid_config_table_entry)); | 1469 | sizeof(struct pmcraid_config_table_entry)); |
1450 | 1470 | ||
1451 | if (pinstance->ccn.hcam->notification_type == | 1471 | if (pinstance->ccn.hcam->notification_type == |
1452 | NOTIFICATION_TYPE_ENTRY_DELETED) { | 1472 | NOTIFICATION_TYPE_ENTRY_DELETED || hidden_entry) { |
1453 | if (res->scsi_dev) { | 1473 | if (res->scsi_dev) { |
1474 | res->cfg_entry.unique_flags1 &= 0x7F; | ||
1454 | res->change_detected = RES_CHANGE_DEL; | 1475 | res->change_detected = RES_CHANGE_DEL; |
1455 | res->cfg_entry.resource_handle = | 1476 | res->cfg_entry.resource_handle = |
1456 | PMCRAID_INVALID_RES_HANDLE; | 1477 | PMCRAID_INVALID_RES_HANDLE; |
@@ -2251,7 +2272,7 @@ static void pmcraid_request_sense(struct pmcraid_cmd *cmd) | |||
2251 | 2272 | ||
2252 | ioadl->address = cpu_to_le64(cmd->sense_buffer_dma); | 2273 | ioadl->address = cpu_to_le64(cmd->sense_buffer_dma); |
2253 | ioadl->data_len = cpu_to_le32(SCSI_SENSE_BUFFERSIZE); | 2274 | ioadl->data_len = cpu_to_le32(SCSI_SENSE_BUFFERSIZE); |
2254 | ioadl->flags = cpu_to_le32(IOADL_FLAGS_LAST_DESC); | 2275 | ioadl->flags = IOADL_FLAGS_LAST_DESC; |
2255 | 2276 | ||
2256 | /* request sense might be called as part of error response processing | 2277 | /* request sense might be called as part of error response processing |
2257 | * which runs in tasklets context. It is possible that mid-layer might | 2278 | * which runs in tasklets context. It is possible that mid-layer might |
@@ -3017,7 +3038,7 @@ static int pmcraid_build_ioadl( | |||
3017 | ioadl[i].flags = 0; | 3038 | ioadl[i].flags = 0; |
3018 | } | 3039 | } |
3019 | /* setup last descriptor */ | 3040 | /* setup last descriptor */ |
3020 | ioadl[i - 1].flags = cpu_to_le32(IOADL_FLAGS_LAST_DESC); | 3041 | ioadl[i - 1].flags = IOADL_FLAGS_LAST_DESC; |
3021 | 3042 | ||
3022 | return 0; | 3043 | return 0; |
3023 | } | 3044 | } |
@@ -3342,7 +3363,7 @@ static int pmcraid_chr_fasync(int fd, struct file *filep, int mode) | |||
3342 | * @direction : data transfer direction | 3363 | * @direction : data transfer direction |
3343 | * | 3364 | * |
3344 | * Return value | 3365 | * Return value |
3345 | * 0 on sucess, non-zero error code on failure | 3366 | * 0 on success, non-zero error code on failure |
3346 | */ | 3367 | */ |
3347 | static int pmcraid_build_passthrough_ioadls( | 3368 | static int pmcraid_build_passthrough_ioadls( |
3348 | struct pmcraid_cmd *cmd, | 3369 | struct pmcraid_cmd *cmd, |
@@ -3387,7 +3408,7 @@ static int pmcraid_build_passthrough_ioadls( | |||
3387 | } | 3408 | } |
3388 | 3409 | ||
3389 | /* setup the last descriptor */ | 3410 | /* setup the last descriptor */ |
3390 | ioadl[i - 1].flags = cpu_to_le32(IOADL_FLAGS_LAST_DESC); | 3411 | ioadl[i - 1].flags = IOADL_FLAGS_LAST_DESC; |
3391 | 3412 | ||
3392 | return 0; | 3413 | return 0; |
3393 | } | 3414 | } |
@@ -3401,7 +3422,7 @@ static int pmcraid_build_passthrough_ioadls( | |||
3401 | * @direction: data transfer direction | 3422 | * @direction: data transfer direction |
3402 | * | 3423 | * |
3403 | * Return value | 3424 | * Return value |
3404 | * 0 on sucess, non-zero error code on failure | 3425 | * 0 on success, non-zero error code on failure |
3405 | */ | 3426 | */ |
3406 | static void pmcraid_release_passthrough_ioadls( | 3427 | static void pmcraid_release_passthrough_ioadls( |
3407 | struct pmcraid_cmd *cmd, | 3428 | struct pmcraid_cmd *cmd, |
@@ -3429,7 +3450,7 @@ static void pmcraid_release_passthrough_ioadls( | |||
3429 | * @arg: pointer to pmcraid_passthrough_buffer user buffer | 3450 | * @arg: pointer to pmcraid_passthrough_buffer user buffer |
3430 | * | 3451 | * |
3431 | * Return value | 3452 | * Return value |
3432 | * 0 on sucess, non-zero error code on failure | 3453 | * 0 on success, non-zero error code on failure |
3433 | */ | 3454 | */ |
3434 | static long pmcraid_ioctl_passthrough( | 3455 | static long pmcraid_ioctl_passthrough( |
3435 | struct pmcraid_instance *pinstance, | 3456 | struct pmcraid_instance *pinstance, |
@@ -5314,7 +5335,7 @@ static void pmcraid_querycfg(struct pmcraid_cmd *cmd) | |||
5314 | cpu_to_le32(sizeof(struct pmcraid_config_table)); | 5335 | cpu_to_le32(sizeof(struct pmcraid_config_table)); |
5315 | 5336 | ||
5316 | ioadl = &(ioarcb->add_data.u.ioadl[0]); | 5337 | ioadl = &(ioarcb->add_data.u.ioadl[0]); |
5317 | ioadl->flags = cpu_to_le32(IOADL_FLAGS_LAST_DESC); | 5338 | ioadl->flags = IOADL_FLAGS_LAST_DESC; |
5318 | ioadl->address = cpu_to_le64(pinstance->cfg_table_bus_addr); | 5339 | ioadl->address = cpu_to_le64(pinstance->cfg_table_bus_addr); |
5319 | ioadl->data_len = cpu_to_le32(sizeof(struct pmcraid_config_table)); | 5340 | ioadl->data_len = cpu_to_le32(sizeof(struct pmcraid_config_table)); |
5320 | 5341 | ||