aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/pmcraid.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/pmcraid.c')
-rw-r--r--drivers/scsi/pmcraid.c58
1 files changed, 39 insertions, 19 deletions
diff --git a/drivers/scsi/pmcraid.c b/drivers/scsi/pmcraid.c
index 0a97bc9074bb..53aefffbaead 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 *
@@ -40,6 +41,7 @@
40#include <linux/hdreg.h> 41#include <linux/hdreg.h>
41#include <linux/version.h> 42#include <linux/version.h>
42#include <linux/io.h> 43#include <linux/io.h>
44#include <linux/slab.h>
43#include <asm/irq.h> 45#include <asm/irq.h>
44#include <asm/processor.h> 46#include <asm/processor.h>
45#include <linux/libata.h> 47#include <linux/libata.h>
@@ -79,7 +81,7 @@ DECLARE_BITMAP(pmcraid_minor, PMCRAID_MAX_ADAPTERS);
79/* 81/*
80 * Module parameters 82 * Module parameters
81 */ 83 */
82MODULE_AUTHOR("PMC Sierra Corporation, anil_ravindranath@pmc-sierra.com"); 84MODULE_AUTHOR("Anil Ravindranath<anil_ravindranath@pmc-sierra.com>");
83MODULE_DESCRIPTION("PMC Sierra MaxRAID Controller Driver"); 85MODULE_DESCRIPTION("PMC Sierra MaxRAID Controller Driver");
84MODULE_LICENSE("GPL"); 86MODULE_LICENSE("GPL");
85MODULE_VERSION(PMCRAID_DRIVER_VERSION); 87MODULE_VERSION(PMCRAID_DRIVER_VERSION);
@@ -162,10 +164,10 @@ static int pmcraid_slave_alloc(struct scsi_device *scsi_dev)
162 spin_lock_irqsave(&pinstance->resource_lock, lock_flags); 164 spin_lock_irqsave(&pinstance->resource_lock, lock_flags);
163 list_for_each_entry(temp, &pinstance->used_res_q, queue) { 165 list_for_each_entry(temp, &pinstance->used_res_q, queue) {
164 166
165 /* do not expose VSETs with order-ids >= 240 */ 167 /* do not expose VSETs with order-ids > MAX_VSET_TARGETS */
166 if (RES_IS_VSET(temp->cfg_entry)) { 168 if (RES_IS_VSET(temp->cfg_entry)) {
167 target = temp->cfg_entry.unique_flags1; 169 target = temp->cfg_entry.unique_flags1;
168 if (target >= PMCRAID_MAX_VSET_TARGETS) 170 if (target > PMCRAID_MAX_VSET_TARGETS)
169 continue; 171 continue;
170 bus = PMCRAID_VSET_BUS_ID; 172 bus = PMCRAID_VSET_BUS_ID;
171 lun = 0; 173 lun = 0;
@@ -234,7 +236,7 @@ static int pmcraid_slave_configure(struct scsi_device *scsi_dev)
234 scsi_dev->allow_restart = 1; 236 scsi_dev->allow_restart = 1;
235 blk_queue_rq_timeout(scsi_dev->request_queue, 237 blk_queue_rq_timeout(scsi_dev->request_queue,
236 PMCRAID_VSET_IO_TIMEOUT); 238 PMCRAID_VSET_IO_TIMEOUT);
237 blk_queue_max_sectors(scsi_dev->request_queue, 239 blk_queue_max_hw_sectors(scsi_dev->request_queue,
238 PMCRAID_VSET_MAX_SECTORS); 240 PMCRAID_VSET_MAX_SECTORS);
239 } 241 }
240 242
@@ -278,12 +280,17 @@ static void pmcraid_slave_destroy(struct scsi_device *scsi_dev)
278 * pmcraid_change_queue_depth - Change the device's queue depth 280 * pmcraid_change_queue_depth - Change the device's queue depth
279 * @scsi_dev: scsi device struct 281 * @scsi_dev: scsi device struct
280 * @depth: depth to set 282 * @depth: depth to set
283 * @reason: calling context
281 * 284 *
282 * Return value 285 * Return value
283 * actual depth set 286 * actual depth set
284 */ 287 */
285static int pmcraid_change_queue_depth(struct scsi_device *scsi_dev, int depth) 288static int pmcraid_change_queue_depth(struct scsi_device *scsi_dev, int depth,
289 int reason)
286{ 290{
291 if (reason != SCSI_QDEPTH_DEFAULT)
292 return -EOPNOTSUPP;
293
287 if (depth > PMCRAID_MAX_CMD_PER_LUN) 294 if (depth > PMCRAID_MAX_CMD_PER_LUN)
288 depth = PMCRAID_MAX_CMD_PER_LUN; 295 depth = PMCRAID_MAX_CMD_PER_LUN;
289 296
@@ -1205,7 +1212,7 @@ static int pmcraid_expose_resource(struct pmcraid_config_table_entry *cfgte)
1205 int retval = 0; 1212 int retval = 0;
1206 1213
1207 if (cfgte->resource_type == RES_TYPE_VSET) 1214 if (cfgte->resource_type == RES_TYPE_VSET)
1208 retval = ((cfgte->unique_flags1 & 0xFF) < 0xFE); 1215 retval = ((cfgte->unique_flags1 & 0x80) == 0);
1209 else if (cfgte->resource_type == RES_TYPE_GSCSI) 1216 else if (cfgte->resource_type == RES_TYPE_GSCSI)
1210 retval = (RES_BUS(cfgte->resource_address) != 1217 retval = (RES_BUS(cfgte->resource_address) !=
1211 PMCRAID_VIRTUAL_ENCL_BUS_ID); 1218 PMCRAID_VIRTUAL_ENCL_BUS_ID);
@@ -1356,6 +1363,7 @@ static int pmcraid_notify_aen(struct pmcraid_instance *pinstance, u8 type)
1356 * Return value: 1363 * Return value:
1357 * none 1364 * none
1358 */ 1365 */
1366
1359static void pmcraid_handle_config_change(struct pmcraid_instance *pinstance) 1367static void pmcraid_handle_config_change(struct pmcraid_instance *pinstance)
1360{ 1368{
1361 struct pmcraid_config_table_entry *cfg_entry; 1369 struct pmcraid_config_table_entry *cfg_entry;
@@ -1363,9 +1371,10 @@ static void pmcraid_handle_config_change(struct pmcraid_instance *pinstance)
1363 struct pmcraid_cmd *cmd; 1371 struct pmcraid_cmd *cmd;
1364 struct pmcraid_cmd *cfgcmd; 1372 struct pmcraid_cmd *cfgcmd;
1365 struct pmcraid_resource_entry *res = NULL; 1373 struct pmcraid_resource_entry *res = NULL;
1366 u32 new_entry = 1;
1367 unsigned long lock_flags; 1374 unsigned long lock_flags;
1368 unsigned long host_lock_flags; 1375 unsigned long host_lock_flags;
1376 u32 new_entry = 1;
1377 u32 hidden_entry = 0;
1369 int rc; 1378 int rc;
1370 1379
1371 ccn_hcam = (struct pmcraid_hcam_ccn *)pinstance->ccn.hcam; 1380 ccn_hcam = (struct pmcraid_hcam_ccn *)pinstance->ccn.hcam;
@@ -1401,9 +1410,15 @@ static void pmcraid_handle_config_change(struct pmcraid_instance *pinstance)
1401 } 1410 }
1402 1411
1403 /* If this resource is not going to be added to mid-layer, just notify 1412 /* If this resource is not going to be added to mid-layer, just notify
1404 * applications and return 1413 * applications and return. If this notification is about hiding a VSET
1414 * resource, check if it was exposed already.
1405 */ 1415 */
1406 if (!pmcraid_expose_resource(cfg_entry)) 1416 if (pinstance->ccn.hcam->notification_type ==
1417 NOTIFICATION_TYPE_ENTRY_CHANGED &&
1418 cfg_entry->resource_type == RES_TYPE_VSET &&
1419 cfg_entry->unique_flags1 & 0x80) {
1420 hidden_entry = 1;
1421 } else if (!pmcraid_expose_resource(cfg_entry))
1407 goto out_notify_apps; 1422 goto out_notify_apps;
1408 1423
1409 spin_lock_irqsave(&pinstance->resource_lock, lock_flags); 1424 spin_lock_irqsave(&pinstance->resource_lock, lock_flags);
@@ -1419,6 +1434,12 @@ static void pmcraid_handle_config_change(struct pmcraid_instance *pinstance)
1419 1434
1420 if (new_entry) { 1435 if (new_entry) {
1421 1436
1437 if (hidden_entry) {
1438 spin_unlock_irqrestore(&pinstance->resource_lock,
1439 lock_flags);
1440 goto out_notify_apps;
1441 }
1442
1422 /* If there are more number of resources than what driver can 1443 /* If there are more number of resources than what driver can
1423 * manage, do not notify the applications about the CCN. Just 1444 * manage, do not notify the applications about the CCN. Just
1424 * ignore this notifications and re-register the same HCAM 1445 * ignore this notifications and re-register the same HCAM
@@ -1449,8 +1470,9 @@ static void pmcraid_handle_config_change(struct pmcraid_instance *pinstance)
1449 sizeof(struct pmcraid_config_table_entry)); 1470 sizeof(struct pmcraid_config_table_entry));
1450 1471
1451 if (pinstance->ccn.hcam->notification_type == 1472 if (pinstance->ccn.hcam->notification_type ==
1452 NOTIFICATION_TYPE_ENTRY_DELETED) { 1473 NOTIFICATION_TYPE_ENTRY_DELETED || hidden_entry) {
1453 if (res->scsi_dev) { 1474 if (res->scsi_dev) {
1475 res->cfg_entry.unique_flags1 &= 0x7F;
1454 res->change_detected = RES_CHANGE_DEL; 1476 res->change_detected = RES_CHANGE_DEL;
1455 res->cfg_entry.resource_handle = 1477 res->cfg_entry.resource_handle =
1456 PMCRAID_INVALID_RES_HANDLE; 1478 PMCRAID_INVALID_RES_HANDLE;
@@ -2462,14 +2484,12 @@ static int pmcraid_error_handler(struct pmcraid_cmd *cmd)
2462 sense_copied = 1; 2484 sense_copied = 1;
2463 } 2485 }
2464 2486
2465 if (RES_IS_GSCSI(res->cfg_entry)) { 2487 if (RES_IS_GSCSI(res->cfg_entry))
2466 pmcraid_cancel_all(cmd, sense_copied); 2488 pmcraid_cancel_all(cmd, sense_copied);
2467 } else if (sense_copied) { 2489 else if (sense_copied)
2468 pmcraid_erp_done(cmd); 2490 pmcraid_erp_done(cmd);
2469 return 0; 2491 else
2470 } else {
2471 pmcraid_request_sense(cmd); 2492 pmcraid_request_sense(cmd);
2472 }
2473 2493
2474 return 1; 2494 return 1;
2475 2495
@@ -3342,7 +3362,7 @@ static int pmcraid_chr_fasync(int fd, struct file *filep, int mode)
3342 * @direction : data transfer direction 3362 * @direction : data transfer direction
3343 * 3363 *
3344 * Return value 3364 * Return value
3345 * 0 on sucess, non-zero error code on failure 3365 * 0 on success, non-zero error code on failure
3346 */ 3366 */
3347static int pmcraid_build_passthrough_ioadls( 3367static int pmcraid_build_passthrough_ioadls(
3348 struct pmcraid_cmd *cmd, 3368 struct pmcraid_cmd *cmd,
@@ -3401,7 +3421,7 @@ static int pmcraid_build_passthrough_ioadls(
3401 * @direction: data transfer direction 3421 * @direction: data transfer direction
3402 * 3422 *
3403 * Return value 3423 * Return value
3404 * 0 on sucess, non-zero error code on failure 3424 * 0 on success, non-zero error code on failure
3405 */ 3425 */
3406static void pmcraid_release_passthrough_ioadls( 3426static void pmcraid_release_passthrough_ioadls(
3407 struct pmcraid_cmd *cmd, 3427 struct pmcraid_cmd *cmd,
@@ -3429,7 +3449,7 @@ static void pmcraid_release_passthrough_ioadls(
3429 * @arg: pointer to pmcraid_passthrough_buffer user buffer 3449 * @arg: pointer to pmcraid_passthrough_buffer user buffer
3430 * 3450 *
3431 * Return value 3451 * Return value
3432 * 0 on sucess, non-zero error code on failure 3452 * 0 on success, non-zero error code on failure
3433 */ 3453 */
3434static long pmcraid_ioctl_passthrough( 3454static long pmcraid_ioctl_passthrough(
3435 struct pmcraid_instance *pinstance, 3455 struct pmcraid_instance *pinstance,