/** * pdc_get_initiator - Get the SCSI Interface Card params (SCSI ID, SDTR, SE or LVD) * @hwpath: fully bc.mod style path to the device. * @scsi_id: what someone told firmware the ID should be. * @period: time in cycles * @width: 8 or 16-bit wide bus * @mode: 0,1,2 -> SE,HVD,LVD signalling mode * * Get the SCSI operational parameters from PDC. * Needed since HPUX never used BIOS or symbios card NVRAM. * Most ncr/sym cards won't have an entry and just use whatever * capabilities of the card are (eg Ultra, LVD). But there are * several cases where it's useful: * o set SCSI id for Multi-initiator clusters, * o cable too long (ie SE scsi 10Mhz won't support 6m length), * o bus width exported is less than what the interface chip supports. */ int pdc_get_initiator(struct hardware_path *hwpath, unsigned char *scsi_id, unsigned long *period, char *width, char *mode) { int retval; spin_lock_irq(&pdc_lock); /* BCJ-XXXX series boxes. E.G. "9000/785/C3000" */ #define IS_SPROCKETS() (strlen(boot_cpu_data.pdc.sys_model_name) == 14 && \ strncmp(boot_cpu_data.pdc.sys_model_name, "9000/785", 8) == 0) retval = mem_pdc_call(PDC_INITIATOR, PDC_GET_INITIATOR, __pa(pdc_result), __pa(hwpath)); if (retval < PDC_OK) goto fail; *scsi_id = (unsigned char) pdc_result[0]; /* convert Bus speed in Mhz to period (in 1/10 ns) */ switch (pdc_result[1]) { /* * case 0: driver determines rate * case -1: Settings are uninitialized. */ case 5: *period = 2000; break; case 10: *period = 1000; break; case 20: *period = 500; break; case 40: *period = 250; break; case 80: *period = 125; break; default: /* Do nothing */ break; } /* * pdc_result[2] PDC suggested SCSI id * pdc_result[3] PDC suggested SCSI rate */ if (IS_SPROCKETS()) { /* 0 == 8-bit, 1 == 16-bit */ *width = (char) pdc_result[4]; /* ...in case someone needs it in the future. * sym53c8xx.c comments say it can't autodetect * for 825/825A/875 chips. * 0 == SE, 1 == HVD, 2 == LVD */ *mode = (char) pdc_result[5]; } fail: spin_unlock_irq(&pdc_lock); return (retval >= PDC_OK); }
/** * pdc_get_initiator - Get the SCSI Interface Card params (SCSI ID, SDTR, SE or LVD) * @hwpath: fully bc.mod style path to the device. * @initiator: the array to return the result into * * Get the SCSI operational parameters from PDC. * Needed since HPUX never used BIOS or symbios card NVRAM. * Most ncr/sym cards won't have an entry and just use whatever * capabilities of the card are (eg Ultra, LVD). But there are * several cases where it's useful: * o set SCSI id for Multi-initiator clusters, * o cable too long (ie SE scsi 10Mhz won't support 6m length), * o bus width exported is less than what the interface chip supports. */ int pdc_get_initiator(struct hardware_path *hwpath, struct pdc_initiator *initiator) { int retval; unsigned long flags; spin_lock_irqsave(&pdc_lock, flags); /* BCJ-XXXX series boxes. E.G. "9000/785/C3000" */ #define IS_SPROCKETS() (strlen(boot_cpu_data.pdc.sys_model_name) == 14 && \ strncmp(boot_cpu_data.pdc.sys_model_name, "9000/785", 8) == 0) retval = mem_pdc_call(PDC_INITIATOR, PDC_GET_INITIATOR, __pa(pdc_result), __pa(hwpath)); if (retval < PDC_OK) goto out; if (pdc_result[0] < 16) { initiator->host_id = pdc_result[0]; } else { initiator->host_id = -1; } /* * Sprockets and Piranha return 20 or 40 (MT/s). Prelude returns * 1, 2, 5 or 10 for 5, 10, 20 or 40 MT/s, respectively */ switch (pdc_result[1]) { case 1: initiator->factor = 50; break; case 2: initiator->factor = 25; break; case 5: initiator->factor = 12; break; case 25: initiator->factor = 10; break; case 20: initiator->factor = 12; break; case 40: initiator->factor = 10; break; default: initiator->factor = -1; break; } if (IS_SPROCKETS()) { initiator->width = pdc_result[4]; initiator->mode = pdc_result[5]; } else { initiator->width = -1; initiator->mode = -1; } out: spin_unlock_irqrestore(&pdc_lock, flags); return (retval >= PDC_OK); }