diff options
| author | Mark Haverkamp <markh@osdl.org> | 2005-08-15 13:50:24 -0400 |
|---|---|---|
| committer | James Bottomley <jejb@mulgrave.(none)> | 2005-08-28 12:14:07 -0400 |
| commit | 3b2946cc96bfafa90a555c70b2e876cbbd0fae98 (patch) | |
| tree | 204bd462cf3e484173fea17724ed0bfa68fc614c | |
| parent | ebd8bb7647e908e8654e565fa289b0300f9f8fa7 (diff) | |
[SCSI] aacraid: Fix aacraid probe breakage (updated)
This patch fixes the bad assumption of the aacraid driver with use_sg.
I used the 3w-xxxx driver fix as a guide for this.
Signed-off-by: Mark Haverkamp <markh@osdl.org>
Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
| -rw-r--r-- | drivers/scsi/aacraid/aachba.c | 79 |
1 files changed, 53 insertions, 26 deletions
diff --git a/drivers/scsi/aacraid/aachba.c b/drivers/scsi/aacraid/aachba.c index 8e3493587299..83bfab73ff65 100644 --- a/drivers/scsi/aacraid/aachba.c +++ b/drivers/scsi/aacraid/aachba.c | |||
| @@ -349,6 +349,27 @@ static void aac_io_done(struct scsi_cmnd * scsicmd) | |||
| 349 | spin_unlock_irqrestore(host->host_lock, cpu_flags); | 349 | spin_unlock_irqrestore(host->host_lock, cpu_flags); |
| 350 | } | 350 | } |
| 351 | 351 | ||
| 352 | static void aac_internal_transfer(struct scsi_cmnd *scsicmd, void *data, unsigned int offset, unsigned int len) | ||
| 353 | { | ||
| 354 | void *buf; | ||
| 355 | unsigned int transfer_len; | ||
| 356 | struct scatterlist *sg = scsicmd->request_buffer; | ||
| 357 | |||
| 358 | if (scsicmd->use_sg) { | ||
| 359 | buf = kmap_atomic(sg->page, KM_IRQ0) + sg->offset; | ||
| 360 | transfer_len = min(sg->length, len + offset); | ||
| 361 | } else { | ||
| 362 | buf = scsicmd->request_buffer; | ||
| 363 | transfer_len = min(scsicmd->request_bufflen, len + offset); | ||
| 364 | } | ||
| 365 | |||
| 366 | memcpy(buf + offset, data, transfer_len - offset); | ||
| 367 | |||
| 368 | if (scsicmd->use_sg) | ||
| 369 | kunmap_atomic(buf - sg->offset, KM_IRQ0); | ||
| 370 | |||
| 371 | } | ||
| 372 | |||
| 352 | static void get_container_name_callback(void *context, struct fib * fibptr) | 373 | static void get_container_name_callback(void *context, struct fib * fibptr) |
| 353 | { | 374 | { |
| 354 | struct aac_get_name_resp * get_name_reply; | 375 | struct aac_get_name_resp * get_name_reply; |
| @@ -364,18 +385,22 @@ static void get_container_name_callback(void *context, struct fib * fibptr) | |||
| 364 | /* Failure is irrelevant, using default value instead */ | 385 | /* Failure is irrelevant, using default value instead */ |
| 365 | if ((le32_to_cpu(get_name_reply->status) == CT_OK) | 386 | if ((le32_to_cpu(get_name_reply->status) == CT_OK) |
| 366 | && (get_name_reply->data[0] != '\0')) { | 387 | && (get_name_reply->data[0] != '\0')) { |
| 367 | int count; | 388 | char *sp = get_name_reply->data; |
| 368 | char * dp; | ||
| 369 | char * sp = get_name_reply->data; | ||
| 370 | sp[sizeof(((struct aac_get_name_resp *)NULL)->data)-1] = '\0'; | 389 | sp[sizeof(((struct aac_get_name_resp *)NULL)->data)-1] = '\0'; |
| 371 | while (*sp == ' ') | 390 | while (*sp == ' ') |
| 372 | ++sp; | 391 | ++sp; |
| 373 | count = sizeof(((struct inquiry_data *)NULL)->inqd_pid); | 392 | if (*sp) { |
| 374 | dp = ((struct inquiry_data *)scsicmd->request_buffer)->inqd_pid; | 393 | char d[sizeof(((struct inquiry_data *)NULL)->inqd_pid)]; |
| 375 | if (*sp) do { | 394 | int count = sizeof(d); |
| 376 | *dp++ = (*sp) ? *sp++ : ' '; | 395 | char *dp = d; |
| 377 | } while (--count > 0); | 396 | do { |
| 397 | *dp++ = (*sp) ? *sp++ : ' '; | ||
| 398 | } while (--count > 0); | ||
| 399 | aac_internal_transfer(scsicmd, d, | ||
| 400 | offsetof(struct inquiry_data, inqd_pid), sizeof(d)); | ||
| 401 | } | ||
| 378 | } | 402 | } |
| 403 | |||
| 379 | scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD; | 404 | scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD; |
| 380 | 405 | ||
| 381 | fib_complete(fibptr); | 406 | fib_complete(fibptr); |
| @@ -1344,44 +1369,45 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd) | |||
| 1344 | switch (scsicmd->cmnd[0]) { | 1369 | switch (scsicmd->cmnd[0]) { |
| 1345 | case INQUIRY: | 1370 | case INQUIRY: |
| 1346 | { | 1371 | { |
| 1347 | struct inquiry_data *inq_data_ptr; | 1372 | struct inquiry_data inq_data; |
| 1348 | 1373 | ||
| 1349 | dprintk((KERN_DEBUG "INQUIRY command, ID: %d.\n", scsicmd->device->id)); | 1374 | dprintk((KERN_DEBUG "INQUIRY command, ID: %d.\n", scsicmd->device->id)); |
| 1350 | inq_data_ptr = (struct inquiry_data *)scsicmd->request_buffer; | 1375 | memset(&inq_data, 0, sizeof (struct inquiry_data)); |
| 1351 | memset(inq_data_ptr, 0, sizeof (struct inquiry_data)); | ||
| 1352 | 1376 | ||
| 1353 | inq_data_ptr->inqd_ver = 2; /* claim compliance to SCSI-2 */ | 1377 | inq_data.inqd_ver = 2; /* claim compliance to SCSI-2 */ |
| 1354 | inq_data_ptr->inqd_dtq = 0x80; /* set RMB bit to one indicating that the medium is removable */ | 1378 | inq_data.inqd_dtq = 0x80; /* set RMB bit to one indicating that the medium is removable */ |
| 1355 | inq_data_ptr->inqd_rdf = 2; /* A response data format value of two indicates that the data shall be in the format specified in SCSI-2 */ | 1379 | inq_data.inqd_rdf = 2; /* A response data format value of two indicates that the data shall be in the format specified in SCSI-2 */ |
| 1356 | inq_data_ptr->inqd_len = 31; | 1380 | inq_data.inqd_len = 31; |
| 1357 | /*Format for "pad2" is RelAdr | WBus32 | WBus16 | Sync | Linked |Reserved| CmdQue | SftRe */ | 1381 | /*Format for "pad2" is RelAdr | WBus32 | WBus16 | Sync | Linked |Reserved| CmdQue | SftRe */ |
| 1358 | inq_data_ptr->inqd_pad2= 0x32 ; /*WBus16|Sync|CmdQue */ | 1382 | inq_data.inqd_pad2= 0x32 ; /*WBus16|Sync|CmdQue */ |
| 1359 | /* | 1383 | /* |
| 1360 | * Set the Vendor, Product, and Revision Level | 1384 | * Set the Vendor, Product, and Revision Level |
| 1361 | * see: <vendor>.c i.e. aac.c | 1385 | * see: <vendor>.c i.e. aac.c |
| 1362 | */ | 1386 | */ |
| 1363 | if (scsicmd->device->id == host->this_id) { | 1387 | if (scsicmd->device->id == host->this_id) { |
| 1364 | setinqstr(cardtype, (void *) (inq_data_ptr->inqd_vid), (sizeof(container_types)/sizeof(char *))); | 1388 | setinqstr(cardtype, (void *) (inq_data.inqd_vid), (sizeof(container_types)/sizeof(char *))); |
| 1365 | inq_data_ptr->inqd_pdt = INQD_PDT_PROC; /* Processor device */ | 1389 | inq_data.inqd_pdt = INQD_PDT_PROC; /* Processor device */ |
| 1390 | aac_internal_transfer(scsicmd, &inq_data, 0, sizeof(inq_data)); | ||
| 1366 | scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD; | 1391 | scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD; |
| 1367 | scsicmd->scsi_done(scsicmd); | 1392 | scsicmd->scsi_done(scsicmd); |
| 1368 | return 0; | 1393 | return 0; |
| 1369 | } | 1394 | } |
| 1370 | setinqstr(cardtype, (void *) (inq_data_ptr->inqd_vid), fsa_dev_ptr[cid].type); | 1395 | setinqstr(cardtype, (void *) (inq_data.inqd_vid), fsa_dev_ptr[cid].type); |
| 1371 | inq_data_ptr->inqd_pdt = INQD_PDT_DA; /* Direct/random access device */ | 1396 | inq_data.inqd_pdt = INQD_PDT_DA; /* Direct/random access device */ |
| 1397 | aac_internal_transfer(scsicmd, &inq_data, 0, sizeof(inq_data)); | ||
| 1372 | return aac_get_container_name(scsicmd, cid); | 1398 | return aac_get_container_name(scsicmd, cid); |
| 1373 | } | 1399 | } |
| 1374 | case READ_CAPACITY: | 1400 | case READ_CAPACITY: |
| 1375 | { | 1401 | { |
| 1376 | u32 capacity; | 1402 | u32 capacity; |
| 1377 | char *cp; | 1403 | char cp[8]; |
| 1378 | 1404 | ||
| 1379 | dprintk((KERN_DEBUG "READ CAPACITY command.\n")); | 1405 | dprintk((KERN_DEBUG "READ CAPACITY command.\n")); |
| 1380 | if (fsa_dev_ptr[cid].size <= 0x100000000LL) | 1406 | if (fsa_dev_ptr[cid].size <= 0x100000000LL) |
| 1381 | capacity = fsa_dev_ptr[cid].size - 1; | 1407 | capacity = fsa_dev_ptr[cid].size - 1; |
| 1382 | else | 1408 | else |
| 1383 | capacity = (u32)-1; | 1409 | capacity = (u32)-1; |
| 1384 | cp = scsicmd->request_buffer; | 1410 | |
| 1385 | cp[0] = (capacity >> 24) & 0xff; | 1411 | cp[0] = (capacity >> 24) & 0xff; |
| 1386 | cp[1] = (capacity >> 16) & 0xff; | 1412 | cp[1] = (capacity >> 16) & 0xff; |
| 1387 | cp[2] = (capacity >> 8) & 0xff; | 1413 | cp[2] = (capacity >> 8) & 0xff; |
| @@ -1390,6 +1416,7 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd) | |||
| 1390 | cp[5] = 0; | 1416 | cp[5] = 0; |
| 1391 | cp[6] = 2; | 1417 | cp[6] = 2; |
| 1392 | cp[7] = 0; | 1418 | cp[7] = 0; |
| 1419 | aac_internal_transfer(scsicmd, cp, 0, sizeof(cp)); | ||
| 1393 | 1420 | ||
| 1394 | scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD; | 1421 | scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD; |
| 1395 | scsicmd->scsi_done(scsicmd); | 1422 | scsicmd->scsi_done(scsicmd); |
| @@ -1399,15 +1426,15 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd) | |||
| 1399 | 1426 | ||
| 1400 | case MODE_SENSE: | 1427 | case MODE_SENSE: |
| 1401 | { | 1428 | { |
| 1402 | char *mode_buf; | 1429 | char mode_buf[4]; |
| 1403 | 1430 | ||
| 1404 | dprintk((KERN_DEBUG "MODE SENSE command.\n")); | 1431 | dprintk((KERN_DEBUG "MODE SENSE command.\n")); |
| 1405 | mode_buf = scsicmd->request_buffer; | ||
| 1406 | mode_buf[0] = 3; /* Mode data length */ | 1432 | mode_buf[0] = 3; /* Mode data length */ |
| 1407 | mode_buf[1] = 0; /* Medium type - default */ | 1433 | mode_buf[1] = 0; /* Medium type - default */ |
| 1408 | mode_buf[2] = 0; /* Device-specific param, bit 8: 0/1 = write enabled/protected */ | 1434 | mode_buf[2] = 0; /* Device-specific param, bit 8: 0/1 = write enabled/protected */ |
| 1409 | mode_buf[3] = 0; /* Block descriptor length */ | 1435 | mode_buf[3] = 0; /* Block descriptor length */ |
| 1410 | 1436 | ||
| 1437 | aac_internal_transfer(scsicmd, mode_buf, 0, sizeof(mode_buf)); | ||
| 1411 | scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD; | 1438 | scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD; |
| 1412 | scsicmd->scsi_done(scsicmd); | 1439 | scsicmd->scsi_done(scsicmd); |
| 1413 | 1440 | ||
| @@ -1415,10 +1442,9 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd) | |||
| 1415 | } | 1442 | } |
| 1416 | case MODE_SENSE_10: | 1443 | case MODE_SENSE_10: |
| 1417 | { | 1444 | { |
| 1418 | char *mode_buf; | 1445 | char mode_buf[8]; |
| 1419 | 1446 | ||
| 1420 | dprintk((KERN_DEBUG "MODE SENSE 10 byte command.\n")); | 1447 | dprintk((KERN_DEBUG "MODE SENSE 10 byte command.\n")); |
| 1421 | mode_buf = scsicmd->request_buffer; | ||
| 1422 | mode_buf[0] = 0; /* Mode data length (MSB) */ | 1448 | mode_buf[0] = 0; /* Mode data length (MSB) */ |
| 1423 | mode_buf[1] = 6; /* Mode data length (LSB) */ | 1449 | mode_buf[1] = 6; /* Mode data length (LSB) */ |
| 1424 | mode_buf[2] = 0; /* Medium type - default */ | 1450 | mode_buf[2] = 0; /* Medium type - default */ |
| @@ -1427,6 +1453,7 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd) | |||
| 1427 | mode_buf[5] = 0; /* reserved */ | 1453 | mode_buf[5] = 0; /* reserved */ |
| 1428 | mode_buf[6] = 0; /* Block descriptor length (MSB) */ | 1454 | mode_buf[6] = 0; /* Block descriptor length (MSB) */ |
| 1429 | mode_buf[7] = 0; /* Block descriptor length (LSB) */ | 1455 | mode_buf[7] = 0; /* Block descriptor length (LSB) */ |
| 1456 | aac_internal_transfer(scsicmd, mode_buf, 0, sizeof(mode_buf)); | ||
| 1430 | 1457 | ||
| 1431 | scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD; | 1458 | scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD; |
| 1432 | scsicmd->scsi_done(scsicmd); | 1459 | scsicmd->scsi_done(scsicmd); |
