Loading drivers/scsi/advansys.c +107 −275 Original line number Diff line number Diff line Loading @@ -12931,6 +12931,78 @@ static void AdvBuildCarrierFreelist(struct adv_dvc_var *asc_dvc) } while (buf_size > 0); } /* * Load the Microcode * * Write the microcode image to RISC memory starting at address 0. * * The microcode is stored compressed in the following format: * * 254 word (508 byte) table indexed by byte code followed * by the following byte codes: * * 1-Byte Code: * 00: Emit word 0 in table. * 01: Emit word 1 in table. * . * FD: Emit word 253 in table. * * Multi-Byte Code: * FE WW WW: (3 byte code) Word to emit is the next word WW WW. * FF BB WW WW: (4 byte code) Emit BB count times next word WW WW. * * Returns 0 or an error if the checksum doesn't match */ static int AdvLoadMicrocode(AdvPortAddr iop_base, unsigned char *buf, int size, int memsize, int chksum) { int i, j, end, len = 0; ADV_DCNT sum; AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0); for (i = 253 * 2; i < size; i++) { if (buf[i] == 0xff) { unsigned short word = (buf[i + 3] << 8) | buf[i + 2]; for (j = 0; j < buf[i + 1]; j++) { AdvWriteWordAutoIncLram(iop_base, word); len += 2; } i += 3; } else if (buf[i] == 0xfe) { unsigned short word = (buf[i + 2] << 8) | buf[i + 1]; AdvWriteWordAutoIncLram(iop_base, word); i += 2; len += 2; } else { unsigned char off = buf[i] * 2; unsigned short word = (buf[off + 1] << 8) | buf[off]; AdvWriteWordAutoIncLram(iop_base, word); len += 2; } } end = len; while (len < memsize) { AdvWriteWordAutoIncLram(iop_base, 0); len += 2; } /* Verify the microcode checksum. */ sum = 0; AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0); for (len = 0; len < end; len += 2) { sum += AdvReadWordAutoIncLram(iop_base); } if (sum != chksum) return ASC_IERR_MCODE_CHKSUM; return 0; } /* * Initialize the ASC-3550. * Loading @@ -12945,13 +13017,10 @@ static int AdvInitAsc3550Driver(ADV_DVC_VAR *asc_dvc) { AdvPortAddr iop_base; ushort warn_code; ADV_DCNT sum; int begin_addr; int end_addr; ushort code_sum; int word; int j; int adv_asc3550_expanded_size; int i; ushort scsi_cfg1; uchar tid; Loading @@ -12960,15 +13029,14 @@ static int AdvInitAsc3550Driver(ADV_DVC_VAR *asc_dvc) uchar max_cmd[ADV_MAX_TID + 1]; /* If there is already an error, don't continue. */ if (asc_dvc->err_code != 0) { if (asc_dvc->err_code != 0) return ADV_ERROR; } /* * The caller must set 'chip_type' to ADV_CHIP_ASC3550. */ if (asc_dvc->chip_type != ADV_CHIP_ASC3550) { asc_dvc->err_code |= ASC_IERR_BAD_CHIPTYPE; asc_dvc->err_code = ASC_IERR_BAD_CHIPTYPE; return ADV_ERROR; } Loading Loading @@ -13012,84 +13080,11 @@ static int AdvInitAsc3550Driver(ADV_DVC_VAR *asc_dvc) max_cmd[tid]); } /* * Load the Microcode * * Write the microcode image to RISC memory starting at address 0. */ AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0); /* Assume the following compressed format of the microcode buffer: * * 254 word (508 byte) table indexed by byte code followed * by the following byte codes: * * 1-Byte Code: * 00: Emit word 0 in table. * 01: Emit word 1 in table. * . * FD: Emit word 253 in table. * * Multi-Byte Code: * FE WW WW: (3 byte code) Word to emit is the next word WW WW. * FF BB WW WW: (4 byte code) Emit BB count times next word WW WW. */ word = 0; for (i = 253 * 2; i < _adv_asc3550_size; i++) { if (_adv_asc3550_buf[i] == 0xff) { for (j = 0; j < _adv_asc3550_buf[i + 1]; j++) { AdvWriteWordAutoIncLram(iop_base, (((ushort) _adv_asc3550_buf [i + 3] << 8) | _adv_asc3550_buf [i + 2])); word++; } i += 3; } else if (_adv_asc3550_buf[i] == 0xfe) { AdvWriteWordAutoIncLram(iop_base, (((ushort) _adv_asc3550_buf[i + 2] << 8) | _adv_asc3550_buf[i + 1])); i += 2; word++; } else { AdvWriteWordAutoIncLram(iop_base, (((ushort) _adv_asc3550_buf[(_adv_asc3550_buf[i] * 2) + 1] << 8) | _adv_asc3550_buf[_adv_asc3550_buf[i] * 2])); word++; } } /* * Set 'word' for later use to clear the rest of memory and save * the expanded mcode size. */ word *= 2; adv_asc3550_expanded_size = word; /* * Clear the rest of ASC-3550 Internal RAM (8KB). */ for (; word < ADV_3550_MEMSIZE; word += 2) { AdvWriteWordAutoIncLram(iop_base, 0); } /* * Verify the microcode checksum. */ sum = 0; AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0); for (word = 0; word < adv_asc3550_expanded_size; word += 2) { sum += AdvReadWordAutoIncLram(iop_base); } if (sum != _adv_asc3550_chksum) { asc_dvc->err_code |= ASC_IERR_MCODE_CHKSUM; asc_dvc->err_code = AdvLoadMicrocode(iop_base, _adv_asc3550_buf, _adv_asc3550_size, ADV_3550_MEMSIZE, _adv_asc3550_chksum); if (asc_dvc->err_code) return ADV_ERROR; } /* * Restore the RISC memory BIOS region. Loading Loading @@ -13460,13 +13455,10 @@ static int AdvInitAsc38C0800Driver(ADV_DVC_VAR *asc_dvc) { AdvPortAddr iop_base; ushort warn_code; ADV_DCNT sum; int begin_addr; int end_addr; ushort code_sum; int word; int j; int adv_asc38C0800_expanded_size; int i; ushort scsi_cfg1; uchar byte; Loading @@ -13476,9 +13468,8 @@ static int AdvInitAsc38C0800Driver(ADV_DVC_VAR *asc_dvc) uchar max_cmd[ADV_MAX_TID + 1]; /* If there is already an error, don't continue. */ if (asc_dvc->err_code != 0) { if (asc_dvc->err_code != 0) return ADV_ERROR; } /* * The caller must set 'chip_type' to ADV_CHIP_ASC38C0800. Loading Loading @@ -13550,7 +13541,7 @@ static int AdvInitAsc38C0800Driver(ADV_DVC_VAR *asc_dvc) byte = AdvReadByteRegister(iop_base, IOPB_RAM_BIST); if ((byte & RAM_TEST_DONE) == 0 || (byte & 0x0F) != PRE_TEST_VALUE) { asc_dvc->err_code |= ASC_IERR_BIST_PRE_TEST; asc_dvc->err_code = ASC_IERR_BIST_PRE_TEST; return ADV_ERROR; } Loading @@ -13558,7 +13549,7 @@ static int AdvInitAsc38C0800Driver(ADV_DVC_VAR *asc_dvc) DvcSleepMilliSecond(10); /* Wait for 10ms before reading back. */ if (AdvReadByteRegister(iop_base, IOPB_RAM_BIST) != NORMAL_VALUE) { asc_dvc->err_code |= ASC_IERR_BIST_PRE_TEST; asc_dvc->err_code = ASC_IERR_BIST_PRE_TEST; return ADV_ERROR; } } Loading @@ -13577,99 +13568,18 @@ static int AdvInitAsc38C0800Driver(ADV_DVC_VAR *asc_dvc) if ((byte & RAM_TEST_DONE) == 0 || (byte & RAM_TEST_STATUS) != 0) { /* Get here if Done bit not set or Status not 0. */ asc_dvc->bist_err_code = byte; /* for BIOS display message */ asc_dvc->err_code |= ASC_IERR_BIST_RAM_TEST; asc_dvc->err_code = ASC_IERR_BIST_RAM_TEST; return ADV_ERROR; } /* We need to reset back to normal mode after LRAM test passes. */ AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, NORMAL_MODE); /* * Load the Microcode * * Write the microcode image to RISC memory starting at address 0. * */ AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0); /* Assume the following compressed format of the microcode buffer: * * 254 word (508 byte) table indexed by byte code followed * by the following byte codes: * * 1-Byte Code: * 00: Emit word 0 in table. * 01: Emit word 1 in table. * . * FD: Emit word 253 in table. * * Multi-Byte Code: * FE WW WW: (3 byte code) Word to emit is the next word WW WW. * FF BB WW WW: (4 byte code) Emit BB count times next word WW WW. */ word = 0; for (i = 253 * 2; i < _adv_asc38C0800_size; i++) { if (_adv_asc38C0800_buf[i] == 0xff) { for (j = 0; j < _adv_asc38C0800_buf[i + 1]; j++) { AdvWriteWordAutoIncLram(iop_base, (((ushort) _adv_asc38C0800_buf [i + 3] << 8) | _adv_asc38C0800_buf [i + 2])); word++; } i += 3; } else if (_adv_asc38C0800_buf[i] == 0xfe) { AdvWriteWordAutoIncLram(iop_base, (((ushort) _adv_asc38C0800_buf [i + 2] << 8) | _adv_asc38C0800_buf[i + 1])); i += 2; word++; } else { AdvWriteWordAutoIncLram(iop_base, (((ushort) _adv_asc38C0800_buf[(_adv_asc38C0800_buf[i] * 2) + 1] << 8) | _adv_asc38C0800_buf[_adv_asc38C0800_buf[i] * 2])); word++; } } /* * Set 'word' for later use to clear the rest of memory and save * the expanded mcode size. */ word *= 2; adv_asc38C0800_expanded_size = word; /* * Clear the rest of ASC-38C0800 Internal RAM (16KB). */ for (; word < ADV_38C0800_MEMSIZE; word += 2) { AdvWriteWordAutoIncLram(iop_base, 0); } /* * Verify the microcode checksum. */ sum = 0; AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0); for (word = 0; word < adv_asc38C0800_expanded_size; word += 2) { sum += AdvReadWordAutoIncLram(iop_base); } ASC_DBG2(1, "AdvInitAsc38C0800Driver: word %d, i %d\n", word, i); ASC_DBG2(1, "AdvInitAsc38C0800Driver: sum 0x%lx, _adv_asc38C0800_chksum 0x%lx\n", (ulong)sum, (ulong)_adv_asc38C0800_chksum); if (sum != _adv_asc38C0800_chksum) { asc_dvc->err_code |= ASC_IERR_MCODE_CHKSUM; asc_dvc->err_code = AdvLoadMicrocode(iop_base, _adv_asc38C0800_buf, _adv_asc38C0800_size, ADV_38C0800_MEMSIZE, _adv_asc38C0800_chksum); if (asc_dvc->err_code) return ADV_ERROR; } /* * Restore the RISC memory BIOS region. Loading Loading @@ -13807,16 +13717,18 @@ static int AdvInitAsc38C0800Driver(ADV_DVC_VAR *asc_dvc) } /* * All kind of combinations of devices attached to one of four connectors * are acceptable except HVD device attached. For example, LVD device can * be attached to SE connector while SE device attached to LVD connector. * If LVD device attached to SE connector, it only runs up to Ultra speed. * All kind of combinations of devices attached to one of four * connectors are acceptable except HVD device attached. For example, * LVD device can be attached to SE connector while SE device attached * to LVD connector. If LVD device attached to SE connector, it only * runs up to Ultra speed. * * If an HVD device is attached to one of LVD connectors, return an error. * However, there is no way to detect HVD device attached to SE connectors. * If an HVD device is attached to one of LVD connectors, return an * error. However, there is no way to detect HVD device attached to * SE connectors. */ if (scsi_cfg1 & HVD) { asc_dvc->err_code |= ASC_IERR_HVD_DEVICE; asc_dvc->err_code = ASC_IERR_HVD_DEVICE; return ADV_ERROR; } Loading @@ -13825,8 +13737,8 @@ static int AdvInitAsc38C0800Driver(ADV_DVC_VAR *asc_dvc) * set the termination value based on a table listed in a_condor.h. * * If manual termination was specified with an EEPROM setting then * 'termination' was set-up in AdvInitFrom38C0800EEPROM() and is ready to * be 'ored' into SCSI_CFG1. * 'termination' was set-up in AdvInitFrom38C0800EEPROM() and is ready * to be 'ored' into SCSI_CFG1. */ if ((asc_dvc->cfg->termination & TERM_SE) == 0) { /* SE automatic termination control is enabled. */ Loading Loading @@ -13872,9 +13784,9 @@ static int AdvInitAsc38C0800Driver(ADV_DVC_VAR *asc_dvc) scsi_cfg1 |= (~asc_dvc->cfg->termination & 0xF0); /* * Clear BIG_ENDIAN, DIS_TERM_DRV, Terminator Polarity and HVD/LVD/SE bits * and set possibly modified termination control bits in the Microcode * SCSI_CFG1 Register Value. * Clear BIG_ENDIAN, DIS_TERM_DRV, Terminator Polarity and HVD/LVD/SE * bits and set possibly modified termination control bits in the * Microcode SCSI_CFG1 Register Value. */ scsi_cfg1 &= (~BIG_ENDIAN & ~DIS_TERM_DRV & ~TERM_POL & ~HVD_LVD_SE); Loading Loading @@ -14022,13 +13934,10 @@ static int AdvInitAsc38C1600Driver(ADV_DVC_VAR *asc_dvc) { AdvPortAddr iop_base; ushort warn_code; ADV_DCNT sum; int begin_addr; int end_addr; ushort code_sum; long word; int j; int adv_asc38C1600_expanded_size; int i; ushort scsi_cfg1; uchar byte; Loading Loading @@ -14113,7 +14022,7 @@ static int AdvInitAsc38C1600Driver(ADV_DVC_VAR *asc_dvc) byte = AdvReadByteRegister(iop_base, IOPB_RAM_BIST); if ((byte & RAM_TEST_DONE) == 0 || (byte & 0x0F) != PRE_TEST_VALUE) { asc_dvc->err_code |= ASC_IERR_BIST_PRE_TEST; asc_dvc->err_code = ASC_IERR_BIST_PRE_TEST; return ADV_ERROR; } Loading @@ -14121,7 +14030,7 @@ static int AdvInitAsc38C1600Driver(ADV_DVC_VAR *asc_dvc) DvcSleepMilliSecond(10); /* Wait for 10ms before reading back. */ if (AdvReadByteRegister(iop_base, IOPB_RAM_BIST) != NORMAL_VALUE) { asc_dvc->err_code |= ASC_IERR_BIST_PRE_TEST; asc_dvc->err_code = ASC_IERR_BIST_PRE_TEST; return ADV_ERROR; } } Loading @@ -14140,95 +14049,18 @@ static int AdvInitAsc38C1600Driver(ADV_DVC_VAR *asc_dvc) if ((byte & RAM_TEST_DONE) == 0 || (byte & RAM_TEST_STATUS) != 0) { /* Get here if Done bit not set or Status not 0. */ asc_dvc->bist_err_code = byte; /* for BIOS display message */ asc_dvc->err_code |= ASC_IERR_BIST_RAM_TEST; asc_dvc->err_code = ASC_IERR_BIST_RAM_TEST; return ADV_ERROR; } /* We need to reset back to normal mode after LRAM test passes. */ AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, NORMAL_MODE); /* * Load the Microcode * * Write the microcode image to RISC memory starting at address 0. * */ AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0); /* * Assume the following compressed format of the microcode buffer: * * 254 word (508 byte) table indexed by byte code followed * by the following byte codes: * * 1-Byte Code: * 00: Emit word 0 in table. * 01: Emit word 1 in table. * . * FD: Emit word 253 in table. * * Multi-Byte Code: * FE WW WW: (3 byte code) Word to emit is the next word WW WW. * FF BB WW WW: (4 byte code) Emit BB count times next word WW WW. */ word = 0; for (i = 253 * 2; i < _adv_asc38C1600_size; i++) { if (_adv_asc38C1600_buf[i] == 0xff) { for (j = 0; j < _adv_asc38C1600_buf[i + 1]; j++) { AdvWriteWordAutoIncLram(iop_base, (((ushort) _adv_asc38C1600_buf [i + 3] << 8) | _adv_asc38C1600_buf [i + 2])); word++; } i += 3; } else if (_adv_asc38C1600_buf[i] == 0xfe) { AdvWriteWordAutoIncLram(iop_base, (((ushort) _adv_asc38C1600_buf [i + 2] << 8) | _adv_asc38C1600_buf[i + 1])); i += 2; word++; } else { AdvWriteWordAutoIncLram(iop_base, (((ushort) _adv_asc38C1600_buf[(_adv_asc38C1600_buf[i] * 2) + 1] << 8) | _adv_asc38C1600_buf[_adv_asc38C1600_buf[i] * 2])); word++; } } /* * Set 'word' for later use to clear the rest of memory and save * the expanded mcode size. */ word *= 2; adv_asc38C1600_expanded_size = word; /* * Clear the rest of ASC-38C1600 Internal RAM (32KB). */ for (; word < ADV_38C1600_MEMSIZE; word += 2) { AdvWriteWordAutoIncLram(iop_base, 0); } /* * Verify the microcode checksum. */ sum = 0; AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0); for (word = 0; word < adv_asc38C1600_expanded_size; word += 2) { sum += AdvReadWordAutoIncLram(iop_base); } if (sum != _adv_asc38C1600_chksum) { asc_dvc->err_code |= ASC_IERR_MCODE_CHKSUM; asc_dvc->err_code = AdvLoadMicrocode(iop_base, _adv_asc38C1600_buf, _adv_asc38C1600_size, ADV_38C1600_MEMSIZE, _adv_asc38C1600_chksum); if (asc_dvc->err_code) return ADV_ERROR; } /* * Restore the RISC memory BIOS region. Loading Loading
drivers/scsi/advansys.c +107 −275 Original line number Diff line number Diff line Loading @@ -12931,6 +12931,78 @@ static void AdvBuildCarrierFreelist(struct adv_dvc_var *asc_dvc) } while (buf_size > 0); } /* * Load the Microcode * * Write the microcode image to RISC memory starting at address 0. * * The microcode is stored compressed in the following format: * * 254 word (508 byte) table indexed by byte code followed * by the following byte codes: * * 1-Byte Code: * 00: Emit word 0 in table. * 01: Emit word 1 in table. * . * FD: Emit word 253 in table. * * Multi-Byte Code: * FE WW WW: (3 byte code) Word to emit is the next word WW WW. * FF BB WW WW: (4 byte code) Emit BB count times next word WW WW. * * Returns 0 or an error if the checksum doesn't match */ static int AdvLoadMicrocode(AdvPortAddr iop_base, unsigned char *buf, int size, int memsize, int chksum) { int i, j, end, len = 0; ADV_DCNT sum; AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0); for (i = 253 * 2; i < size; i++) { if (buf[i] == 0xff) { unsigned short word = (buf[i + 3] << 8) | buf[i + 2]; for (j = 0; j < buf[i + 1]; j++) { AdvWriteWordAutoIncLram(iop_base, word); len += 2; } i += 3; } else if (buf[i] == 0xfe) { unsigned short word = (buf[i + 2] << 8) | buf[i + 1]; AdvWriteWordAutoIncLram(iop_base, word); i += 2; len += 2; } else { unsigned char off = buf[i] * 2; unsigned short word = (buf[off + 1] << 8) | buf[off]; AdvWriteWordAutoIncLram(iop_base, word); len += 2; } } end = len; while (len < memsize) { AdvWriteWordAutoIncLram(iop_base, 0); len += 2; } /* Verify the microcode checksum. */ sum = 0; AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0); for (len = 0; len < end; len += 2) { sum += AdvReadWordAutoIncLram(iop_base); } if (sum != chksum) return ASC_IERR_MCODE_CHKSUM; return 0; } /* * Initialize the ASC-3550. * Loading @@ -12945,13 +13017,10 @@ static int AdvInitAsc3550Driver(ADV_DVC_VAR *asc_dvc) { AdvPortAddr iop_base; ushort warn_code; ADV_DCNT sum; int begin_addr; int end_addr; ushort code_sum; int word; int j; int adv_asc3550_expanded_size; int i; ushort scsi_cfg1; uchar tid; Loading @@ -12960,15 +13029,14 @@ static int AdvInitAsc3550Driver(ADV_DVC_VAR *asc_dvc) uchar max_cmd[ADV_MAX_TID + 1]; /* If there is already an error, don't continue. */ if (asc_dvc->err_code != 0) { if (asc_dvc->err_code != 0) return ADV_ERROR; } /* * The caller must set 'chip_type' to ADV_CHIP_ASC3550. */ if (asc_dvc->chip_type != ADV_CHIP_ASC3550) { asc_dvc->err_code |= ASC_IERR_BAD_CHIPTYPE; asc_dvc->err_code = ASC_IERR_BAD_CHIPTYPE; return ADV_ERROR; } Loading Loading @@ -13012,84 +13080,11 @@ static int AdvInitAsc3550Driver(ADV_DVC_VAR *asc_dvc) max_cmd[tid]); } /* * Load the Microcode * * Write the microcode image to RISC memory starting at address 0. */ AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0); /* Assume the following compressed format of the microcode buffer: * * 254 word (508 byte) table indexed by byte code followed * by the following byte codes: * * 1-Byte Code: * 00: Emit word 0 in table. * 01: Emit word 1 in table. * . * FD: Emit word 253 in table. * * Multi-Byte Code: * FE WW WW: (3 byte code) Word to emit is the next word WW WW. * FF BB WW WW: (4 byte code) Emit BB count times next word WW WW. */ word = 0; for (i = 253 * 2; i < _adv_asc3550_size; i++) { if (_adv_asc3550_buf[i] == 0xff) { for (j = 0; j < _adv_asc3550_buf[i + 1]; j++) { AdvWriteWordAutoIncLram(iop_base, (((ushort) _adv_asc3550_buf [i + 3] << 8) | _adv_asc3550_buf [i + 2])); word++; } i += 3; } else if (_adv_asc3550_buf[i] == 0xfe) { AdvWriteWordAutoIncLram(iop_base, (((ushort) _adv_asc3550_buf[i + 2] << 8) | _adv_asc3550_buf[i + 1])); i += 2; word++; } else { AdvWriteWordAutoIncLram(iop_base, (((ushort) _adv_asc3550_buf[(_adv_asc3550_buf[i] * 2) + 1] << 8) | _adv_asc3550_buf[_adv_asc3550_buf[i] * 2])); word++; } } /* * Set 'word' for later use to clear the rest of memory and save * the expanded mcode size. */ word *= 2; adv_asc3550_expanded_size = word; /* * Clear the rest of ASC-3550 Internal RAM (8KB). */ for (; word < ADV_3550_MEMSIZE; word += 2) { AdvWriteWordAutoIncLram(iop_base, 0); } /* * Verify the microcode checksum. */ sum = 0; AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0); for (word = 0; word < adv_asc3550_expanded_size; word += 2) { sum += AdvReadWordAutoIncLram(iop_base); } if (sum != _adv_asc3550_chksum) { asc_dvc->err_code |= ASC_IERR_MCODE_CHKSUM; asc_dvc->err_code = AdvLoadMicrocode(iop_base, _adv_asc3550_buf, _adv_asc3550_size, ADV_3550_MEMSIZE, _adv_asc3550_chksum); if (asc_dvc->err_code) return ADV_ERROR; } /* * Restore the RISC memory BIOS region. Loading Loading @@ -13460,13 +13455,10 @@ static int AdvInitAsc38C0800Driver(ADV_DVC_VAR *asc_dvc) { AdvPortAddr iop_base; ushort warn_code; ADV_DCNT sum; int begin_addr; int end_addr; ushort code_sum; int word; int j; int adv_asc38C0800_expanded_size; int i; ushort scsi_cfg1; uchar byte; Loading @@ -13476,9 +13468,8 @@ static int AdvInitAsc38C0800Driver(ADV_DVC_VAR *asc_dvc) uchar max_cmd[ADV_MAX_TID + 1]; /* If there is already an error, don't continue. */ if (asc_dvc->err_code != 0) { if (asc_dvc->err_code != 0) return ADV_ERROR; } /* * The caller must set 'chip_type' to ADV_CHIP_ASC38C0800. Loading Loading @@ -13550,7 +13541,7 @@ static int AdvInitAsc38C0800Driver(ADV_DVC_VAR *asc_dvc) byte = AdvReadByteRegister(iop_base, IOPB_RAM_BIST); if ((byte & RAM_TEST_DONE) == 0 || (byte & 0x0F) != PRE_TEST_VALUE) { asc_dvc->err_code |= ASC_IERR_BIST_PRE_TEST; asc_dvc->err_code = ASC_IERR_BIST_PRE_TEST; return ADV_ERROR; } Loading @@ -13558,7 +13549,7 @@ static int AdvInitAsc38C0800Driver(ADV_DVC_VAR *asc_dvc) DvcSleepMilliSecond(10); /* Wait for 10ms before reading back. */ if (AdvReadByteRegister(iop_base, IOPB_RAM_BIST) != NORMAL_VALUE) { asc_dvc->err_code |= ASC_IERR_BIST_PRE_TEST; asc_dvc->err_code = ASC_IERR_BIST_PRE_TEST; return ADV_ERROR; } } Loading @@ -13577,99 +13568,18 @@ static int AdvInitAsc38C0800Driver(ADV_DVC_VAR *asc_dvc) if ((byte & RAM_TEST_DONE) == 0 || (byte & RAM_TEST_STATUS) != 0) { /* Get here if Done bit not set or Status not 0. */ asc_dvc->bist_err_code = byte; /* for BIOS display message */ asc_dvc->err_code |= ASC_IERR_BIST_RAM_TEST; asc_dvc->err_code = ASC_IERR_BIST_RAM_TEST; return ADV_ERROR; } /* We need to reset back to normal mode after LRAM test passes. */ AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, NORMAL_MODE); /* * Load the Microcode * * Write the microcode image to RISC memory starting at address 0. * */ AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0); /* Assume the following compressed format of the microcode buffer: * * 254 word (508 byte) table indexed by byte code followed * by the following byte codes: * * 1-Byte Code: * 00: Emit word 0 in table. * 01: Emit word 1 in table. * . * FD: Emit word 253 in table. * * Multi-Byte Code: * FE WW WW: (3 byte code) Word to emit is the next word WW WW. * FF BB WW WW: (4 byte code) Emit BB count times next word WW WW. */ word = 0; for (i = 253 * 2; i < _adv_asc38C0800_size; i++) { if (_adv_asc38C0800_buf[i] == 0xff) { for (j = 0; j < _adv_asc38C0800_buf[i + 1]; j++) { AdvWriteWordAutoIncLram(iop_base, (((ushort) _adv_asc38C0800_buf [i + 3] << 8) | _adv_asc38C0800_buf [i + 2])); word++; } i += 3; } else if (_adv_asc38C0800_buf[i] == 0xfe) { AdvWriteWordAutoIncLram(iop_base, (((ushort) _adv_asc38C0800_buf [i + 2] << 8) | _adv_asc38C0800_buf[i + 1])); i += 2; word++; } else { AdvWriteWordAutoIncLram(iop_base, (((ushort) _adv_asc38C0800_buf[(_adv_asc38C0800_buf[i] * 2) + 1] << 8) | _adv_asc38C0800_buf[_adv_asc38C0800_buf[i] * 2])); word++; } } /* * Set 'word' for later use to clear the rest of memory and save * the expanded mcode size. */ word *= 2; adv_asc38C0800_expanded_size = word; /* * Clear the rest of ASC-38C0800 Internal RAM (16KB). */ for (; word < ADV_38C0800_MEMSIZE; word += 2) { AdvWriteWordAutoIncLram(iop_base, 0); } /* * Verify the microcode checksum. */ sum = 0; AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0); for (word = 0; word < adv_asc38C0800_expanded_size; word += 2) { sum += AdvReadWordAutoIncLram(iop_base); } ASC_DBG2(1, "AdvInitAsc38C0800Driver: word %d, i %d\n", word, i); ASC_DBG2(1, "AdvInitAsc38C0800Driver: sum 0x%lx, _adv_asc38C0800_chksum 0x%lx\n", (ulong)sum, (ulong)_adv_asc38C0800_chksum); if (sum != _adv_asc38C0800_chksum) { asc_dvc->err_code |= ASC_IERR_MCODE_CHKSUM; asc_dvc->err_code = AdvLoadMicrocode(iop_base, _adv_asc38C0800_buf, _adv_asc38C0800_size, ADV_38C0800_MEMSIZE, _adv_asc38C0800_chksum); if (asc_dvc->err_code) return ADV_ERROR; } /* * Restore the RISC memory BIOS region. Loading Loading @@ -13807,16 +13717,18 @@ static int AdvInitAsc38C0800Driver(ADV_DVC_VAR *asc_dvc) } /* * All kind of combinations of devices attached to one of four connectors * are acceptable except HVD device attached. For example, LVD device can * be attached to SE connector while SE device attached to LVD connector. * If LVD device attached to SE connector, it only runs up to Ultra speed. * All kind of combinations of devices attached to one of four * connectors are acceptable except HVD device attached. For example, * LVD device can be attached to SE connector while SE device attached * to LVD connector. If LVD device attached to SE connector, it only * runs up to Ultra speed. * * If an HVD device is attached to one of LVD connectors, return an error. * However, there is no way to detect HVD device attached to SE connectors. * If an HVD device is attached to one of LVD connectors, return an * error. However, there is no way to detect HVD device attached to * SE connectors. */ if (scsi_cfg1 & HVD) { asc_dvc->err_code |= ASC_IERR_HVD_DEVICE; asc_dvc->err_code = ASC_IERR_HVD_DEVICE; return ADV_ERROR; } Loading @@ -13825,8 +13737,8 @@ static int AdvInitAsc38C0800Driver(ADV_DVC_VAR *asc_dvc) * set the termination value based on a table listed in a_condor.h. * * If manual termination was specified with an EEPROM setting then * 'termination' was set-up in AdvInitFrom38C0800EEPROM() and is ready to * be 'ored' into SCSI_CFG1. * 'termination' was set-up in AdvInitFrom38C0800EEPROM() and is ready * to be 'ored' into SCSI_CFG1. */ if ((asc_dvc->cfg->termination & TERM_SE) == 0) { /* SE automatic termination control is enabled. */ Loading Loading @@ -13872,9 +13784,9 @@ static int AdvInitAsc38C0800Driver(ADV_DVC_VAR *asc_dvc) scsi_cfg1 |= (~asc_dvc->cfg->termination & 0xF0); /* * Clear BIG_ENDIAN, DIS_TERM_DRV, Terminator Polarity and HVD/LVD/SE bits * and set possibly modified termination control bits in the Microcode * SCSI_CFG1 Register Value. * Clear BIG_ENDIAN, DIS_TERM_DRV, Terminator Polarity and HVD/LVD/SE * bits and set possibly modified termination control bits in the * Microcode SCSI_CFG1 Register Value. */ scsi_cfg1 &= (~BIG_ENDIAN & ~DIS_TERM_DRV & ~TERM_POL & ~HVD_LVD_SE); Loading Loading @@ -14022,13 +13934,10 @@ static int AdvInitAsc38C1600Driver(ADV_DVC_VAR *asc_dvc) { AdvPortAddr iop_base; ushort warn_code; ADV_DCNT sum; int begin_addr; int end_addr; ushort code_sum; long word; int j; int adv_asc38C1600_expanded_size; int i; ushort scsi_cfg1; uchar byte; Loading Loading @@ -14113,7 +14022,7 @@ static int AdvInitAsc38C1600Driver(ADV_DVC_VAR *asc_dvc) byte = AdvReadByteRegister(iop_base, IOPB_RAM_BIST); if ((byte & RAM_TEST_DONE) == 0 || (byte & 0x0F) != PRE_TEST_VALUE) { asc_dvc->err_code |= ASC_IERR_BIST_PRE_TEST; asc_dvc->err_code = ASC_IERR_BIST_PRE_TEST; return ADV_ERROR; } Loading @@ -14121,7 +14030,7 @@ static int AdvInitAsc38C1600Driver(ADV_DVC_VAR *asc_dvc) DvcSleepMilliSecond(10); /* Wait for 10ms before reading back. */ if (AdvReadByteRegister(iop_base, IOPB_RAM_BIST) != NORMAL_VALUE) { asc_dvc->err_code |= ASC_IERR_BIST_PRE_TEST; asc_dvc->err_code = ASC_IERR_BIST_PRE_TEST; return ADV_ERROR; } } Loading @@ -14140,95 +14049,18 @@ static int AdvInitAsc38C1600Driver(ADV_DVC_VAR *asc_dvc) if ((byte & RAM_TEST_DONE) == 0 || (byte & RAM_TEST_STATUS) != 0) { /* Get here if Done bit not set or Status not 0. */ asc_dvc->bist_err_code = byte; /* for BIOS display message */ asc_dvc->err_code |= ASC_IERR_BIST_RAM_TEST; asc_dvc->err_code = ASC_IERR_BIST_RAM_TEST; return ADV_ERROR; } /* We need to reset back to normal mode after LRAM test passes. */ AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, NORMAL_MODE); /* * Load the Microcode * * Write the microcode image to RISC memory starting at address 0. * */ AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0); /* * Assume the following compressed format of the microcode buffer: * * 254 word (508 byte) table indexed by byte code followed * by the following byte codes: * * 1-Byte Code: * 00: Emit word 0 in table. * 01: Emit word 1 in table. * . * FD: Emit word 253 in table. * * Multi-Byte Code: * FE WW WW: (3 byte code) Word to emit is the next word WW WW. * FF BB WW WW: (4 byte code) Emit BB count times next word WW WW. */ word = 0; for (i = 253 * 2; i < _adv_asc38C1600_size; i++) { if (_adv_asc38C1600_buf[i] == 0xff) { for (j = 0; j < _adv_asc38C1600_buf[i + 1]; j++) { AdvWriteWordAutoIncLram(iop_base, (((ushort) _adv_asc38C1600_buf [i + 3] << 8) | _adv_asc38C1600_buf [i + 2])); word++; } i += 3; } else if (_adv_asc38C1600_buf[i] == 0xfe) { AdvWriteWordAutoIncLram(iop_base, (((ushort) _adv_asc38C1600_buf [i + 2] << 8) | _adv_asc38C1600_buf[i + 1])); i += 2; word++; } else { AdvWriteWordAutoIncLram(iop_base, (((ushort) _adv_asc38C1600_buf[(_adv_asc38C1600_buf[i] * 2) + 1] << 8) | _adv_asc38C1600_buf[_adv_asc38C1600_buf[i] * 2])); word++; } } /* * Set 'word' for later use to clear the rest of memory and save * the expanded mcode size. */ word *= 2; adv_asc38C1600_expanded_size = word; /* * Clear the rest of ASC-38C1600 Internal RAM (32KB). */ for (; word < ADV_38C1600_MEMSIZE; word += 2) { AdvWriteWordAutoIncLram(iop_base, 0); } /* * Verify the microcode checksum. */ sum = 0; AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0); for (word = 0; word < adv_asc38C1600_expanded_size; word += 2) { sum += AdvReadWordAutoIncLram(iop_base); } if (sum != _adv_asc38C1600_chksum) { asc_dvc->err_code |= ASC_IERR_MCODE_CHKSUM; asc_dvc->err_code = AdvLoadMicrocode(iop_base, _adv_asc38C1600_buf, _adv_asc38C1600_size, ADV_38C1600_MEMSIZE, _adv_asc38C1600_chksum); if (asc_dvc->err_code) return ADV_ERROR; } /* * Restore the RISC memory BIOS region. Loading