Commit 95d7e822 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull more ata updates from Niklas Cassel:

 - Add ATA_QUIRK_NOLPM for Samsung SSD 870 QVO drives (Daniel)

 - Ensure that PIO transfers using libata-sff cannot write outside the
   allocated buffer (me)

* tag 'ata-6.14-rc1-part2' of git://git.kernel.org/pub/scm/linux/kernel/git/libata/linux:
  ata: libata-sff: Ensure that we cannot write outside the allocated buffer
  ata: libata-core: Add ATA_QUIRK_NOLPM for Samsung SSD 870 QVO drives
parents c545cd32 6e74e53b
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -4143,6 +4143,10 @@ static const struct ata_dev_quirks_entry __ata_dev_quirks[] = {
	{ "Samsung SSD 860*",		NULL,	ATA_QUIRK_NO_NCQ_TRIM |
						ATA_QUIRK_ZERO_AFTER_TRIM |
						ATA_QUIRK_NO_NCQ_ON_ATI },
	{ "Samsung SSD 870 QVO*",	NULL,	ATA_QUIRK_NO_NCQ_TRIM |
						ATA_QUIRK_ZERO_AFTER_TRIM |
						ATA_QUIRK_NO_NCQ_ON_ATI |
						ATA_QUIRK_NOLPM },
	{ "Samsung SSD 870*",		NULL,	ATA_QUIRK_NO_NCQ_TRIM |
						ATA_QUIRK_ZERO_AFTER_TRIM |
						ATA_QUIRK_NO_NCQ_ON_ATI },
+10 −8
Original line number Diff line number Diff line
@@ -601,7 +601,7 @@ static void ata_pio_sector(struct ata_queued_cmd *qc)
{
	struct ata_port *ap = qc->ap;
	struct page *page;
	unsigned int offset;
	unsigned int offset, count;

	if (!qc->cursg) {
		qc->curbytes = qc->nbytes;
@@ -617,25 +617,27 @@ static void ata_pio_sector(struct ata_queued_cmd *qc)
	page = nth_page(page, (offset >> PAGE_SHIFT));
	offset %= PAGE_SIZE;

	trace_ata_sff_pio_transfer_data(qc, offset, qc->sect_size);
	/* don't overrun current sg */
	count = min(qc->cursg->length - qc->cursg_ofs, qc->sect_size);

	trace_ata_sff_pio_transfer_data(qc, offset, count);

	/*
	 * Split the transfer when it splits a page boundary.  Note that the
	 * split still has to be dword aligned like all ATA data transfers.
	 */
	WARN_ON_ONCE(offset % 4);
	if (offset + qc->sect_size > PAGE_SIZE) {
	if (offset + count > PAGE_SIZE) {
		unsigned int split_len = PAGE_SIZE - offset;

		ata_pio_xfer(qc, page, offset, split_len);
		ata_pio_xfer(qc, nth_page(page, 1), 0,
			     qc->sect_size - split_len);
		ata_pio_xfer(qc, nth_page(page, 1), 0, count - split_len);
	} else {
		ata_pio_xfer(qc, page, offset, qc->sect_size);
		ata_pio_xfer(qc, page, offset, count);
	}

	qc->curbytes += qc->sect_size;
	qc->cursg_ofs += qc->sect_size;
	qc->curbytes += count;
	qc->cursg_ofs += count;

	if (qc->cursg_ofs == qc->cursg->length) {
		qc->cursg = sg_next(qc->cursg);