drivers/scsi/aic7xxx/aic7xxx_pci.c

Source file repositories/reference/linux-study-clean/drivers/scsi/aic7xxx/aic7xxx_pci.c

File Facts

System
Linux kernel
Corpus path
drivers/scsi/aic7xxx/aic7xxx_pci.c
Extension
.c
Size
61690 bytes
Lines
2461
Domain
Driver Families
Bucket
drivers/scsi
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

switch (SUBID_9005_TYPE(subdevice)) {
		case SUBID_9005_TYPE_MB:
			break;
		case SUBID_9005_TYPE_CARD:
		case SUBID_9005_TYPE_LCCARD:
			/*
			 * Currently only trust Adaptec cards to
			 * get the sub device info correct.
			 */
			if (DEVID_9005_TYPE(device) == DEVID_9005_TYPE_HBA)
				result = 1;
			break;
		case SUBID_9005_TYPE_RAID:
			break;
		default:
			break;
		}
	}
	return (result);
}

const struct ahc_pci_identity *
ahc_find_pci_device(ahc_dev_softc_t pci)
{
	uint64_t  full_id;
	uint16_t  device;
	uint16_t  vendor;
	uint16_t  subdevice;
	uint16_t  subvendor;
	const struct ahc_pci_identity *entry;
	u_int	  i;

	vendor = ahc_pci_read_config(pci, PCIR_DEVVENDOR, /*bytes*/2);
	device = ahc_pci_read_config(pci, PCIR_DEVICE, /*bytes*/2);
	subvendor = ahc_pci_read_config(pci, PCI_SUBSYSTEM_VENDOR_ID, /*bytes*/2);
	subdevice = ahc_pci_read_config(pci, PCI_SUBSYSTEM_ID, /*bytes*/2);
	full_id = ahc_compose_id(device, vendor, subdevice, subvendor);

	/*
	 * If the second function is not hooked up, ignore it.
	 * Unfortunately, not all MB vendors implement the
	 * subdevice ID as per the Adaptec spec, so do our best
	 * to sanity check it prior to accepting the subdevice
	 * ID as valid.
	 */
	if (ahc_get_pci_function(pci) > 0
	 && ahc_9005_subdevinfo_valid(device, vendor, subdevice, subvendor)
	 && SUBID_9005_MFUNCENB(subdevice) == 0)
		return (NULL);

	for (i = 0; i < ahc_num_pci_devs; i++) {
		entry = &ahc_pci_ident_table[i];
		if (entry->full_id == (full_id & entry->id_mask)) {
			/* Honor exclusion entries. */
			if (entry->name == NULL)
				return (NULL);
			return (entry);
		}
	}
	return (NULL);
}

int
ahc_pci_config(struct ahc_softc *ahc, const struct ahc_pci_identity *entry)
{
	u_int	 command;
	u_int	 our_id;
	u_int	 sxfrctl1;
	u_int	 scsiseq;
	u_int	 dscommand0;
	uint32_t devconfig;
	int	 error;
	uint8_t	 sblkctl;

	our_id = 0;
	error = entry->setup(ahc);
	if (error != 0)
		return (error);
	ahc->chip |= AHC_PCI;
	ahc->description = entry->name;

	pci_set_power_state(ahc->dev_softc, AHC_POWER_STATE_D0);

	error = ahc_pci_map_registers(ahc);
	if (error != 0)
		return (error);

	/*
	 * Before we continue probing the card, ensure that
	 * its interrupts are *disabled*.  We don't want

Annotation

Implementation Notes