diff options
Diffstat (limited to 'drivers/scsi/aacraid')
| -rw-r--r-- | drivers/scsi/aacraid/aachba.c | 402 | ||||
| -rw-r--r-- | drivers/scsi/aacraid/aacraid.h | 76 | ||||
| -rw-r--r-- | drivers/scsi/aacraid/commctrl.c | 286 | ||||
| -rw-r--r-- | drivers/scsi/aacraid/comminit.c | 4 | ||||
| -rw-r--r-- | drivers/scsi/aacraid/commsup.c | 112 | ||||
| -rw-r--r-- | drivers/scsi/aacraid/dpcsup.c | 36 | ||||
| -rw-r--r-- | drivers/scsi/aacraid/linit.c | 65 | ||||
| -rw-r--r-- | drivers/scsi/aacraid/nark.c | 3 | ||||
| -rw-r--r-- | drivers/scsi/aacraid/rkt.c | 3 | ||||
| -rw-r--r-- | drivers/scsi/aacraid/rx.c | 115 | ||||
| -rw-r--r-- | drivers/scsi/aacraid/sa.c | 1 |
11 files changed, 640 insertions, 463 deletions
diff --git a/drivers/scsi/aacraid/aachba.c b/drivers/scsi/aacraid/aachba.c index d789e61bdc49..1e82c69b36b0 100644 --- a/drivers/scsi/aacraid/aachba.c +++ b/drivers/scsi/aacraid/aachba.c | |||
| @@ -5,7 +5,7 @@ | |||
| 5 | * based on the old aacraid driver that is.. | 5 | * based on the old aacraid driver that is.. |
| 6 | * Adaptec aacraid device driver for Linux. | 6 | * Adaptec aacraid device driver for Linux. |
| 7 | * | 7 | * |
| 8 | * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com) | 8 | * Copyright (c) 2000-2007 Adaptec, Inc. (aacraid@adaptec.com) |
| 9 | * | 9 | * |
| 10 | * This program is free software; you can redistribute it and/or modify | 10 | * This program is free software; you can redistribute it and/or modify |
| 11 | * it under the terms of the GNU General Public License as published by | 11 | * it under the terms of the GNU General Public License as published by |
| @@ -172,6 +172,30 @@ MODULE_PARM_DESC(acbsize, "Request a specific adapter control block (FIB) size. | |||
| 172 | int expose_physicals = -1; | 172 | int expose_physicals = -1; |
| 173 | module_param(expose_physicals, int, S_IRUGO|S_IWUSR); | 173 | module_param(expose_physicals, int, S_IRUGO|S_IWUSR); |
| 174 | MODULE_PARM_DESC(expose_physicals, "Expose physical components of the arrays. -1=protect 0=off, 1=on"); | 174 | MODULE_PARM_DESC(expose_physicals, "Expose physical components of the arrays. -1=protect 0=off, 1=on"); |
| 175 | |||
| 176 | |||
| 177 | static inline int aac_valid_context(struct scsi_cmnd *scsicmd, | ||
| 178 | struct fib *fibptr) { | ||
| 179 | struct scsi_device *device; | ||
| 180 | |||
| 181 | if (unlikely(!scsicmd || !scsicmd->scsi_done )) { | ||
| 182 | dprintk((KERN_WARNING "aac_valid_context: scsi command corrupt\n")) | ||
| 183 | ; | ||
| 184 | aac_fib_complete(fibptr); | ||
| 185 | aac_fib_free(fibptr); | ||
| 186 | return 0; | ||
| 187 | } | ||
| 188 | scsicmd->SCp.phase = AAC_OWNER_MIDLEVEL; | ||
| 189 | device = scsicmd->device; | ||
| 190 | if (unlikely(!device || !scsi_device_online(device))) { | ||
| 191 | dprintk((KERN_WARNING "aac_valid_context: scsi device corrupt\n")); | ||
| 192 | aac_fib_complete(fibptr); | ||
| 193 | aac_fib_free(fibptr); | ||
| 194 | return 0; | ||
| 195 | } | ||
| 196 | return 1; | ||
| 197 | } | ||
| 198 | |||
| 175 | /** | 199 | /** |
| 176 | * aac_get_config_status - check the adapter configuration | 200 | * aac_get_config_status - check the adapter configuration |
| 177 | * @common: adapter to query | 201 | * @common: adapter to query |
| @@ -258,13 +282,10 @@ int aac_get_containers(struct aac_dev *dev) | |||
| 258 | u32 index; | 282 | u32 index; |
| 259 | int status = 0; | 283 | int status = 0; |
| 260 | struct fib * fibptr; | 284 | struct fib * fibptr; |
| 261 | unsigned instance; | ||
| 262 | struct aac_get_container_count *dinfo; | 285 | struct aac_get_container_count *dinfo; |
| 263 | struct aac_get_container_count_resp *dresp; | 286 | struct aac_get_container_count_resp *dresp; |
| 264 | int maximum_num_containers = MAXIMUM_NUM_CONTAINERS; | 287 | int maximum_num_containers = MAXIMUM_NUM_CONTAINERS; |
| 265 | 288 | ||
| 266 | instance = dev->scsi_host_ptr->unique_id; | ||
| 267 | |||
| 268 | if (!(fibptr = aac_fib_alloc(dev))) | 289 | if (!(fibptr = aac_fib_alloc(dev))) |
| 269 | return -ENOMEM; | 290 | return -ENOMEM; |
| 270 | 291 | ||
| @@ -284,88 +305,35 @@ int aac_get_containers(struct aac_dev *dev) | |||
| 284 | maximum_num_containers = le32_to_cpu(dresp->ContainerSwitchEntries); | 305 | maximum_num_containers = le32_to_cpu(dresp->ContainerSwitchEntries); |
| 285 | aac_fib_complete(fibptr); | 306 | aac_fib_complete(fibptr); |
| 286 | } | 307 | } |
| 308 | aac_fib_free(fibptr); | ||
| 287 | 309 | ||
| 288 | if (maximum_num_containers < MAXIMUM_NUM_CONTAINERS) | 310 | if (maximum_num_containers < MAXIMUM_NUM_CONTAINERS) |
| 289 | maximum_num_containers = MAXIMUM_NUM_CONTAINERS; | 311 | maximum_num_containers = MAXIMUM_NUM_CONTAINERS; |
| 290 | fsa_dev_ptr = kmalloc( | 312 | fsa_dev_ptr = kmalloc(sizeof(*fsa_dev_ptr) * maximum_num_containers, |
| 291 | sizeof(*fsa_dev_ptr) * maximum_num_containers, GFP_KERNEL); | 313 | GFP_KERNEL); |
| 292 | if (!fsa_dev_ptr) { | 314 | if (!fsa_dev_ptr) |
| 293 | aac_fib_free(fibptr); | ||
| 294 | return -ENOMEM; | 315 | return -ENOMEM; |
| 295 | } | ||
| 296 | memset(fsa_dev_ptr, 0, sizeof(*fsa_dev_ptr) * maximum_num_containers); | 316 | memset(fsa_dev_ptr, 0, sizeof(*fsa_dev_ptr) * maximum_num_containers); |
| 297 | 317 | ||
| 298 | dev->fsa_dev = fsa_dev_ptr; | 318 | dev->fsa_dev = fsa_dev_ptr; |
| 299 | dev->maximum_num_containers = maximum_num_containers; | 319 | dev->maximum_num_containers = maximum_num_containers; |
| 300 | 320 | ||
| 301 | for (index = 0; index < dev->maximum_num_containers; index++) { | 321 | for (index = 0; index < dev->maximum_num_containers; ) { |
| 302 | struct aac_query_mount *dinfo; | ||
| 303 | struct aac_mount *dresp; | ||
| 304 | |||
| 305 | fsa_dev_ptr[index].devname[0] = '\0'; | 322 | fsa_dev_ptr[index].devname[0] = '\0'; |
| 306 | 323 | ||
| 307 | aac_fib_init(fibptr); | 324 | status = aac_probe_container(dev, index); |
| 308 | dinfo = (struct aac_query_mount *) fib_data(fibptr); | ||
| 309 | |||
| 310 | dinfo->command = cpu_to_le32(VM_NameServe); | ||
| 311 | dinfo->count = cpu_to_le32(index); | ||
| 312 | dinfo->type = cpu_to_le32(FT_FILESYS); | ||
| 313 | 325 | ||
| 314 | status = aac_fib_send(ContainerCommand, | 326 | if (status < 0) { |
| 315 | fibptr, | ||
| 316 | sizeof (struct aac_query_mount), | ||
| 317 | FsaNormal, | ||
| 318 | 1, 1, | ||
| 319 | NULL, NULL); | ||
| 320 | if (status < 0 ) { | ||
| 321 | printk(KERN_WARNING "aac_get_containers: SendFIB failed.\n"); | 327 | printk(KERN_WARNING "aac_get_containers: SendFIB failed.\n"); |
| 322 | break; | 328 | break; |
| 323 | } | 329 | } |
| 324 | dresp = (struct aac_mount *)fib_data(fibptr); | ||
| 325 | 330 | ||
| 326 | if ((le32_to_cpu(dresp->status) == ST_OK) && | ||
| 327 | (le32_to_cpu(dresp->mnt[0].vol) == CT_NONE)) { | ||
| 328 | dinfo->command = cpu_to_le32(VM_NameServe64); | ||
| 329 | dinfo->count = cpu_to_le32(index); | ||
| 330 | dinfo->type = cpu_to_le32(FT_FILESYS); | ||
| 331 | |||
| 332 | if (aac_fib_send(ContainerCommand, | ||
| 333 | fibptr, | ||
| 334 | sizeof(struct aac_query_mount), | ||
| 335 | FsaNormal, | ||
| 336 | 1, 1, | ||
| 337 | NULL, NULL) < 0) | ||
| 338 | continue; | ||
| 339 | } else | ||
| 340 | dresp->mnt[0].capacityhigh = 0; | ||
| 341 | |||
| 342 | dprintk ((KERN_DEBUG | ||
| 343 | "VM_NameServe cid=%d status=%d vol=%d state=%d cap=%llu\n", | ||
| 344 | (int)index, (int)le32_to_cpu(dresp->status), | ||
| 345 | (int)le32_to_cpu(dresp->mnt[0].vol), | ||
| 346 | (int)le32_to_cpu(dresp->mnt[0].state), | ||
| 347 | ((u64)le32_to_cpu(dresp->mnt[0].capacity)) + | ||
| 348 | (((u64)le32_to_cpu(dresp->mnt[0].capacityhigh)) << 32))); | ||
| 349 | if ((le32_to_cpu(dresp->status) == ST_OK) && | ||
| 350 | (le32_to_cpu(dresp->mnt[0].vol) != CT_NONE) && | ||
| 351 | (le32_to_cpu(dresp->mnt[0].state) != FSCS_HIDDEN)) { | ||
| 352 | fsa_dev_ptr[index].valid = 1; | ||
| 353 | fsa_dev_ptr[index].type = le32_to_cpu(dresp->mnt[0].vol); | ||
| 354 | fsa_dev_ptr[index].size | ||
| 355 | = ((u64)le32_to_cpu(dresp->mnt[0].capacity)) + | ||
| 356 | (((u64)le32_to_cpu(dresp->mnt[0].capacityhigh)) << 32); | ||
| 357 | if (le32_to_cpu(dresp->mnt[0].state) & FSCS_READONLY) | ||
| 358 | fsa_dev_ptr[index].ro = 1; | ||
| 359 | } | ||
| 360 | aac_fib_complete(fibptr); | ||
| 361 | /* | 331 | /* |
| 362 | * If there are no more containers, then stop asking. | 332 | * If there are no more containers, then stop asking. |
| 363 | */ | 333 | */ |
| 364 | if ((index + 1) >= le32_to_cpu(dresp->count)){ | 334 | if (++index >= status) |
| 365 | break; | 335 | break; |
| 366 | } | ||
| 367 | } | 336 | } |
| 368 | aac_fib_free(fibptr); | ||
| 369 | return status; | 337 | return status; |
| 370 | } | 338 | } |
| 371 | 339 | ||
| @@ -382,8 +350,9 @@ static void aac_internal_transfer(struct scsi_cmnd *scsicmd, void *data, unsigne | |||
| 382 | buf = scsicmd->request_buffer; | 350 | buf = scsicmd->request_buffer; |
| 383 | transfer_len = min(scsicmd->request_bufflen, len + offset); | 351 | transfer_len = min(scsicmd->request_bufflen, len + offset); |
| 384 | } | 352 | } |
| 385 | 353 | transfer_len -= offset; | |
| 386 | memcpy(buf + offset, data, transfer_len - offset); | 354 | if (buf && transfer_len) |
| 355 | memcpy(buf + offset, data, transfer_len); | ||
| 387 | 356 | ||
| 388 | if (scsicmd->use_sg) | 357 | if (scsicmd->use_sg) |
| 389 | kunmap_atomic(buf - sg->offset, KM_IRQ0); | 358 | kunmap_atomic(buf - sg->offset, KM_IRQ0); |
| @@ -396,7 +365,9 @@ static void get_container_name_callback(void *context, struct fib * fibptr) | |||
| 396 | struct scsi_cmnd * scsicmd; | 365 | struct scsi_cmnd * scsicmd; |
| 397 | 366 | ||
| 398 | scsicmd = (struct scsi_cmnd *) context; | 367 | scsicmd = (struct scsi_cmnd *) context; |
| 399 | scsicmd->SCp.phase = AAC_OWNER_MIDLEVEL; | 368 | |
| 369 | if (!aac_valid_context(scsicmd, fibptr)) | ||
| 370 | return; | ||
| 400 | 371 | ||
| 401 | dprintk((KERN_DEBUG "get_container_name_callback[cpu %d]: t = %ld.\n", smp_processor_id(), jiffies)); | 372 | dprintk((KERN_DEBUG "get_container_name_callback[cpu %d]: t = %ld.\n", smp_processor_id(), jiffies)); |
| 402 | BUG_ON(fibptr == NULL); | 373 | BUG_ON(fibptr == NULL); |
| @@ -431,7 +402,7 @@ static void get_container_name_callback(void *context, struct fib * fibptr) | |||
| 431 | /** | 402 | /** |
| 432 | * aac_get_container_name - get container name, none blocking. | 403 | * aac_get_container_name - get container name, none blocking. |
| 433 | */ | 404 | */ |
| 434 | static int aac_get_container_name(struct scsi_cmnd * scsicmd, int cid) | 405 | static int aac_get_container_name(struct scsi_cmnd * scsicmd) |
| 435 | { | 406 | { |
| 436 | int status; | 407 | int status; |
| 437 | struct aac_get_name *dinfo; | 408 | struct aac_get_name *dinfo; |
| @@ -448,7 +419,7 @@ static int aac_get_container_name(struct scsi_cmnd * scsicmd, int cid) | |||
| 448 | 419 | ||
| 449 | dinfo->command = cpu_to_le32(VM_ContainerConfig); | 420 | dinfo->command = cpu_to_le32(VM_ContainerConfig); |
| 450 | dinfo->type = cpu_to_le32(CT_READ_NAME); | 421 | dinfo->type = cpu_to_le32(CT_READ_NAME); |
| 451 | dinfo->cid = cpu_to_le32(cid); | 422 | dinfo->cid = cpu_to_le32(scmd_id(scsicmd)); |
| 452 | dinfo->count = cpu_to_le32(sizeof(((struct aac_get_name_resp *)NULL)->data)); | 423 | dinfo->count = cpu_to_le32(sizeof(((struct aac_get_name_resp *)NULL)->data)); |
| 453 | 424 | ||
| 454 | status = aac_fib_send(ContainerCommand, | 425 | status = aac_fib_send(ContainerCommand, |
| @@ -473,85 +444,192 @@ static int aac_get_container_name(struct scsi_cmnd * scsicmd, int cid) | |||
| 473 | return -1; | 444 | return -1; |
| 474 | } | 445 | } |
| 475 | 446 | ||
| 476 | /** | 447 | static int aac_probe_container_callback2(struct scsi_cmnd * scsicmd) |
| 477 | * aac_probe_container - query a logical volume | 448 | { |
| 478 | * @dev: device to query | 449 | struct fsa_dev_info *fsa_dev_ptr = ((struct aac_dev *)(scsicmd->device->host->hostdata))->fsa_dev; |
| 479 | * @cid: container identifier | 450 | |
| 480 | * | 451 | if (fsa_dev_ptr[scmd_id(scsicmd)].valid) |
| 481 | * Queries the controller about the given volume. The volume information | 452 | return aac_scsi_cmd(scsicmd); |
| 482 | * is updated in the struct fsa_dev_info structure rather than returned. | 453 | |
| 483 | */ | 454 | scsicmd->result = DID_NO_CONNECT << 16; |
| 484 | 455 | scsicmd->scsi_done(scsicmd); | |
| 485 | int aac_probe_container(struct aac_dev *dev, int cid) | 456 | return 0; |
| 457 | } | ||
| 458 | |||
| 459 | static int _aac_probe_container2(void * context, struct fib * fibptr) | ||
| 486 | { | 460 | { |
| 487 | struct fsa_dev_info *fsa_dev_ptr; | 461 | struct fsa_dev_info *fsa_dev_ptr; |
| 488 | int status; | 462 | int (*callback)(struct scsi_cmnd *); |
| 463 | struct scsi_cmnd * scsicmd = (struct scsi_cmnd *)context; | ||
| 464 | |||
| 465 | if (!aac_valid_context(scsicmd, fibptr)) | ||
| 466 | return 0; | ||
| 467 | |||
| 468 | fsa_dev_ptr = ((struct aac_dev *)(scsicmd->device->host->hostdata))->fsa_dev; | ||
| 469 | |||
| 470 | scsicmd->SCp.Status = 0; | ||
| 471 | if (fsa_dev_ptr) { | ||
| 472 | struct aac_mount * dresp = (struct aac_mount *) fib_data(fibptr); | ||
| 473 | fsa_dev_ptr += scmd_id(scsicmd); | ||
| 474 | |||
| 475 | if ((le32_to_cpu(dresp->status) == ST_OK) && | ||
| 476 | (le32_to_cpu(dresp->mnt[0].vol) != CT_NONE) && | ||
| 477 | (le32_to_cpu(dresp->mnt[0].state) != FSCS_HIDDEN)) { | ||
| 478 | fsa_dev_ptr->valid = 1; | ||
| 479 | fsa_dev_ptr->type = le32_to_cpu(dresp->mnt[0].vol); | ||
| 480 | fsa_dev_ptr->size | ||
| 481 | = ((u64)le32_to_cpu(dresp->mnt[0].capacity)) + | ||
| 482 | (((u64)le32_to_cpu(dresp->mnt[0].capacityhigh)) << 32); | ||
| 483 | fsa_dev_ptr->ro = ((le32_to_cpu(dresp->mnt[0].state) & FSCS_READONLY) != 0); | ||
| 484 | } | ||
| 485 | if ((fsa_dev_ptr->valid & 1) == 0) | ||
| 486 | fsa_dev_ptr->valid = 0; | ||
| 487 | scsicmd->SCp.Status = le32_to_cpu(dresp->count); | ||
| 488 | } | ||
| 489 | aac_fib_complete(fibptr); | ||
| 490 | aac_fib_free(fibptr); | ||
| 491 | callback = (int (*)(struct scsi_cmnd *))(scsicmd->SCp.ptr); | ||
| 492 | scsicmd->SCp.ptr = NULL; | ||
| 493 | return (*callback)(scsicmd); | ||
| 494 | } | ||
| 495 | |||
| 496 | static int _aac_probe_container1(void * context, struct fib * fibptr) | ||
| 497 | { | ||
| 498 | struct scsi_cmnd * scsicmd; | ||
| 499 | struct aac_mount * dresp; | ||
| 489 | struct aac_query_mount *dinfo; | 500 | struct aac_query_mount *dinfo; |
| 490 | struct aac_mount *dresp; | 501 | int status; |
| 491 | struct fib * fibptr; | ||
| 492 | unsigned instance; | ||
| 493 | 502 | ||
| 494 | fsa_dev_ptr = dev->fsa_dev; | 503 | dresp = (struct aac_mount *) fib_data(fibptr); |
| 495 | if (!fsa_dev_ptr) | 504 | dresp->mnt[0].capacityhigh = 0; |
| 496 | return -ENOMEM; | 505 | if ((le32_to_cpu(dresp->status) != ST_OK) || |
| 497 | instance = dev->scsi_host_ptr->unique_id; | 506 | (le32_to_cpu(dresp->mnt[0].vol) != CT_NONE)) |
| 507 | return _aac_probe_container2(context, fibptr); | ||
| 508 | scsicmd = (struct scsi_cmnd *) context; | ||
| 509 | scsicmd->SCp.phase = AAC_OWNER_MIDLEVEL; | ||
| 498 | 510 | ||
| 499 | if (!(fibptr = aac_fib_alloc(dev))) | 511 | if (!aac_valid_context(scsicmd, fibptr)) |
| 500 | return -ENOMEM; | 512 | return 0; |
| 501 | 513 | ||
| 502 | aac_fib_init(fibptr); | 514 | aac_fib_init(fibptr); |
| 503 | 515 | ||
| 504 | dinfo = (struct aac_query_mount *)fib_data(fibptr); | 516 | dinfo = (struct aac_query_mount *)fib_data(fibptr); |
| 505 | 517 | ||
| 506 | dinfo->command = cpu_to_le32(VM_NameServe); | 518 | dinfo->command = cpu_to_le32(VM_NameServe64); |
| 507 | dinfo->count = cpu_to_le32(cid); | 519 | dinfo->count = cpu_to_le32(scmd_id(scsicmd)); |
| 508 | dinfo->type = cpu_to_le32(FT_FILESYS); | 520 | dinfo->type = cpu_to_le32(FT_FILESYS); |
| 509 | 521 | ||
| 510 | status = aac_fib_send(ContainerCommand, | 522 | status = aac_fib_send(ContainerCommand, |
| 511 | fibptr, | 523 | fibptr, |
| 512 | sizeof(struct aac_query_mount), | 524 | sizeof(struct aac_query_mount), |
| 513 | FsaNormal, | 525 | FsaNormal, |
| 514 | 1, 1, | 526 | 0, 1, |
| 515 | NULL, NULL); | 527 | (fib_callback) _aac_probe_container2, |
| 528 | (void *) scsicmd); | ||
| 529 | /* | ||
| 530 | * Check that the command queued to the controller | ||
| 531 | */ | ||
| 532 | if (status == -EINPROGRESS) { | ||
| 533 | scsicmd->SCp.phase = AAC_OWNER_FIRMWARE; | ||
| 534 | return 0; | ||
| 535 | } | ||
| 516 | if (status < 0) { | 536 | if (status < 0) { |
| 517 | printk(KERN_WARNING "aacraid: aac_probe_container query failed.\n"); | 537 | /* Inherit results from VM_NameServe, if any */ |
| 518 | goto error; | 538 | dresp->status = cpu_to_le32(ST_OK); |
| 539 | return _aac_probe_container2(context, fibptr); | ||
| 519 | } | 540 | } |
| 541 | return 0; | ||
| 542 | } | ||
| 520 | 543 | ||
| 521 | dresp = (struct aac_mount *) fib_data(fibptr); | 544 | static int _aac_probe_container(struct scsi_cmnd * scsicmd, int (*callback)(struct scsi_cmnd *)) |
| 545 | { | ||
| 546 | struct fib * fibptr; | ||
| 547 | int status = -ENOMEM; | ||
| 522 | 548 | ||
| 523 | if ((le32_to_cpu(dresp->status) == ST_OK) && | 549 | if ((fibptr = aac_fib_alloc((struct aac_dev *)scsicmd->device->host->hostdata))) { |
| 524 | (le32_to_cpu(dresp->mnt[0].vol) == CT_NONE)) { | 550 | struct aac_query_mount *dinfo; |
| 525 | dinfo->command = cpu_to_le32(VM_NameServe64); | ||
| 526 | dinfo->count = cpu_to_le32(cid); | ||
| 527 | dinfo->type = cpu_to_le32(FT_FILESYS); | ||
| 528 | 551 | ||
| 529 | if (aac_fib_send(ContainerCommand, | 552 | aac_fib_init(fibptr); |
| 530 | fibptr, | 553 | |
| 531 | sizeof(struct aac_query_mount), | 554 | dinfo = (struct aac_query_mount *)fib_data(fibptr); |
| 532 | FsaNormal, | 555 | |
| 533 | 1, 1, | 556 | dinfo->command = cpu_to_le32(VM_NameServe); |
| 534 | NULL, NULL) < 0) | 557 | dinfo->count = cpu_to_le32(scmd_id(scsicmd)); |
| 535 | goto error; | 558 | dinfo->type = cpu_to_le32(FT_FILESYS); |
| 536 | } else | 559 | scsicmd->SCp.ptr = (char *)callback; |
| 537 | dresp->mnt[0].capacityhigh = 0; | ||
| 538 | 560 | ||
| 539 | if ((le32_to_cpu(dresp->status) == ST_OK) && | 561 | status = aac_fib_send(ContainerCommand, |
| 540 | (le32_to_cpu(dresp->mnt[0].vol) != CT_NONE) && | 562 | fibptr, |
| 541 | (le32_to_cpu(dresp->mnt[0].state) != FSCS_HIDDEN)) { | 563 | sizeof(struct aac_query_mount), |
| 542 | fsa_dev_ptr[cid].valid = 1; | 564 | FsaNormal, |
| 543 | fsa_dev_ptr[cid].type = le32_to_cpu(dresp->mnt[0].vol); | 565 | 0, 1, |
| 544 | fsa_dev_ptr[cid].size | 566 | (fib_callback) _aac_probe_container1, |
| 545 | = ((u64)le32_to_cpu(dresp->mnt[0].capacity)) + | 567 | (void *) scsicmd); |
| 546 | (((u64)le32_to_cpu(dresp->mnt[0].capacityhigh)) << 32); | 568 | /* |
| 547 | if (le32_to_cpu(dresp->mnt[0].state) & FSCS_READONLY) | 569 | * Check that the command queued to the controller |
| 548 | fsa_dev_ptr[cid].ro = 1; | 570 | */ |
| 571 | if (status == -EINPROGRESS) { | ||
| 572 | scsicmd->SCp.phase = AAC_OWNER_FIRMWARE; | ||
| 573 | return 0; | ||
| 574 | } | ||
| 575 | if (status < 0) { | ||
| 576 | scsicmd->SCp.ptr = NULL; | ||
| 577 | aac_fib_complete(fibptr); | ||
| 578 | aac_fib_free(fibptr); | ||
| 579 | } | ||
| 549 | } | 580 | } |
| 581 | if (status < 0) { | ||
| 582 | struct fsa_dev_info *fsa_dev_ptr = ((struct aac_dev *)(scsicmd->device->host->hostdata))->fsa_dev; | ||
| 583 | if (fsa_dev_ptr) { | ||
| 584 | fsa_dev_ptr += scmd_id(scsicmd); | ||
| 585 | if ((fsa_dev_ptr->valid & 1) == 0) { | ||
| 586 | fsa_dev_ptr->valid = 0; | ||
| 587 | return (*callback)(scsicmd); | ||
| 588 | } | ||
| 589 | } | ||
| 590 | } | ||
| 591 | return status; | ||
| 592 | } | ||
| 550 | 593 | ||
| 551 | error: | 594 | /** |
| 552 | aac_fib_complete(fibptr); | 595 | * aac_probe_container - query a logical volume |
| 553 | aac_fib_free(fibptr); | 596 | * @dev: device to query |
| 597 | * @cid: container identifier | ||
| 598 | * | ||
| 599 | * Queries the controller about the given volume. The volume information | ||
| 600 | * is updated in the struct fsa_dev_info structure rather than returned. | ||
| 601 | */ | ||
| 602 | static int aac_probe_container_callback1(struct scsi_cmnd * scsicmd) | ||
| 603 | { | ||
| 604 | scsicmd->device = NULL; | ||
| 605 | return 0; | ||
| 606 | } | ||
| 607 | |||
| 608 | int aac_probe_container(struct aac_dev *dev, int cid) | ||
| 609 | { | ||
| 610 | struct scsi_cmnd *scsicmd = kmalloc(sizeof(*scsicmd), GFP_KERNEL); | ||
| 611 | struct scsi_device *scsidev = kmalloc(sizeof(*scsidev), GFP_KERNEL); | ||
| 612 | int status; | ||
| 554 | 613 | ||
| 614 | if (!scsicmd || !scsidev) { | ||
| 615 | kfree(scsicmd); | ||
| 616 | kfree(scsidev); | ||
| 617 | return -ENOMEM; | ||
| 618 | } | ||
| 619 | scsicmd->list.next = NULL; | ||
| 620 | scsicmd->scsi_done = (void (*)(struct scsi_cmnd*))_aac_probe_container1; | ||
| 621 | |||
| 622 | scsicmd->device = scsidev; | ||
| 623 | scsidev->sdev_state = 0; | ||
| 624 | scsidev->id = cid; | ||
| 625 | scsidev->host = dev->scsi_host_ptr; | ||
| 626 | |||
| 627 | if (_aac_probe_container(scsicmd, aac_probe_container_callback1) == 0) | ||
| 628 | while (scsicmd->device == scsidev) | ||
| 629 | schedule(); | ||
| 630 | kfree(scsidev); | ||
| 631 | status = scsicmd->SCp.Status; | ||
| 632 | kfree(scsicmd); | ||
| 555 | return status; | 633 | return status; |
| 556 | } | 634 | } |
| 557 | 635 | ||
| @@ -1115,6 +1193,12 @@ int aac_get_adapter_info(struct aac_dev* dev) | |||
| 1115 | printk(KERN_INFO "%s%d: serial %x\n", | 1193 | printk(KERN_INFO "%s%d: serial %x\n", |
| 1116 | dev->name, dev->id, | 1194 | dev->name, dev->id, |
| 1117 | le32_to_cpu(dev->adapter_info.serial[0])); | 1195 | le32_to_cpu(dev->adapter_info.serial[0])); |
| 1196 | if (dev->supplement_adapter_info.VpdInfo.Tsid[0]) { | ||
| 1197 | printk(KERN_INFO "%s%d: TSID %.*s\n", | ||
| 1198 | dev->name, dev->id, | ||
| 1199 | (int)sizeof(dev->supplement_adapter_info.VpdInfo.Tsid), | ||
| 1200 | dev->supplement_adapter_info.VpdInfo.Tsid); | ||
| 1201 | } | ||
| 1118 | } | 1202 | } |
| 1119 | 1203 | ||
| 1120 | dev->nondasd_support = 0; | 1204 | dev->nondasd_support = 0; |
| @@ -1241,7 +1325,9 @@ static void io_callback(void *context, struct fib * fibptr) | |||
| 1241 | u32 cid; | 1325 | u32 cid; |
| 1242 | 1326 | ||
| 1243 | scsicmd = (struct scsi_cmnd *) context; | 1327 | scsicmd = (struct scsi_cmnd *) context; |
| 1244 | scsicmd->SCp.phase = AAC_OWNER_MIDLEVEL; | 1328 | |
| 1329 | if (!aac_valid_context(scsicmd, fibptr)) | ||
| 1330 | return; | ||
| 1245 | 1331 | ||
| 1246 | dev = (struct aac_dev *)scsicmd->device->host->hostdata; | 1332 | dev = (struct aac_dev *)scsicmd->device->host->hostdata; |
| 1247 | cid = scmd_id(scsicmd); | 1333 | cid = scmd_id(scsicmd); |
| @@ -1317,7 +1403,7 @@ static void io_callback(void *context, struct fib * fibptr) | |||
| 1317 | scsicmd->scsi_done(scsicmd); | 1403 | scsicmd->scsi_done(scsicmd); |
| 1318 | } | 1404 | } |
| 1319 | 1405 | ||
| 1320 | static int aac_read(struct scsi_cmnd * scsicmd, int cid) | 1406 | static int aac_read(struct scsi_cmnd * scsicmd) |
| 1321 | { | 1407 | { |
| 1322 | u64 lba; | 1408 | u64 lba; |
| 1323 | u32 count; | 1409 | u32 count; |
| @@ -1331,7 +1417,7 @@ static int aac_read(struct scsi_cmnd * scsicmd, int cid) | |||
| 1331 | */ | 1417 | */ |
| 1332 | switch (scsicmd->cmnd[0]) { | 1418 | switch (scsicmd->cmnd[0]) { |
| 1333 | case READ_6: | 1419 | case READ_6: |
| 1334 | dprintk((KERN_DEBUG "aachba: received a read(6) command on id %d.\n", cid)); | 1420 | dprintk((KERN_DEBUG "aachba: received a read(6) command on id %d.\n", scmd_id(scsicmd))); |
| 1335 | 1421 | ||
| 1336 | lba = ((scsicmd->cmnd[1] & 0x1F) << 16) | | 1422 | lba = ((scsicmd->cmnd[1] & 0x1F) << 16) | |
| 1337 | (scsicmd->cmnd[2] << 8) | scsicmd->cmnd[3]; | 1423 | (scsicmd->cmnd[2] << 8) | scsicmd->cmnd[3]; |
| @@ -1341,7 +1427,7 @@ static int aac_read(struct scsi_cmnd * scsicmd, int cid) | |||
| 1341 | count = 256; | 1427 | count = 256; |
| 1342 | break; | 1428 | break; |
| 1343 | case READ_16: | 1429 | case READ_16: |
| 1344 | dprintk((KERN_DEBUG "aachba: received a read(16) command on id %d.\n", cid)); | 1430 | dprintk((KERN_DEBUG "aachba: received a read(16) command on id %d.\n", scmd_id(scsicmd))); |
| 1345 | 1431 | ||
| 1346 | lba = ((u64)scsicmd->cmnd[2] << 56) | | 1432 | lba = ((u64)scsicmd->cmnd[2] << 56) | |
| 1347 | ((u64)scsicmd->cmnd[3] << 48) | | 1433 | ((u64)scsicmd->cmnd[3] << 48) | |
| @@ -1355,7 +1441,7 @@ static int aac_read(struct scsi_cmnd * scsicmd, int cid) | |||
| 1355 | (scsicmd->cmnd[12] << 8) | scsicmd->cmnd[13]; | 1441 | (scsicmd->cmnd[12] << 8) | scsicmd->cmnd[13]; |
| 1356 | break; | 1442 | break; |
| 1357 | case READ_12: | 1443 | case READ_12: |
| 1358 | dprintk((KERN_DEBUG "aachba: received a read(12) command on id %d.\n", cid)); | 1444 | dprintk((KERN_DEBUG "aachba: received a read(12) command on id %d.\n", scmd_id(scsicmd))); |
| 1359 | 1445 | ||
| 1360 | lba = ((u64)scsicmd->cmnd[2] << 24) | | 1446 | lba = ((u64)scsicmd->cmnd[2] << 24) | |
| 1361 | (scsicmd->cmnd[3] << 16) | | 1447 | (scsicmd->cmnd[3] << 16) | |
| @@ -1365,7 +1451,7 @@ static int aac_read(struct scsi_cmnd * scsicmd, int cid) | |||
| 1365 | (scsicmd->cmnd[8] << 8) | scsicmd->cmnd[9]; | 1451 | (scsicmd->cmnd[8] << 8) | scsicmd->cmnd[9]; |
| 1366 | break; | 1452 | break; |
| 1367 | default: | 1453 | default: |
| 1368 | dprintk((KERN_DEBUG "aachba: received a read(10) command on id %d.\n", cid)); | 1454 | dprintk((KERN_DEBUG "aachba: received a read(10) command on id %d.\n", scmd_id(scsicmd))); |
| 1369 | 1455 | ||
| 1370 | lba = ((u64)scsicmd->cmnd[2] << 24) | | 1456 | lba = ((u64)scsicmd->cmnd[2] << 24) | |
| 1371 | (scsicmd->cmnd[3] << 16) | | 1457 | (scsicmd->cmnd[3] << 16) | |
| @@ -1405,7 +1491,7 @@ static int aac_read(struct scsi_cmnd * scsicmd, int cid) | |||
| 1405 | return 0; | 1491 | return 0; |
| 1406 | } | 1492 | } |
| 1407 | 1493 | ||
| 1408 | static int aac_write(struct scsi_cmnd * scsicmd, int cid) | 1494 | static int aac_write(struct scsi_cmnd * scsicmd) |
| 1409 | { | 1495 | { |
| 1410 | u64 lba; | 1496 | u64 lba; |
| 1411 | u32 count; | 1497 | u32 count; |
| @@ -1424,7 +1510,7 @@ static int aac_write(struct scsi_cmnd * scsicmd, int cid) | |||
| 1424 | if (count == 0) | 1510 | if (count == 0) |
| 1425 | count = 256; | 1511 | count = 256; |
| 1426 | } else if (scsicmd->cmnd[0] == WRITE_16) { /* 16 byte command */ | 1512 | } else if (scsicmd->cmnd[0] == WRITE_16) { /* 16 byte command */ |
| 1427 | dprintk((KERN_DEBUG "aachba: received a write(16) command on id %d.\n", cid)); | 1513 | dprintk((KERN_DEBUG "aachba: received a write(16) command on id %d.\n", scmd_id(scsicmd))); |
| 1428 | 1514 | ||
| 1429 | lba = ((u64)scsicmd->cmnd[2] << 56) | | 1515 | lba = ((u64)scsicmd->cmnd[2] << 56) | |
| 1430 | ((u64)scsicmd->cmnd[3] << 48) | | 1516 | ((u64)scsicmd->cmnd[3] << 48) | |
| @@ -1436,14 +1522,14 @@ static int aac_write(struct scsi_cmnd * scsicmd, int cid) | |||
| 1436 | count = (scsicmd->cmnd[10] << 24) | (scsicmd->cmnd[11] << 16) | | 1522 | count = (scsicmd->cmnd[10] << 24) | (scsicmd->cmnd[11] << 16) | |
| 1437 | (scsicmd->cmnd[12] << 8) | scsicmd->cmnd[13]; | 1523 | (scsicmd->cmnd[12] << 8) | scsicmd->cmnd[13]; |
| 1438 | } else if (scsicmd->cmnd[0] == WRITE_12) { /* 12 byte command */ | 1524 | } else if (scsicmd->cmnd[0] == WRITE_12) { /* 12 byte command */ |
| 1439 | dprintk((KERN_DEBUG "aachba: received a write(12) command on id %d.\n", cid)); | 1525 | dprintk((KERN_DEBUG "aachba: received a write(12) command on id %d.\n", scmd_id(scsicmd))); |
| 1440 | 1526 | ||
| 1441 | lba = ((u64)scsicmd->cmnd[2] << 24) | (scsicmd->cmnd[3] << 16) | 1527 | lba = ((u64)scsicmd->cmnd[2] << 24) | (scsicmd->cmnd[3] << 16) |
| 1442 | | (scsicmd->cmnd[4] << 8) | scsicmd->cmnd[5]; | 1528 | | (scsicmd->cmnd[4] << 8) | scsicmd->cmnd[5]; |
| 1443 | count = (scsicmd->cmnd[6] << 24) | (scsicmd->cmnd[7] << 16) | 1529 | count = (scsicmd->cmnd[6] << 24) | (scsicmd->cmnd[7] << 16) |
| 1444 | | (scsicmd->cmnd[8] << 8) | scsicmd->cmnd[9]; | 1530 | | (scsicmd->cmnd[8] << 8) | scsicmd->cmnd[9]; |
| 1445 | } else { | 1531 | } else { |
| 1446 | dprintk((KERN_DEBUG "aachba: received a write(10) command on id %d.\n", cid)); | 1532 | dprintk((KERN_DEBUG "aachba: received a write(10) command on id %d.\n", scmd_id(scsicmd))); |
| 1447 | lba = ((u64)scsicmd->cmnd[2] << 24) | (scsicmd->cmnd[3] << 16) | (scsicmd->cmnd[4] << 8) | scsicmd->cmnd[5]; | 1533 | lba = ((u64)scsicmd->cmnd[2] << 24) | (scsicmd->cmnd[3] << 16) | (scsicmd->cmnd[4] << 8) | scsicmd->cmnd[5]; |
| 1448 | count = (scsicmd->cmnd[7] << 8) | scsicmd->cmnd[8]; | 1534 | count = (scsicmd->cmnd[7] << 8) | scsicmd->cmnd[8]; |
| 1449 | } | 1535 | } |
| @@ -1488,7 +1574,9 @@ static void synchronize_callback(void *context, struct fib *fibptr) | |||
| 1488 | struct scsi_cmnd *cmd; | 1574 | struct scsi_cmnd *cmd; |
| 1489 | 1575 | ||
| 1490 | cmd = context; | 1576 | cmd = context; |
| 1491 | cmd->SCp.phase = AAC_OWNER_MIDLEVEL; | 1577 | |
| 1578 | if (!aac_valid_context(cmd, fibptr)) | ||
| 1579 | return; | ||
| 1492 | 1580 | ||
| 1493 | dprintk((KERN_DEBUG "synchronize_callback[cpu %d]: t = %ld.\n", | 1581 | dprintk((KERN_DEBUG "synchronize_callback[cpu %d]: t = %ld.\n", |
| 1494 | smp_processor_id(), jiffies)); | 1582 | smp_processor_id(), jiffies)); |
| @@ -1523,7 +1611,7 @@ static void synchronize_callback(void *context, struct fib *fibptr) | |||
| 1523 | cmd->scsi_done(cmd); | 1611 | cmd->scsi_done(cmd); |
| 1524 | } | 1612 | } |
| 1525 | 1613 | ||
| 1526 | static int aac_synchronize(struct scsi_cmnd *scsicmd, int cid) | 1614 | static int aac_synchronize(struct scsi_cmnd *scsicmd) |
| 1527 | { | 1615 | { |
| 1528 | int status; | 1616 | int status; |
| 1529 | struct fib *cmd_fibcontext; | 1617 | struct fib *cmd_fibcontext; |
| @@ -1568,7 +1656,7 @@ static int aac_synchronize(struct scsi_cmnd *scsicmd, int cid) | |||
| 1568 | synchronizecmd = fib_data(cmd_fibcontext); | 1656 | synchronizecmd = fib_data(cmd_fibcontext); |
| 1569 | synchronizecmd->command = cpu_to_le32(VM_ContainerConfig); | 1657 | synchronizecmd->command = cpu_to_le32(VM_ContainerConfig); |
| 1570 | synchronizecmd->type = cpu_to_le32(CT_FLUSH_CACHE); | 1658 | synchronizecmd->type = cpu_to_le32(CT_FLUSH_CACHE); |
| 1571 | synchronizecmd->cid = cpu_to_le32(cid); | 1659 | synchronizecmd->cid = cpu_to_le32(scmd_id(scsicmd)); |
| 1572 | synchronizecmd->count = | 1660 | synchronizecmd->count = |
| 1573 | cpu_to_le32(sizeof(((struct aac_synchronize_reply *)NULL)->data)); | 1661 | cpu_to_le32(sizeof(((struct aac_synchronize_reply *)NULL)->data)); |
| 1574 | 1662 | ||
| @@ -1646,29 +1734,12 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd) | |||
| 1646 | case TEST_UNIT_READY: | 1734 | case TEST_UNIT_READY: |
| 1647 | if (dev->in_reset) | 1735 | if (dev->in_reset) |
| 1648 | return -1; | 1736 | return -1; |
| 1649 | spin_unlock_irq(host->host_lock); | 1737 | return _aac_probe_container(scsicmd, |
| 1650 | aac_probe_container(dev, cid); | 1738 | aac_probe_container_callback2); |
| 1651 | if ((fsa_dev_ptr[cid].valid & 1) == 0) | ||
| 1652 | fsa_dev_ptr[cid].valid = 0; | ||
| 1653 | spin_lock_irq(host->host_lock); | ||
| 1654 | if (fsa_dev_ptr[cid].valid == 0) { | ||
| 1655 | scsicmd->result = DID_NO_CONNECT << 16; | ||
| 1656 | scsicmd->scsi_done(scsicmd); | ||
| 1657 | return 0; | ||
| 1658 | } | ||
| 1659 | default: | 1739 | default: |
| 1660 | break; | 1740 | break; |
| 1661 | } | 1741 | } |
| 1662 | } | 1742 | } |
| 1663 | /* | ||
| 1664 | * If the target container still doesn't exist, | ||
| 1665 | * return failure | ||
| 1666 | */ | ||
| 1667 | if (fsa_dev_ptr[cid].valid == 0) { | ||
| 1668 | scsicmd->result = DID_BAD_TARGET << 16; | ||
| 1669 | scsicmd->scsi_done(scsicmd); | ||
| 1670 | return 0; | ||
| 1671 | } | ||
| 1672 | } else { /* check for physical non-dasd devices */ | 1743 | } else { /* check for physical non-dasd devices */ |
| 1673 | if ((dev->nondasd_support == 1) || expose_physicals) { | 1744 | if ((dev->nondasd_support == 1) || expose_physicals) { |
| 1674 | if (dev->in_reset) | 1745 | if (dev->in_reset) |
| @@ -1733,7 +1804,7 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd) | |||
| 1733 | setinqstr(dev, (void *) (inq_data.inqd_vid), fsa_dev_ptr[cid].type); | 1804 | setinqstr(dev, (void *) (inq_data.inqd_vid), fsa_dev_ptr[cid].type); |
| 1734 | inq_data.inqd_pdt = INQD_PDT_DA; /* Direct/random access device */ | 1805 | inq_data.inqd_pdt = INQD_PDT_DA; /* Direct/random access device */ |
| 1735 | aac_internal_transfer(scsicmd, &inq_data, 0, sizeof(inq_data)); | 1806 | aac_internal_transfer(scsicmd, &inq_data, 0, sizeof(inq_data)); |
| 1736 | return aac_get_container_name(scsicmd, cid); | 1807 | return aac_get_container_name(scsicmd); |
| 1737 | } | 1808 | } |
| 1738 | case SERVICE_ACTION_IN: | 1809 | case SERVICE_ACTION_IN: |
| 1739 | if (!(dev->raw_io_interface) || | 1810 | if (!(dev->raw_io_interface) || |
| @@ -1899,7 +1970,7 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd) | |||
| 1899 | min(sizeof(fsa_dev_ptr[cid].devname), | 1970 | min(sizeof(fsa_dev_ptr[cid].devname), |
| 1900 | sizeof(scsicmd->request->rq_disk->disk_name) + 1)); | 1971 | sizeof(scsicmd->request->rq_disk->disk_name) + 1)); |
| 1901 | 1972 | ||
| 1902 | return aac_read(scsicmd, cid); | 1973 | return aac_read(scsicmd); |
| 1903 | 1974 | ||
| 1904 | case WRITE_6: | 1975 | case WRITE_6: |
| 1905 | case WRITE_10: | 1976 | case WRITE_10: |
| @@ -1907,11 +1978,11 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd) | |||
| 1907 | case WRITE_16: | 1978 | case WRITE_16: |
| 1908 | if (dev->in_reset) | 1979 | if (dev->in_reset) |
| 1909 | return -1; | 1980 | return -1; |
| 1910 | return aac_write(scsicmd, cid); | 1981 | return aac_write(scsicmd); |
| 1911 | 1982 | ||
| 1912 | case SYNCHRONIZE_CACHE: | 1983 | case SYNCHRONIZE_CACHE: |
| 1913 | /* Issue FIB to tell Firmware to flush it's cache */ | 1984 | /* Issue FIB to tell Firmware to flush it's cache */ |
| 1914 | return aac_synchronize(scsicmd, cid); | 1985 | return aac_synchronize(scsicmd); |
| 1915 | 1986 | ||
| 1916 | default: | 1987 | default: |
| 1917 | /* | 1988 | /* |
| @@ -2058,7 +2129,10 @@ static void aac_srb_callback(void *context, struct fib * fibptr) | |||
| 2058 | struct scsi_cmnd *scsicmd; | 2129 | struct scsi_cmnd *scsicmd; |
| 2059 | 2130 | ||
| 2060 | scsicmd = (struct scsi_cmnd *) context; | 2131 | scsicmd = (struct scsi_cmnd *) context; |
| 2061 | scsicmd->SCp.phase = AAC_OWNER_MIDLEVEL; | 2132 | |
| 2133 | if (!aac_valid_context(scsicmd, fibptr)) | ||
| 2134 | return; | ||
| 2135 | |||
| 2062 | dev = (struct aac_dev *)scsicmd->device->host->hostdata; | 2136 | dev = (struct aac_dev *)scsicmd->device->host->hostdata; |
| 2063 | 2137 | ||
| 2064 | BUG_ON(fibptr == NULL); | 2138 | BUG_ON(fibptr == NULL); |
diff --git a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h index 39ecd0d22eb0..45ca3e801619 100644 --- a/drivers/scsi/aacraid/aacraid.h +++ b/drivers/scsi/aacraid/aacraid.h | |||
| @@ -12,8 +12,8 @@ | |||
| 12 | *----------------------------------------------------------------------------*/ | 12 | *----------------------------------------------------------------------------*/ |
| 13 | 13 | ||
| 14 | #ifndef AAC_DRIVER_BUILD | 14 | #ifndef AAC_DRIVER_BUILD |
| 15 | # define AAC_DRIVER_BUILD 2423 | 15 | # define AAC_DRIVER_BUILD 2437 |
| 16 | # define AAC_DRIVER_BRANCH "-mh3" | 16 | # define AAC_DRIVER_BRANCH "-mh4" |
| 17 | #endif | 17 | #endif |
| 18 | #define MAXIMUM_NUM_CONTAINERS 32 | 18 | #define MAXIMUM_NUM_CONTAINERS 32 |
| 19 | 19 | ||
| @@ -48,49 +48,13 @@ struct diskparm | |||
| 48 | 48 | ||
| 49 | 49 | ||
| 50 | /* | 50 | /* |
| 51 | * DON'T CHANGE THE ORDER, this is set by the firmware | 51 | * Firmware constants |
| 52 | */ | 52 | */ |
| 53 | 53 | ||
| 54 | #define CT_NONE 0 | 54 | #define CT_NONE 0 |
| 55 | #define CT_VOLUME 1 | ||
| 56 | #define CT_MIRROR 2 | ||
| 57 | #define CT_STRIPE 3 | ||
| 58 | #define CT_RAID5 4 | ||
| 59 | #define CT_SSRW 5 | ||
| 60 | #define CT_SSRO 6 | ||
| 61 | #define CT_MORPH 7 | ||
| 62 | #define CT_PASSTHRU 8 | ||
| 63 | #define CT_RAID4 9 | ||
| 64 | #define CT_RAID10 10 /* stripe of mirror */ | ||
| 65 | #define CT_RAID00 11 /* stripe of stripe */ | ||
| 66 | #define CT_VOLUME_OF_MIRRORS 12 /* volume of mirror */ | ||
| 67 | #define CT_PSEUDO_RAID 13 /* really raid4 */ | ||
| 68 | #define CT_LAST_VOLUME_TYPE 14 | ||
| 69 | #define CT_OK 218 | 55 | #define CT_OK 218 |
| 70 | |||
| 71 | /* | ||
| 72 | * Types of objects addressable in some fashion by the client. | ||
| 73 | * This is a superset of those objects handled just by the filesystem | ||
| 74 | * and includes "raw" objects that an administrator would use to | ||
| 75 | * configure containers and filesystems. | ||
| 76 | */ | ||
| 77 | |||
| 78 | #define FT_REG 1 /* regular file */ | ||
| 79 | #define FT_DIR 2 /* directory */ | ||
| 80 | #define FT_BLK 3 /* "block" device - reserved */ | ||
| 81 | #define FT_CHR 4 /* "character special" device - reserved */ | ||
| 82 | #define FT_LNK 5 /* symbolic link */ | ||
| 83 | #define FT_SOCK 6 /* socket */ | ||
| 84 | #define FT_FIFO 7 /* fifo */ | ||
| 85 | #define FT_FILESYS 8 /* ADAPTEC's "FSA"(tm) filesystem */ | 56 | #define FT_FILESYS 8 /* ADAPTEC's "FSA"(tm) filesystem */ |
| 86 | #define FT_DRIVE 9 /* physical disk - addressable in scsi by bus/id/lun */ | 57 | #define FT_DRIVE 9 /* physical disk - addressable in scsi by bus/id/lun */ |
| 87 | #define FT_SLICE 10 /* virtual disk - raw volume - slice */ | ||
| 88 | #define FT_PARTITION 11 /* FSA partition - carved out of a slice - building block for containers */ | ||
| 89 | #define FT_VOLUME 12 /* Container - Volume Set */ | ||
| 90 | #define FT_STRIPE 13 /* Container - Stripe Set */ | ||
| 91 | #define FT_MIRROR 14 /* Container - Mirror Set */ | ||
| 92 | #define FT_RAID5 15 /* Container - Raid 5 Set */ | ||
| 93 | #define FT_DATABASE 16 /* Storage object with "foreign" content manager */ | ||
| 94 | 58 | ||
| 95 | /* | 59 | /* |
| 96 | * Host side memory scatter gather list | 60 | * Host side memory scatter gather list |
| @@ -497,6 +461,7 @@ struct adapter_ops | |||
| 497 | void (*adapter_enable_int)(struct aac_dev *dev); | 461 | void (*adapter_enable_int)(struct aac_dev *dev); |
| 498 | int (*adapter_sync_cmd)(struct aac_dev *dev, u32 command, u32 p1, u32 p2, u32 p3, u32 p4, u32 p5, u32 p6, u32 *status, u32 *r1, u32 *r2, u32 *r3, u32 *r4); | 462 | int (*adapter_sync_cmd)(struct aac_dev *dev, u32 command, u32 p1, u32 p2, u32 p3, u32 p4, u32 p5, u32 p6, u32 *status, u32 *r1, u32 *r2, u32 *r3, u32 *r4); |
| 499 | int (*adapter_check_health)(struct aac_dev *dev); | 463 | int (*adapter_check_health)(struct aac_dev *dev); |
| 464 | int (*adapter_restart)(struct aac_dev *dev, int bled); | ||
| 500 | /* Transport operations */ | 465 | /* Transport operations */ |
| 501 | int (*adapter_ioremap)(struct aac_dev * dev, u32 size); | 466 | int (*adapter_ioremap)(struct aac_dev * dev, u32 size); |
| 502 | irqreturn_t (*adapter_intr)(int irq, void *dev_id); | 467 | irqreturn_t (*adapter_intr)(int irq, void *dev_id); |
| @@ -833,7 +798,7 @@ struct fib { | |||
| 833 | */ | 798 | */ |
| 834 | struct list_head fiblink; | 799 | struct list_head fiblink; |
| 835 | void *data; | 800 | void *data; |
| 836 | struct hw_fib *hw_fib; /* Actual shared object */ | 801 | struct hw_fib *hw_fib_va; /* Actual shared object */ |
| 837 | dma_addr_t hw_fib_pa; /* physical address of hw_fib*/ | 802 | dma_addr_t hw_fib_pa; /* physical address of hw_fib*/ |
| 838 | }; | 803 | }; |
| 839 | 804 | ||
| @@ -878,10 +843,25 @@ struct aac_supplement_adapter_info | |||
| 878 | __le32 Version; | 843 | __le32 Version; |
| 879 | __le32 FeatureBits; | 844 | __le32 FeatureBits; |
| 880 | u8 SlotNumber; | 845 | u8 SlotNumber; |
| 881 | u8 ReservedPad0[0]; | 846 | u8 ReservedPad0[3]; |
| 882 | u8 BuildDate[12]; | 847 | u8 BuildDate[12]; |
| 883 | __le32 CurrentNumberPorts; | 848 | __le32 CurrentNumberPorts; |
| 884 | __le32 ReservedGrowth[24]; | 849 | struct { |
| 850 | u8 AssemblyPn[8]; | ||
| 851 | u8 FruPn[8]; | ||
| 852 | u8 BatteryFruPn[8]; | ||
| 853 | u8 EcVersionString[8]; | ||
| 854 | u8 Tsid[12]; | ||
| 855 | } VpdInfo; | ||
| 856 | __le32 FlashFirmwareRevision; | ||
| 857 | __le32 FlashFirmwareBuild; | ||
| 858 | __le32 RaidTypeMorphOptions; | ||
| 859 | __le32 FlashFirmwareBootRevision; | ||
| 860 | __le32 FlashFirmwareBootBuild; | ||
| 861 | u8 MfgPcbaSerialNo[12]; | ||
| 862 | u8 MfgWWNName[8]; | ||
| 863 | __le32 MoreFeatureBits; | ||
| 864 | __le32 ReservedGrowth[1]; | ||
| 885 | }; | 865 | }; |
| 886 | #define AAC_FEATURE_FALCON 0x00000010 | 866 | #define AAC_FEATURE_FALCON 0x00000010 |
| 887 | #define AAC_SIS_VERSION_V3 3 | 867 | #define AAC_SIS_VERSION_V3 3 |
| @@ -970,7 +950,6 @@ struct aac_dev | |||
| 970 | struct fib *fibs; | 950 | struct fib *fibs; |
| 971 | 951 | ||
| 972 | struct fib *free_fib; | 952 | struct fib *free_fib; |
| 973 | struct fib *timeout_fib; | ||
| 974 | spinlock_t fib_lock; | 953 | spinlock_t fib_lock; |
| 975 | 954 | ||
| 976 | struct aac_queue_block *queues; | 955 | struct aac_queue_block *queues; |
| @@ -1060,6 +1039,9 @@ struct aac_dev | |||
| 1060 | #define aac_adapter_check_health(dev) \ | 1039 | #define aac_adapter_check_health(dev) \ |
| 1061 | (dev)->a_ops.adapter_check_health(dev) | 1040 | (dev)->a_ops.adapter_check_health(dev) |
| 1062 | 1041 | ||
| 1042 | #define aac_adapter_restart(dev,bled) \ | ||
| 1043 | (dev)->a_ops.adapter_restart(dev,bled) | ||
| 1044 | |||
| 1063 | #define aac_adapter_ioremap(dev, size) \ | 1045 | #define aac_adapter_ioremap(dev, size) \ |
| 1064 | (dev)->a_ops.adapter_ioremap(dev, size) | 1046 | (dev)->a_ops.adapter_ioremap(dev, size) |
| 1065 | 1047 | ||
| @@ -1516,8 +1498,7 @@ struct aac_mntent { | |||
| 1516 | struct creation_info create_info; /* if applicable */ | 1498 | struct creation_info create_info; /* if applicable */ |
| 1517 | __le32 capacity; | 1499 | __le32 capacity; |
| 1518 | __le32 vol; /* substrate structure */ | 1500 | __le32 vol; /* substrate structure */ |
| 1519 | __le32 obj; /* FT_FILESYS, | 1501 | __le32 obj; /* FT_FILESYS, etc. */ |
| 1520 | FT_DATABASE, etc. */ | ||
| 1521 | __le32 state; /* unready for mounting, | 1502 | __le32 state; /* unready for mounting, |
| 1522 | readonly, etc. */ | 1503 | readonly, etc. */ |
| 1523 | union aac_contentinfo fileinfo; /* Info specific to content | 1504 | union aac_contentinfo fileinfo; /* Info specific to content |
| @@ -1817,7 +1798,7 @@ int aac_fib_send(u16 command, struct fib * context, unsigned long size, int prio | |||
| 1817 | int aac_consumer_get(struct aac_dev * dev, struct aac_queue * q, struct aac_entry **entry); | 1798 | int aac_consumer_get(struct aac_dev * dev, struct aac_queue * q, struct aac_entry **entry); |
| 1818 | void aac_consumer_free(struct aac_dev * dev, struct aac_queue * q, u32 qnum); | 1799 | void aac_consumer_free(struct aac_dev * dev, struct aac_queue * q, u32 qnum); |
| 1819 | int aac_fib_complete(struct fib * context); | 1800 | int aac_fib_complete(struct fib * context); |
| 1820 | #define fib_data(fibctx) ((void *)(fibctx)->hw_fib->data) | 1801 | #define fib_data(fibctx) ((void *)(fibctx)->hw_fib_va->data) |
| 1821 | struct aac_dev *aac_init_adapter(struct aac_dev *dev); | 1802 | struct aac_dev *aac_init_adapter(struct aac_dev *dev); |
| 1822 | int aac_get_config_status(struct aac_dev *dev, int commit_flag); | 1803 | int aac_get_config_status(struct aac_dev *dev, int commit_flag); |
| 1823 | int aac_get_containers(struct aac_dev *dev); | 1804 | int aac_get_containers(struct aac_dev *dev); |
| @@ -1840,8 +1821,11 @@ struct aac_driver_ident* aac_get_driver_ident(int devtype); | |||
| 1840 | int aac_get_adapter_info(struct aac_dev* dev); | 1821 | int aac_get_adapter_info(struct aac_dev* dev); |
| 1841 | int aac_send_shutdown(struct aac_dev *dev); | 1822 | int aac_send_shutdown(struct aac_dev *dev); |
| 1842 | int aac_probe_container(struct aac_dev *dev, int cid); | 1823 | int aac_probe_container(struct aac_dev *dev, int cid); |
| 1824 | int _aac_rx_init(struct aac_dev *dev); | ||
| 1825 | int aac_rx_select_comm(struct aac_dev *dev, int comm); | ||
| 1843 | extern int numacb; | 1826 | extern int numacb; |
| 1844 | extern int acbsize; | 1827 | extern int acbsize; |
| 1845 | extern char aac_driver_version[]; | 1828 | extern char aac_driver_version[]; |
| 1846 | extern int startup_timeout; | 1829 | extern int startup_timeout; |
| 1847 | extern int aif_timeout; | 1830 | extern int aif_timeout; |
| 1831 | extern int expose_physicals; | ||
diff --git a/drivers/scsi/aacraid/commctrl.c b/drivers/scsi/aacraid/commctrl.c index e21070f4eac1..72b0393b4596 100644 --- a/drivers/scsi/aacraid/commctrl.c +++ b/drivers/scsi/aacraid/commctrl.c | |||
| @@ -5,7 +5,7 @@ | |||
| 5 | * based on the old aacraid driver that is.. | 5 | * based on the old aacraid driver that is.. |
| 6 | * Adaptec aacraid device driver for Linux. | 6 | * Adaptec aacraid device driver for Linux. |
| 7 | * | 7 | * |
| 8 | * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com) | 8 | * Copyright (c) 2000-2007 Adaptec, Inc. (aacraid@adaptec.com) |
| 9 | * | 9 | * |
| 10 | * This program is free software; you can redistribute it and/or modify | 10 | * This program is free software; you can redistribute it and/or modify |
| 11 | * it under the terms of the GNU General Public License as published by | 11 | * it under the terms of the GNU General Public License as published by |
| @@ -64,12 +64,15 @@ static int ioctl_send_fib(struct aac_dev * dev, void __user *arg) | |||
| 64 | unsigned size; | 64 | unsigned size; |
| 65 | int retval; | 65 | int retval; |
| 66 | 66 | ||
| 67 | if (dev->in_reset) { | ||
| 68 | return -EBUSY; | ||
| 69 | } | ||
| 67 | fibptr = aac_fib_alloc(dev); | 70 | fibptr = aac_fib_alloc(dev); |
| 68 | if(fibptr == NULL) { | 71 | if(fibptr == NULL) { |
| 69 | return -ENOMEM; | 72 | return -ENOMEM; |
| 70 | } | 73 | } |
| 71 | 74 | ||
| 72 | kfib = fibptr->hw_fib; | 75 | kfib = fibptr->hw_fib_va; |
| 73 | /* | 76 | /* |
| 74 | * First copy in the header so that we can check the size field. | 77 | * First copy in the header so that we can check the size field. |
| 75 | */ | 78 | */ |
| @@ -91,9 +94,9 @@ static int ioctl_send_fib(struct aac_dev * dev, void __user *arg) | |||
| 91 | goto cleanup; | 94 | goto cleanup; |
| 92 | } | 95 | } |
| 93 | /* Highjack the hw_fib */ | 96 | /* Highjack the hw_fib */ |
| 94 | hw_fib = fibptr->hw_fib; | 97 | hw_fib = fibptr->hw_fib_va; |
| 95 | hw_fib_pa = fibptr->hw_fib_pa; | 98 | hw_fib_pa = fibptr->hw_fib_pa; |
| 96 | fibptr->hw_fib = kfib = pci_alloc_consistent(dev->pdev, size, &fibptr->hw_fib_pa); | 99 | fibptr->hw_fib_va = kfib = pci_alloc_consistent(dev->pdev, size, &fibptr->hw_fib_pa); |
| 97 | memset(((char *)kfib) + dev->max_fib_size, 0, size - dev->max_fib_size); | 100 | memset(((char *)kfib) + dev->max_fib_size, 0, size - dev->max_fib_size); |
| 98 | memcpy(kfib, hw_fib, dev->max_fib_size); | 101 | memcpy(kfib, hw_fib, dev->max_fib_size); |
| 99 | } | 102 | } |
| @@ -137,7 +140,7 @@ cleanup: | |||
| 137 | if (hw_fib) { | 140 | if (hw_fib) { |
| 138 | pci_free_consistent(dev->pdev, size, kfib, fibptr->hw_fib_pa); | 141 | pci_free_consistent(dev->pdev, size, kfib, fibptr->hw_fib_pa); |
| 139 | fibptr->hw_fib_pa = hw_fib_pa; | 142 | fibptr->hw_fib_pa = hw_fib_pa; |
| 140 | fibptr->hw_fib = hw_fib; | 143 | fibptr->hw_fib_va = hw_fib; |
| 141 | } | 144 | } |
| 142 | if (retval != -EINTR) | 145 | if (retval != -EINTR) |
| 143 | aac_fib_free(fibptr); | 146 | aac_fib_free(fibptr); |
| @@ -282,15 +285,15 @@ return_fib: | |||
| 282 | fib = list_entry(entry, struct fib, fiblink); | 285 | fib = list_entry(entry, struct fib, fiblink); |
| 283 | fibctx->count--; | 286 | fibctx->count--; |
| 284 | spin_unlock_irqrestore(&dev->fib_lock, flags); | 287 | spin_unlock_irqrestore(&dev->fib_lock, flags); |
| 285 | if (copy_to_user(f.fib, fib->hw_fib, sizeof(struct hw_fib))) { | 288 | if (copy_to_user(f.fib, fib->hw_fib_va, sizeof(struct hw_fib))) { |
| 286 | kfree(fib->hw_fib); | 289 | kfree(fib->hw_fib_va); |
| 287 | kfree(fib); | 290 | kfree(fib); |
| 288 | return -EFAULT; | 291 | return -EFAULT; |
| 289 | } | 292 | } |
| 290 | /* | 293 | /* |
| 291 | * Free the space occupied by this copy of the fib. | 294 | * Free the space occupied by this copy of the fib. |
| 292 | */ | 295 | */ |
| 293 | kfree(fib->hw_fib); | 296 | kfree(fib->hw_fib_va); |
| 294 | kfree(fib); | 297 | kfree(fib); |
| 295 | status = 0; | 298 | status = 0; |
| 296 | } else { | 299 | } else { |
| @@ -340,7 +343,7 @@ int aac_close_fib_context(struct aac_dev * dev, struct aac_fib_context * fibctx) | |||
| 340 | /* | 343 | /* |
| 341 | * Free the space occupied by this copy of the fib. | 344 | * Free the space occupied by this copy of the fib. |
| 342 | */ | 345 | */ |
| 343 | kfree(fib->hw_fib); | 346 | kfree(fib->hw_fib_va); |
| 344 | kfree(fib); | 347 | kfree(fib); |
| 345 | } | 348 | } |
| 346 | /* | 349 | /* |
| @@ -388,10 +391,8 @@ static int close_getadapter_fib(struct aac_dev * dev, void __user *arg) | |||
| 388 | /* | 391 | /* |
| 389 | * Extract the fibctx from the input parameters | 392 | * Extract the fibctx from the input parameters |
| 390 | */ | 393 | */ |
| 391 | if (fibctx->unique == (u32)(unsigned long)arg) { | 394 | if (fibctx->unique == (u32)(ptrdiff_t)arg) /* We found a winner */ |
| 392 | /* We found a winner */ | ||
| 393 | break; | 395 | break; |
| 394 | } | ||
| 395 | entry = entry->next; | 396 | entry = entry->next; |
| 396 | fibctx = NULL; | 397 | fibctx = NULL; |
| 397 | } | 398 | } |
| @@ -465,16 +466,20 @@ static int aac_send_raw_srb(struct aac_dev* dev, void __user * arg) | |||
| 465 | void *sg_list[32]; | 466 | void *sg_list[32]; |
| 466 | u32 sg_indx = 0; | 467 | u32 sg_indx = 0; |
| 467 | u32 byte_count = 0; | 468 | u32 byte_count = 0; |
| 468 | u32 actual_fibsize = 0; | 469 | u32 actual_fibsize64, actual_fibsize = 0; |
| 469 | int i; | 470 | int i; |
| 470 | 471 | ||
| 471 | 472 | ||
| 473 | if (dev->in_reset) { | ||
| 474 | dprintk((KERN_DEBUG"aacraid: send raw srb -EBUSY\n")); | ||
| 475 | return -EBUSY; | ||
| 476 | } | ||
| 472 | if (!capable(CAP_SYS_ADMIN)){ | 477 | if (!capable(CAP_SYS_ADMIN)){ |
| 473 | dprintk((KERN_DEBUG"aacraid: No permission to send raw srb\n")); | 478 | dprintk((KERN_DEBUG"aacraid: No permission to send raw srb\n")); |
| 474 | return -EPERM; | 479 | return -EPERM; |
| 475 | } | 480 | } |
| 476 | /* | 481 | /* |
| 477 | * Allocate and initialize a Fib then setup a BlockWrite command | 482 | * Allocate and initialize a Fib then setup a SRB command |
| 478 | */ | 483 | */ |
| 479 | if (!(srbfib = aac_fib_alloc(dev))) { | 484 | if (!(srbfib = aac_fib_alloc(dev))) { |
| 480 | return -ENOMEM; | 485 | return -ENOMEM; |
| @@ -541,129 +546,183 @@ static int aac_send_raw_srb(struct aac_dev* dev, void __user * arg) | |||
| 541 | rcode = -EINVAL; | 546 | rcode = -EINVAL; |
| 542 | goto cleanup; | 547 | goto cleanup; |
| 543 | } | 548 | } |
| 544 | if (dev->dac_support == 1) { | 549 | actual_fibsize = sizeof(struct aac_srb) - sizeof(struct sgentry) + |
| 550 | ((user_srbcmd->sg.count & 0xff) * sizeof(struct sgentry)); | ||
| 551 | actual_fibsize64 = actual_fibsize + (user_srbcmd->sg.count & 0xff) * | ||
| 552 | (sizeof(struct sgentry64) - sizeof(struct sgentry)); | ||
| 553 | /* User made a mistake - should not continue */ | ||
| 554 | if ((actual_fibsize != fibsize) && (actual_fibsize64 != fibsize)) { | ||
| 555 | dprintk((KERN_DEBUG"aacraid: Bad Size specified in " | ||
| 556 | "Raw SRB command calculated fibsize=%lu;%lu " | ||
| 557 | "user_srbcmd->sg.count=%d aac_srb=%lu sgentry=%lu;%lu " | ||
| 558 | "issued fibsize=%d\n", | ||
| 559 | actual_fibsize, actual_fibsize64, user_srbcmd->sg.count, | ||
| 560 | sizeof(struct aac_srb), sizeof(struct sgentry), | ||
| 561 | sizeof(struct sgentry64), fibsize)); | ||
| 562 | rcode = -EINVAL; | ||
| 563 | goto cleanup; | ||
| 564 | } | ||
| 565 | if ((data_dir == DMA_NONE) && user_srbcmd->sg.count) { | ||
| 566 | dprintk((KERN_DEBUG"aacraid: SG with no direction specified in Raw SRB command\n")); | ||
| 567 | rcode = -EINVAL; | ||
| 568 | goto cleanup; | ||
| 569 | } | ||
| 570 | byte_count = 0; | ||
| 571 | if (dev->adapter_info.options & AAC_OPT_SGMAP_HOST64) { | ||
| 545 | struct user_sgmap64* upsg = (struct user_sgmap64*)&user_srbcmd->sg; | 572 | struct user_sgmap64* upsg = (struct user_sgmap64*)&user_srbcmd->sg; |
| 546 | struct sgmap64* psg = (struct sgmap64*)&srbcmd->sg; | 573 | struct sgmap64* psg = (struct sgmap64*)&srbcmd->sg; |
| 547 | struct user_sgmap* usg; | ||
| 548 | byte_count = 0; | ||
| 549 | 574 | ||
| 550 | /* | 575 | /* |
| 551 | * This should also catch if user used the 32 bit sgmap | 576 | * This should also catch if user used the 32 bit sgmap |
| 552 | */ | 577 | */ |
| 553 | actual_fibsize = sizeof(struct aac_srb) - | 578 | if (actual_fibsize64 == fibsize) { |
| 554 | sizeof(struct sgentry) + | 579 | actual_fibsize = actual_fibsize64; |
| 555 | ((upsg->count & 0xff) * | 580 | for (i = 0; i < upsg->count; i++) { |
| 556 | sizeof(struct sgentry)); | 581 | u64 addr; |
| 557 | if(actual_fibsize != fibsize){ // User made a mistake - should not continue | 582 | void* p; |
| 558 | dprintk((KERN_DEBUG"aacraid: Bad Size specified in Raw SRB command\n")); | 583 | /* Does this really need to be GFP_DMA? */ |
| 559 | rcode = -EINVAL; | 584 | p = kmalloc(upsg->sg[i].count,GFP_KERNEL|__GFP_DMA); |
| 560 | goto cleanup; | 585 | if(p == 0) { |
| 561 | } | 586 | dprintk((KERN_DEBUG"aacraid: Could not allocate SG buffer - size = %d buffer number %d of %d\n", |
| 562 | usg = kmalloc(actual_fibsize - sizeof(struct aac_srb) | 587 | upsg->sg[i].count,i,upsg->count)); |
| 563 | + sizeof(struct sgmap), GFP_KERNEL); | 588 | rcode = -ENOMEM; |
| 564 | if (!usg) { | 589 | goto cleanup; |
| 565 | dprintk((KERN_DEBUG"aacraid: Allocation error in Raw SRB command\n")); | 590 | } |
| 566 | rcode = -ENOMEM; | 591 | addr = (u64)upsg->sg[i].addr[0]; |
| 567 | goto cleanup; | 592 | addr += ((u64)upsg->sg[i].addr[1]) << 32; |
| 568 | } | 593 | sg_user[i] = (void __user *)(ptrdiff_t)addr; |
| 569 | memcpy (usg, upsg, actual_fibsize - sizeof(struct aac_srb) | 594 | sg_list[i] = p; // save so we can clean up later |
| 570 | + sizeof(struct sgmap)); | 595 | sg_indx = i; |
| 571 | actual_fibsize = sizeof(struct aac_srb) - | 596 | |
| 572 | sizeof(struct sgentry) + ((usg->count & 0xff) * | 597 | if( flags & SRB_DataOut ){ |
| 573 | sizeof(struct sgentry64)); | 598 | if(copy_from_user(p,sg_user[i],upsg->sg[i].count)){ |
| 574 | if ((data_dir == DMA_NONE) && upsg->count) { | 599 | dprintk((KERN_DEBUG"aacraid: Could not copy sg data from user\n")); |
| 575 | kfree (usg); | 600 | rcode = -EFAULT; |
| 576 | dprintk((KERN_DEBUG"aacraid: SG with no direction specified in Raw SRB command\n")); | 601 | goto cleanup; |
| 577 | rcode = -EINVAL; | 602 | } |
| 578 | goto cleanup; | 603 | } |
| 579 | } | 604 | addr = pci_map_single(dev->pdev, p, upsg->sg[i].count, data_dir); |
| 580 | 605 | ||
| 581 | for (i = 0; i < usg->count; i++) { | 606 | psg->sg[i].addr[0] = cpu_to_le32(addr & 0xffffffff); |
| 582 | u64 addr; | 607 | psg->sg[i].addr[1] = cpu_to_le32(addr>>32); |
| 583 | void* p; | 608 | byte_count += upsg->sg[i].count; |
| 584 | /* Does this really need to be GFP_DMA? */ | 609 | psg->sg[i].count = cpu_to_le32(upsg->sg[i].count); |
| 585 | p = kmalloc(usg->sg[i].count,GFP_KERNEL|__GFP_DMA); | 610 | } |
| 586 | if(p == 0) { | 611 | } else { |
| 587 | kfree (usg); | 612 | struct user_sgmap* usg; |
| 588 | dprintk((KERN_DEBUG"aacraid: Could not allocate SG buffer - size = %d buffer number %d of %d\n", | 613 | usg = kmalloc(actual_fibsize - sizeof(struct aac_srb) |
| 589 | usg->sg[i].count,i,usg->count)); | 614 | + sizeof(struct sgmap), GFP_KERNEL); |
| 615 | if (!usg) { | ||
| 616 | dprintk((KERN_DEBUG"aacraid: Allocation error in Raw SRB command\n")); | ||
| 590 | rcode = -ENOMEM; | 617 | rcode = -ENOMEM; |
| 591 | goto cleanup; | 618 | goto cleanup; |
| 592 | } | 619 | } |
| 593 | sg_user[i] = (void __user *)(long)usg->sg[i].addr; | 620 | memcpy (usg, upsg, actual_fibsize - sizeof(struct aac_srb) |
| 594 | sg_list[i] = p; // save so we can clean up later | 621 | + sizeof(struct sgmap)); |
| 595 | sg_indx = i; | 622 | actual_fibsize = actual_fibsize64; |
| 596 | 623 | ||
| 597 | if( flags & SRB_DataOut ){ | 624 | for (i = 0; i < usg->count; i++) { |
| 598 | if(copy_from_user(p,sg_user[i],upsg->sg[i].count)){ | 625 | u64 addr; |
| 626 | void* p; | ||
| 627 | /* Does this really need to be GFP_DMA? */ | ||
| 628 | p = kmalloc(usg->sg[i].count,GFP_KERNEL|__GFP_DMA); | ||
| 629 | if(p == 0) { | ||
| 599 | kfree (usg); | 630 | kfree (usg); |
| 600 | dprintk((KERN_DEBUG"aacraid: Could not copy sg data from user\n")); | 631 | dprintk((KERN_DEBUG"aacraid: Could not allocate SG buffer - size = %d buffer number %d of %d\n", |
| 601 | rcode = -EFAULT; | 632 | usg->sg[i].count,i,usg->count)); |
| 633 | rcode = -ENOMEM; | ||
| 602 | goto cleanup; | 634 | goto cleanup; |
| 603 | } | 635 | } |
| 604 | } | 636 | sg_user[i] = (void __user *)(ptrdiff_t)usg->sg[i].addr; |
| 605 | addr = pci_map_single(dev->pdev, p, usg->sg[i].count, data_dir); | 637 | sg_list[i] = p; // save so we can clean up later |
| 638 | sg_indx = i; | ||
| 639 | |||
| 640 | if( flags & SRB_DataOut ){ | ||
| 641 | if(copy_from_user(p,sg_user[i],upsg->sg[i].count)){ | ||
| 642 | kfree (usg); | ||
| 643 | dprintk((KERN_DEBUG"aacraid: Could not copy sg data from user\n")); | ||
| 644 | rcode = -EFAULT; | ||
| 645 | goto cleanup; | ||
| 646 | } | ||
| 647 | } | ||
| 648 | addr = pci_map_single(dev->pdev, p, usg->sg[i].count, data_dir); | ||
| 606 | 649 | ||
| 607 | psg->sg[i].addr[0] = cpu_to_le32(addr & 0xffffffff); | 650 | psg->sg[i].addr[0] = cpu_to_le32(addr & 0xffffffff); |
| 608 | psg->sg[i].addr[1] = cpu_to_le32(addr>>32); | 651 | psg->sg[i].addr[1] = cpu_to_le32(addr>>32); |
| 609 | psg->sg[i].count = cpu_to_le32(usg->sg[i].count); | 652 | byte_count += usg->sg[i].count; |
| 610 | byte_count += usg->sg[i].count; | 653 | psg->sg[i].count = cpu_to_le32(usg->sg[i].count); |
| 654 | } | ||
| 655 | kfree (usg); | ||
| 611 | } | 656 | } |
| 612 | kfree (usg); | ||
| 613 | |||
| 614 | srbcmd->count = cpu_to_le32(byte_count); | 657 | srbcmd->count = cpu_to_le32(byte_count); |
| 615 | psg->count = cpu_to_le32(sg_indx+1); | 658 | psg->count = cpu_to_le32(sg_indx+1); |
| 616 | status = aac_fib_send(ScsiPortCommand64, srbfib, actual_fibsize, FsaNormal, 1, 1,NULL,NULL); | 659 | status = aac_fib_send(ScsiPortCommand64, srbfib, actual_fibsize, FsaNormal, 1, 1,NULL,NULL); |
| 617 | } else { | 660 | } else { |
| 618 | struct user_sgmap* upsg = &user_srbcmd->sg; | 661 | struct user_sgmap* upsg = &user_srbcmd->sg; |
| 619 | struct sgmap* psg = &srbcmd->sg; | 662 | struct sgmap* psg = &srbcmd->sg; |
| 620 | byte_count = 0; | 663 | |
| 621 | 664 | if (actual_fibsize64 == fibsize) { | |
| 622 | actual_fibsize = sizeof (struct aac_srb) + (((user_srbcmd->sg.count & 0xff) - 1) * sizeof (struct sgentry)); | 665 | struct user_sgmap64* usg = (struct user_sgmap64 *)upsg; |
| 623 | if(actual_fibsize != fibsize){ // User made a mistake - should not continue | 666 | for (i = 0; i < upsg->count; i++) { |
| 624 | dprintk((KERN_DEBUG"aacraid: Bad Size specified in " | 667 | u64 addr; |
| 625 | "Raw SRB command calculated fibsize=%d " | 668 | void* p; |
| 626 | "user_srbcmd->sg.count=%d aac_srb=%d sgentry=%d " | 669 | /* Does this really need to be GFP_DMA? */ |
| 627 | "issued fibsize=%d\n", | 670 | p = kmalloc(usg->sg[i].count,GFP_KERNEL|__GFP_DMA); |
| 628 | actual_fibsize, user_srbcmd->sg.count, | 671 | if(p == 0) { |
| 629 | sizeof(struct aac_srb), sizeof(struct sgentry), | 672 | dprintk((KERN_DEBUG"aacraid: Could not allocate SG buffer - size = %d buffer number %d of %d\n", |
| 630 | fibsize)); | 673 | usg->sg[i].count,i,usg->count)); |
| 631 | rcode = -EINVAL; | 674 | rcode = -ENOMEM; |
| 632 | goto cleanup; | ||
| 633 | } | ||
| 634 | if ((data_dir == DMA_NONE) && upsg->count) { | ||
| 635 | dprintk((KERN_DEBUG"aacraid: SG with no direction specified in Raw SRB command\n")); | ||
| 636 | rcode = -EINVAL; | ||
| 637 | goto cleanup; | ||
| 638 | } | ||
| 639 | for (i = 0; i < upsg->count; i++) { | ||
| 640 | dma_addr_t addr; | ||
| 641 | void* p; | ||
| 642 | p = kmalloc(upsg->sg[i].count, GFP_KERNEL); | ||
| 643 | if(p == 0) { | ||
| 644 | dprintk((KERN_DEBUG"aacraid: Could not allocate SG buffer - size = %d buffer number %d of %d\n", | ||
| 645 | upsg->sg[i].count, i, upsg->count)); | ||
| 646 | rcode = -ENOMEM; | ||
| 647 | goto cleanup; | ||
| 648 | } | ||
| 649 | sg_user[i] = (void __user *)(long)upsg->sg[i].addr; | ||
| 650 | sg_list[i] = p; // save so we can clean up later | ||
| 651 | sg_indx = i; | ||
| 652 | |||
| 653 | if( flags & SRB_DataOut ){ | ||
| 654 | if(copy_from_user(p, sg_user[i], | ||
| 655 | upsg->sg[i].count)) { | ||
| 656 | dprintk((KERN_DEBUG"aacraid: Could not copy sg data from user\n")); | ||
| 657 | rcode = -EFAULT; | ||
| 658 | goto cleanup; | 675 | goto cleanup; |
| 659 | } | 676 | } |
| 677 | addr = (u64)usg->sg[i].addr[0]; | ||
| 678 | addr += ((u64)usg->sg[i].addr[1]) << 32; | ||
| 679 | sg_user[i] = (void __user *)(ptrdiff_t)addr; | ||
| 680 | sg_list[i] = p; // save so we can clean up later | ||
| 681 | sg_indx = i; | ||
| 682 | |||
| 683 | if( flags & SRB_DataOut ){ | ||
| 684 | if(copy_from_user(p,sg_user[i],usg->sg[i].count)){ | ||
| 685 | dprintk((KERN_DEBUG"aacraid: Could not copy sg data from user\n")); | ||
| 686 | rcode = -EFAULT; | ||
| 687 | goto cleanup; | ||
| 688 | } | ||
| 689 | } | ||
| 690 | addr = pci_map_single(dev->pdev, p, usg->sg[i].count, data_dir); | ||
| 691 | |||
| 692 | psg->sg[i].addr = cpu_to_le32(addr & 0xffffffff); | ||
| 693 | byte_count += usg->sg[i].count; | ||
| 694 | psg->sg[i].count = cpu_to_le32(usg->sg[i].count); | ||
| 660 | } | 695 | } |
| 661 | addr = pci_map_single(dev->pdev, p, | 696 | } else { |
| 662 | upsg->sg[i].count, data_dir); | 697 | for (i = 0; i < upsg->count; i++) { |
| 698 | dma_addr_t addr; | ||
| 699 | void* p; | ||
| 700 | p = kmalloc(upsg->sg[i].count, GFP_KERNEL); | ||
| 701 | if(p == 0) { | ||
| 702 | dprintk((KERN_DEBUG"aacraid: Could not allocate SG buffer - size = %d buffer number %d of %d\n", | ||
| 703 | upsg->sg[i].count, i, upsg->count)); | ||
| 704 | rcode = -ENOMEM; | ||
| 705 | goto cleanup; | ||
| 706 | } | ||
| 707 | sg_user[i] = (void __user *)(ptrdiff_t)upsg->sg[i].addr; | ||
| 708 | sg_list[i] = p; // save so we can clean up later | ||
| 709 | sg_indx = i; | ||
| 710 | |||
| 711 | if( flags & SRB_DataOut ){ | ||
| 712 | if(copy_from_user(p, sg_user[i], | ||
| 713 | upsg->sg[i].count)) { | ||
| 714 | dprintk((KERN_DEBUG"aacraid: Could not copy sg data from user\n")); | ||
| 715 | rcode = -EFAULT; | ||
| 716 | goto cleanup; | ||
| 717 | } | ||
| 718 | } | ||
| 719 | addr = pci_map_single(dev->pdev, p, | ||
| 720 | upsg->sg[i].count, data_dir); | ||
| 663 | 721 | ||
| 664 | psg->sg[i].addr = cpu_to_le32(addr); | 722 | psg->sg[i].addr = cpu_to_le32(addr); |
| 665 | psg->sg[i].count = cpu_to_le32(upsg->sg[i].count); | 723 | byte_count += upsg->sg[i].count; |
| 666 | byte_count += upsg->sg[i].count; | 724 | psg->sg[i].count = cpu_to_le32(upsg->sg[i].count); |
| 725 | } | ||
| 667 | } | 726 | } |
| 668 | srbcmd->count = cpu_to_le32(byte_count); | 727 | srbcmd->count = cpu_to_le32(byte_count); |
| 669 | psg->count = cpu_to_le32(sg_indx+1); | 728 | psg->count = cpu_to_le32(sg_indx+1); |
| @@ -682,7 +741,8 @@ static int aac_send_raw_srb(struct aac_dev* dev, void __user * arg) | |||
| 682 | 741 | ||
| 683 | if( flags & SRB_DataIn ) { | 742 | if( flags & SRB_DataIn ) { |
| 684 | for(i = 0 ; i <= sg_indx; i++){ | 743 | for(i = 0 ; i <= sg_indx; i++){ |
| 685 | byte_count = le32_to_cpu((dev->dac_support == 1) | 744 | byte_count = le32_to_cpu( |
| 745 | (dev->adapter_info.options & AAC_OPT_SGMAP_HOST64) | ||
| 686 | ? ((struct sgmap64*)&srbcmd->sg)->sg[i].count | 746 | ? ((struct sgmap64*)&srbcmd->sg)->sg[i].count |
| 687 | : srbcmd->sg.sg[i].count); | 747 | : srbcmd->sg.sg[i].count); |
| 688 | if(copy_to_user(sg_user[i], sg_list[i], byte_count)){ | 748 | if(copy_to_user(sg_user[i], sg_list[i], byte_count)){ |
diff --git a/drivers/scsi/aacraid/comminit.c b/drivers/scsi/aacraid/comminit.c index ae34768987a4..33682ce96a5d 100644 --- a/drivers/scsi/aacraid/comminit.c +++ b/drivers/scsi/aacraid/comminit.c | |||
| @@ -5,7 +5,7 @@ | |||
| 5 | * based on the old aacraid driver that is.. | 5 | * based on the old aacraid driver that is.. |
| 6 | * Adaptec aacraid device driver for Linux. | 6 | * Adaptec aacraid device driver for Linux. |
| 7 | * | 7 | * |
| 8 | * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com) | 8 | * Copyright (c) 2000-2007 Adaptec, Inc. (aacraid@adaptec.com) |
| 9 | * | 9 | * |
| 10 | * This program is free software; you can redistribute it and/or modify | 10 | * This program is free software; you can redistribute it and/or modify |
| 11 | * it under the terms of the GNU General Public License as published by | 11 | * it under the terms of the GNU General Public License as published by |
| @@ -110,7 +110,7 @@ static int aac_alloc_comm(struct aac_dev *dev, void **commaddr, unsigned long co | |||
| 110 | /* | 110 | /* |
| 111 | * Align the beginning of Headers to commalign | 111 | * Align the beginning of Headers to commalign |
| 112 | */ | 112 | */ |
| 113 | align = (commalign - ((unsigned long)(base) & (commalign - 1))); | 113 | align = (commalign - ((ptrdiff_t)(base) & (commalign - 1))); |
| 114 | base = base + align; | 114 | base = base + align; |
| 115 | phys = phys + align; | 115 | phys = phys + align; |
| 116 | /* | 116 | /* |
diff --git a/drivers/scsi/aacraid/commsup.c b/drivers/scsi/aacraid/commsup.c index 1b97f60652ba..5824a757a753 100644 --- a/drivers/scsi/aacraid/commsup.c +++ b/drivers/scsi/aacraid/commsup.c | |||
| @@ -5,7 +5,7 @@ | |||
| 5 | * based on the old aacraid driver that is.. | 5 | * based on the old aacraid driver that is.. |
| 6 | * Adaptec aacraid device driver for Linux. | 6 | * Adaptec aacraid device driver for Linux. |
| 7 | * | 7 | * |
| 8 | * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com) | 8 | * Copyright (c) 2000-2007 Adaptec, Inc. (aacraid@adaptec.com) |
| 9 | * | 9 | * |
| 10 | * This program is free software; you can redistribute it and/or modify | 10 | * This program is free software; you can redistribute it and/or modify |
| 11 | * it under the terms of the GNU General Public License as published by | 11 | * it under the terms of the GNU General Public License as published by |
| @@ -94,7 +94,7 @@ void aac_fib_map_free(struct aac_dev *dev) | |||
| 94 | int aac_fib_setup(struct aac_dev * dev) | 94 | int aac_fib_setup(struct aac_dev * dev) |
| 95 | { | 95 | { |
| 96 | struct fib *fibptr; | 96 | struct fib *fibptr; |
| 97 | struct hw_fib *hw_fib_va; | 97 | struct hw_fib *hw_fib; |
| 98 | dma_addr_t hw_fib_pa; | 98 | dma_addr_t hw_fib_pa; |
| 99 | int i; | 99 | int i; |
| 100 | 100 | ||
| @@ -106,24 +106,24 @@ int aac_fib_setup(struct aac_dev * dev) | |||
| 106 | if (i<0) | 106 | if (i<0) |
| 107 | return -ENOMEM; | 107 | return -ENOMEM; |
| 108 | 108 | ||
| 109 | hw_fib_va = dev->hw_fib_va; | 109 | hw_fib = dev->hw_fib_va; |
| 110 | hw_fib_pa = dev->hw_fib_pa; | 110 | hw_fib_pa = dev->hw_fib_pa; |
| 111 | memset(hw_fib_va, 0, dev->max_fib_size * (dev->scsi_host_ptr->can_queue + AAC_NUM_MGT_FIB)); | 111 | memset(hw_fib, 0, dev->max_fib_size * (dev->scsi_host_ptr->can_queue + AAC_NUM_MGT_FIB)); |
| 112 | /* | 112 | /* |
| 113 | * Initialise the fibs | 113 | * Initialise the fibs |
| 114 | */ | 114 | */ |
| 115 | for (i = 0, fibptr = &dev->fibs[i]; i < (dev->scsi_host_ptr->can_queue + AAC_NUM_MGT_FIB); i++, fibptr++) | 115 | for (i = 0, fibptr = &dev->fibs[i]; i < (dev->scsi_host_ptr->can_queue + AAC_NUM_MGT_FIB); i++, fibptr++) |
| 116 | { | 116 | { |
| 117 | fibptr->dev = dev; | 117 | fibptr->dev = dev; |
| 118 | fibptr->hw_fib = hw_fib_va; | 118 | fibptr->hw_fib_va = hw_fib; |
| 119 | fibptr->data = (void *) fibptr->hw_fib->data; | 119 | fibptr->data = (void *) fibptr->hw_fib_va->data; |
| 120 | fibptr->next = fibptr+1; /* Forward chain the fibs */ | 120 | fibptr->next = fibptr+1; /* Forward chain the fibs */ |
| 121 | init_MUTEX_LOCKED(&fibptr->event_wait); | 121 | init_MUTEX_LOCKED(&fibptr->event_wait); |
| 122 | spin_lock_init(&fibptr->event_lock); | 122 | spin_lock_init(&fibptr->event_lock); |
| 123 | hw_fib_va->header.XferState = cpu_to_le32(0xffffffff); | 123 | hw_fib->header.XferState = cpu_to_le32(0xffffffff); |
| 124 | hw_fib_va->header.SenderSize = cpu_to_le16(dev->max_fib_size); | 124 | hw_fib->header.SenderSize = cpu_to_le16(dev->max_fib_size); |
| 125 | fibptr->hw_fib_pa = hw_fib_pa; | 125 | fibptr->hw_fib_pa = hw_fib_pa; |
| 126 | hw_fib_va = (struct hw_fib *)((unsigned char *)hw_fib_va + dev->max_fib_size); | 126 | hw_fib = (struct hw_fib *)((unsigned char *)hw_fib + dev->max_fib_size); |
| 127 | hw_fib_pa = hw_fib_pa + dev->max_fib_size; | 127 | hw_fib_pa = hw_fib_pa + dev->max_fib_size; |
| 128 | } | 128 | } |
| 129 | /* | 129 | /* |
| @@ -166,7 +166,7 @@ struct fib *aac_fib_alloc(struct aac_dev *dev) | |||
| 166 | * Null out fields that depend on being zero at the start of | 166 | * Null out fields that depend on being zero at the start of |
| 167 | * each I/O | 167 | * each I/O |
| 168 | */ | 168 | */ |
| 169 | fibptr->hw_fib->header.XferState = 0; | 169 | fibptr->hw_fib_va->header.XferState = 0; |
| 170 | fibptr->callback = NULL; | 170 | fibptr->callback = NULL; |
| 171 | fibptr->callback_data = NULL; | 171 | fibptr->callback_data = NULL; |
| 172 | 172 | ||
| @@ -178,7 +178,6 @@ struct fib *aac_fib_alloc(struct aac_dev *dev) | |||
| 178 | * @fibptr: fib to free up | 178 | * @fibptr: fib to free up |
| 179 | * | 179 | * |
| 180 | * Frees up a fib and places it on the appropriate queue | 180 | * Frees up a fib and places it on the appropriate queue |
| 181 | * (either free or timed out) | ||
| 182 | */ | 181 | */ |
| 183 | 182 | ||
| 184 | void aac_fib_free(struct fib *fibptr) | 183 | void aac_fib_free(struct fib *fibptr) |
| @@ -186,19 +185,15 @@ void aac_fib_free(struct fib *fibptr) | |||
| 186 | unsigned long flags; | 185 | unsigned long flags; |
| 187 | 186 | ||
| 188 | spin_lock_irqsave(&fibptr->dev->fib_lock, flags); | 187 | spin_lock_irqsave(&fibptr->dev->fib_lock, flags); |
| 189 | if (fibptr->flags & FIB_CONTEXT_FLAG_TIMED_OUT) { | 188 | if (unlikely(fibptr->flags & FIB_CONTEXT_FLAG_TIMED_OUT)) |
| 190 | aac_config.fib_timeouts++; | 189 | aac_config.fib_timeouts++; |
| 191 | fibptr->next = fibptr->dev->timeout_fib; | 190 | if (fibptr->hw_fib_va->header.XferState != 0) { |
| 192 | fibptr->dev->timeout_fib = fibptr; | 191 | printk(KERN_WARNING "aac_fib_free, XferState != 0, fibptr = 0x%p, XferState = 0x%x\n", |
| 193 | } else { | 192 | (void*)fibptr, |
| 194 | if (fibptr->hw_fib->header.XferState != 0) { | 193 | le32_to_cpu(fibptr->hw_fib_va->header.XferState)); |
| 195 | printk(KERN_WARNING "aac_fib_free, XferState != 0, fibptr = 0x%p, XferState = 0x%x\n", | 194 | } |
| 196 | (void*)fibptr, | 195 | fibptr->next = fibptr->dev->free_fib; |
| 197 | le32_to_cpu(fibptr->hw_fib->header.XferState)); | 196 | fibptr->dev->free_fib = fibptr; |
| 198 | } | ||
| 199 | fibptr->next = fibptr->dev->free_fib; | ||
| 200 | fibptr->dev->free_fib = fibptr; | ||
| 201 | } | ||
| 202 | spin_unlock_irqrestore(&fibptr->dev->fib_lock, flags); | 197 | spin_unlock_irqrestore(&fibptr->dev->fib_lock, flags); |
| 203 | } | 198 | } |
| 204 | 199 | ||
| @@ -211,7 +206,7 @@ void aac_fib_free(struct fib *fibptr) | |||
| 211 | 206 | ||
| 212 | void aac_fib_init(struct fib *fibptr) | 207 | void aac_fib_init(struct fib *fibptr) |
| 213 | { | 208 | { |
| 214 | struct hw_fib *hw_fib = fibptr->hw_fib; | 209 | struct hw_fib *hw_fib = fibptr->hw_fib_va; |
| 215 | 210 | ||
| 216 | hw_fib->header.StructType = FIB_MAGIC; | 211 | hw_fib->header.StructType = FIB_MAGIC; |
| 217 | hw_fib->header.Size = cpu_to_le16(fibptr->dev->max_fib_size); | 212 | hw_fib->header.Size = cpu_to_le16(fibptr->dev->max_fib_size); |
| @@ -231,7 +226,7 @@ void aac_fib_init(struct fib *fibptr) | |||
| 231 | 226 | ||
| 232 | static void fib_dealloc(struct fib * fibptr) | 227 | static void fib_dealloc(struct fib * fibptr) |
| 233 | { | 228 | { |
| 234 | struct hw_fib *hw_fib = fibptr->hw_fib; | 229 | struct hw_fib *hw_fib = fibptr->hw_fib_va; |
| 235 | BUG_ON(hw_fib->header.StructType != FIB_MAGIC); | 230 | BUG_ON(hw_fib->header.StructType != FIB_MAGIC); |
| 236 | hw_fib->header.XferState = 0; | 231 | hw_fib->header.XferState = 0; |
| 237 | } | 232 | } |
| @@ -386,7 +381,7 @@ int aac_fib_send(u16 command, struct fib *fibptr, unsigned long size, | |||
| 386 | void *callback_data) | 381 | void *callback_data) |
| 387 | { | 382 | { |
| 388 | struct aac_dev * dev = fibptr->dev; | 383 | struct aac_dev * dev = fibptr->dev; |
| 389 | struct hw_fib * hw_fib = fibptr->hw_fib; | 384 | struct hw_fib * hw_fib = fibptr->hw_fib_va; |
| 390 | unsigned long flags = 0; | 385 | unsigned long flags = 0; |
| 391 | unsigned long qflags; | 386 | unsigned long qflags; |
| 392 | 387 | ||
| @@ -430,7 +425,7 @@ int aac_fib_send(u16 command, struct fib *fibptr, unsigned long size, | |||
| 430 | */ | 425 | */ |
| 431 | hw_fib->header.Command = cpu_to_le16(command); | 426 | hw_fib->header.Command = cpu_to_le16(command); |
| 432 | hw_fib->header.XferState |= cpu_to_le32(SentFromHost); | 427 | hw_fib->header.XferState |= cpu_to_le32(SentFromHost); |
| 433 | fibptr->hw_fib->header.Flags = 0; /* 0 the flags field - internal only*/ | 428 | fibptr->hw_fib_va->header.Flags = 0; /* 0 the flags field - internal only*/ |
| 434 | /* | 429 | /* |
| 435 | * Set the size of the Fib we want to send to the adapter | 430 | * Set the size of the Fib we want to send to the adapter |
| 436 | */ | 431 | */ |
| @@ -462,7 +457,7 @@ int aac_fib_send(u16 command, struct fib *fibptr, unsigned long size, | |||
| 462 | dprintk((KERN_DEBUG " Command = %d.\n", le32_to_cpu(hw_fib->header.Command))); | 457 | dprintk((KERN_DEBUG " Command = %d.\n", le32_to_cpu(hw_fib->header.Command))); |
| 463 | dprintk((KERN_DEBUG " SubCommand = %d.\n", le32_to_cpu(((struct aac_query_mount *)fib_data(fibptr))->command))); | 458 | dprintk((KERN_DEBUG " SubCommand = %d.\n", le32_to_cpu(((struct aac_query_mount *)fib_data(fibptr))->command))); |
| 464 | dprintk((KERN_DEBUG " XferState = %x.\n", le32_to_cpu(hw_fib->header.XferState))); | 459 | dprintk((KERN_DEBUG " XferState = %x.\n", le32_to_cpu(hw_fib->header.XferState))); |
| 465 | dprintk((KERN_DEBUG " hw_fib va being sent=%p\n",fibptr->hw_fib)); | 460 | dprintk((KERN_DEBUG " hw_fib va being sent=%p\n",fibptr->hw_fib_va)); |
| 466 | dprintk((KERN_DEBUG " hw_fib pa being sent=%lx\n",(ulong)fibptr->hw_fib_pa)); | 461 | dprintk((KERN_DEBUG " hw_fib pa being sent=%lx\n",(ulong)fibptr->hw_fib_pa)); |
| 467 | dprintk((KERN_DEBUG " fib being sent=%p\n",fibptr)); | 462 | dprintk((KERN_DEBUG " fib being sent=%p\n",fibptr)); |
| 468 | 463 | ||
| @@ -513,22 +508,20 @@ int aac_fib_send(u16 command, struct fib *fibptr, unsigned long size, | |||
| 513 | } | 508 | } |
| 514 | udelay(5); | 509 | udelay(5); |
| 515 | } | 510 | } |
| 516 | } else if (down_interruptible(&fibptr->event_wait)) { | 511 | } else |
| 517 | spin_lock_irqsave(&fibptr->event_lock, flags); | 512 | (void)down_interruptible(&fibptr->event_wait); |
| 518 | if (fibptr->done == 0) { | 513 | spin_lock_irqsave(&fibptr->event_lock, flags); |
| 519 | fibptr->done = 2; /* Tell interrupt we aborted */ | 514 | if (fibptr->done == 0) { |
| 520 | spin_unlock_irqrestore(&fibptr->event_lock, flags); | 515 | fibptr->done = 2; /* Tell interrupt we aborted */ |
| 521 | return -EINTR; | ||
| 522 | } | ||
| 523 | spin_unlock_irqrestore(&fibptr->event_lock, flags); | 516 | spin_unlock_irqrestore(&fibptr->event_lock, flags); |
| 517 | return -EINTR; | ||
| 524 | } | 518 | } |
| 519 | spin_unlock_irqrestore(&fibptr->event_lock, flags); | ||
| 525 | BUG_ON(fibptr->done == 0); | 520 | BUG_ON(fibptr->done == 0); |
| 526 | 521 | ||
| 527 | if((fibptr->flags & FIB_CONTEXT_FLAG_TIMED_OUT)){ | 522 | if(unlikely(fibptr->flags & FIB_CONTEXT_FLAG_TIMED_OUT)) |
| 528 | return -ETIMEDOUT; | 523 | return -ETIMEDOUT; |
| 529 | } else { | 524 | return 0; |
| 530 | return 0; | ||
| 531 | } | ||
| 532 | } | 525 | } |
| 533 | /* | 526 | /* |
| 534 | * If the user does not want a response than return success otherwise | 527 | * If the user does not want a response than return success otherwise |
| @@ -624,7 +617,7 @@ void aac_consumer_free(struct aac_dev * dev, struct aac_queue *q, u32 qid) | |||
| 624 | 617 | ||
| 625 | int aac_fib_adapter_complete(struct fib *fibptr, unsigned short size) | 618 | int aac_fib_adapter_complete(struct fib *fibptr, unsigned short size) |
| 626 | { | 619 | { |
| 627 | struct hw_fib * hw_fib = fibptr->hw_fib; | 620 | struct hw_fib * hw_fib = fibptr->hw_fib_va; |
| 628 | struct aac_dev * dev = fibptr->dev; | 621 | struct aac_dev * dev = fibptr->dev; |
| 629 | struct aac_queue * q; | 622 | struct aac_queue * q; |
| 630 | unsigned long nointr = 0; | 623 | unsigned long nointr = 0; |
| @@ -688,7 +681,7 @@ int aac_fib_adapter_complete(struct fib *fibptr, unsigned short size) | |||
| 688 | 681 | ||
| 689 | int aac_fib_complete(struct fib *fibptr) | 682 | int aac_fib_complete(struct fib *fibptr) |
| 690 | { | 683 | { |
| 691 | struct hw_fib * hw_fib = fibptr->hw_fib; | 684 | struct hw_fib * hw_fib = fibptr->hw_fib_va; |
| 692 | 685 | ||
| 693 | /* | 686 | /* |
| 694 | * Check for a fib which has already been completed | 687 | * Check for a fib which has already been completed |
| @@ -774,9 +767,8 @@ void aac_printf(struct aac_dev *dev, u32 val) | |||
| 774 | #define AIF_SNIFF_TIMEOUT (30*HZ) | 767 | #define AIF_SNIFF_TIMEOUT (30*HZ) |
| 775 | static void aac_handle_aif(struct aac_dev * dev, struct fib * fibptr) | 768 | static void aac_handle_aif(struct aac_dev * dev, struct fib * fibptr) |
| 776 | { | 769 | { |
| 777 | struct hw_fib * hw_fib = fibptr->hw_fib; | 770 | struct hw_fib * hw_fib = fibptr->hw_fib_va; |
| 778 | struct aac_aifcmd * aifcmd = (struct aac_aifcmd *)hw_fib->data; | 771 | struct aac_aifcmd * aifcmd = (struct aac_aifcmd *)hw_fib->data; |
| 779 | int busy; | ||
| 780 | u32 container; | 772 | u32 container; |
| 781 | struct scsi_device *device; | 773 | struct scsi_device *device; |
| 782 | enum { | 774 | enum { |
| @@ -988,9 +980,6 @@ static void aac_handle_aif(struct aac_dev * dev, struct fib * fibptr) | |||
| 988 | * behind you. | 980 | * behind you. |
| 989 | */ | 981 | */ |
| 990 | 982 | ||
| 991 | busy = 0; | ||
| 992 | |||
| 993 | |||
| 994 | /* | 983 | /* |
| 995 | * Find the scsi_device associated with the SCSI address, | 984 | * Find the scsi_device associated with the SCSI address, |
| 996 | * and mark it as changed, invalidating the cache. This deals | 985 | * and mark it as changed, invalidating the cache. This deals |
| @@ -1035,7 +1024,6 @@ static void aac_handle_aif(struct aac_dev * dev, struct fib * fibptr) | |||
| 1035 | static int _aac_reset_adapter(struct aac_dev *aac) | 1024 | static int _aac_reset_adapter(struct aac_dev *aac) |
| 1036 | { | 1025 | { |
| 1037 | int index, quirks; | 1026 | int index, quirks; |
| 1038 | u32 ret; | ||
| 1039 | int retval; | 1027 | int retval; |
| 1040 | struct Scsi_Host *host; | 1028 | struct Scsi_Host *host; |
| 1041 | struct scsi_device *dev; | 1029 | struct scsi_device *dev; |
| @@ -1059,35 +1047,29 @@ static int _aac_reset_adapter(struct aac_dev *aac) | |||
| 1059 | * If a positive health, means in a known DEAD PANIC | 1047 | * If a positive health, means in a known DEAD PANIC |
| 1060 | * state and the adapter could be reset to `try again'. | 1048 | * state and the adapter could be reset to `try again'. |
| 1061 | */ | 1049 | */ |
| 1062 | retval = aac_adapter_check_health(aac); | 1050 | retval = aac_adapter_restart(aac, aac_adapter_check_health(aac)); |
| 1063 | if (retval == 0) | ||
| 1064 | retval = aac_adapter_sync_cmd(aac, IOP_RESET_ALWAYS, | ||
| 1065 | 0, 0, 0, 0, 0, 0, &ret, NULL, NULL, NULL, NULL); | ||
| 1066 | if (retval) | ||
| 1067 | retval = aac_adapter_sync_cmd(aac, IOP_RESET, | ||
| 1068 | 0, 0, 0, 0, 0, 0, &ret, NULL, NULL, NULL, NULL); | ||
| 1069 | 1051 | ||
| 1070 | if (retval) | 1052 | if (retval) |
| 1071 | goto out; | 1053 | goto out; |
| 1072 | if (ret != 0x00000001) { | ||
| 1073 | retval = -ENODEV; | ||
| 1074 | goto out; | ||
| 1075 | } | ||
| 1076 | 1054 | ||
| 1077 | /* | 1055 | /* |
| 1078 | * Loop through the fibs, close the synchronous FIBS | 1056 | * Loop through the fibs, close the synchronous FIBS |
| 1079 | */ | 1057 | */ |
| 1080 | for (index = 0; index < (aac->scsi_host_ptr->can_queue + AAC_NUM_MGT_FIB); index++) { | 1058 | for (retval = 1, index = 0; index < (aac->scsi_host_ptr->can_queue + AAC_NUM_MGT_FIB); index++) { |
| 1081 | struct fib *fib = &aac->fibs[index]; | 1059 | struct fib *fib = &aac->fibs[index]; |
| 1082 | if (!(fib->hw_fib->header.XferState & cpu_to_le32(NoResponseExpected | Async)) && | 1060 | if (!(fib->hw_fib_va->header.XferState & cpu_to_le32(NoResponseExpected | Async)) && |
| 1083 | (fib->hw_fib->header.XferState & cpu_to_le32(ResponseExpected))) { | 1061 | (fib->hw_fib_va->header.XferState & cpu_to_le32(ResponseExpected))) { |
| 1084 | unsigned long flagv; | 1062 | unsigned long flagv; |
| 1085 | spin_lock_irqsave(&fib->event_lock, flagv); | 1063 | spin_lock_irqsave(&fib->event_lock, flagv); |
| 1086 | up(&fib->event_wait); | 1064 | up(&fib->event_wait); |
| 1087 | spin_unlock_irqrestore(&fib->event_lock, flagv); | 1065 | spin_unlock_irqrestore(&fib->event_lock, flagv); |
| 1088 | schedule(); | 1066 | schedule(); |
| 1067 | retval = 0; | ||
| 1089 | } | 1068 | } |
| 1090 | } | 1069 | } |
| 1070 | /* Give some extra time for ioctls to complete. */ | ||
| 1071 | if (retval == 0) | ||
| 1072 | ssleep(2); | ||
| 1091 | index = aac->cardtype; | 1073 | index = aac->cardtype; |
| 1092 | 1074 | ||
| 1093 | /* | 1075 | /* |
| @@ -1248,7 +1230,7 @@ int aac_check_health(struct aac_dev * aac) | |||
| 1248 | 1230 | ||
| 1249 | memset(hw_fib, 0, sizeof(struct hw_fib)); | 1231 | memset(hw_fib, 0, sizeof(struct hw_fib)); |
| 1250 | memset(fib, 0, sizeof(struct fib)); | 1232 | memset(fib, 0, sizeof(struct fib)); |
| 1251 | fib->hw_fib = hw_fib; | 1233 | fib->hw_fib_va = hw_fib; |
| 1252 | fib->dev = aac; | 1234 | fib->dev = aac; |
| 1253 | aac_fib_init(fib); | 1235 | aac_fib_init(fib); |
| 1254 | fib->type = FSAFS_NTC_FIB_CONTEXT; | 1236 | fib->type = FSAFS_NTC_FIB_CONTEXT; |
| @@ -1354,11 +1336,11 @@ int aac_command_thread(void *data) | |||
| 1354 | * do anything at this point since we don't have | 1336 | * do anything at this point since we don't have |
| 1355 | * anything defined for this thread to do. | 1337 | * anything defined for this thread to do. |
| 1356 | */ | 1338 | */ |
| 1357 | hw_fib = fib->hw_fib; | 1339 | hw_fib = fib->hw_fib_va; |
| 1358 | memset(fib, 0, sizeof(struct fib)); | 1340 | memset(fib, 0, sizeof(struct fib)); |
| 1359 | fib->type = FSAFS_NTC_FIB_CONTEXT; | 1341 | fib->type = FSAFS_NTC_FIB_CONTEXT; |
| 1360 | fib->size = sizeof( struct fib ); | 1342 | fib->size = sizeof( struct fib ); |
| 1361 | fib->hw_fib = hw_fib; | 1343 | fib->hw_fib_va = hw_fib; |
| 1362 | fib->data = hw_fib->data; | 1344 | fib->data = hw_fib->data; |
| 1363 | fib->dev = dev; | 1345 | fib->dev = dev; |
| 1364 | /* | 1346 | /* |
| @@ -1485,7 +1467,7 @@ int aac_command_thread(void *data) | |||
| 1485 | */ | 1467 | */ |
| 1486 | memcpy(hw_newfib, hw_fib, sizeof(struct hw_fib)); | 1468 | memcpy(hw_newfib, hw_fib, sizeof(struct hw_fib)); |
| 1487 | memcpy(newfib, fib, sizeof(struct fib)); | 1469 | memcpy(newfib, fib, sizeof(struct fib)); |
| 1488 | newfib->hw_fib = hw_newfib; | 1470 | newfib->hw_fib_va = hw_newfib; |
| 1489 | /* | 1471 | /* |
| 1490 | * Put the FIB onto the | 1472 | * Put the FIB onto the |
| 1491 | * fibctx's fibs | 1473 | * fibctx's fibs |
diff --git a/drivers/scsi/aacraid/dpcsup.c b/drivers/scsi/aacraid/dpcsup.c index d38b628be1ad..42c7dcda6d9b 100644 --- a/drivers/scsi/aacraid/dpcsup.c +++ b/drivers/scsi/aacraid/dpcsup.c | |||
| @@ -5,7 +5,7 @@ | |||
| 5 | * based on the old aacraid driver that is.. | 5 | * based on the old aacraid driver that is.. |
| 6 | * Adaptec aacraid device driver for Linux. | 6 | * Adaptec aacraid device driver for Linux. |
| 7 | * | 7 | * |
| 8 | * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com) | 8 | * Copyright (c) 2000-2007 Adaptec, Inc. (aacraid@adaptec.com) |
| 9 | * | 9 | * |
| 10 | * This program is free software; you can redistribute it and/or modify | 10 | * This program is free software; you can redistribute it and/or modify |
| 11 | * it under the terms of the GNU General Public License as published by | 11 | * it under the terms of the GNU General Public License as published by |
| @@ -32,7 +32,6 @@ | |||
| 32 | #include <linux/kernel.h> | 32 | #include <linux/kernel.h> |
| 33 | #include <linux/init.h> | 33 | #include <linux/init.h> |
| 34 | #include <linux/types.h> | 34 | #include <linux/types.h> |
| 35 | #include <linux/pci.h> | ||
| 36 | #include <linux/spinlock.h> | 35 | #include <linux/spinlock.h> |
| 37 | #include <linux/slab.h> | 36 | #include <linux/slab.h> |
| 38 | #include <linux/completion.h> | 37 | #include <linux/completion.h> |
| @@ -73,7 +72,7 @@ unsigned int aac_response_normal(struct aac_queue * q) | |||
| 73 | u32 index = le32_to_cpu(entry->addr); | 72 | u32 index = le32_to_cpu(entry->addr); |
| 74 | fast = index & 0x01; | 73 | fast = index & 0x01; |
| 75 | fib = &dev->fibs[index >> 2]; | 74 | fib = &dev->fibs[index >> 2]; |
| 76 | hwfib = fib->hw_fib; | 75 | hwfib = fib->hw_fib_va; |
| 77 | 76 | ||
| 78 | aac_consumer_free(dev, q, HostNormRespQueue); | 77 | aac_consumer_free(dev, q, HostNormRespQueue); |
| 79 | /* | 78 | /* |
| @@ -84,11 +83,13 @@ unsigned int aac_response_normal(struct aac_queue * q) | |||
| 84 | * continue. The caller has already been notified that | 83 | * continue. The caller has already been notified that |
| 85 | * the fib timed out. | 84 | * the fib timed out. |
| 86 | */ | 85 | */ |
| 87 | if (!(fib->flags & FIB_CONTEXT_FLAG_TIMED_OUT)) | 86 | dev->queues->queue[AdapNormCmdQueue].numpending--; |
| 88 | dev->queues->queue[AdapNormCmdQueue].numpending--; | 87 | |
| 89 | else { | 88 | if (unlikely(fib->flags & FIB_CONTEXT_FLAG_TIMED_OUT)) { |
| 90 | printk(KERN_WARNING "aacraid: FIB timeout (%x).\n", fib->flags); | 89 | spin_unlock_irqrestore(q->lock, flags); |
| 91 | printk(KERN_DEBUG"aacraid: hwfib=%p fib index=%i fib=%p\n",hwfib, hwfib->header.SenderData,fib); | 90 | aac_fib_complete(fib); |
| 91 | aac_fib_free(fib); | ||
| 92 | spin_lock_irqsave(q->lock, flags); | ||
| 92 | continue; | 93 | continue; |
| 93 | } | 94 | } |
| 94 | spin_unlock_irqrestore(q->lock, flags); | 95 | spin_unlock_irqrestore(q->lock, flags); |
| @@ -193,7 +194,7 @@ unsigned int aac_command_normal(struct aac_queue *q) | |||
| 193 | INIT_LIST_HEAD(&fib->fiblink); | 194 | INIT_LIST_HEAD(&fib->fiblink); |
| 194 | fib->type = FSAFS_NTC_FIB_CONTEXT; | 195 | fib->type = FSAFS_NTC_FIB_CONTEXT; |
| 195 | fib->size = sizeof(struct fib); | 196 | fib->size = sizeof(struct fib); |
| 196 | fib->hw_fib = hw_fib; | 197 | fib->hw_fib_va = hw_fib; |
| 197 | fib->data = hw_fib->data; | 198 | fib->data = hw_fib->data; |
| 198 | fib->dev = dev; | 199 | fib->dev = dev; |
| 199 | 200 | ||
| @@ -254,12 +255,13 @@ unsigned int aac_intr_normal(struct aac_dev * dev, u32 Index) | |||
| 254 | return 1; | 255 | return 1; |
| 255 | } | 256 | } |
| 256 | memset(hw_fib, 0, sizeof(struct hw_fib)); | 257 | memset(hw_fib, 0, sizeof(struct hw_fib)); |
| 257 | memcpy(hw_fib, (struct hw_fib *)(((unsigned long)(dev->regs.sa)) + (index & ~0x00000002L)), sizeof(struct hw_fib)); | 258 | memcpy(hw_fib, (struct hw_fib *)(((ptrdiff_t)(dev->regs.sa)) + |
| 259 | (index & ~0x00000002L)), sizeof(struct hw_fib)); | ||
| 258 | memset(fib, 0, sizeof(struct fib)); | 260 | memset(fib, 0, sizeof(struct fib)); |
| 259 | INIT_LIST_HEAD(&fib->fiblink); | 261 | INIT_LIST_HEAD(&fib->fiblink); |
| 260 | fib->type = FSAFS_NTC_FIB_CONTEXT; | 262 | fib->type = FSAFS_NTC_FIB_CONTEXT; |
| 261 | fib->size = sizeof(struct fib); | 263 | fib->size = sizeof(struct fib); |
| 262 | fib->hw_fib = hw_fib; | 264 | fib->hw_fib_va = hw_fib; |
| 263 | fib->data = hw_fib->data; | 265 | fib->data = hw_fib->data; |
| 264 | fib->dev = dev; | 266 | fib->dev = dev; |
| 265 | 267 | ||
| @@ -271,7 +273,7 @@ unsigned int aac_intr_normal(struct aac_dev * dev, u32 Index) | |||
| 271 | } else { | 273 | } else { |
| 272 | int fast = index & 0x01; | 274 | int fast = index & 0x01; |
| 273 | struct fib * fib = &dev->fibs[index >> 2]; | 275 | struct fib * fib = &dev->fibs[index >> 2]; |
| 274 | struct hw_fib * hwfib = fib->hw_fib; | 276 | struct hw_fib * hwfib = fib->hw_fib_va; |
| 275 | 277 | ||
| 276 | /* | 278 | /* |
| 277 | * Remove this fib from the Outstanding I/O queue. | 279 | * Remove this fib from the Outstanding I/O queue. |
| @@ -281,14 +283,14 @@ unsigned int aac_intr_normal(struct aac_dev * dev, u32 Index) | |||
| 281 | * continue. The caller has already been notified that | 283 | * continue. The caller has already been notified that |
| 282 | * the fib timed out. | 284 | * the fib timed out. |
| 283 | */ | 285 | */ |
| 284 | if ((fib->flags & FIB_CONTEXT_FLAG_TIMED_OUT)) { | 286 | dev->queues->queue[AdapNormCmdQueue].numpending--; |
| 285 | printk(KERN_WARNING "aacraid: FIB timeout (%x).\n", fib->flags); | 287 | |
| 286 | printk(KERN_DEBUG"aacraid: hwfib=%p index=%i fib=%p\n",hwfib, hwfib->header.SenderData,fib); | 288 | if (unlikely(fib->flags & FIB_CONTEXT_FLAG_TIMED_OUT)) { |
| 289 | aac_fib_complete(fib); | ||
| 290 | aac_fib_free(fib); | ||
| 287 | return 0; | 291 | return 0; |
| 288 | } | 292 | } |
| 289 | 293 | ||
| 290 | dev->queues->queue[AdapNormCmdQueue].numpending--; | ||
| 291 | |||
| 292 | if (fast) { | 294 | if (fast) { |
| 293 | /* | 295 | /* |
| 294 | * Doctor the fib | 296 | * Doctor the fib |
diff --git a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c index 0f948c2fb609..350ea7feb61d 100644 --- a/drivers/scsi/aacraid/linit.c +++ b/drivers/scsi/aacraid/linit.c | |||
| @@ -5,7 +5,7 @@ | |||
| 5 | * based on the old aacraid driver that is.. | 5 | * based on the old aacraid driver that is.. |
| 6 | * Adaptec aacraid device driver for Linux. | 6 | * Adaptec aacraid device driver for Linux. |
| 7 | * | 7 | * |
| 8 | * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com) | 8 | * Copyright (c) 2000-2007 Adaptec, Inc. (aacraid@adaptec.com) |
| 9 | * | 9 | * |
| 10 | * This program is free software; you can redistribute it and/or modify | 10 | * This program is free software; you can redistribute it and/or modify |
| 11 | * it under the terms of the GNU General Public License as published by | 11 | * it under the terms of the GNU General Public License as published by |
| @@ -82,8 +82,6 @@ static LIST_HEAD(aac_devices); | |||
| 82 | static int aac_cfg_major = -1; | 82 | static int aac_cfg_major = -1; |
| 83 | char aac_driver_version[] = AAC_DRIVER_FULL_VERSION; | 83 | char aac_driver_version[] = AAC_DRIVER_FULL_VERSION; |
| 84 | 84 | ||
| 85 | extern int expose_physicals; | ||
| 86 | |||
| 87 | /* | 85 | /* |
| 88 | * Because of the way Linux names scsi devices, the order in this table has | 86 | * Because of the way Linux names scsi devices, the order in this table has |
| 89 | * become important. Check for on-board Raid first, add-in cards second. | 87 | * become important. Check for on-board Raid first, add-in cards second. |
| @@ -247,7 +245,19 @@ static struct aac_driver_ident aac_drivers[] = { | |||
| 247 | 245 | ||
| 248 | static int aac_queuecommand(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *)) | 246 | static int aac_queuecommand(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *)) |
| 249 | { | 247 | { |
| 248 | struct Scsi_Host *host = cmd->device->host; | ||
| 249 | struct aac_dev *dev = (struct aac_dev *)host->hostdata; | ||
| 250 | u32 count = 0; | ||
| 250 | cmd->scsi_done = done; | 251 | cmd->scsi_done = done; |
| 252 | for (; count < (host->can_queue + AAC_NUM_MGT_FIB); ++count) { | ||
| 253 | struct fib * fib = &dev->fibs[count]; | ||
| 254 | struct scsi_cmnd * command; | ||
| 255 | if (fib->hw_fib_va->header.XferState && | ||
| 256 | ((command = fib->callback_data)) && | ||
| 257 | (command == cmd) && | ||
| 258 | (cmd->SCp.phase == AAC_OWNER_FIRMWARE)) | ||
| 259 | return 0; /* Already owned by Adapter */ | ||
| 260 | } | ||
| 251 | cmd->SCp.phase = AAC_OWNER_LOWLEVEL; | 261 | cmd->SCp.phase = AAC_OWNER_LOWLEVEL; |
| 252 | return (aac_scsi_cmd(cmd) ? FAILED : 0); | 262 | return (aac_scsi_cmd(cmd) ? FAILED : 0); |
| 253 | } | 263 | } |
| @@ -446,6 +456,40 @@ static int aac_ioctl(struct scsi_device *sdev, int cmd, void __user * arg) | |||
| 446 | return aac_do_ioctl(dev, cmd, arg); | 456 | return aac_do_ioctl(dev, cmd, arg); |
| 447 | } | 457 | } |
| 448 | 458 | ||
| 459 | static int aac_eh_abort(struct scsi_cmnd* cmd) | ||
| 460 | { | ||
| 461 | struct scsi_device * dev = cmd->device; | ||
| 462 | struct Scsi_Host * host = dev->host; | ||
| 463 | struct aac_dev * aac = (struct aac_dev *)host->hostdata; | ||
| 464 | int count; | ||
| 465 | int ret = FAILED; | ||
| 466 | |||
| 467 | printk(KERN_ERR "%s: Host adapter abort request (%d,%d,%d,%d)\n", | ||
| 468 | AAC_DRIVERNAME, | ||
| 469 | host->host_no, sdev_channel(dev), sdev_id(dev), dev->lun); | ||
| 470 | switch (cmd->cmnd[0]) { | ||
| 471 | case SERVICE_ACTION_IN: | ||
| 472 | if (!(aac->raw_io_interface) || | ||
| 473 | !(aac->raw_io_64) || | ||
| 474 | ((cmd->cmnd[1] & 0x1f) != SAI_READ_CAPACITY_16)) | ||
| 475 | break; | ||
| 476 | case INQUIRY: | ||
| 477 | case READ_CAPACITY: | ||
| 478 | case TEST_UNIT_READY: | ||
| 479 | /* Mark associated FIB to not complete, eh handler does this */ | ||
| 480 | for (count = 0; count < (host->can_queue + AAC_NUM_MGT_FIB); ++count) { | ||
| 481 | struct fib * fib = &aac->fibs[count]; | ||
| 482 | if (fib->hw_fib_va->header.XferState && | ||
| 483 | (fib->callback_data == cmd)) { | ||
| 484 | fib->flags |= FIB_CONTEXT_FLAG_TIMED_OUT; | ||
| 485 | cmd->SCp.phase = AAC_OWNER_ERROR_HANDLER; | ||
| 486 | ret = SUCCESS; | ||
| 487 | } | ||
| 488 | } | ||
| 489 | } | ||
| 490 | return ret; | ||
| 491 | } | ||
| 492 | |||
| 449 | /* | 493 | /* |
| 450 | * aac_eh_reset - Reset command handling | 494 | * aac_eh_reset - Reset command handling |
| 451 | * @scsi_cmd: SCSI command block causing the reset | 495 | * @scsi_cmd: SCSI command block causing the reset |
| @@ -457,12 +501,20 @@ static int aac_eh_reset(struct scsi_cmnd* cmd) | |||
| 457 | struct Scsi_Host * host = dev->host; | 501 | struct Scsi_Host * host = dev->host; |
| 458 | struct scsi_cmnd * command; | 502 | struct scsi_cmnd * command; |
| 459 | int count; | 503 | int count; |
| 460 | struct aac_dev * aac; | 504 | struct aac_dev * aac = (struct aac_dev *)host->hostdata; |
| 461 | unsigned long flags; | 505 | unsigned long flags; |
| 462 | 506 | ||
| 507 | /* Mark the associated FIB to not complete, eh handler does this */ | ||
| 508 | for (count = 0; count < (host->can_queue + AAC_NUM_MGT_FIB); ++count) { | ||
| 509 | struct fib * fib = &aac->fibs[count]; | ||
| 510 | if (fib->hw_fib_va->header.XferState && | ||
| 511 | (fib->callback_data == cmd)) { | ||
| 512 | fib->flags |= FIB_CONTEXT_FLAG_TIMED_OUT; | ||
| 513 | cmd->SCp.phase = AAC_OWNER_ERROR_HANDLER; | ||
| 514 | } | ||
| 515 | } | ||
| 463 | printk(KERN_ERR "%s: Host adapter reset request. SCSI hang ?\n", | 516 | printk(KERN_ERR "%s: Host adapter reset request. SCSI hang ?\n", |
| 464 | AAC_DRIVERNAME); | 517 | AAC_DRIVERNAME); |
| 465 | aac = (struct aac_dev *)host->hostdata; | ||
| 466 | 518 | ||
| 467 | if ((count = aac_check_health(aac))) | 519 | if ((count = aac_check_health(aac))) |
| 468 | return count; | 520 | return count; |
| @@ -496,7 +548,7 @@ static int aac_eh_reset(struct scsi_cmnd* cmd) | |||
| 496 | ssleep(1); | 548 | ssleep(1); |
| 497 | } | 549 | } |
| 498 | printk(KERN_ERR "%s: SCSI bus appears hung\n", AAC_DRIVERNAME); | 550 | printk(KERN_ERR "%s: SCSI bus appears hung\n", AAC_DRIVERNAME); |
| 499 | return -ETIMEDOUT; | 551 | return SUCCESS; /* Cause an immediate retry of the command with a ten second delay after successful tur */ |
| 500 | } | 552 | } |
| 501 | 553 | ||
| 502 | /** | 554 | /** |
| @@ -796,6 +848,7 @@ static struct scsi_host_template aac_driver_template = { | |||
| 796 | .bios_param = aac_biosparm, | 848 | .bios_param = aac_biosparm, |
| 797 | .shost_attrs = aac_attrs, | 849 | .shost_attrs = aac_attrs, |
| 798 | .slave_configure = aac_slave_configure, | 850 | .slave_configure = aac_slave_configure, |
| 851 | .eh_abort_handler = aac_eh_abort, | ||
| 799 | .eh_host_reset_handler = aac_eh_reset, | 852 | .eh_host_reset_handler = aac_eh_reset, |
| 800 | .can_queue = AAC_NUM_IO_FIB, | 853 | .can_queue = AAC_NUM_IO_FIB, |
| 801 | .this_id = MAXIMUM_NUM_CONTAINERS, | 854 | .this_id = MAXIMUM_NUM_CONTAINERS, |
diff --git a/drivers/scsi/aacraid/nark.c b/drivers/scsi/aacraid/nark.c index c76b611b6afb..a8ace5677813 100644 --- a/drivers/scsi/aacraid/nark.c +++ b/drivers/scsi/aacraid/nark.c | |||
| @@ -74,9 +74,6 @@ static int aac_nark_ioremap(struct aac_dev * dev, u32 size) | |||
| 74 | 74 | ||
| 75 | int aac_nark_init(struct aac_dev * dev) | 75 | int aac_nark_init(struct aac_dev * dev) |
| 76 | { | 76 | { |
| 77 | extern int _aac_rx_init(struct aac_dev *dev); | ||
| 78 | extern int aac_rx_select_comm(struct aac_dev *dev, int comm); | ||
| 79 | |||
| 80 | /* | 77 | /* |
| 81 | * Fill in the function dispatch table. | 78 | * Fill in the function dispatch table. |
| 82 | */ | 79 | */ |
diff --git a/drivers/scsi/aacraid/rkt.c b/drivers/scsi/aacraid/rkt.c index d953c3fe998a..9c5fcfb398c2 100644 --- a/drivers/scsi/aacraid/rkt.c +++ b/drivers/scsi/aacraid/rkt.c | |||
| @@ -45,7 +45,6 @@ | |||
| 45 | static int aac_rkt_select_comm(struct aac_dev *dev, int comm) | 45 | static int aac_rkt_select_comm(struct aac_dev *dev, int comm) |
| 46 | { | 46 | { |
| 47 | int retval; | 47 | int retval; |
| 48 | extern int aac_rx_select_comm(struct aac_dev *dev, int comm); | ||
| 49 | retval = aac_rx_select_comm(dev, comm); | 48 | retval = aac_rx_select_comm(dev, comm); |
| 50 | if (comm == AAC_COMM_MESSAGE) { | 49 | if (comm == AAC_COMM_MESSAGE) { |
| 51 | /* | 50 | /* |
| @@ -97,8 +96,6 @@ static int aac_rkt_ioremap(struct aac_dev * dev, u32 size) | |||
| 97 | 96 | ||
| 98 | int aac_rkt_init(struct aac_dev *dev) | 97 | int aac_rkt_init(struct aac_dev *dev) |
| 99 | { | 98 | { |
| 100 | extern int _aac_rx_init(struct aac_dev *dev); | ||
| 101 | |||
| 102 | /* | 99 | /* |
| 103 | * Fill in the function dispatch table. | 100 | * Fill in the function dispatch table. |
| 104 | */ | 101 | */ |
diff --git a/drivers/scsi/aacraid/rx.c b/drivers/scsi/aacraid/rx.c index d242e2611d67..0c71315cbf1a 100644 --- a/drivers/scsi/aacraid/rx.c +++ b/drivers/scsi/aacraid/rx.c | |||
| @@ -5,7 +5,7 @@ | |||
| 5 | * based on the old aacraid driver that is.. | 5 | * based on the old aacraid driver that is.. |
| 6 | * Adaptec aacraid device driver for Linux. | 6 | * Adaptec aacraid device driver for Linux. |
| 7 | * | 7 | * |
| 8 | * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com) | 8 | * Copyright (c) 2000-2007 Adaptec, Inc. (aacraid@adaptec.com) |
| 9 | * | 9 | * |
| 10 | * This program is free software; you can redistribute it and/or modify | 10 | * This program is free software; you can redistribute it and/or modify |
| 11 | * it under the terms of the GNU General Public License as published by | 11 | * it under the terms of the GNU General Public License as published by |
| @@ -57,25 +57,25 @@ static irqreturn_t aac_rx_intr_producer(int irq, void *dev_id) | |||
| 57 | * been enabled. | 57 | * been enabled. |
| 58 | * Check to see if this is our interrupt. If it isn't just return | 58 | * Check to see if this is our interrupt. If it isn't just return |
| 59 | */ | 59 | */ |
| 60 | if (intstat & ~(dev->OIMR)) { | 60 | if (likely(intstat & ~(dev->OIMR))) { |
| 61 | bellbits = rx_readl(dev, OutboundDoorbellReg); | 61 | bellbits = rx_readl(dev, OutboundDoorbellReg); |
| 62 | if (bellbits & DoorBellPrintfReady) { | 62 | if (unlikely(bellbits & DoorBellPrintfReady)) { |
| 63 | aac_printf(dev, readl (&dev->IndexRegs->Mailbox[5])); | 63 | aac_printf(dev, readl (&dev->IndexRegs->Mailbox[5])); |
| 64 | rx_writel(dev, MUnit.ODR,DoorBellPrintfReady); | 64 | rx_writel(dev, MUnit.ODR,DoorBellPrintfReady); |
| 65 | rx_writel(dev, InboundDoorbellReg,DoorBellPrintfDone); | 65 | rx_writel(dev, InboundDoorbellReg,DoorBellPrintfDone); |
| 66 | } | 66 | } |
| 67 | else if (bellbits & DoorBellAdapterNormCmdReady) { | 67 | else if (unlikely(bellbits & DoorBellAdapterNormCmdReady)) { |
| 68 | rx_writel(dev, MUnit.ODR, DoorBellAdapterNormCmdReady); | 68 | rx_writel(dev, MUnit.ODR, DoorBellAdapterNormCmdReady); |
| 69 | aac_command_normal(&dev->queues->queue[HostNormCmdQueue]); | 69 | aac_command_normal(&dev->queues->queue[HostNormCmdQueue]); |
| 70 | } | 70 | } |
| 71 | else if (bellbits & DoorBellAdapterNormRespReady) { | 71 | else if (likely(bellbits & DoorBellAdapterNormRespReady)) { |
| 72 | rx_writel(dev, MUnit.ODR,DoorBellAdapterNormRespReady); | 72 | rx_writel(dev, MUnit.ODR,DoorBellAdapterNormRespReady); |
| 73 | aac_response_normal(&dev->queues->queue[HostNormRespQueue]); | 73 | aac_response_normal(&dev->queues->queue[HostNormRespQueue]); |
| 74 | } | 74 | } |
| 75 | else if (bellbits & DoorBellAdapterNormCmdNotFull) { | 75 | else if (unlikely(bellbits & DoorBellAdapterNormCmdNotFull)) { |
| 76 | rx_writel(dev, MUnit.ODR, DoorBellAdapterNormCmdNotFull); | 76 | rx_writel(dev, MUnit.ODR, DoorBellAdapterNormCmdNotFull); |
| 77 | } | 77 | } |
| 78 | else if (bellbits & DoorBellAdapterNormRespNotFull) { | 78 | else if (unlikely(bellbits & DoorBellAdapterNormRespNotFull)) { |
| 79 | rx_writel(dev, MUnit.ODR, DoorBellAdapterNormCmdNotFull); | 79 | rx_writel(dev, MUnit.ODR, DoorBellAdapterNormCmdNotFull); |
| 80 | rx_writel(dev, MUnit.ODR, DoorBellAdapterNormRespNotFull); | 80 | rx_writel(dev, MUnit.ODR, DoorBellAdapterNormRespNotFull); |
| 81 | } | 81 | } |
| @@ -88,11 +88,11 @@ static irqreturn_t aac_rx_intr_message(int irq, void *dev_id) | |||
| 88 | { | 88 | { |
| 89 | struct aac_dev *dev = dev_id; | 89 | struct aac_dev *dev = dev_id; |
| 90 | u32 Index = rx_readl(dev, MUnit.OutboundQueue); | 90 | u32 Index = rx_readl(dev, MUnit.OutboundQueue); |
| 91 | if (Index == 0xFFFFFFFFL) | 91 | if (unlikely(Index == 0xFFFFFFFFL)) |
| 92 | Index = rx_readl(dev, MUnit.OutboundQueue); | 92 | Index = rx_readl(dev, MUnit.OutboundQueue); |
| 93 | if (Index != 0xFFFFFFFFL) { | 93 | if (likely(Index != 0xFFFFFFFFL)) { |
| 94 | do { | 94 | do { |
| 95 | if (aac_intr_normal(dev, Index)) { | 95 | if (unlikely(aac_intr_normal(dev, Index))) { |
| 96 | rx_writel(dev, MUnit.OutboundQueue, Index); | 96 | rx_writel(dev, MUnit.OutboundQueue, Index); |
| 97 | rx_writel(dev, MUnit.ODR, DoorBellAdapterNormRespReady); | 97 | rx_writel(dev, MUnit.ODR, DoorBellAdapterNormRespReady); |
| 98 | } | 98 | } |
| @@ -204,7 +204,7 @@ static int rx_sync_cmd(struct aac_dev *dev, u32 command, | |||
| 204 | */ | 204 | */ |
| 205 | msleep(1); | 205 | msleep(1); |
| 206 | } | 206 | } |
| 207 | if (ok != 1) { | 207 | if (unlikely(ok != 1)) { |
| 208 | /* | 208 | /* |
| 209 | * Restore interrupt mask even though we timed out | 209 | * Restore interrupt mask even though we timed out |
| 210 | */ | 210 | */ |
| @@ -294,7 +294,7 @@ static void aac_rx_notify_adapter(struct aac_dev *dev, u32 event) | |||
| 294 | * Start up processing on an i960 based AAC adapter | 294 | * Start up processing on an i960 based AAC adapter |
| 295 | */ | 295 | */ |
| 296 | 296 | ||
| 297 | void aac_rx_start_adapter(struct aac_dev *dev) | 297 | static void aac_rx_start_adapter(struct aac_dev *dev) |
| 298 | { | 298 | { |
| 299 | struct aac_init *init; | 299 | struct aac_init *init; |
| 300 | 300 | ||
| @@ -319,12 +319,12 @@ static int aac_rx_check_health(struct aac_dev *dev) | |||
| 319 | /* | 319 | /* |
| 320 | * Check to see if the board failed any self tests. | 320 | * Check to see if the board failed any self tests. |
| 321 | */ | 321 | */ |
| 322 | if (status & SELF_TEST_FAILED) | 322 | if (unlikely(status & SELF_TEST_FAILED)) |
| 323 | return -1; | 323 | return -1; |
| 324 | /* | 324 | /* |
| 325 | * Check to see if the board panic'd. | 325 | * Check to see if the board panic'd. |
| 326 | */ | 326 | */ |
| 327 | if (status & KERNEL_PANIC) { | 327 | if (unlikely(status & KERNEL_PANIC)) { |
| 328 | char * buffer; | 328 | char * buffer; |
| 329 | struct POSTSTATUS { | 329 | struct POSTSTATUS { |
| 330 | __le32 Post_Command; | 330 | __le32 Post_Command; |
| @@ -333,15 +333,15 @@ static int aac_rx_check_health(struct aac_dev *dev) | |||
| 333 | dma_addr_t paddr, baddr; | 333 | dma_addr_t paddr, baddr; |
| 334 | int ret; | 334 | int ret; |
| 335 | 335 | ||
| 336 | if ((status & 0xFF000000L) == 0xBC000000L) | 336 | if (likely((status & 0xFF000000L) == 0xBC000000L)) |
| 337 | return (status >> 16) & 0xFF; | 337 | return (status >> 16) & 0xFF; |
| 338 | buffer = pci_alloc_consistent(dev->pdev, 512, &baddr); | 338 | buffer = pci_alloc_consistent(dev->pdev, 512, &baddr); |
| 339 | ret = -2; | 339 | ret = -2; |
| 340 | if (buffer == NULL) | 340 | if (unlikely(buffer == NULL)) |
| 341 | return ret; | 341 | return ret; |
| 342 | post = pci_alloc_consistent(dev->pdev, | 342 | post = pci_alloc_consistent(dev->pdev, |
| 343 | sizeof(struct POSTSTATUS), &paddr); | 343 | sizeof(struct POSTSTATUS), &paddr); |
| 344 | if (post == NULL) { | 344 | if (unlikely(post == NULL)) { |
| 345 | pci_free_consistent(dev->pdev, 512, buffer, baddr); | 345 | pci_free_consistent(dev->pdev, 512, buffer, baddr); |
| 346 | return ret; | 346 | return ret; |
| 347 | } | 347 | } |
| @@ -353,7 +353,7 @@ static int aac_rx_check_health(struct aac_dev *dev) | |||
| 353 | NULL, NULL, NULL, NULL, NULL); | 353 | NULL, NULL, NULL, NULL, NULL); |
| 354 | pci_free_consistent(dev->pdev, sizeof(struct POSTSTATUS), | 354 | pci_free_consistent(dev->pdev, sizeof(struct POSTSTATUS), |
| 355 | post, paddr); | 355 | post, paddr); |
| 356 | if ((buffer[0] == '0') && ((buffer[1] == 'x') || (buffer[1] == 'X'))) { | 356 | if (likely((buffer[0] == '0') && ((buffer[1] == 'x') || (buffer[1] == 'X')))) { |
| 357 | ret = (buffer[2] <= '9') ? (buffer[2] - '0') : (buffer[2] - 'A' + 10); | 357 | ret = (buffer[2] <= '9') ? (buffer[2] - '0') : (buffer[2] - 'A' + 10); |
| 358 | ret <<= 4; | 358 | ret <<= 4; |
| 359 | ret += (buffer[3] <= '9') ? (buffer[3] - '0') : (buffer[3] - 'A' + 10); | 359 | ret += (buffer[3] <= '9') ? (buffer[3] - '0') : (buffer[3] - 'A' + 10); |
| @@ -364,7 +364,7 @@ static int aac_rx_check_health(struct aac_dev *dev) | |||
| 364 | /* | 364 | /* |
| 365 | * Wait for the adapter to be up and running. | 365 | * Wait for the adapter to be up and running. |
| 366 | */ | 366 | */ |
| 367 | if (!(status & KERNEL_UP_AND_RUNNING)) | 367 | if (unlikely(!(status & KERNEL_UP_AND_RUNNING))) |
| 368 | return -3; | 368 | return -3; |
| 369 | /* | 369 | /* |
| 370 | * Everything is OK | 370 | * Everything is OK |
| @@ -387,7 +387,7 @@ static int aac_rx_deliver_producer(struct fib * fib) | |||
| 387 | unsigned long nointr = 0; | 387 | unsigned long nointr = 0; |
| 388 | 388 | ||
| 389 | spin_lock_irqsave(q->lock, qflags); | 389 | spin_lock_irqsave(q->lock, qflags); |
| 390 | aac_queue_get( dev, &Index, AdapNormCmdQueue, fib->hw_fib, 1, fib, &nointr); | 390 | aac_queue_get( dev, &Index, AdapNormCmdQueue, fib->hw_fib_va, 1, fib, &nointr); |
| 391 | 391 | ||
| 392 | q->numpending++; | 392 | q->numpending++; |
| 393 | *(q->headers.producer) = cpu_to_le32(Index + 1); | 393 | *(q->headers.producer) = cpu_to_le32(Index + 1); |
| @@ -419,9 +419,9 @@ static int aac_rx_deliver_message(struct fib * fib) | |||
| 419 | spin_unlock_irqrestore(q->lock, qflags); | 419 | spin_unlock_irqrestore(q->lock, qflags); |
| 420 | for(;;) { | 420 | for(;;) { |
| 421 | Index = rx_readl(dev, MUnit.InboundQueue); | 421 | Index = rx_readl(dev, MUnit.InboundQueue); |
| 422 | if (Index == 0xFFFFFFFFL) | 422 | if (unlikely(Index == 0xFFFFFFFFL)) |
| 423 | Index = rx_readl(dev, MUnit.InboundQueue); | 423 | Index = rx_readl(dev, MUnit.InboundQueue); |
| 424 | if (Index != 0xFFFFFFFFL) | 424 | if (likely(Index != 0xFFFFFFFFL)) |
| 425 | break; | 425 | break; |
| 426 | if (--count == 0) { | 426 | if (--count == 0) { |
| 427 | spin_lock_irqsave(q->lock, qflags); | 427 | spin_lock_irqsave(q->lock, qflags); |
| @@ -437,7 +437,7 @@ static int aac_rx_deliver_message(struct fib * fib) | |||
| 437 | device += sizeof(u32); | 437 | device += sizeof(u32); |
| 438 | writel((u32)(addr >> 32), device); | 438 | writel((u32)(addr >> 32), device); |
| 439 | device += sizeof(u32); | 439 | device += sizeof(u32); |
| 440 | writel(le16_to_cpu(fib->hw_fib->header.Size), device); | 440 | writel(le16_to_cpu(fib->hw_fib_va->header.Size), device); |
| 441 | rx_writel(dev, MUnit.InboundQueue, Index); | 441 | rx_writel(dev, MUnit.InboundQueue, Index); |
| 442 | return 0; | 442 | return 0; |
| 443 | } | 443 | } |
| @@ -460,22 +460,34 @@ static int aac_rx_ioremap(struct aac_dev * dev, u32 size) | |||
| 460 | return 0; | 460 | return 0; |
| 461 | } | 461 | } |
| 462 | 462 | ||
| 463 | static int aac_rx_restart_adapter(struct aac_dev *dev) | 463 | static int aac_rx_restart_adapter(struct aac_dev *dev, int bled) |
| 464 | { | 464 | { |
| 465 | u32 var; | 465 | u32 var; |
| 466 | 466 | ||
| 467 | printk(KERN_ERR "%s%d: adapter kernel panic'd.\n", | 467 | if (bled) |
| 468 | dev->name, dev->id); | 468 | printk(KERN_ERR "%s%d: adapter kernel panic'd %x.\n", |
| 469 | 469 | dev->name, dev->id, bled); | |
| 470 | if (aac_rx_check_health(dev) <= 0) | 470 | else { |
| 471 | return 1; | 471 | bled = aac_adapter_sync_cmd(dev, IOP_RESET_ALWAYS, |
| 472 | if (rx_sync_cmd(dev, IOP_RESET, 0, 0, 0, 0, 0, 0, | 472 | 0, 0, 0, 0, 0, 0, &var, NULL, NULL, NULL, NULL); |
| 473 | &var, NULL, NULL, NULL, NULL)) | 473 | if (!bled && (var != 0x00000001)) |
| 474 | return 1; | 474 | bled = -EINVAL; |
| 475 | } | ||
| 476 | if (bled && (bled != -ETIMEDOUT)) | ||
| 477 | bled = aac_adapter_sync_cmd(dev, IOP_RESET, | ||
| 478 | 0, 0, 0, 0, 0, 0, &var, NULL, NULL, NULL, NULL); | ||
| 479 | |||
| 480 | if (bled && (bled != -ETIMEDOUT)) | ||
| 481 | return -EINVAL; | ||
| 482 | if (bled || (var == 0x3803000F)) { /* USE_OTHER_METHOD */ | ||
| 483 | rx_writel(dev, MUnit.reserved2, 3); | ||
| 484 | msleep(5000); /* Delay 5 seconds */ | ||
| 485 | var = 0x00000001; | ||
| 486 | } | ||
| 475 | if (var != 0x00000001) | 487 | if (var != 0x00000001) |
| 476 | return 1; | 488 | return -EINVAL; |
| 477 | if (rx_readl(dev, MUnit.OMRx[0]) & KERNEL_PANIC) | 489 | if (rx_readl(dev, MUnit.OMRx[0]) & KERNEL_PANIC) |
| 478 | return 1; | 490 | return -ENODEV; |
| 479 | return 0; | 491 | return 0; |
| 480 | } | 492 | } |
| 481 | 493 | ||
| @@ -517,24 +529,29 @@ int _aac_rx_init(struct aac_dev *dev) | |||
| 517 | { | 529 | { |
| 518 | unsigned long start; | 530 | unsigned long start; |
| 519 | unsigned long status; | 531 | unsigned long status; |
| 520 | int instance; | 532 | int restart = 0; |
| 521 | const char * name; | 533 | int instance = dev->id; |
| 522 | 534 | const char * name = dev->name; | |
| 523 | instance = dev->id; | ||
| 524 | name = dev->name; | ||
| 525 | 535 | ||
| 526 | if (aac_adapter_ioremap(dev, dev->base_size)) { | 536 | if (aac_adapter_ioremap(dev, dev->base_size)) { |
| 527 | printk(KERN_WARNING "%s: unable to map adapter.\n", name); | 537 | printk(KERN_WARNING "%s: unable to map adapter.\n", name); |
| 528 | goto error_iounmap; | 538 | goto error_iounmap; |
| 529 | } | 539 | } |
| 530 | 540 | ||
| 541 | /* Failure to reset here is an option ... */ | ||
| 542 | dev->OIMR = status = rx_readb (dev, MUnit.OIMR); | ||
| 543 | if ((((status & 0xff) != 0xff) || reset_devices) && | ||
| 544 | !aac_rx_restart_adapter(dev, 0)) | ||
| 545 | ++restart; | ||
| 531 | /* | 546 | /* |
| 532 | * Check to see if the board panic'd while booting. | 547 | * Check to see if the board panic'd while booting. |
| 533 | */ | 548 | */ |
| 534 | status = rx_readl(dev, MUnit.OMRx[0]); | 549 | status = rx_readl(dev, MUnit.OMRx[0]); |
| 535 | if (status & KERNEL_PANIC) | 550 | if (status & KERNEL_PANIC) { |
| 536 | if (aac_rx_restart_adapter(dev)) | 551 | if (aac_rx_restart_adapter(dev, aac_rx_check_health(dev))) |
| 537 | goto error_iounmap; | 552 | goto error_iounmap; |
| 553 | ++restart; | ||
| 554 | } | ||
| 538 | /* | 555 | /* |
| 539 | * Check to see if the board failed any self tests. | 556 | * Check to see if the board failed any self tests. |
| 540 | */ | 557 | */ |
| @@ -556,12 +573,23 @@ int _aac_rx_init(struct aac_dev *dev) | |||
| 556 | */ | 573 | */ |
| 557 | while (!((status = rx_readl(dev, MUnit.OMRx[0])) & KERNEL_UP_AND_RUNNING)) | 574 | while (!((status = rx_readl(dev, MUnit.OMRx[0])) & KERNEL_UP_AND_RUNNING)) |
| 558 | { | 575 | { |
| 559 | if(time_after(jiffies, start+startup_timeout*HZ)) | 576 | if ((restart && |
| 560 | { | 577 | (status & (KERNEL_PANIC|SELF_TEST_FAILED|MONITOR_PANIC))) || |
| 578 | time_after(jiffies, start+HZ*startup_timeout)) { | ||
| 561 | printk(KERN_ERR "%s%d: adapter kernel failed to start, init status = %lx.\n", | 579 | printk(KERN_ERR "%s%d: adapter kernel failed to start, init status = %lx.\n", |
| 562 | dev->name, instance, status); | 580 | dev->name, instance, status); |
| 563 | goto error_iounmap; | 581 | goto error_iounmap; |
| 564 | } | 582 | } |
| 583 | if (!restart && | ||
| 584 | ((status & (KERNEL_PANIC|SELF_TEST_FAILED|MONITOR_PANIC)) || | ||
| 585 | time_after(jiffies, start + HZ * | ||
| 586 | ((startup_timeout > 60) | ||
| 587 | ? (startup_timeout - 60) | ||
| 588 | : (startup_timeout / 2))))) { | ||
| 589 | if (likely(!aac_rx_restart_adapter(dev, aac_rx_check_health(dev)))) | ||
| 590 | start = jiffies; | ||
| 591 | ++restart; | ||
| 592 | } | ||
| 565 | msleep(1); | 593 | msleep(1); |
| 566 | } | 594 | } |
| 567 | /* | 595 | /* |
| @@ -572,6 +600,7 @@ int _aac_rx_init(struct aac_dev *dev) | |||
| 572 | dev->a_ops.adapter_notify = aac_rx_notify_adapter; | 600 | dev->a_ops.adapter_notify = aac_rx_notify_adapter; |
| 573 | dev->a_ops.adapter_sync_cmd = rx_sync_cmd; | 601 | dev->a_ops.adapter_sync_cmd = rx_sync_cmd; |
| 574 | dev->a_ops.adapter_check_health = aac_rx_check_health; | 602 | dev->a_ops.adapter_check_health = aac_rx_check_health; |
| 603 | dev->a_ops.adapter_restart = aac_rx_restart_adapter; | ||
| 575 | 604 | ||
| 576 | /* | 605 | /* |
| 577 | * First clear out all interrupts. Then enable the one's that we | 606 | * First clear out all interrupts. Then enable the one's that we |
diff --git a/drivers/scsi/aacraid/sa.c b/drivers/scsi/aacraid/sa.c index 6f1a1780efce..f4b5e9742ab0 100644 --- a/drivers/scsi/aacraid/sa.c +++ b/drivers/scsi/aacraid/sa.c | |||
| @@ -31,7 +31,6 @@ | |||
| 31 | #include <linux/kernel.h> | 31 | #include <linux/kernel.h> |
| 32 | #include <linux/init.h> | 32 | #include <linux/init.h> |
| 33 | #include <linux/types.h> | 33 | #include <linux/types.h> |
| 34 | #include <linux/pci.h> | ||
| 35 | #include <linux/spinlock.h> | 34 | #include <linux/spinlock.h> |
| 36 | #include <linux/slab.h> | 35 | #include <linux/slab.h> |
| 37 | #include <linux/blkdev.h> | 36 | #include <linux/blkdev.h> |
