aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi
diff options
context:
space:
mode:
authorMark Haverkamp <markh@osdl.org>2005-08-15 13:50:24 -0400
committerJames Bottomley <jejb@mulgrave.(none)>2005-08-28 12:14:07 -0400
commit3b2946cc96bfafa90a555c70b2e876cbbd0fae98 (patch)
tree204bd462cf3e484173fea17724ed0bfa68fc614c /drivers/scsi
parentebd8bb7647e908e8654e565fa289b0300f9f8fa7 (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>
Diffstat (limited to 'drivers/scsi')
-rw-r--r--drivers/scsi/aacraid/aachba.c79
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
352static 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
352static void get_container_name_callback(void *context, struct fib * fibptr) 373static 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);