drivers/scsi/pm8001/pm8001_sas.c

Source file repositories/reference/linux-study-clean/drivers/scsi/pm8001/pm8001_sas.c

File Facts

System
Linux kernel
Corpus path
drivers/scsi/pm8001/pm8001_sas.c
Extension
.c
Size
36761 bytes
Lines
1265
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

if (qc) {
			*ata_op = qc->tf.command;
			*ata_tag = qc->tag;
		}
	}
}

u32 pm80xx_get_local_phy_id(struct domain_device *dev)
{
	struct pm8001_device *pm8001_dev = dev->lldd_dev;

	if (dev_parent_is_expander(dev))
		return dev->parent->ex_dev.ex_phy->phy_id;

	return pm8001_dev->attached_phy;
}

void pm80xx_show_pending_commands(struct pm8001_hba_info *pm8001_ha,
				  struct pm8001_device *target_pm8001_dev)
{
	int i = 0, ata_op = 0, ata_tag = -1;
	struct pm8001_ccb_info *ccb = NULL;
	struct sas_task *task = NULL;
	struct pm8001_device *pm8001_dev = NULL;
	bool task_aborted;

	for (i = 0; i < pm8001_ha->ccb_count; i++) {
		ccb = &pm8001_ha->ccb_info[i];
		if (ccb->ccb_tag == PM8001_INVALID_TAG)
			continue;
		pm8001_dev = ccb->device;
		if (target_pm8001_dev && pm8001_dev &&
		    target_pm8001_dev != pm8001_dev)
			continue;
		task = ccb->task;
		pm80xx_get_tag_opcodes(task, &ata_op, &ata_tag, &task_aborted);
		pm8001_dbg(pm8001_ha, FAIL,
			"tag %#x, device %#x task %p task aborted %d ata opcode %#x ata tag %d\n",
			ccb->ccb_tag,
			(pm8001_dev ? pm8001_dev->device_id : 0),
			task, task_aborted,
			ata_op, ata_tag);
	}
}

/**
 * pm8001_mem_alloc - allocate memory for pm8001.
 * @pdev: pci device.
 * @virt_addr: the allocated virtual address
 * @pphys_addr: DMA address for this device
 * @pphys_addr_hi: the physical address high byte address.
 * @pphys_addr_lo: the physical address low byte address.
 * @mem_size: memory size.
 * @align: requested byte alignment
 */
int pm8001_mem_alloc(struct pci_dev *pdev, void **virt_addr,
	dma_addr_t *pphys_addr, u32 *pphys_addr_hi,
	u32 *pphys_addr_lo, u32 mem_size, u32 align)
{
	caddr_t mem_virt_alloc;
	dma_addr_t mem_dma_handle;
	u64 phys_align;
	u64 align_offset = 0;
	if (align)
		align_offset = (dma_addr_t)align - 1;
	mem_virt_alloc = dma_alloc_coherent(&pdev->dev, mem_size + align,
					    &mem_dma_handle, GFP_KERNEL);
	if (!mem_virt_alloc)
		return -ENOMEM;
	*pphys_addr = mem_dma_handle;
	phys_align = (*pphys_addr + align_offset) & ~align_offset;
	*virt_addr = (void *)mem_virt_alloc + phys_align - *pphys_addr;
	*pphys_addr_hi = upper_32_bits(phys_align);
	*pphys_addr_lo = lower_32_bits(phys_align);
	return 0;
}

/**
  * pm8001_find_ha_by_dev - from domain device which come from sas layer to
  * find out our hba struct.
  * @dev: the domain device which from sas layer.
  */
static
struct pm8001_hba_info *pm8001_find_ha_by_dev(struct domain_device *dev)
{
	struct sas_ha_struct *sha = dev->port->ha;
	struct pm8001_hba_info *pm8001_ha = sha->lldd_ha;
	return pm8001_ha;
}

Annotation

Implementation Notes