diff options
Diffstat (limited to 'drivers/scsi/53c700.c')
-rw-r--r-- | drivers/scsi/53c700.c | 107 |
1 files changed, 56 insertions, 51 deletions
diff --git a/drivers/scsi/53c700.c b/drivers/scsi/53c700.c index 6a0f9506ea0..3c683dc2354 100644 --- a/drivers/scsi/53c700.c +++ b/drivers/scsi/53c700.c | |||
@@ -183,6 +183,10 @@ STATIC struct device_attribute *NCR_700_dev_attrs[]; | |||
183 | 183 | ||
184 | STATIC struct scsi_transport_template *NCR_700_transport_template = NULL; | 184 | STATIC struct scsi_transport_template *NCR_700_transport_template = NULL; |
185 | 185 | ||
186 | struct NCR_700_sense { | ||
187 | unsigned char cmnd[MAX_COMMAND_SIZE]; | ||
188 | }; | ||
189 | |||
186 | static char *NCR_700_phase[] = { | 190 | static char *NCR_700_phase[] = { |
187 | "", | 191 | "", |
188 | "after selection", | 192 | "after selection", |
@@ -316,7 +320,7 @@ NCR_700_detect(struct scsi_host_template *tpnt, | |||
316 | BUG_ON(!dma_is_consistent(pScript) && L1_CACHE_BYTES < dma_get_cache_alignment()); | 320 | BUG_ON(!dma_is_consistent(pScript) && L1_CACHE_BYTES < dma_get_cache_alignment()); |
317 | hostdata->slots = (struct NCR_700_command_slot *)(memory + SLOTS_OFFSET); | 321 | hostdata->slots = (struct NCR_700_command_slot *)(memory + SLOTS_OFFSET); |
318 | hostdata->dev = dev; | 322 | hostdata->dev = dev; |
319 | 323 | ||
320 | pSlots = pScript + SLOTS_OFFSET; | 324 | pSlots = pScript + SLOTS_OFFSET; |
321 | 325 | ||
322 | /* Fill in the missing routines from the host template */ | 326 | /* Fill in the missing routines from the host template */ |
@@ -332,19 +336,18 @@ NCR_700_detect(struct scsi_host_template *tpnt, | |||
332 | tpnt->slave_destroy = NCR_700_slave_destroy; | 336 | tpnt->slave_destroy = NCR_700_slave_destroy; |
333 | tpnt->change_queue_depth = NCR_700_change_queue_depth; | 337 | tpnt->change_queue_depth = NCR_700_change_queue_depth; |
334 | tpnt->change_queue_type = NCR_700_change_queue_type; | 338 | tpnt->change_queue_type = NCR_700_change_queue_type; |
335 | 339 | ||
336 | if(tpnt->name == NULL) | 340 | if(tpnt->name == NULL) |
337 | tpnt->name = "53c700"; | 341 | tpnt->name = "53c700"; |
338 | if(tpnt->proc_name == NULL) | 342 | if(tpnt->proc_name == NULL) |
339 | tpnt->proc_name = "53c700"; | 343 | tpnt->proc_name = "53c700"; |
340 | |||
341 | 344 | ||
342 | host = scsi_host_alloc(tpnt, 4); | 345 | host = scsi_host_alloc(tpnt, 4); |
343 | if (!host) | 346 | if (!host) |
344 | return NULL; | 347 | return NULL; |
345 | memset(hostdata->slots, 0, sizeof(struct NCR_700_command_slot) | 348 | memset(hostdata->slots, 0, sizeof(struct NCR_700_command_slot) |
346 | * NCR_700_COMMAND_SLOTS_PER_HOST); | 349 | * NCR_700_COMMAND_SLOTS_PER_HOST); |
347 | for(j = 0; j < NCR_700_COMMAND_SLOTS_PER_HOST; j++) { | 350 | for (j = 0; j < NCR_700_COMMAND_SLOTS_PER_HOST; j++) { |
348 | dma_addr_t offset = (dma_addr_t)((unsigned long)&hostdata->slots[j].SG[0] | 351 | dma_addr_t offset = (dma_addr_t)((unsigned long)&hostdata->slots[j].SG[0] |
349 | - (unsigned long)&hostdata->slots[0].SG[0]); | 352 | - (unsigned long)&hostdata->slots[0].SG[0]); |
350 | hostdata->slots[j].pSG = (struct NCR_700_SG_List *)((unsigned long)(pSlots + offset)); | 353 | hostdata->slots[j].pSG = (struct NCR_700_SG_List *)((unsigned long)(pSlots + offset)); |
@@ -355,14 +358,12 @@ NCR_700_detect(struct scsi_host_template *tpnt, | |||
355 | hostdata->slots[j].state = NCR_700_SLOT_FREE; | 358 | hostdata->slots[j].state = NCR_700_SLOT_FREE; |
356 | } | 359 | } |
357 | 360 | ||
358 | for(j = 0; j < sizeof(SCRIPT)/sizeof(SCRIPT[0]); j++) { | 361 | for (j = 0; j < ARRAY_SIZE(SCRIPT); j++) |
359 | script[j] = bS_to_host(SCRIPT[j]); | 362 | script[j] = bS_to_host(SCRIPT[j]); |
360 | } | ||
361 | 363 | ||
362 | /* adjust all labels to be bus physical */ | 364 | /* adjust all labels to be bus physical */ |
363 | for(j = 0; j < PATCHES; j++) { | 365 | for (j = 0; j < PATCHES; j++) |
364 | script[LABELPATCHES[j]] = bS_to_host(pScript + SCRIPT[LABELPATCHES[j]]); | 366 | script[LABELPATCHES[j]] = bS_to_host(pScript + SCRIPT[LABELPATCHES[j]]); |
365 | } | ||
366 | /* now patch up fixed addresses. */ | 367 | /* now patch up fixed addresses. */ |
367 | script_patch_32(script, MessageLocation, | 368 | script_patch_32(script, MessageLocation, |
368 | pScript + MSGOUT_OFFSET); | 369 | pScript + MSGOUT_OFFSET); |
@@ -376,7 +377,7 @@ NCR_700_detect(struct scsi_host_template *tpnt, | |||
376 | dma_sync_single_for_device(hostdata->dev, pScript, sizeof(SCRIPT), DMA_TO_DEVICE); | 377 | dma_sync_single_for_device(hostdata->dev, pScript, sizeof(SCRIPT), DMA_TO_DEVICE); |
377 | hostdata->state = NCR_700_HOST_FREE; | 378 | hostdata->state = NCR_700_HOST_FREE; |
378 | hostdata->cmd = NULL; | 379 | hostdata->cmd = NULL; |
379 | host->max_id = 7; | 380 | host->max_id = 8; |
380 | host->max_lun = NCR_700_MAX_LUNS; | 381 | host->max_lun = NCR_700_MAX_LUNS; |
381 | BUG_ON(NCR_700_transport_template == NULL); | 382 | BUG_ON(NCR_700_transport_template == NULL); |
382 | host->transportt = NCR_700_transport_template; | 383 | host->transportt = NCR_700_transport_template; |
@@ -385,17 +386,17 @@ NCR_700_detect(struct scsi_host_template *tpnt, | |||
385 | host->hostdata[0] = (unsigned long)hostdata; | 386 | host->hostdata[0] = (unsigned long)hostdata; |
386 | /* kick the chip */ | 387 | /* kick the chip */ |
387 | NCR_700_writeb(0xff, host, CTEST9_REG); | 388 | NCR_700_writeb(0xff, host, CTEST9_REG); |
388 | if(hostdata->chip710) | 389 | if (hostdata->chip710) |
389 | hostdata->rev = (NCR_700_readb(host, CTEST8_REG)>>4) & 0x0f; | 390 | hostdata->rev = (NCR_700_readb(host, CTEST8_REG)>>4) & 0x0f; |
390 | else | 391 | else |
391 | hostdata->rev = (NCR_700_readb(host, CTEST7_REG)>>4) & 0x0f; | 392 | hostdata->rev = (NCR_700_readb(host, CTEST7_REG)>>4) & 0x0f; |
392 | hostdata->fast = (NCR_700_readb(host, CTEST9_REG) == 0); | 393 | hostdata->fast = (NCR_700_readb(host, CTEST9_REG) == 0); |
393 | if(banner == 0) { | 394 | if (banner == 0) { |
394 | printk(KERN_NOTICE "53c700: Version " NCR_700_VERSION " By James.Bottomley@HansenPartnership.com\n"); | 395 | printk(KERN_NOTICE "53c700: Version " NCR_700_VERSION " By James.Bottomley@HansenPartnership.com\n"); |
395 | banner = 1; | 396 | banner = 1; |
396 | } | 397 | } |
397 | printk(KERN_NOTICE "scsi%d: %s rev %d %s\n", host->host_no, | 398 | printk(KERN_NOTICE "scsi%d: %s rev %d %s\n", host->host_no, |
398 | hostdata->chip710 ? "53c710" : | 399 | hostdata->chip710 ? "53c710" : |
399 | (hostdata->fast ? "53c700-66" : "53c700"), | 400 | (hostdata->fast ? "53c700-66" : "53c700"), |
400 | hostdata->rev, hostdata->differential ? | 401 | hostdata->rev, hostdata->differential ? |
401 | "(Differential)" : ""); | 402 | "(Differential)" : ""); |
@@ -540,6 +541,7 @@ find_empty_slot(struct NCR_700_Host_Parameters *hostdata) | |||
540 | * finish routine. If we cannot queue the command when it | 541 | * finish routine. If we cannot queue the command when it |
541 | * is properly build, we then change to NCR_700_SLOT_QUEUED */ | 542 | * is properly build, we then change to NCR_700_SLOT_QUEUED */ |
542 | slot->state = NCR_700_SLOT_BUSY; | 543 | slot->state = NCR_700_SLOT_BUSY; |
544 | slot->flags = 0; | ||
543 | hostdata->command_slot_count++; | 545 | hostdata->command_slot_count++; |
544 | 546 | ||
545 | return slot; | 547 | return slot; |
@@ -589,7 +591,7 @@ NCR_700_unmap(struct NCR_700_Host_Parameters *hostdata, struct scsi_cmnd *SCp, | |||
589 | if(SCp->sc_data_direction != DMA_NONE && | 591 | if(SCp->sc_data_direction != DMA_NONE && |
590 | SCp->sc_data_direction != DMA_BIDIRECTIONAL) { | 592 | SCp->sc_data_direction != DMA_BIDIRECTIONAL) { |
591 | if(SCp->use_sg) { | 593 | if(SCp->use_sg) { |
592 | dma_unmap_sg(hostdata->dev, SCp->buffer, | 594 | dma_unmap_sg(hostdata->dev, SCp->request_buffer, |
593 | SCp->use_sg, SCp->sc_data_direction); | 595 | SCp->use_sg, SCp->sc_data_direction); |
594 | } else { | 596 | } else { |
595 | dma_unmap_single(hostdata->dev, slot->dma_handle, | 597 | dma_unmap_single(hostdata->dev, slot->dma_handle, |
@@ -611,30 +613,23 @@ NCR_700_scsi_done(struct NCR_700_Host_Parameters *hostdata, | |||
611 | (struct NCR_700_command_slot *)SCp->host_scribble; | 613 | (struct NCR_700_command_slot *)SCp->host_scribble; |
612 | 614 | ||
613 | NCR_700_unmap(hostdata, SCp, slot); | 615 | NCR_700_unmap(hostdata, SCp, slot); |
614 | dma_unmap_single(hostdata->dev, slot->pCmd, | 616 | if (slot->flags == NCR_700_FLAG_AUTOSENSE) { |
615 | sizeof(SCp->cmnd), DMA_TO_DEVICE); | 617 | struct NCR_700_sense *sense = SCp->device->hostdata; |
616 | if(SCp->cmnd[0] == REQUEST_SENSE && SCp->cmnd[6] == NCR_700_INTERNAL_SENSE_MAGIC) { | ||
617 | #ifdef NCR_700_DEBUG | 618 | #ifdef NCR_700_DEBUG |
618 | printk(" ORIGINAL CMD %p RETURNED %d, new return is %d sense is\n", | 619 | printk(" ORIGINAL CMD %p RETURNED %d, new return is %d sense is\n", |
619 | SCp, SCp->cmnd[7], result); | 620 | SCp, SCp->cmnd[7], result); |
620 | scsi_print_sense("53c700", SCp); | 621 | scsi_print_sense("53c700", SCp); |
621 | 622 | ||
622 | #endif | 623 | #endif |
624 | dma_unmap_single(hostdata->dev, slot->dma_handle, sizeof(SCp->sense_buffer), DMA_FROM_DEVICE); | ||
623 | /* restore the old result if the request sense was | 625 | /* restore the old result if the request sense was |
624 | * successful */ | 626 | * successful */ |
625 | if(result == 0) | 627 | if(result == 0) |
626 | result = SCp->cmnd[7]; | 628 | result = sense->cmnd[7]; |
627 | /* now restore the original command */ | 629 | } else |
628 | memcpy((void *) SCp->cmnd, (void *) SCp->data_cmnd, | 630 | dma_unmap_single(hostdata->dev, slot->pCmd, |
629 | sizeof(SCp->data_cmnd)); | 631 | sizeof(SCp->cmnd), DMA_TO_DEVICE); |
630 | SCp->request_buffer = SCp->buffer; | 632 | |
631 | SCp->request_bufflen = SCp->bufflen; | ||
632 | SCp->use_sg = SCp->old_use_sg; | ||
633 | SCp->cmd_len = SCp->old_cmd_len; | ||
634 | SCp->sc_data_direction = SCp->sc_old_data_direction; | ||
635 | SCp->underflow = SCp->old_underflow; | ||
636 | |||
637 | } | ||
638 | free_slot(slot, hostdata); | 633 | free_slot(slot, hostdata); |
639 | #ifdef NCR_700_DEBUG | 634 | #ifdef NCR_700_DEBUG |
640 | if(NCR_700_get_depth(SCp->device) == 0 || | 635 | if(NCR_700_get_depth(SCp->device) == 0 || |
@@ -982,6 +977,7 @@ process_script_interrupt(__u32 dsps, __u32 dsp, struct scsi_cmnd *SCp, | |||
982 | "broken device is looping in contingent allegiance: ignoring\n"); | 977 | "broken device is looping in contingent allegiance: ignoring\n"); |
983 | NCR_700_scsi_done(hostdata, SCp, hostdata->status[0]); | 978 | NCR_700_scsi_done(hostdata, SCp, hostdata->status[0]); |
984 | } else { | 979 | } else { |
980 | struct NCR_700_sense *sense = SCp->device->hostdata; | ||
985 | #ifdef NCR_DEBUG | 981 | #ifdef NCR_DEBUG |
986 | scsi_print_command(SCp); | 982 | scsi_print_command(SCp); |
987 | printk(" cmd %p has status %d, requesting sense\n", | 983 | printk(" cmd %p has status %d, requesting sense\n", |
@@ -995,27 +991,25 @@ process_script_interrupt(__u32 dsps, __u32 dsp, struct scsi_cmnd *SCp, | |||
995 | * data associated with the command | 991 | * data associated with the command |
996 | * here */ | 992 | * here */ |
997 | NCR_700_unmap(hostdata, SCp, slot); | 993 | NCR_700_unmap(hostdata, SCp, slot); |
998 | 994 | dma_unmap_single(hostdata->dev, slot->pCmd, | |
999 | SCp->cmnd[0] = REQUEST_SENSE; | 995 | sizeof(SCp->cmnd), |
1000 | SCp->cmnd[1] = (SCp->device->lun & 0x7) << 5; | 996 | DMA_TO_DEVICE); |
1001 | SCp->cmnd[2] = 0; | 997 | |
1002 | SCp->cmnd[3] = 0; | 998 | sense->cmnd[0] = REQUEST_SENSE; |
1003 | SCp->cmnd[4] = sizeof(SCp->sense_buffer); | 999 | sense->cmnd[1] = (SCp->device->lun & 0x7) << 5; |
1004 | SCp->cmnd[5] = 0; | 1000 | sense->cmnd[2] = 0; |
1005 | SCp->cmd_len = 6; | 1001 | sense->cmnd[3] = 0; |
1002 | sense->cmnd[4] = sizeof(SCp->sense_buffer); | ||
1003 | sense->cmnd[5] = 0; | ||
1006 | /* Here's a quiet hack: the | 1004 | /* Here's a quiet hack: the |
1007 | * REQUEST_SENSE command is six bytes, | 1005 | * REQUEST_SENSE command is six bytes, |
1008 | * so store a flag indicating that | 1006 | * so store a flag indicating that |
1009 | * this was an internal sense request | 1007 | * this was an internal sense request |
1010 | * and the original status at the end | 1008 | * and the original status at the end |
1011 | * of the command */ | 1009 | * of the command */ |
1012 | SCp->cmnd[6] = NCR_700_INTERNAL_SENSE_MAGIC; | 1010 | sense->cmnd[6] = NCR_700_INTERNAL_SENSE_MAGIC; |
1013 | SCp->cmnd[7] = hostdata->status[0]; | 1011 | sense->cmnd[7] = hostdata->status[0]; |
1014 | SCp->use_sg = 0; | 1012 | slot->pCmd = dma_map_single(hostdata->dev, sense->cmnd, sizeof(sense->cmnd), DMA_TO_DEVICE); |
1015 | SCp->sc_data_direction = DMA_FROM_DEVICE; | ||
1016 | dma_sync_single_for_device(hostdata->dev, slot->pCmd, | ||
1017 | SCp->cmd_len, DMA_TO_DEVICE); | ||
1018 | SCp->request_bufflen = sizeof(SCp->sense_buffer); | ||
1019 | slot->dma_handle = dma_map_single(hostdata->dev, SCp->sense_buffer, sizeof(SCp->sense_buffer), DMA_FROM_DEVICE); | 1013 | slot->dma_handle = dma_map_single(hostdata->dev, SCp->sense_buffer, sizeof(SCp->sense_buffer), DMA_FROM_DEVICE); |
1020 | slot->SG[0].ins = bS_to_host(SCRIPT_MOVE_DATA_IN | sizeof(SCp->sense_buffer)); | 1014 | slot->SG[0].ins = bS_to_host(SCRIPT_MOVE_DATA_IN | sizeof(SCp->sense_buffer)); |
1021 | slot->SG[0].pAddr = bS_to_host(slot->dma_handle); | 1015 | slot->SG[0].pAddr = bS_to_host(slot->dma_handle); |
@@ -1027,6 +1021,7 @@ process_script_interrupt(__u32 dsps, __u32 dsp, struct scsi_cmnd *SCp, | |||
1027 | 1021 | ||
1028 | /* queue the command for reissue */ | 1022 | /* queue the command for reissue */ |
1029 | slot->state = NCR_700_SLOT_QUEUED; | 1023 | slot->state = NCR_700_SLOT_QUEUED; |
1024 | slot->flags = NCR_700_FLAG_AUTOSENSE; | ||
1030 | hostdata->state = NCR_700_HOST_FREE; | 1025 | hostdata->state = NCR_700_HOST_FREE; |
1031 | hostdata->cmd = NULL; | 1026 | hostdata->cmd = NULL; |
1032 | } | 1027 | } |
@@ -1247,7 +1242,7 @@ process_script_interrupt(__u32 dsps, __u32 dsp, struct scsi_cmnd *SCp, | |||
1247 | 1242 | ||
1248 | if(SCp->use_sg) { | 1243 | if(SCp->use_sg) { |
1249 | for(i = 0; i < SCp->use_sg + 1; i++) { | 1244 | for(i = 0; i < SCp->use_sg + 1; i++) { |
1250 | printk(KERN_INFO " SG[%d].length = %d, move_insn=%08x, addr %08x\n", i, ((struct scatterlist *)SCp->buffer)[i].length, ((struct NCR_700_command_slot *)SCp->host_scribble)->SG[i].ins, ((struct NCR_700_command_slot *)SCp->host_scribble)->SG[i].pAddr); | 1245 | printk(KERN_INFO " SG[%d].length = %d, move_insn=%08x, addr %08x\n", i, ((struct scatterlist *)SCp->request_buffer)[i].length, ((struct NCR_700_command_slot *)SCp->host_scribble)->SG[i].ins, ((struct NCR_700_command_slot *)SCp->host_scribble)->SG[i].pAddr); |
1251 | } | 1246 | } |
1252 | } | 1247 | } |
1253 | } | 1248 | } |
@@ -1406,12 +1401,14 @@ NCR_700_start_command(struct scsi_cmnd *SCp) | |||
1406 | /* keep interrupts disabled until we have the command correctly | 1401 | /* keep interrupts disabled until we have the command correctly |
1407 | * set up so we cannot take a selection interrupt */ | 1402 | * set up so we cannot take a selection interrupt */ |
1408 | 1403 | ||
1409 | hostdata->msgout[0] = NCR_700_identify(SCp->cmnd[0] != REQUEST_SENSE, | 1404 | hostdata->msgout[0] = NCR_700_identify((SCp->cmnd[0] != REQUEST_SENSE && |
1405 | slot->flags != NCR_700_FLAG_AUTOSENSE), | ||
1410 | SCp->device->lun); | 1406 | SCp->device->lun); |
1411 | /* for INQUIRY or REQUEST_SENSE commands, we cannot be sure | 1407 | /* for INQUIRY or REQUEST_SENSE commands, we cannot be sure |
1412 | * if the negotiated transfer parameters still hold, so | 1408 | * if the negotiated transfer parameters still hold, so |
1413 | * always renegotiate them */ | 1409 | * always renegotiate them */ |
1414 | if(SCp->cmnd[0] == INQUIRY || SCp->cmnd[0] == REQUEST_SENSE) { | 1410 | if(SCp->cmnd[0] == INQUIRY || SCp->cmnd[0] == REQUEST_SENSE || |
1411 | slot->flags == NCR_700_FLAG_AUTOSENSE) { | ||
1415 | NCR_700_clear_flag(SCp->device, NCR_700_DEV_NEGOTIATED_SYNC); | 1412 | NCR_700_clear_flag(SCp->device, NCR_700_DEV_NEGOTIATED_SYNC); |
1416 | } | 1413 | } |
1417 | 1414 | ||
@@ -1420,7 +1417,8 @@ NCR_700_start_command(struct scsi_cmnd *SCp) | |||
1420 | * will refuse all tags, so send the request sense as untagged | 1417 | * will refuse all tags, so send the request sense as untagged |
1421 | * */ | 1418 | * */ |
1422 | if((hostdata->tag_negotiated & (1<<scmd_id(SCp))) | 1419 | if((hostdata->tag_negotiated & (1<<scmd_id(SCp))) |
1423 | && (slot->tag != SCSI_NO_TAG && SCp->cmnd[0] != REQUEST_SENSE)) { | 1420 | && (slot->tag != SCSI_NO_TAG && SCp->cmnd[0] != REQUEST_SENSE && |
1421 | slot->flags != NCR_700_FLAG_AUTOSENSE)) { | ||
1424 | count += scsi_populate_tag_msg(SCp, &hostdata->msgout[count]); | 1422 | count += scsi_populate_tag_msg(SCp, &hostdata->msgout[count]); |
1425 | } | 1423 | } |
1426 | 1424 | ||
@@ -1866,8 +1864,9 @@ NCR_700_queuecommand(struct scsi_cmnd *SCp, void (*done)(struct scsi_cmnd *)) | |||
1866 | __u32 count = 0; | 1864 | __u32 count = 0; |
1867 | 1865 | ||
1868 | if(SCp->use_sg) { | 1866 | if(SCp->use_sg) { |
1869 | sg_count = dma_map_sg(hostdata->dev, SCp->buffer, | 1867 | sg_count = dma_map_sg(hostdata->dev, |
1870 | SCp->use_sg, direction); | 1868 | SCp->request_buffer, SCp->use_sg, |
1869 | direction); | ||
1871 | } else { | 1870 | } else { |
1872 | vPtr = dma_map_single(hostdata->dev, | 1871 | vPtr = dma_map_single(hostdata->dev, |
1873 | SCp->request_buffer, | 1872 | SCp->request_buffer, |
@@ -1882,7 +1881,7 @@ NCR_700_queuecommand(struct scsi_cmnd *SCp, void (*done)(struct scsi_cmnd *)) | |||
1882 | for(i = 0; i < sg_count; i++) { | 1881 | for(i = 0; i < sg_count; i++) { |
1883 | 1882 | ||
1884 | if(SCp->use_sg) { | 1883 | if(SCp->use_sg) { |
1885 | struct scatterlist *sg = SCp->buffer; | 1884 | struct scatterlist *sg = SCp->request_buffer; |
1886 | 1885 | ||
1887 | vPtr = sg_dma_address(&sg[i]); | 1886 | vPtr = sg_dma_address(&sg[i]); |
1888 | count = sg_dma_len(&sg[i]); | 1887 | count = sg_dma_len(&sg[i]); |
@@ -2045,6 +2044,11 @@ NCR_700_slave_configure(struct scsi_device *SDp) | |||
2045 | struct NCR_700_Host_Parameters *hostdata = | 2044 | struct NCR_700_Host_Parameters *hostdata = |
2046 | (struct NCR_700_Host_Parameters *)SDp->host->hostdata[0]; | 2045 | (struct NCR_700_Host_Parameters *)SDp->host->hostdata[0]; |
2047 | 2046 | ||
2047 | SDp->hostdata = kmalloc(GFP_KERNEL, sizeof(struct NCR_700_sense)); | ||
2048 | |||
2049 | if (!SDp->hostdata) | ||
2050 | return -ENOMEM; | ||
2051 | |||
2048 | /* to do here: allocate memory; build a queue_full list */ | 2052 | /* to do here: allocate memory; build a queue_full list */ |
2049 | if(SDp->tagged_supported) { | 2053 | if(SDp->tagged_supported) { |
2050 | scsi_set_tag_type(SDp, MSG_ORDERED_TAG); | 2054 | scsi_set_tag_type(SDp, MSG_ORDERED_TAG); |
@@ -2068,7 +2072,8 @@ NCR_700_slave_configure(struct scsi_device *SDp) | |||
2068 | STATIC void | 2072 | STATIC void |
2069 | NCR_700_slave_destroy(struct scsi_device *SDp) | 2073 | NCR_700_slave_destroy(struct scsi_device *SDp) |
2070 | { | 2074 | { |
2071 | /* to do here: deallocate memory */ | 2075 | kfree(SDp->hostdata); |
2076 | SDp->hostdata = NULL; | ||
2072 | } | 2077 | } |
2073 | 2078 | ||
2074 | static int | 2079 | static int |