diff options
Diffstat (limited to 'drivers/scsi/a100u2w.c')
-rw-r--r-- | drivers/scsi/a100u2w.c | 49 |
1 files changed, 28 insertions, 21 deletions
diff --git a/drivers/scsi/a100u2w.c b/drivers/scsi/a100u2w.c index ced3eebe252c..84bb61628372 100644 --- a/drivers/scsi/a100u2w.c +++ b/drivers/scsi/a100u2w.c | |||
@@ -389,7 +389,7 @@ static u8 orc_load_firmware(struct orc_host * host) | |||
389 | 389 | ||
390 | outb(PRGMRST | DOWNLOAD, host->base + ORC_RISCCTL); /* Enable SRAM programming */ | 390 | outb(PRGMRST | DOWNLOAD, host->base + ORC_RISCCTL); /* Enable SRAM programming */ |
391 | data32_ptr = (u8 *) & data32; | 391 | data32_ptr = (u8 *) & data32; |
392 | data32 = 0; /* Initial FW address to 0 */ | 392 | data32 = cpu_to_le32(0); /* Initial FW address to 0 */ |
393 | outw(0x0010, host->base + ORC_EBIOSADR0); | 393 | outw(0x0010, host->base + ORC_EBIOSADR0); |
394 | *data32_ptr = inb(host->base + ORC_EBIOSDATA); /* Read from BIOS */ | 394 | *data32_ptr = inb(host->base + ORC_EBIOSDATA); /* Read from BIOS */ |
395 | outw(0x0011, host->base + ORC_EBIOSADR0); | 395 | outw(0x0011, host->base + ORC_EBIOSADR0); |
@@ -397,18 +397,19 @@ static u8 orc_load_firmware(struct orc_host * host) | |||
397 | outw(0x0012, host->base + ORC_EBIOSADR0); | 397 | outw(0x0012, host->base + ORC_EBIOSADR0); |
398 | *(data32_ptr + 2) = inb(host->base + ORC_EBIOSDATA); /* Read from BIOS */ | 398 | *(data32_ptr + 2) = inb(host->base + ORC_EBIOSDATA); /* Read from BIOS */ |
399 | outw(*(data32_ptr + 2), host->base + ORC_EBIOSADR2); | 399 | outw(*(data32_ptr + 2), host->base + ORC_EBIOSADR2); |
400 | outl(data32, host->base + ORC_FWBASEADR); /* Write FW address */ | 400 | outl(le32_to_cpu(data32), host->base + ORC_FWBASEADR); /* Write FW address */ |
401 | 401 | ||
402 | /* Copy the code from the BIOS to the SRAM */ | 402 | /* Copy the code from the BIOS to the SRAM */ |
403 | 403 | ||
404 | bios_addr = (u16) data32; /* FW code locate at BIOS address + ? */ | 404 | udelay(500); /* Required on Sun Ultra 5 ... 350 -> failures */ |
405 | bios_addr = (u16) le32_to_cpu(data32); /* FW code locate at BIOS address + ? */ | ||
405 | for (i = 0, data32_ptr = (u8 *) & data32; /* Download the code */ | 406 | for (i = 0, data32_ptr = (u8 *) & data32; /* Download the code */ |
406 | i < 0x1000; /* Firmware code size = 4K */ | 407 | i < 0x1000; /* Firmware code size = 4K */ |
407 | i++, bios_addr++) { | 408 | i++, bios_addr++) { |
408 | outw(bios_addr, host->base + ORC_EBIOSADR0); | 409 | outw(bios_addr, host->base + ORC_EBIOSADR0); |
409 | *data32_ptr++ = inb(host->base + ORC_EBIOSDATA); /* Read from BIOS */ | 410 | *data32_ptr++ = inb(host->base + ORC_EBIOSDATA); /* Read from BIOS */ |
410 | if ((i % 4) == 3) { | 411 | if ((i % 4) == 3) { |
411 | outl(data32, host->base + ORC_RISCRAM); /* Write every 4 bytes */ | 412 | outl(le32_to_cpu(data32), host->base + ORC_RISCRAM); /* Write every 4 bytes */ |
412 | data32_ptr = (u8 *) & data32; | 413 | data32_ptr = (u8 *) & data32; |
413 | } | 414 | } |
414 | } | 415 | } |
@@ -423,7 +424,7 @@ static u8 orc_load_firmware(struct orc_host * host) | |||
423 | outw(bios_addr, host->base + ORC_EBIOSADR0); | 424 | outw(bios_addr, host->base + ORC_EBIOSADR0); |
424 | *data32_ptr++ = inb(host->base + ORC_EBIOSDATA); /* Read from BIOS */ | 425 | *data32_ptr++ = inb(host->base + ORC_EBIOSDATA); /* Read from BIOS */ |
425 | if ((i % 4) == 3) { | 426 | if ((i % 4) == 3) { |
426 | if (inl(host->base + ORC_RISCRAM) != data32) { | 427 | if (inl(host->base + ORC_RISCRAM) != le32_to_cpu(data32)) { |
427 | outb(PRGMRST, host->base + ORC_RISCCTL); /* Reset program to 0 */ | 428 | outb(PRGMRST, host->base + ORC_RISCCTL); /* Reset program to 0 */ |
428 | outb(data, host->base + ORC_GCFG); /*Disable EEPROM programming */ | 429 | outb(data, host->base + ORC_GCFG); /*Disable EEPROM programming */ |
429 | return 0; | 430 | return 0; |
@@ -459,8 +460,8 @@ static void setup_SCBs(struct orc_host * host) | |||
459 | 460 | ||
460 | for (i = 0; i < ORC_MAXQUEUE; i++) { | 461 | for (i = 0; i < ORC_MAXQUEUE; i++) { |
461 | escb_phys = (host->escb_phys + (sizeof(struct orc_extended_scb) * i)); | 462 | escb_phys = (host->escb_phys + (sizeof(struct orc_extended_scb) * i)); |
462 | scb->sg_addr = (u32) escb_phys; | 463 | scb->sg_addr = cpu_to_le32((u32) escb_phys); |
463 | scb->sense_addr = (u32) escb_phys; | 464 | scb->sense_addr = cpu_to_le32((u32) escb_phys); |
464 | scb->escb = escb; | 465 | scb->escb = escb; |
465 | scb->scbidx = i; | 466 | scb->scbidx = i; |
466 | scb++; | 467 | scb++; |
@@ -642,8 +643,8 @@ static int orc_device_reset(struct orc_host * host, struct scsi_cmnd *cmd, unsig | |||
642 | scb->link = 0xFF; | 643 | scb->link = 0xFF; |
643 | scb->reserved0 = 0; | 644 | scb->reserved0 = 0; |
644 | scb->reserved1 = 0; | 645 | scb->reserved1 = 0; |
645 | scb->xferlen = 0; | 646 | scb->xferlen = cpu_to_le32(0); |
646 | scb->sg_len = 0; | 647 | scb->sg_len = cpu_to_le32(0); |
647 | 648 | ||
648 | escb->srb = NULL; | 649 | escb->srb = NULL; |
649 | escb->srb = cmd; | 650 | escb->srb = cmd; |
@@ -839,7 +840,7 @@ static irqreturn_t orc_interrupt(struct orc_host * host) | |||
839 | * Build a host adapter control block from the SCSI mid layer command | 840 | * Build a host adapter control block from the SCSI mid layer command |
840 | */ | 841 | */ |
841 | 842 | ||
842 | static void inia100_build_scb(struct orc_host * host, struct orc_scb * scb, struct scsi_cmnd * cmd) | 843 | static int inia100_build_scb(struct orc_host * host, struct orc_scb * scb, struct scsi_cmnd * cmd) |
843 | { /* Create corresponding SCB */ | 844 | { /* Create corresponding SCB */ |
844 | struct scatterlist *sg; | 845 | struct scatterlist *sg; |
845 | struct orc_sgent *sgent; /* Pointer to SG list */ | 846 | struct orc_sgent *sgent; /* Pointer to SG list */ |
@@ -858,28 +859,30 @@ static void inia100_build_scb(struct orc_host * host, struct orc_scb * scb, stru | |||
858 | scb->lun = cmd->device->lun; | 859 | scb->lun = cmd->device->lun; |
859 | scb->reserved0 = 0; | 860 | scb->reserved0 = 0; |
860 | scb->reserved1 = 0; | 861 | scb->reserved1 = 0; |
861 | scb->sg_len = 0; | 862 | scb->sg_len = cpu_to_le32(0); |
862 | 863 | ||
863 | scb->xferlen = (u32) scsi_bufflen(cmd); | 864 | scb->xferlen = cpu_to_le32((u32) scsi_bufflen(cmd)); |
864 | sgent = (struct orc_sgent *) & escb->sglist[0]; | 865 | sgent = (struct orc_sgent *) & escb->sglist[0]; |
865 | 866 | ||
866 | count_sg = scsi_dma_map(cmd); | 867 | count_sg = scsi_dma_map(cmd); |
867 | BUG_ON(count_sg < 0); | 868 | if (count_sg < 0) |
869 | return count_sg; | ||
870 | BUG_ON(count_sg > TOTAL_SG_ENTRY); | ||
868 | 871 | ||
869 | /* Build the scatter gather lists */ | 872 | /* Build the scatter gather lists */ |
870 | if (count_sg) { | 873 | if (count_sg) { |
871 | scb->sg_len = (u32) (count_sg * 8); | 874 | scb->sg_len = cpu_to_le32((u32) (count_sg * 8)); |
872 | scsi_for_each_sg(cmd, sg, count_sg, i) { | 875 | scsi_for_each_sg(cmd, sg, count_sg, i) { |
873 | sgent->base = (u32) sg_dma_address(sg); | 876 | sgent->base = cpu_to_le32((u32) sg_dma_address(sg)); |
874 | sgent->length = (u32) sg_dma_len(sg); | 877 | sgent->length = cpu_to_le32((u32) sg_dma_len(sg)); |
875 | sgent++; | 878 | sgent++; |
876 | } | 879 | } |
877 | } else { | 880 | } else { |
878 | scb->sg_len = 0; | 881 | scb->sg_len = cpu_to_le32(0); |
879 | sgent->base = 0; | 882 | sgent->base = cpu_to_le32(0); |
880 | sgent->length = 0; | 883 | sgent->length = cpu_to_le32(0); |
881 | } | 884 | } |
882 | scb->sg_addr = (u32) scb->sense_addr; | 885 | scb->sg_addr = (u32) scb->sense_addr; /* sense_addr is already little endian */ |
883 | scb->hastat = 0; | 886 | scb->hastat = 0; |
884 | scb->tastat = 0; | 887 | scb->tastat = 0; |
885 | scb->link = 0xFF; | 888 | scb->link = 0xFF; |
@@ -896,6 +899,7 @@ static void inia100_build_scb(struct orc_host * host, struct orc_scb * scb, stru | |||
896 | scb->tag_msg = 0; /* No tag support */ | 899 | scb->tag_msg = 0; /* No tag support */ |
897 | } | 900 | } |
898 | memcpy(scb->cdb, cmd->cmnd, scb->cdb_len); | 901 | memcpy(scb->cdb, cmd->cmnd, scb->cdb_len); |
902 | return 0; | ||
899 | } | 903 | } |
900 | 904 | ||
901 | /** | 905 | /** |
@@ -919,7 +923,10 @@ static int inia100_queue(struct scsi_cmnd * cmd, void (*done) (struct scsi_cmnd | |||
919 | if ((scb = orc_alloc_scb(host)) == NULL) | 923 | if ((scb = orc_alloc_scb(host)) == NULL) |
920 | return SCSI_MLQUEUE_HOST_BUSY; | 924 | return SCSI_MLQUEUE_HOST_BUSY; |
921 | 925 | ||
922 | inia100_build_scb(host, scb, cmd); | 926 | if (inia100_build_scb(host, scb, cmd)) { |
927 | orc_release_scb(host, scb); | ||
928 | return SCSI_MLQUEUE_HOST_BUSY; | ||
929 | } | ||
923 | orc_exec_scb(host, scb); /* Start execute SCB */ | 930 | orc_exec_scb(host, scb); /* Start execute SCB */ |
924 | return 0; | 931 | return 0; |
925 | } | 932 | } |